ActivityManagerService.java revision 6d51571835737c7502a2e111ee9dc2527ebad984
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.IUserSwitchObserver; 53import android.app.Instrumentation; 54import android.app.Notification; 55import android.app.NotificationManager; 56import android.app.PendingIntent; 57import android.app.backup.IBackupManager; 58import android.content.ActivityNotFoundException; 59import android.content.BroadcastReceiver; 60import android.content.ClipData; 61import android.content.ComponentCallbacks2; 62import android.content.ComponentName; 63import android.content.ContentProvider; 64import android.content.ContentResolver; 65import android.content.Context; 66import android.content.DialogInterface; 67import android.content.IContentProvider; 68import android.content.IIntentReceiver; 69import android.content.IIntentSender; 70import android.content.Intent; 71import android.content.IntentFilter; 72import android.content.IntentSender; 73import android.content.pm.ActivityInfo; 74import android.content.pm.ApplicationInfo; 75import android.content.pm.ConfigurationInfo; 76import android.content.pm.IPackageDataObserver; 77import android.content.pm.IPackageManager; 78import android.content.pm.InstrumentationInfo; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageManager; 81import android.content.pm.UserInfo; 82import android.content.pm.PackageManager.NameNotFoundException; 83import android.content.pm.PathPermission; 84import android.content.pm.ProviderInfo; 85import android.content.pm.ResolveInfo; 86import android.content.pm.ServiceInfo; 87import android.content.res.CompatibilityInfo; 88import android.content.res.Configuration; 89import android.graphics.Bitmap; 90import android.net.Proxy; 91import android.net.ProxyProperties; 92import android.net.Uri; 93import android.os.Binder; 94import android.os.Build; 95import android.os.Bundle; 96import android.os.Debug; 97import android.os.DropBoxManager; 98import android.os.Environment; 99import android.os.FileObserver; 100import android.os.FileUtils; 101import android.os.Handler; 102import android.os.IBinder; 103import android.os.IPermissionController; 104import android.os.IRemoteCallback; 105import android.os.IUserManager; 106import android.os.Looper; 107import android.os.Message; 108import android.os.Parcel; 109import android.os.ParcelFileDescriptor; 110import android.os.Process; 111import android.os.RemoteCallbackList; 112import android.os.RemoteException; 113import android.os.SELinux; 114import android.os.ServiceManager; 115import android.os.StrictMode; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.provider.Settings; 120import android.text.format.Time; 121import android.util.EventLog; 122import android.util.Log; 123import android.util.Pair; 124import android.util.PrintWriterPrinter; 125import android.util.Slog; 126import android.util.SparseArray; 127import android.util.TimeUtils; 128import android.view.Gravity; 129import android.view.LayoutInflater; 130import android.view.View; 131import android.view.WindowManager; 132import android.view.WindowManagerPolicy; 133 134import java.io.BufferedInputStream; 135import java.io.BufferedOutputStream; 136import java.io.BufferedReader; 137import java.io.DataInputStream; 138import java.io.DataOutputStream; 139import java.io.File; 140import java.io.FileDescriptor; 141import java.io.FileInputStream; 142import java.io.FileNotFoundException; 143import java.io.FileOutputStream; 144import java.io.IOException; 145import java.io.InputStreamReader; 146import java.io.PrintWriter; 147import java.io.StringWriter; 148import java.lang.ref.WeakReference; 149import java.util.ArrayList; 150import java.util.Arrays; 151import java.util.Collections; 152import java.util.Comparator; 153import java.util.HashMap; 154import java.util.HashSet; 155import java.util.Iterator; 156import java.util.List; 157import java.util.Locale; 158import java.util.Map; 159import java.util.Set; 160import java.util.concurrent.atomic.AtomicBoolean; 161import java.util.concurrent.atomic.AtomicLong; 162 163public final class ActivityManagerService extends ActivityManagerNative 164 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 165 private static final String USER_DATA_DIR = "/data/user/"; 166 static final String TAG = "ActivityManager"; 167 static final String TAG_MU = "ActivityManagerServiceMU"; 168 static final boolean DEBUG = false; 169 static final boolean localLOGV = DEBUG; 170 static final boolean DEBUG_SWITCH = localLOGV || false; 171 static final boolean DEBUG_TASKS = localLOGV || false; 172 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 173 static final boolean DEBUG_PAUSE = localLOGV || false; 174 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 175 static final boolean DEBUG_TRANSITION = localLOGV || false; 176 static final boolean DEBUG_BROADCAST = localLOGV || false; 177 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 178 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 179 static final boolean DEBUG_SERVICE = localLOGV || false; 180 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 181 static final boolean DEBUG_VISBILITY = localLOGV || false; 182 static final boolean DEBUG_PROCESSES = localLOGV || false; 183 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 184 static final boolean DEBUG_PROVIDER = localLOGV || false; 185 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 186 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 187 static final boolean DEBUG_RESULTS = localLOGV || false; 188 static final boolean DEBUG_BACKUP = localLOGV || false; 189 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 190 static final boolean DEBUG_POWER = localLOGV || false; 191 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 192 static final boolean DEBUG_MU = localLOGV || false; 193 static final boolean VALIDATE_TOKENS = false; 194 static final boolean SHOW_ACTIVITY_START_TIME = true; 195 196 // Control over CPU and battery monitoring. 197 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 198 static final boolean MONITOR_CPU_USAGE = true; 199 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 200 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 201 static final boolean MONITOR_THREAD_CPU_USAGE = false; 202 203 // The flags that are set for all calls we make to the package manager. 204 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 205 206 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 207 208 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 209 210 // Maximum number of recent tasks that we can remember. 211 static final int MAX_RECENT_TASKS = 20; 212 213 // Amount of time after a call to stopAppSwitches() during which we will 214 // prevent further untrusted switches from happening. 215 static final long APP_SWITCH_DELAY_TIME = 5*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real. 219 static final int PROC_START_TIMEOUT = 10*1000; 220 221 // How long we wait for a launched process to attach to the activity manager 222 // before we decide it's never going to come up for real, when the process was 223 // started with a wrapper for instrumentation (such as Valgrind) because it 224 // could take much longer than usual. 225 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 226 227 // How long to wait after going idle before forcing apps to GC. 228 static final int GC_TIMEOUT = 5*1000; 229 230 // The minimum amount of time between successive GC requests for a process. 231 static final int GC_MIN_INTERVAL = 60*1000; 232 233 // The rate at which we check for apps using excessive power -- 15 mins. 234 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on wake locks to start killing things. 238 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // The minimum sample duration we will allow before deciding we have 241 // enough data on CPU usage to start killing things. 242 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 243 244 // How long we allow a receiver to run before giving up on it. 245 static final int BROADCAST_FG_TIMEOUT = 10*1000; 246 static final int BROADCAST_BG_TIMEOUT = 60*1000; 247 248 // How long we wait until we timeout on key dispatching. 249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 250 251 // How long we wait until we timeout on key dispatching during instrumentation. 252 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 253 254 // Amount of time we wait for observers to handle a user switch before 255 // giving up on them and unfreezing the screen. 256 static final int USER_SWITCH_TIMEOUT = 2*1000; 257 258 // Maximum number of users we allow to be running at a time. 259 static final int MAX_RUNNING_USERS = 3; 260 261 static final int MY_PID = Process.myPid(); 262 263 static final String[] EMPTY_STRING_ARRAY = new String[0]; 264 265 public ActivityStack mMainStack; 266 267 private final boolean mHeadless; 268 269 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 270 // default actuion automatically. Important for devices without direct input 271 // devices. 272 private boolean mShowDialogs = true; 273 274 /** 275 * Description of a request to start a new activity, which has been held 276 * due to app switches being disabled. 277 */ 278 static class PendingActivityLaunch { 279 ActivityRecord r; 280 ActivityRecord sourceRecord; 281 int startFlags; 282 } 283 284 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 285 = new ArrayList<PendingActivityLaunch>(); 286 287 288 BroadcastQueue mFgBroadcastQueue; 289 BroadcastQueue mBgBroadcastQueue; 290 // Convenient for easy iteration over the queues. Foreground is first 291 // so that dispatch of foreground broadcasts gets precedence. 292 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 293 294 BroadcastQueue broadcastQueueForIntent(Intent intent) { 295 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 296 if (DEBUG_BACKGROUND_BROADCAST) { 297 Slog.i(TAG, "Broadcast intent " + intent + " on " 298 + (isFg ? "foreground" : "background") 299 + " queue"); 300 } 301 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 302 } 303 304 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 305 for (BroadcastQueue queue : mBroadcastQueues) { 306 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 307 if (r != null) { 308 return r; 309 } 310 } 311 return null; 312 } 313 314 /** 315 * Activity we have told the window manager to have key focus. 316 */ 317 ActivityRecord mFocusedActivity = null; 318 /** 319 * List of intents that were used to start the most recent tasks. 320 */ 321 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 322 323 /** 324 * Process management. 325 */ 326 final ProcessList mProcessList = new ProcessList(); 327 328 /** 329 * All of the applications we currently have running organized by name. 330 * The keys are strings of the application package name (as 331 * returned by the package manager), and the keys are ApplicationRecord 332 * objects. 333 */ 334 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 335 336 /** 337 * The currently running isolated processes. 338 */ 339 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 340 341 /** 342 * Counter for assigning isolated process uids, to avoid frequently reusing the 343 * same ones. 344 */ 345 int mNextIsolatedProcessUid = 0; 346 347 /** 348 * The currently running heavy-weight process, if any. 349 */ 350 ProcessRecord mHeavyWeightProcess = null; 351 352 /** 353 * The last time that various processes have crashed. 354 */ 355 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 356 357 /** 358 * Set of applications that we consider to be bad, and will reject 359 * incoming broadcasts from (which the user has no control over). 360 * Processes are added to this set when they have crashed twice within 361 * a minimum amount of time; they are removed from it when they are 362 * later restarted (hopefully due to some user action). The value is the 363 * time it was added to the list. 364 */ 365 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 366 367 /** 368 * All of the processes we currently have running organized by pid. 369 * The keys are the pid running the application. 370 * 371 * <p>NOTE: This object is protected by its own lock, NOT the global 372 * activity manager lock! 373 */ 374 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 375 376 /** 377 * All of the processes that have been forced to be foreground. The key 378 * is the pid of the caller who requested it (we hold a death 379 * link on it). 380 */ 381 abstract class ForegroundToken implements IBinder.DeathRecipient { 382 int pid; 383 IBinder token; 384 } 385 final SparseArray<ForegroundToken> mForegroundProcesses 386 = new SparseArray<ForegroundToken>(); 387 388 /** 389 * List of records for processes that someone had tried to start before the 390 * system was ready. We don't start them at that point, but ensure they 391 * are started by the time booting is complete. 392 */ 393 final ArrayList<ProcessRecord> mProcessesOnHold 394 = new ArrayList<ProcessRecord>(); 395 396 /** 397 * List of persistent applications that are in the process 398 * of being started. 399 */ 400 final ArrayList<ProcessRecord> mPersistentStartingProcesses 401 = new ArrayList<ProcessRecord>(); 402 403 /** 404 * Processes that are being forcibly torn down. 405 */ 406 final ArrayList<ProcessRecord> mRemovedProcesses 407 = new ArrayList<ProcessRecord>(); 408 409 /** 410 * List of running applications, sorted by recent usage. 411 * The first entry in the list is the least recently used. 412 * It contains ApplicationRecord objects. This list does NOT include 413 * any persistent application records (since we never want to exit them). 414 */ 415 final ArrayList<ProcessRecord> mLruProcesses 416 = new ArrayList<ProcessRecord>(); 417 418 /** 419 * List of processes that should gc as soon as things are idle. 420 */ 421 final ArrayList<ProcessRecord> mProcessesToGc 422 = new ArrayList<ProcessRecord>(); 423 424 /** 425 * This is the process holding what we currently consider to be 426 * the "home" activity. 427 */ 428 ProcessRecord mHomeProcess; 429 430 /** 431 * This is the process holding the activity the user last visited that 432 * is in a different process from the one they are currently in. 433 */ 434 ProcessRecord mPreviousProcess; 435 436 /** 437 * The time at which the previous process was last visible. 438 */ 439 long mPreviousProcessVisibleTime; 440 441 /** 442 * Which uses have been started, so are allowed to run code. 443 */ 444 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 445 446 /** 447 * LRU list of history of current users. Most recently current is at the end. 448 */ 449 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 450 451 /** 452 * Constant array of the users that are currently started. 453 */ 454 int[] mStartedUserArray = new int[] { 0 }; 455 456 /** 457 * Registered observers of the user switching mechanics. 458 */ 459 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 460 = new RemoteCallbackList<IUserSwitchObserver>(); 461 462 /** 463 * Currently active user switch. 464 */ 465 Object mCurUserSwitchCallback; 466 467 /** 468 * Packages that the user has asked to have run in screen size 469 * compatibility mode instead of filling the screen. 470 */ 471 final CompatModePackages mCompatModePackages; 472 473 /** 474 * Set of PendingResultRecord objects that are currently active. 475 */ 476 final HashSet mPendingResultRecords = new HashSet(); 477 478 /** 479 * Set of IntentSenderRecord objects that are currently active. 480 */ 481 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 482 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 483 484 /** 485 * Fingerprints (hashCode()) of stack traces that we've 486 * already logged DropBox entries for. Guarded by itself. If 487 * something (rogue user app) forces this over 488 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 489 */ 490 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 491 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 492 493 /** 494 * Strict Mode background batched logging state. 495 * 496 * The string buffer is guarded by itself, and its lock is also 497 * used to determine if another batched write is already 498 * in-flight. 499 */ 500 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 501 502 /** 503 * Keeps track of all IIntentReceivers that have been registered for 504 * broadcasts. Hash keys are the receiver IBinder, hash value is 505 * a ReceiverList. 506 */ 507 final HashMap mRegisteredReceivers = new HashMap(); 508 509 /** 510 * Resolver for broadcast intents to registered receivers. 511 * Holds BroadcastFilter (subclass of IntentFilter). 512 */ 513 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 514 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 515 @Override 516 protected boolean allowFilterResult( 517 BroadcastFilter filter, List<BroadcastFilter> dest) { 518 IBinder target = filter.receiverList.receiver.asBinder(); 519 for (int i=dest.size()-1; i>=0; i--) { 520 if (dest.get(i).receiverList.receiver.asBinder() == target) { 521 return false; 522 } 523 } 524 return true; 525 } 526 527 @Override 528 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 529 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 530 || userId == filter.owningUserId) { 531 return super.newResult(filter, match, userId); 532 } 533 return null; 534 } 535 536 @Override 537 protected BroadcastFilter[] newArray(int size) { 538 return new BroadcastFilter[size]; 539 } 540 541 @Override 542 protected String packageForFilter(BroadcastFilter filter) { 543 return filter.packageName; 544 } 545 }; 546 547 /** 548 * State of all active sticky broadcasts per user. Keys are the action of the 549 * sticky Intent, values are an ArrayList of all broadcasted intents with 550 * that action (which should usually be one). The SparseArray is keyed 551 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 552 * for stickies that are sent to all users. 553 */ 554 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 555 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 556 557 final ActiveServices mServices; 558 559 /** 560 * Backup/restore process management 561 */ 562 String mBackupAppName = null; 563 BackupRecord mBackupTarget = null; 564 565 /** 566 * List of PendingThumbnailsRecord objects of clients who are still 567 * waiting to receive all of the thumbnails for a task. 568 */ 569 final ArrayList mPendingThumbnails = new ArrayList(); 570 571 /** 572 * List of HistoryRecord objects that have been finished and must 573 * still report back to a pending thumbnail receiver. 574 */ 575 final ArrayList mCancelledThumbnails = new ArrayList(); 576 577 final ProviderMap mProviderMap; 578 579 /** 580 * List of content providers who have clients waiting for them. The 581 * application is currently being launched and the provider will be 582 * removed from this list once it is published. 583 */ 584 final ArrayList<ContentProviderRecord> mLaunchingProviders 585 = new ArrayList<ContentProviderRecord>(); 586 587 /** 588 * Global set of specific Uri permissions that have been granted. 589 */ 590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 591 = new SparseArray<HashMap<Uri, UriPermission>>(); 592 593 CoreSettingsObserver mCoreSettingsObserver; 594 595 /** 596 * Thread-local storage used to carry caller permissions over through 597 * indirect content-provider access. 598 * @see #ActivityManagerService.openContentUri() 599 */ 600 private class Identity { 601 public int pid; 602 public int uid; 603 604 Identity(int _pid, int _uid) { 605 pid = _pid; 606 uid = _uid; 607 } 608 } 609 610 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 611 612 /** 613 * All information we have collected about the runtime performance of 614 * any user id that can impact battery performance. 615 */ 616 final BatteryStatsService mBatteryStatsService; 617 618 /** 619 * information about component usage 620 */ 621 final UsageStatsService mUsageStatsService; 622 623 /** 624 * Current configuration information. HistoryRecord objects are given 625 * a reference to this object to indicate which configuration they are 626 * currently running in, so this object must be kept immutable. 627 */ 628 Configuration mConfiguration = new Configuration(); 629 630 /** 631 * Current sequencing integer of the configuration, for skipping old 632 * configurations. 633 */ 634 int mConfigurationSeq = 0; 635 636 /** 637 * Hardware-reported OpenGLES version. 638 */ 639 final int GL_ES_VERSION; 640 641 /** 642 * List of initialization arguments to pass to all processes when binding applications to them. 643 * For example, references to the commonly used services. 644 */ 645 HashMap<String, IBinder> mAppBindArgs; 646 647 /** 648 * Temporary to avoid allocations. Protected by main lock. 649 */ 650 final StringBuilder mStringBuilder = new StringBuilder(256); 651 652 /** 653 * Used to control how we initialize the service. 654 */ 655 boolean mStartRunning = false; 656 ComponentName mTopComponent; 657 String mTopAction; 658 String mTopData; 659 boolean mProcessesReady = false; 660 boolean mSystemReady = false; 661 boolean mBooting = false; 662 boolean mWaitingUpdate = false; 663 boolean mDidUpdate = false; 664 boolean mOnBattery = false; 665 boolean mLaunchWarningShown = false; 666 667 Context mContext; 668 669 int mFactoryTest; 670 671 boolean mCheckedForSetup; 672 673 /** 674 * The time at which we will allow normal application switches again, 675 * after a call to {@link #stopAppSwitches()}. 676 */ 677 long mAppSwitchesAllowedTime; 678 679 /** 680 * This is set to true after the first switch after mAppSwitchesAllowedTime 681 * is set; any switches after that will clear the time. 682 */ 683 boolean mDidAppSwitch; 684 685 /** 686 * Last time (in realtime) at which we checked for power usage. 687 */ 688 long mLastPowerCheckRealtime; 689 690 /** 691 * Last time (in uptime) at which we checked for power usage. 692 */ 693 long mLastPowerCheckUptime; 694 695 /** 696 * Set while we are wanting to sleep, to prevent any 697 * activities from being started/resumed. 698 */ 699 boolean mSleeping = false; 700 701 /** 702 * State of external calls telling us if the device is asleep. 703 */ 704 boolean mWentToSleep = false; 705 706 /** 707 * State of external call telling us if the lock screen is shown. 708 */ 709 boolean mLockScreenShown = false; 710 711 /** 712 * Set if we are shutting down the system, similar to sleeping. 713 */ 714 boolean mShuttingDown = false; 715 716 /** 717 * Task identifier that activities are currently being started 718 * in. Incremented each time a new task is created. 719 * todo: Replace this with a TokenSpace class that generates non-repeating 720 * integers that won't wrap. 721 */ 722 int mCurTask = 1; 723 724 /** 725 * Current sequence id for oom_adj computation traversal. 726 */ 727 int mAdjSeq = 0; 728 729 /** 730 * Current sequence id for process LRU updating. 731 */ 732 int mLruSeq = 0; 733 734 /** 735 * Keep track of the non-hidden/empty process we last found, to help 736 * determine how to distribute hidden/empty processes next time. 737 */ 738 int mNumNonHiddenProcs = 0; 739 740 /** 741 * Keep track of the number of hidden procs, to balance oom adj 742 * distribution between those and empty procs. 743 */ 744 int mNumHiddenProcs = 0; 745 746 /** 747 * Keep track of the number of service processes we last found, to 748 * determine on the next iteration which should be B services. 749 */ 750 int mNumServiceProcs = 0; 751 int mNewNumServiceProcs = 0; 752 753 /** 754 * System monitoring: number of processes that died since the last 755 * N procs were started. 756 */ 757 int[] mProcDeaths = new int[20]; 758 759 /** 760 * This is set if we had to do a delayed dexopt of an app before launching 761 * it, to increasing the ANR timeouts in that case. 762 */ 763 boolean mDidDexOpt; 764 765 String mDebugApp = null; 766 boolean mWaitForDebugger = false; 767 boolean mDebugTransient = false; 768 String mOrigDebugApp = null; 769 boolean mOrigWaitForDebugger = false; 770 boolean mAlwaysFinishActivities = false; 771 IActivityController mController = null; 772 String mProfileApp = null; 773 ProcessRecord mProfileProc = null; 774 String mProfileFile; 775 ParcelFileDescriptor mProfileFd; 776 int mProfileType = 0; 777 boolean mAutoStopProfiler = false; 778 String mOpenGlTraceApp = null; 779 780 static class ProcessChangeItem { 781 static final int CHANGE_ACTIVITIES = 1<<0; 782 static final int CHANGE_IMPORTANCE= 1<<1; 783 int changes; 784 int uid; 785 int pid; 786 int importance; 787 boolean foregroundActivities; 788 } 789 790 final RemoteCallbackList<IProcessObserver> mProcessObservers 791 = new RemoteCallbackList<IProcessObserver>(); 792 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 793 794 final ArrayList<ProcessChangeItem> mPendingProcessChanges 795 = new ArrayList<ProcessChangeItem>(); 796 final ArrayList<ProcessChangeItem> mAvailProcessChanges 797 = new ArrayList<ProcessChangeItem>(); 798 799 /** 800 * Callback of last caller to {@link #requestPss}. 801 */ 802 Runnable mRequestPssCallback; 803 804 /** 805 * Remaining processes for which we are waiting results from the last 806 * call to {@link #requestPss}. 807 */ 808 final ArrayList<ProcessRecord> mRequestPssList 809 = new ArrayList<ProcessRecord>(); 810 811 /** 812 * Runtime statistics collection thread. This object's lock is used to 813 * protect all related state. 814 */ 815 final Thread mProcessStatsThread; 816 817 /** 818 * Used to collect process stats when showing not responding dialog. 819 * Protected by mProcessStatsThread. 820 */ 821 final ProcessStats mProcessStats = new ProcessStats( 822 MONITOR_THREAD_CPU_USAGE); 823 final AtomicLong mLastCpuTime = new AtomicLong(0); 824 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 825 826 long mLastWriteTime = 0; 827 828 /** 829 * Set to true after the system has finished booting. 830 */ 831 boolean mBooted = false; 832 833 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 834 int mProcessLimitOverride = -1; 835 836 WindowManagerService mWindowManager; 837 838 static ActivityManagerService mSelf; 839 static ActivityThread mSystemThread; 840 841 private int mCurrentUserId = 0; 842 private int[] mCurrentUserArray = new int[] { 0 }; 843 private UserManagerService mUserManager; 844 845 private final class AppDeathRecipient implements IBinder.DeathRecipient { 846 final ProcessRecord mApp; 847 final int mPid; 848 final IApplicationThread mAppThread; 849 850 AppDeathRecipient(ProcessRecord app, int pid, 851 IApplicationThread thread) { 852 if (localLOGV) Slog.v( 853 TAG, "New death recipient " + this 854 + " for thread " + thread.asBinder()); 855 mApp = app; 856 mPid = pid; 857 mAppThread = thread; 858 } 859 860 public void binderDied() { 861 if (localLOGV) Slog.v( 862 TAG, "Death received in " + this 863 + " for thread " + mAppThread.asBinder()); 864 synchronized(ActivityManagerService.this) { 865 appDiedLocked(mApp, mPid, mAppThread); 866 } 867 } 868 } 869 870 static final int SHOW_ERROR_MSG = 1; 871 static final int SHOW_NOT_RESPONDING_MSG = 2; 872 static final int SHOW_FACTORY_ERROR_MSG = 3; 873 static final int UPDATE_CONFIGURATION_MSG = 4; 874 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 875 static final int WAIT_FOR_DEBUGGER_MSG = 6; 876 static final int SERVICE_TIMEOUT_MSG = 12; 877 static final int UPDATE_TIME_ZONE = 13; 878 static final int SHOW_UID_ERROR_MSG = 14; 879 static final int IM_FEELING_LUCKY_MSG = 15; 880 static final int PROC_START_TIMEOUT_MSG = 20; 881 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 882 static final int KILL_APPLICATION_MSG = 22; 883 static final int FINALIZE_PENDING_INTENT_MSG = 23; 884 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 885 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 886 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 887 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 888 static final int CLEAR_DNS_CACHE = 28; 889 static final int UPDATE_HTTP_PROXY = 29; 890 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 891 static final int DISPATCH_PROCESSES_CHANGED = 31; 892 static final int DISPATCH_PROCESS_DIED = 32; 893 static final int REPORT_MEM_USAGE = 33; 894 static final int REPORT_USER_SWITCH_MSG = 34; 895 static final int CONTINUE_USER_SWITCH_MSG = 35; 896 static final int USER_SWITCH_TIMEOUT_MSG = 36; 897 898 static final int FIRST_ACTIVITY_STACK_MSG = 100; 899 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 900 static final int FIRST_COMPAT_MODE_MSG = 300; 901 902 AlertDialog mUidAlert; 903 CompatModeDialog mCompatModeDialog; 904 long mLastMemUsageReportTime = 0; 905 906 final Handler mHandler = new Handler() { 907 //public Handler() { 908 // if (localLOGV) Slog.v(TAG, "Handler started!"); 909 //} 910 911 public void handleMessage(Message msg) { 912 switch (msg.what) { 913 case SHOW_ERROR_MSG: { 914 HashMap data = (HashMap) msg.obj; 915 synchronized (ActivityManagerService.this) { 916 ProcessRecord proc = (ProcessRecord)data.get("app"); 917 if (proc != null && proc.crashDialog != null) { 918 Slog.e(TAG, "App already has crash dialog: " + proc); 919 return; 920 } 921 AppErrorResult res = (AppErrorResult) data.get("result"); 922 if (mShowDialogs && !mSleeping && !mShuttingDown) { 923 Dialog d = new AppErrorDialog(mContext, res, proc); 924 d.show(); 925 proc.crashDialog = d; 926 } else { 927 // The device is asleep, so just pretend that the user 928 // saw a crash dialog and hit "force quit". 929 res.set(0); 930 } 931 } 932 933 ensureBootCompleted(); 934 } break; 935 case SHOW_NOT_RESPONDING_MSG: { 936 synchronized (ActivityManagerService.this) { 937 HashMap data = (HashMap) msg.obj; 938 ProcessRecord proc = (ProcessRecord)data.get("app"); 939 if (proc != null && proc.anrDialog != null) { 940 Slog.e(TAG, "App already has anr dialog: " + proc); 941 return; 942 } 943 944 Intent intent = new Intent("android.intent.action.ANR"); 945 if (!mProcessesReady) { 946 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 947 | Intent.FLAG_RECEIVER_FOREGROUND); 948 } 949 broadcastIntentLocked(null, null, intent, 950 null, null, 0, null, null, null, 951 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 952 953 if (mShowDialogs) { 954 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 955 mContext, proc, (ActivityRecord)data.get("activity")); 956 d.show(); 957 proc.anrDialog = d; 958 } else { 959 // Just kill the app if there is no dialog to be shown. 960 killAppAtUsersRequest(proc, null); 961 } 962 } 963 964 ensureBootCompleted(); 965 } break; 966 case SHOW_STRICT_MODE_VIOLATION_MSG: { 967 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 968 synchronized (ActivityManagerService.this) { 969 ProcessRecord proc = (ProcessRecord) data.get("app"); 970 if (proc == null) { 971 Slog.e(TAG, "App not found when showing strict mode dialog."); 972 break; 973 } 974 if (proc.crashDialog != null) { 975 Slog.e(TAG, "App already has strict mode dialog: " + proc); 976 return; 977 } 978 AppErrorResult res = (AppErrorResult) data.get("result"); 979 if (mShowDialogs && !mSleeping && !mShuttingDown) { 980 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 981 d.show(); 982 proc.crashDialog = d; 983 } else { 984 // The device is asleep, so just pretend that the user 985 // saw a crash dialog and hit "force quit". 986 res.set(0); 987 } 988 } 989 ensureBootCompleted(); 990 } break; 991 case SHOW_FACTORY_ERROR_MSG: { 992 Dialog d = new FactoryErrorDialog( 993 mContext, msg.getData().getCharSequence("msg")); 994 d.show(); 995 ensureBootCompleted(); 996 } break; 997 case UPDATE_CONFIGURATION_MSG: { 998 final ContentResolver resolver = mContext.getContentResolver(); 999 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1000 } break; 1001 case GC_BACKGROUND_PROCESSES_MSG: { 1002 synchronized (ActivityManagerService.this) { 1003 performAppGcsIfAppropriateLocked(); 1004 } 1005 } break; 1006 case WAIT_FOR_DEBUGGER_MSG: { 1007 synchronized (ActivityManagerService.this) { 1008 ProcessRecord app = (ProcessRecord)msg.obj; 1009 if (msg.arg1 != 0) { 1010 if (!app.waitedForDebugger) { 1011 Dialog d = new AppWaitingForDebuggerDialog( 1012 ActivityManagerService.this, 1013 mContext, app); 1014 app.waitDialog = d; 1015 app.waitedForDebugger = true; 1016 d.show(); 1017 } 1018 } else { 1019 if (app.waitDialog != null) { 1020 app.waitDialog.dismiss(); 1021 app.waitDialog = null; 1022 } 1023 } 1024 } 1025 } break; 1026 case SERVICE_TIMEOUT_MSG: { 1027 if (mDidDexOpt) { 1028 mDidDexOpt = false; 1029 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1030 nmsg.obj = msg.obj; 1031 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1032 return; 1033 } 1034 mServices.serviceTimeout((ProcessRecord)msg.obj); 1035 } break; 1036 case UPDATE_TIME_ZONE: { 1037 synchronized (ActivityManagerService.this) { 1038 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1039 ProcessRecord r = mLruProcesses.get(i); 1040 if (r.thread != null) { 1041 try { 1042 r.thread.updateTimeZone(); 1043 } catch (RemoteException ex) { 1044 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1045 } 1046 } 1047 } 1048 } 1049 } break; 1050 case CLEAR_DNS_CACHE: { 1051 synchronized (ActivityManagerService.this) { 1052 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1053 ProcessRecord r = mLruProcesses.get(i); 1054 if (r.thread != null) { 1055 try { 1056 r.thread.clearDnsCache(); 1057 } catch (RemoteException ex) { 1058 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1059 } 1060 } 1061 } 1062 } 1063 } break; 1064 case UPDATE_HTTP_PROXY: { 1065 ProxyProperties proxy = (ProxyProperties)msg.obj; 1066 String host = ""; 1067 String port = ""; 1068 String exclList = ""; 1069 if (proxy != null) { 1070 host = proxy.getHost(); 1071 port = Integer.toString(proxy.getPort()); 1072 exclList = proxy.getExclusionList(); 1073 } 1074 synchronized (ActivityManagerService.this) { 1075 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1076 ProcessRecord r = mLruProcesses.get(i); 1077 if (r.thread != null) { 1078 try { 1079 r.thread.setHttpProxy(host, port, exclList); 1080 } catch (RemoteException ex) { 1081 Slog.w(TAG, "Failed to update http proxy for: " + 1082 r.info.processName); 1083 } 1084 } 1085 } 1086 } 1087 } break; 1088 case SHOW_UID_ERROR_MSG: { 1089 String title = "System UIDs Inconsistent"; 1090 String text = "UIDs on the system are inconsistent, you need to wipe your" 1091 + " data partition or your device will be unstable."; 1092 Log.e(TAG, title + ": " + text); 1093 if (mShowDialogs) { 1094 // XXX This is a temporary dialog, no need to localize. 1095 AlertDialog d = new BaseErrorDialog(mContext); 1096 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1097 d.setCancelable(false); 1098 d.setTitle(title); 1099 d.setMessage(text); 1100 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1101 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1102 mUidAlert = d; 1103 d.show(); 1104 } 1105 } break; 1106 case IM_FEELING_LUCKY_MSG: { 1107 if (mUidAlert != null) { 1108 mUidAlert.dismiss(); 1109 mUidAlert = null; 1110 } 1111 } break; 1112 case PROC_START_TIMEOUT_MSG: { 1113 if (mDidDexOpt) { 1114 mDidDexOpt = false; 1115 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1116 nmsg.obj = msg.obj; 1117 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1118 return; 1119 } 1120 ProcessRecord app = (ProcessRecord)msg.obj; 1121 synchronized (ActivityManagerService.this) { 1122 processStartTimedOutLocked(app); 1123 } 1124 } break; 1125 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1126 synchronized (ActivityManagerService.this) { 1127 doPendingActivityLaunchesLocked(true); 1128 } 1129 } break; 1130 case KILL_APPLICATION_MSG: { 1131 synchronized (ActivityManagerService.this) { 1132 int appid = msg.arg1; 1133 boolean restart = (msg.arg2 == 1); 1134 String pkg = (String) msg.obj; 1135 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1136 UserHandle.USER_ALL); 1137 } 1138 } break; 1139 case FINALIZE_PENDING_INTENT_MSG: { 1140 ((PendingIntentRecord)msg.obj).completeFinalize(); 1141 } break; 1142 case POST_HEAVY_NOTIFICATION_MSG: { 1143 INotificationManager inm = NotificationManager.getService(); 1144 if (inm == null) { 1145 return; 1146 } 1147 1148 ActivityRecord root = (ActivityRecord)msg.obj; 1149 ProcessRecord process = root.app; 1150 if (process == null) { 1151 return; 1152 } 1153 1154 try { 1155 Context context = mContext.createPackageContext(process.info.packageName, 0); 1156 String text = mContext.getString(R.string.heavy_weight_notification, 1157 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1158 Notification notification = new Notification(); 1159 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1160 notification.when = 0; 1161 notification.flags = Notification.FLAG_ONGOING_EVENT; 1162 notification.tickerText = text; 1163 notification.defaults = 0; // please be quiet 1164 notification.sound = null; 1165 notification.vibrate = null; 1166 notification.setLatestEventInfo(context, text, 1167 mContext.getText(R.string.heavy_weight_notification_detail), 1168 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1169 PendingIntent.FLAG_CANCEL_CURRENT, null, 1170 new UserHandle(root.userId))); 1171 1172 try { 1173 int[] outId = new int[1]; 1174 inm.enqueueNotificationWithTag("android", null, 1175 R.string.heavy_weight_notification, 1176 notification, outId, root.userId); 1177 } catch (RuntimeException e) { 1178 Slog.w(ActivityManagerService.TAG, 1179 "Error showing notification for heavy-weight app", e); 1180 } catch (RemoteException e) { 1181 } 1182 } catch (NameNotFoundException e) { 1183 Slog.w(TAG, "Unable to create context for heavy notification", e); 1184 } 1185 } break; 1186 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1187 INotificationManager inm = NotificationManager.getService(); 1188 if (inm == null) { 1189 return; 1190 } 1191 try { 1192 inm.cancelNotificationWithTag("android", null, 1193 R.string.heavy_weight_notification, msg.arg1); 1194 } catch (RuntimeException e) { 1195 Slog.w(ActivityManagerService.TAG, 1196 "Error canceling notification for service", e); 1197 } catch (RemoteException e) { 1198 } 1199 } break; 1200 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1201 synchronized (ActivityManagerService.this) { 1202 checkExcessivePowerUsageLocked(true); 1203 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1204 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1205 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1206 } 1207 } break; 1208 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1209 synchronized (ActivityManagerService.this) { 1210 ActivityRecord ar = (ActivityRecord)msg.obj; 1211 if (mCompatModeDialog != null) { 1212 if (mCompatModeDialog.mAppInfo.packageName.equals( 1213 ar.info.applicationInfo.packageName)) { 1214 return; 1215 } 1216 mCompatModeDialog.dismiss(); 1217 mCompatModeDialog = null; 1218 } 1219 if (ar != null && false) { 1220 if (mCompatModePackages.getPackageAskCompatModeLocked( 1221 ar.packageName)) { 1222 int mode = mCompatModePackages.computeCompatModeLocked( 1223 ar.info.applicationInfo); 1224 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1225 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1226 mCompatModeDialog = new CompatModeDialog( 1227 ActivityManagerService.this, mContext, 1228 ar.info.applicationInfo); 1229 mCompatModeDialog.show(); 1230 } 1231 } 1232 } 1233 } 1234 break; 1235 } 1236 case DISPATCH_PROCESSES_CHANGED: { 1237 dispatchProcessesChanged(); 1238 break; 1239 } 1240 case DISPATCH_PROCESS_DIED: { 1241 final int pid = msg.arg1; 1242 final int uid = msg.arg2; 1243 dispatchProcessDied(pid, uid); 1244 break; 1245 } 1246 case REPORT_MEM_USAGE: { 1247 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1248 if (!isDebuggable) { 1249 return; 1250 } 1251 synchronized (ActivityManagerService.this) { 1252 long now = SystemClock.uptimeMillis(); 1253 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1254 // Don't report more than every 5 minutes to somewhat 1255 // avoid spamming. 1256 return; 1257 } 1258 mLastMemUsageReportTime = now; 1259 } 1260 Thread thread = new Thread() { 1261 @Override public void run() { 1262 StringBuilder dropBuilder = new StringBuilder(1024); 1263 StringBuilder logBuilder = new StringBuilder(1024); 1264 StringWriter oomSw = new StringWriter(); 1265 PrintWriter oomPw = new PrintWriter(oomSw); 1266 StringWriter catSw = new StringWriter(); 1267 PrintWriter catPw = new PrintWriter(catSw); 1268 String[] emptyArgs = new String[] { }; 1269 StringBuilder tag = new StringBuilder(128); 1270 StringBuilder stack = new StringBuilder(128); 1271 tag.append("Low on memory -- "); 1272 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1273 tag, stack); 1274 dropBuilder.append(stack); 1275 dropBuilder.append('\n'); 1276 dropBuilder.append('\n'); 1277 String oomString = oomSw.toString(); 1278 dropBuilder.append(oomString); 1279 dropBuilder.append('\n'); 1280 logBuilder.append(oomString); 1281 try { 1282 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1283 "procrank", }); 1284 final InputStreamReader converter = new InputStreamReader( 1285 proc.getInputStream()); 1286 BufferedReader in = new BufferedReader(converter); 1287 String line; 1288 while (true) { 1289 line = in.readLine(); 1290 if (line == null) { 1291 break; 1292 } 1293 if (line.length() > 0) { 1294 logBuilder.append(line); 1295 logBuilder.append('\n'); 1296 } 1297 dropBuilder.append(line); 1298 dropBuilder.append('\n'); 1299 } 1300 converter.close(); 1301 } catch (IOException e) { 1302 } 1303 synchronized (ActivityManagerService.this) { 1304 catPw.println(); 1305 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1306 catPw.println(); 1307 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1308 false, false, null); 1309 catPw.println(); 1310 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1311 } 1312 dropBuilder.append(catSw.toString()); 1313 addErrorToDropBox("lowmem", null, "system_server", null, 1314 null, tag.toString(), dropBuilder.toString(), null, null); 1315 Slog.i(TAG, logBuilder.toString()); 1316 synchronized (ActivityManagerService.this) { 1317 long now = SystemClock.uptimeMillis(); 1318 if (mLastMemUsageReportTime < now) { 1319 mLastMemUsageReportTime = now; 1320 } 1321 } 1322 } 1323 }; 1324 thread.start(); 1325 break; 1326 } 1327 case REPORT_USER_SWITCH_MSG: { 1328 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1329 break; 1330 } 1331 case CONTINUE_USER_SWITCH_MSG: { 1332 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1333 break; 1334 } 1335 case USER_SWITCH_TIMEOUT_MSG: { 1336 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1337 break; 1338 } 1339 } 1340 } 1341 }; 1342 1343 public static void setSystemProcess() { 1344 try { 1345 ActivityManagerService m = mSelf; 1346 1347 ServiceManager.addService("activity", m, true); 1348 ServiceManager.addService("meminfo", new MemBinder(m)); 1349 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1350 ServiceManager.addService("dbinfo", new DbBinder(m)); 1351 if (MONITOR_CPU_USAGE) { 1352 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1353 } 1354 ServiceManager.addService("permission", new PermissionController(m)); 1355 1356 ApplicationInfo info = 1357 mSelf.mContext.getPackageManager().getApplicationInfo( 1358 "android", STOCK_PM_FLAGS); 1359 mSystemThread.installSystemApplicationInfo(info); 1360 1361 synchronized (mSelf) { 1362 ProcessRecord app = mSelf.newProcessRecordLocked( 1363 mSystemThread.getApplicationThread(), info, 1364 info.processName, false); 1365 app.persistent = true; 1366 app.pid = MY_PID; 1367 app.maxAdj = ProcessList.SYSTEM_ADJ; 1368 mSelf.mProcessNames.put(app.processName, app.uid, app); 1369 synchronized (mSelf.mPidsSelfLocked) { 1370 mSelf.mPidsSelfLocked.put(app.pid, app); 1371 } 1372 mSelf.updateLruProcessLocked(app, true, true); 1373 } 1374 } catch (PackageManager.NameNotFoundException e) { 1375 throw new RuntimeException( 1376 "Unable to find android system package", e); 1377 } 1378 } 1379 1380 public void setWindowManager(WindowManagerService wm) { 1381 mWindowManager = wm; 1382 } 1383 1384 public static final Context main(int factoryTest) { 1385 AThread thr = new AThread(); 1386 thr.start(); 1387 1388 synchronized (thr) { 1389 while (thr.mService == null) { 1390 try { 1391 thr.wait(); 1392 } catch (InterruptedException e) { 1393 } 1394 } 1395 } 1396 1397 ActivityManagerService m = thr.mService; 1398 mSelf = m; 1399 ActivityThread at = ActivityThread.systemMain(); 1400 mSystemThread = at; 1401 Context context = at.getSystemContext(); 1402 context.setTheme(android.R.style.Theme_Holo); 1403 m.mContext = context; 1404 m.mFactoryTest = factoryTest; 1405 m.mMainStack = new ActivityStack(m, context, true); 1406 1407 m.mBatteryStatsService.publish(context); 1408 m.mUsageStatsService.publish(context); 1409 1410 synchronized (thr) { 1411 thr.mReady = true; 1412 thr.notifyAll(); 1413 } 1414 1415 m.startRunning(null, null, null, null); 1416 1417 return context; 1418 } 1419 1420 public static ActivityManagerService self() { 1421 return mSelf; 1422 } 1423 1424 static class AThread extends Thread { 1425 ActivityManagerService mService; 1426 boolean mReady = false; 1427 1428 public AThread() { 1429 super("ActivityManager"); 1430 } 1431 1432 public void run() { 1433 Looper.prepare(); 1434 1435 android.os.Process.setThreadPriority( 1436 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1437 android.os.Process.setCanSelfBackground(false); 1438 1439 ActivityManagerService m = new ActivityManagerService(); 1440 1441 synchronized (this) { 1442 mService = m; 1443 notifyAll(); 1444 } 1445 1446 synchronized (this) { 1447 while (!mReady) { 1448 try { 1449 wait(); 1450 } catch (InterruptedException e) { 1451 } 1452 } 1453 } 1454 1455 // For debug builds, log event loop stalls to dropbox for analysis. 1456 if (StrictMode.conditionallyEnableDebugLogging()) { 1457 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1458 } 1459 1460 Looper.loop(); 1461 } 1462 } 1463 1464 static class MemBinder extends Binder { 1465 ActivityManagerService mActivityManagerService; 1466 MemBinder(ActivityManagerService activityManagerService) { 1467 mActivityManagerService = activityManagerService; 1468 } 1469 1470 @Override 1471 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1472 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1473 != PackageManager.PERMISSION_GRANTED) { 1474 pw.println("Permission Denial: can't dump meminfo from from pid=" 1475 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1476 + " without permission " + android.Manifest.permission.DUMP); 1477 return; 1478 } 1479 1480 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1481 false, null, null, null); 1482 } 1483 } 1484 1485 static class GraphicsBinder extends Binder { 1486 ActivityManagerService mActivityManagerService; 1487 GraphicsBinder(ActivityManagerService activityManagerService) { 1488 mActivityManagerService = activityManagerService; 1489 } 1490 1491 @Override 1492 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1493 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1494 != PackageManager.PERMISSION_GRANTED) { 1495 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1496 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1497 + " without permission " + android.Manifest.permission.DUMP); 1498 return; 1499 } 1500 1501 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1502 } 1503 } 1504 1505 static class DbBinder extends Binder { 1506 ActivityManagerService mActivityManagerService; 1507 DbBinder(ActivityManagerService activityManagerService) { 1508 mActivityManagerService = activityManagerService; 1509 } 1510 1511 @Override 1512 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1513 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1514 != PackageManager.PERMISSION_GRANTED) { 1515 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1516 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1517 + " without permission " + android.Manifest.permission.DUMP); 1518 return; 1519 } 1520 1521 mActivityManagerService.dumpDbInfo(fd, pw, args); 1522 } 1523 } 1524 1525 static class CpuBinder extends Binder { 1526 ActivityManagerService mActivityManagerService; 1527 CpuBinder(ActivityManagerService activityManagerService) { 1528 mActivityManagerService = activityManagerService; 1529 } 1530 1531 @Override 1532 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1533 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1534 != PackageManager.PERMISSION_GRANTED) { 1535 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1536 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1537 + " without permission " + android.Manifest.permission.DUMP); 1538 return; 1539 } 1540 1541 synchronized (mActivityManagerService.mProcessStatsThread) { 1542 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1543 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1544 SystemClock.uptimeMillis())); 1545 } 1546 } 1547 } 1548 1549 private ActivityManagerService() { 1550 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1551 1552 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1553 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1554 mBroadcastQueues[0] = mFgBroadcastQueue; 1555 mBroadcastQueues[1] = mBgBroadcastQueue; 1556 1557 mServices = new ActiveServices(this); 1558 mProviderMap = new ProviderMap(this); 1559 1560 File dataDir = Environment.getDataDirectory(); 1561 File systemDir = new File(dataDir, "system"); 1562 systemDir.mkdirs(); 1563 mBatteryStatsService = new BatteryStatsService(new File( 1564 systemDir, "batterystats.bin").toString()); 1565 mBatteryStatsService.getActiveStatistics().readLocked(); 1566 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1567 mOnBattery = DEBUG_POWER ? true 1568 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1569 mBatteryStatsService.getActiveStatistics().setCallback(this); 1570 1571 mUsageStatsService = new UsageStatsService(new File( 1572 systemDir, "usagestats").toString()); 1573 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1574 1575 // User 0 is the first and only user that runs at boot. 1576 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1577 mUserLru.add(Integer.valueOf(0)); 1578 updateStartedUserArrayLocked(); 1579 1580 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1581 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1582 1583 mConfiguration.setToDefaults(); 1584 mConfiguration.setLocale(Locale.getDefault()); 1585 1586 mConfigurationSeq = mConfiguration.seq = 1; 1587 mProcessStats.init(); 1588 1589 mCompatModePackages = new CompatModePackages(this, systemDir); 1590 1591 // Add ourself to the Watchdog monitors. 1592 Watchdog.getInstance().addMonitor(this); 1593 1594 mProcessStatsThread = new Thread("ProcessStats") { 1595 public void run() { 1596 while (true) { 1597 try { 1598 try { 1599 synchronized(this) { 1600 final long now = SystemClock.uptimeMillis(); 1601 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1602 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1603 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1604 // + ", write delay=" + nextWriteDelay); 1605 if (nextWriteDelay < nextCpuDelay) { 1606 nextCpuDelay = nextWriteDelay; 1607 } 1608 if (nextCpuDelay > 0) { 1609 mProcessStatsMutexFree.set(true); 1610 this.wait(nextCpuDelay); 1611 } 1612 } 1613 } catch (InterruptedException e) { 1614 } 1615 updateCpuStatsNow(); 1616 } catch (Exception e) { 1617 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1618 } 1619 } 1620 } 1621 }; 1622 mProcessStatsThread.start(); 1623 } 1624 1625 @Override 1626 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1627 throws RemoteException { 1628 if (code == SYSPROPS_TRANSACTION) { 1629 // We need to tell all apps about the system property change. 1630 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1631 synchronized(this) { 1632 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1633 final int NA = apps.size(); 1634 for (int ia=0; ia<NA; ia++) { 1635 ProcessRecord app = apps.valueAt(ia); 1636 if (app.thread != null) { 1637 procs.add(app.thread.asBinder()); 1638 } 1639 } 1640 } 1641 } 1642 1643 int N = procs.size(); 1644 for (int i=0; i<N; i++) { 1645 Parcel data2 = Parcel.obtain(); 1646 try { 1647 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1648 } catch (RemoteException e) { 1649 } 1650 data2.recycle(); 1651 } 1652 } 1653 try { 1654 return super.onTransact(code, data, reply, flags); 1655 } catch (RuntimeException e) { 1656 // The activity manager only throws security exceptions, so let's 1657 // log all others. 1658 if (!(e instanceof SecurityException)) { 1659 Slog.e(TAG, "Activity Manager Crash", e); 1660 } 1661 throw e; 1662 } 1663 } 1664 1665 void updateCpuStats() { 1666 final long now = SystemClock.uptimeMillis(); 1667 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1668 return; 1669 } 1670 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1671 synchronized (mProcessStatsThread) { 1672 mProcessStatsThread.notify(); 1673 } 1674 } 1675 } 1676 1677 void updateCpuStatsNow() { 1678 synchronized (mProcessStatsThread) { 1679 mProcessStatsMutexFree.set(false); 1680 final long now = SystemClock.uptimeMillis(); 1681 boolean haveNewCpuStats = false; 1682 1683 if (MONITOR_CPU_USAGE && 1684 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1685 mLastCpuTime.set(now); 1686 haveNewCpuStats = true; 1687 mProcessStats.update(); 1688 //Slog.i(TAG, mProcessStats.printCurrentState()); 1689 //Slog.i(TAG, "Total CPU usage: " 1690 // + mProcessStats.getTotalCpuPercent() + "%"); 1691 1692 // Slog the cpu usage if the property is set. 1693 if ("true".equals(SystemProperties.get("events.cpu"))) { 1694 int user = mProcessStats.getLastUserTime(); 1695 int system = mProcessStats.getLastSystemTime(); 1696 int iowait = mProcessStats.getLastIoWaitTime(); 1697 int irq = mProcessStats.getLastIrqTime(); 1698 int softIrq = mProcessStats.getLastSoftIrqTime(); 1699 int idle = mProcessStats.getLastIdleTime(); 1700 1701 int total = user + system + iowait + irq + softIrq + idle; 1702 if (total == 0) total = 1; 1703 1704 EventLog.writeEvent(EventLogTags.CPU, 1705 ((user+system+iowait+irq+softIrq) * 100) / total, 1706 (user * 100) / total, 1707 (system * 100) / total, 1708 (iowait * 100) / total, 1709 (irq * 100) / total, 1710 (softIrq * 100) / total); 1711 } 1712 } 1713 1714 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1715 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1716 synchronized(bstats) { 1717 synchronized(mPidsSelfLocked) { 1718 if (haveNewCpuStats) { 1719 if (mOnBattery) { 1720 int perc = bstats.startAddingCpuLocked(); 1721 int totalUTime = 0; 1722 int totalSTime = 0; 1723 final int N = mProcessStats.countStats(); 1724 for (int i=0; i<N; i++) { 1725 ProcessStats.Stats st = mProcessStats.getStats(i); 1726 if (!st.working) { 1727 continue; 1728 } 1729 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1730 int otherUTime = (st.rel_utime*perc)/100; 1731 int otherSTime = (st.rel_stime*perc)/100; 1732 totalUTime += otherUTime; 1733 totalSTime += otherSTime; 1734 if (pr != null) { 1735 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1736 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1737 st.rel_stime-otherSTime); 1738 ps.addSpeedStepTimes(cpuSpeedTimes); 1739 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1740 } else { 1741 BatteryStatsImpl.Uid.Proc ps = 1742 bstats.getProcessStatsLocked(st.name, st.pid); 1743 if (ps != null) { 1744 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1745 st.rel_stime-otherSTime); 1746 ps.addSpeedStepTimes(cpuSpeedTimes); 1747 } 1748 } 1749 } 1750 bstats.finishAddingCpuLocked(perc, totalUTime, 1751 totalSTime, cpuSpeedTimes); 1752 } 1753 } 1754 } 1755 1756 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1757 mLastWriteTime = now; 1758 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1759 } 1760 } 1761 } 1762 } 1763 1764 @Override 1765 public void batteryNeedsCpuUpdate() { 1766 updateCpuStatsNow(); 1767 } 1768 1769 @Override 1770 public void batteryPowerChanged(boolean onBattery) { 1771 // When plugging in, update the CPU stats first before changing 1772 // the plug state. 1773 updateCpuStatsNow(); 1774 synchronized (this) { 1775 synchronized(mPidsSelfLocked) { 1776 mOnBattery = DEBUG_POWER ? true : onBattery; 1777 } 1778 } 1779 } 1780 1781 /** 1782 * Initialize the application bind args. These are passed to each 1783 * process when the bindApplication() IPC is sent to the process. They're 1784 * lazily setup to make sure the services are running when they're asked for. 1785 */ 1786 private HashMap<String, IBinder> getCommonServicesLocked() { 1787 if (mAppBindArgs == null) { 1788 mAppBindArgs = new HashMap<String, IBinder>(); 1789 1790 // Setup the application init args 1791 mAppBindArgs.put("package", ServiceManager.getService("package")); 1792 mAppBindArgs.put("window", ServiceManager.getService("window")); 1793 mAppBindArgs.put(Context.ALARM_SERVICE, 1794 ServiceManager.getService(Context.ALARM_SERVICE)); 1795 } 1796 return mAppBindArgs; 1797 } 1798 1799 final void setFocusedActivityLocked(ActivityRecord r) { 1800 if (mFocusedActivity != r) { 1801 mFocusedActivity = r; 1802 if (r != null) { 1803 mWindowManager.setFocusedApp(r.appToken, true); 1804 } 1805 } 1806 } 1807 1808 private final void updateLruProcessInternalLocked(ProcessRecord app, 1809 boolean updateActivityTime, int bestPos) { 1810 // put it on the LRU to keep track of when it should be exited. 1811 int lrui = mLruProcesses.indexOf(app); 1812 if (lrui >= 0) mLruProcesses.remove(lrui); 1813 1814 int i = mLruProcesses.size()-1; 1815 int skipTop = 0; 1816 1817 app.lruSeq = mLruSeq; 1818 1819 // compute the new weight for this process. 1820 if (updateActivityTime) { 1821 app.lastActivityTime = SystemClock.uptimeMillis(); 1822 } 1823 if (app.activities.size() > 0) { 1824 // If this process has activities, we more strongly want to keep 1825 // it around. 1826 app.lruWeight = app.lastActivityTime; 1827 } else if (app.pubProviders.size() > 0) { 1828 // If this process contains content providers, we want to keep 1829 // it a little more strongly. 1830 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1831 // Also don't let it kick out the first few "real" hidden processes. 1832 skipTop = ProcessList.MIN_HIDDEN_APPS; 1833 } else { 1834 // If this process doesn't have activities, we less strongly 1835 // want to keep it around, and generally want to avoid getting 1836 // in front of any very recently used activities. 1837 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1838 // Also don't let it kick out the first few "real" hidden processes. 1839 skipTop = ProcessList.MIN_HIDDEN_APPS; 1840 } 1841 1842 while (i >= 0) { 1843 ProcessRecord p = mLruProcesses.get(i); 1844 // If this app shouldn't be in front of the first N background 1845 // apps, then skip over that many that are currently hidden. 1846 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1847 skipTop--; 1848 } 1849 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1850 mLruProcesses.add(i+1, app); 1851 break; 1852 } 1853 i--; 1854 } 1855 if (i < 0) { 1856 mLruProcesses.add(0, app); 1857 } 1858 1859 // If the app is currently using a content provider or service, 1860 // bump those processes as well. 1861 if (app.connections.size() > 0) { 1862 for (ConnectionRecord cr : app.connections) { 1863 if (cr.binding != null && cr.binding.service != null 1864 && cr.binding.service.app != null 1865 && cr.binding.service.app.lruSeq != mLruSeq) { 1866 updateLruProcessInternalLocked(cr.binding.service.app, 1867 updateActivityTime, i+1); 1868 } 1869 } 1870 } 1871 for (int j=app.conProviders.size()-1; j>=0; j--) { 1872 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1873 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1874 updateLruProcessInternalLocked(cpr.proc, 1875 updateActivityTime, i+1); 1876 } 1877 } 1878 } 1879 1880 final void updateLruProcessLocked(ProcessRecord app, 1881 boolean oomAdj, boolean updateActivityTime) { 1882 mLruSeq++; 1883 updateLruProcessInternalLocked(app, updateActivityTime, 0); 1884 1885 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1886 if (oomAdj) { 1887 updateOomAdjLocked(); 1888 } 1889 } 1890 1891 final ProcessRecord getProcessRecordLocked( 1892 String processName, int uid) { 1893 if (uid == Process.SYSTEM_UID) { 1894 // The system gets to run in any process. If there are multiple 1895 // processes with the same uid, just pick the first (this 1896 // should never happen). 1897 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1898 processName); 1899 if (procs == null) return null; 1900 final int N = procs.size(); 1901 for (int i = 0; i < N; i++) { 1902 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1903 } 1904 } 1905 ProcessRecord proc = mProcessNames.get(processName, uid); 1906 return proc; 1907 } 1908 1909 void ensurePackageDexOpt(String packageName) { 1910 IPackageManager pm = AppGlobals.getPackageManager(); 1911 try { 1912 if (pm.performDexOpt(packageName)) { 1913 mDidDexOpt = true; 1914 } 1915 } catch (RemoteException e) { 1916 } 1917 } 1918 1919 boolean isNextTransitionForward() { 1920 int transit = mWindowManager.getPendingAppTransition(); 1921 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1922 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1923 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1924 } 1925 1926 final ProcessRecord startProcessLocked(String processName, 1927 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1928 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1929 boolean isolated) { 1930 ProcessRecord app; 1931 if (!isolated) { 1932 app = getProcessRecordLocked(processName, info.uid); 1933 } else { 1934 // If this is an isolated process, it can't re-use an existing process. 1935 app = null; 1936 } 1937 // We don't have to do anything more if: 1938 // (1) There is an existing application record; and 1939 // (2) The caller doesn't think it is dead, OR there is no thread 1940 // object attached to it so we know it couldn't have crashed; and 1941 // (3) There is a pid assigned to it, so it is either starting or 1942 // already running. 1943 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1944 + " app=" + app + " knownToBeDead=" + knownToBeDead 1945 + " thread=" + (app != null ? app.thread : null) 1946 + " pid=" + (app != null ? app.pid : -1)); 1947 if (app != null && app.pid > 0) { 1948 if (!knownToBeDead || app.thread == null) { 1949 // We already have the app running, or are waiting for it to 1950 // come up (we have a pid but not yet its thread), so keep it. 1951 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1952 // If this is a new package in the process, add the package to the list 1953 app.addPackage(info.packageName); 1954 return app; 1955 } else { 1956 // An application record is attached to a previous process, 1957 // clean it up now. 1958 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1959 handleAppDiedLocked(app, true, true); 1960 } 1961 } 1962 1963 String hostingNameStr = hostingName != null 1964 ? hostingName.flattenToShortString() : null; 1965 1966 if (!isolated) { 1967 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1968 // If we are in the background, then check to see if this process 1969 // is bad. If so, we will just silently fail. 1970 if (mBadProcesses.get(info.processName, info.uid) != null) { 1971 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1972 + "/" + info.processName); 1973 return null; 1974 } 1975 } else { 1976 // When the user is explicitly starting a process, then clear its 1977 // crash count so that we won't make it bad until they see at 1978 // least one crash dialog again, and make the process good again 1979 // if it had been bad. 1980 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1981 + "/" + info.processName); 1982 mProcessCrashTimes.remove(info.processName, info.uid); 1983 if (mBadProcesses.get(info.processName, info.uid) != null) { 1984 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1985 info.processName); 1986 mBadProcesses.remove(info.processName, info.uid); 1987 if (app != null) { 1988 app.bad = false; 1989 } 1990 } 1991 } 1992 } 1993 1994 if (app == null) { 1995 app = newProcessRecordLocked(null, info, processName, isolated); 1996 if (app == null) { 1997 Slog.w(TAG, "Failed making new process record for " 1998 + processName + "/" + info.uid + " isolated=" + isolated); 1999 return null; 2000 } 2001 mProcessNames.put(processName, app.uid, app); 2002 if (isolated) { 2003 mIsolatedProcesses.put(app.uid, app); 2004 } 2005 } else { 2006 // If this is a new package in the process, add the package to the list 2007 app.addPackage(info.packageName); 2008 } 2009 2010 // If the system is not ready yet, then hold off on starting this 2011 // process until it is. 2012 if (!mProcessesReady 2013 && !isAllowedWhileBooting(info) 2014 && !allowWhileBooting) { 2015 if (!mProcessesOnHold.contains(app)) { 2016 mProcessesOnHold.add(app); 2017 } 2018 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2019 return app; 2020 } 2021 2022 startProcessLocked(app, hostingType, hostingNameStr); 2023 return (app.pid != 0) ? app : null; 2024 } 2025 2026 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2027 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2028 } 2029 2030 private final void startProcessLocked(ProcessRecord app, 2031 String hostingType, String hostingNameStr) { 2032 if (app.pid > 0 && app.pid != MY_PID) { 2033 synchronized (mPidsSelfLocked) { 2034 mPidsSelfLocked.remove(app.pid); 2035 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2036 } 2037 app.setPid(0); 2038 } 2039 2040 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2041 "startProcessLocked removing on hold: " + app); 2042 mProcessesOnHold.remove(app); 2043 2044 updateCpuStats(); 2045 2046 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2047 mProcDeaths[0] = 0; 2048 2049 try { 2050 int uid = app.uid; 2051 2052 int[] gids = null; 2053 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2054 if (!app.isolated) { 2055 int[] permGids = null; 2056 try { 2057 final PackageManager pm = mContext.getPackageManager(); 2058 permGids = pm.getPackageGids(app.info.packageName); 2059 2060 if (Environment.isExternalStorageEmulated()) { 2061 if (pm.checkPermission( 2062 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2063 app.info.packageName) == PERMISSION_GRANTED) { 2064 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2065 } else { 2066 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2067 } 2068 } 2069 } catch (PackageManager.NameNotFoundException e) { 2070 Slog.w(TAG, "Unable to retrieve gids", e); 2071 } 2072 2073 /* 2074 * Add shared application GID so applications can share some 2075 * resources like shared libraries 2076 */ 2077 if (permGids == null) { 2078 gids = new int[1]; 2079 } else { 2080 gids = new int[permGids.length + 1]; 2081 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2082 } 2083 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2084 } 2085 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2086 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2087 && mTopComponent != null 2088 && app.processName.equals(mTopComponent.getPackageName())) { 2089 uid = 0; 2090 } 2091 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2092 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2093 uid = 0; 2094 } 2095 } 2096 int debugFlags = 0; 2097 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2098 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2099 // Also turn on CheckJNI for debuggable apps. It's quite 2100 // awkward to turn on otherwise. 2101 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2102 } 2103 // Run the app in safe mode if its manifest requests so or the 2104 // system is booted in safe mode. 2105 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2106 Zygote.systemInSafeMode == true) { 2107 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2108 } 2109 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2110 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2111 } 2112 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2113 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2114 } 2115 if ("1".equals(SystemProperties.get("debug.assert"))) { 2116 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2117 } 2118 2119 // Start the process. It will either succeed and return a result containing 2120 // the PID of the new process, or else throw a RuntimeException. 2121 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2122 app.processName, uid, uid, gids, debugFlags, mountExternal, 2123 app.info.targetSdkVersion, null, null); 2124 2125 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2126 synchronized (bs) { 2127 if (bs.isOnBattery()) { 2128 app.batteryStats.incStartsLocked(); 2129 } 2130 } 2131 2132 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2133 app.processName, hostingType, 2134 hostingNameStr != null ? hostingNameStr : ""); 2135 2136 if (app.persistent) { 2137 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2138 } 2139 2140 StringBuilder buf = mStringBuilder; 2141 buf.setLength(0); 2142 buf.append("Start proc "); 2143 buf.append(app.processName); 2144 buf.append(" for "); 2145 buf.append(hostingType); 2146 if (hostingNameStr != null) { 2147 buf.append(" "); 2148 buf.append(hostingNameStr); 2149 } 2150 buf.append(": pid="); 2151 buf.append(startResult.pid); 2152 buf.append(" uid="); 2153 buf.append(uid); 2154 buf.append(" gids={"); 2155 if (gids != null) { 2156 for (int gi=0; gi<gids.length; gi++) { 2157 if (gi != 0) buf.append(", "); 2158 buf.append(gids[gi]); 2159 2160 } 2161 } 2162 buf.append("}"); 2163 Slog.i(TAG, buf.toString()); 2164 app.setPid(startResult.pid); 2165 app.usingWrapper = startResult.usingWrapper; 2166 app.removed = false; 2167 synchronized (mPidsSelfLocked) { 2168 this.mPidsSelfLocked.put(startResult.pid, app); 2169 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2170 msg.obj = app; 2171 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2172 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2173 } 2174 } catch (RuntimeException e) { 2175 // XXX do better error recovery. 2176 app.setPid(0); 2177 Slog.e(TAG, "Failure starting process " + app.processName, e); 2178 } 2179 } 2180 2181 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2182 if (resumed) { 2183 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2184 } else { 2185 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2186 } 2187 } 2188 2189 boolean startHomeActivityLocked(int userId) { 2190 if (mHeadless) { 2191 // Added because none of the other calls to ensureBootCompleted seem to fire 2192 // when running headless. 2193 ensureBootCompleted(); 2194 return false; 2195 } 2196 2197 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2198 && mTopAction == null) { 2199 // We are running in factory test mode, but unable to find 2200 // the factory test app, so just sit around displaying the 2201 // error message and don't try to start anything. 2202 return false; 2203 } 2204 Intent intent = new Intent( 2205 mTopAction, 2206 mTopData != null ? Uri.parse(mTopData) : null); 2207 intent.setComponent(mTopComponent); 2208 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2209 intent.addCategory(Intent.CATEGORY_HOME); 2210 } 2211 ActivityInfo aInfo = 2212 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2213 if (aInfo != null) { 2214 intent.setComponent(new ComponentName( 2215 aInfo.applicationInfo.packageName, aInfo.name)); 2216 // Don't do this if the home app is currently being 2217 // instrumented. 2218 aInfo = new ActivityInfo(aInfo); 2219 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2220 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2221 aInfo.applicationInfo.uid); 2222 if (app == null || app.instrumentationClass == null) { 2223 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2224 mMainStack.startActivityLocked(null, intent, null, aInfo, 2225 null, null, 0, 0, 0, 0, null, false, null); 2226 } 2227 } 2228 2229 return true; 2230 } 2231 2232 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2233 ActivityInfo ai = null; 2234 ComponentName comp = intent.getComponent(); 2235 try { 2236 if (comp != null) { 2237 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2238 } else { 2239 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2240 intent, 2241 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2242 flags, userId); 2243 2244 if (info != null) { 2245 ai = info.activityInfo; 2246 } 2247 } 2248 } catch (RemoteException e) { 2249 // ignore 2250 } 2251 2252 return ai; 2253 } 2254 2255 /** 2256 * Starts the "new version setup screen" if appropriate. 2257 */ 2258 void startSetupActivityLocked() { 2259 // Only do this once per boot. 2260 if (mCheckedForSetup) { 2261 return; 2262 } 2263 2264 // We will show this screen if the current one is a different 2265 // version than the last one shown, and we are not running in 2266 // low-level factory test mode. 2267 final ContentResolver resolver = mContext.getContentResolver(); 2268 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2269 Settings.Secure.getInt(resolver, 2270 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2271 mCheckedForSetup = true; 2272 2273 // See if we should be showing the platform update setup UI. 2274 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2275 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2276 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2277 2278 // We don't allow third party apps to replace this. 2279 ResolveInfo ri = null; 2280 for (int i=0; ris != null && i<ris.size(); i++) { 2281 if ((ris.get(i).activityInfo.applicationInfo.flags 2282 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2283 ri = ris.get(i); 2284 break; 2285 } 2286 } 2287 2288 if (ri != null) { 2289 String vers = ri.activityInfo.metaData != null 2290 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2291 : null; 2292 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2293 vers = ri.activityInfo.applicationInfo.metaData.getString( 2294 Intent.METADATA_SETUP_VERSION); 2295 } 2296 String lastVers = Settings.Secure.getString( 2297 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2298 if (vers != null && !vers.equals(lastVers)) { 2299 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2300 intent.setComponent(new ComponentName( 2301 ri.activityInfo.packageName, ri.activityInfo.name)); 2302 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2303 null, null, 0, 0, 0, 0, null, false, null); 2304 } 2305 } 2306 } 2307 } 2308 2309 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2310 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2311 } 2312 2313 void enforceNotIsolatedCaller(String caller) { 2314 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2315 throw new SecurityException("Isolated process not allowed to call " + caller); 2316 } 2317 } 2318 2319 public int getFrontActivityScreenCompatMode() { 2320 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2321 synchronized (this) { 2322 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2323 } 2324 } 2325 2326 public void setFrontActivityScreenCompatMode(int mode) { 2327 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2328 "setFrontActivityScreenCompatMode"); 2329 synchronized (this) { 2330 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2331 } 2332 } 2333 2334 public int getPackageScreenCompatMode(String packageName) { 2335 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2336 synchronized (this) { 2337 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2338 } 2339 } 2340 2341 public void setPackageScreenCompatMode(String packageName, int mode) { 2342 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2343 "setPackageScreenCompatMode"); 2344 synchronized (this) { 2345 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2346 } 2347 } 2348 2349 public boolean getPackageAskScreenCompat(String packageName) { 2350 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2351 synchronized (this) { 2352 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2353 } 2354 } 2355 2356 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2357 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2358 "setPackageAskScreenCompat"); 2359 synchronized (this) { 2360 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2361 } 2362 } 2363 2364 void reportResumedActivityLocked(ActivityRecord r) { 2365 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2366 updateUsageStats(r, true); 2367 } 2368 2369 private void dispatchProcessesChanged() { 2370 int N; 2371 synchronized (this) { 2372 N = mPendingProcessChanges.size(); 2373 if (mActiveProcessChanges.length < N) { 2374 mActiveProcessChanges = new ProcessChangeItem[N]; 2375 } 2376 mPendingProcessChanges.toArray(mActiveProcessChanges); 2377 mAvailProcessChanges.addAll(mPendingProcessChanges); 2378 mPendingProcessChanges.clear(); 2379 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2380 } 2381 int i = mProcessObservers.beginBroadcast(); 2382 while (i > 0) { 2383 i--; 2384 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2385 if (observer != null) { 2386 try { 2387 for (int j=0; j<N; j++) { 2388 ProcessChangeItem item = mActiveProcessChanges[j]; 2389 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2390 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2391 + item.pid + " uid=" + item.uid + ": " 2392 + item.foregroundActivities); 2393 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2394 item.foregroundActivities); 2395 } 2396 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2397 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2398 + item.pid + " uid=" + item.uid + ": " + item.importance); 2399 observer.onImportanceChanged(item.pid, item.uid, 2400 item.importance); 2401 } 2402 } 2403 } catch (RemoteException e) { 2404 } 2405 } 2406 } 2407 mProcessObservers.finishBroadcast(); 2408 } 2409 2410 private void dispatchProcessDied(int pid, int uid) { 2411 int i = mProcessObservers.beginBroadcast(); 2412 while (i > 0) { 2413 i--; 2414 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2415 if (observer != null) { 2416 try { 2417 observer.onProcessDied(pid, uid); 2418 } catch (RemoteException e) { 2419 } 2420 } 2421 } 2422 mProcessObservers.finishBroadcast(); 2423 } 2424 2425 final void doPendingActivityLaunchesLocked(boolean doResume) { 2426 final int N = mPendingActivityLaunches.size(); 2427 if (N <= 0) { 2428 return; 2429 } 2430 for (int i=0; i<N; i++) { 2431 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2432 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2433 pal.startFlags, doResume && i == (N-1), null); 2434 } 2435 mPendingActivityLaunches.clear(); 2436 } 2437 2438 public final int startActivity(IApplicationThread caller, 2439 Intent intent, String resolvedType, IBinder resultTo, 2440 String resultWho, int requestCode, int startFlags, 2441 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2442 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2443 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2444 } 2445 2446 public final int startActivityAsUser(IApplicationThread caller, 2447 Intent intent, String resolvedType, IBinder resultTo, 2448 String resultWho, int requestCode, int startFlags, 2449 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2450 enforceNotIsolatedCaller("startActivity"); 2451 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2452 false, true, "startActivity", null); 2453 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2454 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2455 null, null, options, userId); 2456 } 2457 2458 public final WaitResult startActivityAndWait(IApplicationThread caller, 2459 Intent intent, String resolvedType, IBinder resultTo, 2460 String resultWho, int requestCode, int startFlags, String profileFile, 2461 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2462 enforceNotIsolatedCaller("startActivityAndWait"); 2463 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2464 false, true, "startActivityAndWait", null); 2465 WaitResult res = new WaitResult(); 2466 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2467 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2468 res, null, options, UserHandle.getCallingUserId()); 2469 return res; 2470 } 2471 2472 public final int startActivityWithConfig(IApplicationThread caller, 2473 Intent intent, String resolvedType, IBinder resultTo, 2474 String resultWho, int requestCode, int startFlags, Configuration config, 2475 Bundle options, int userId) { 2476 enforceNotIsolatedCaller("startActivityWithConfig"); 2477 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2478 false, true, "startActivityWithConfig", null); 2479 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2480 resultTo, resultWho, requestCode, startFlags, 2481 null, null, null, config, options, userId); 2482 return ret; 2483 } 2484 2485 public int startActivityIntentSender(IApplicationThread caller, 2486 IntentSender intent, Intent fillInIntent, String resolvedType, 2487 IBinder resultTo, String resultWho, int requestCode, 2488 int flagsMask, int flagsValues, Bundle options) { 2489 enforceNotIsolatedCaller("startActivityIntentSender"); 2490 // Refuse possible leaked file descriptors 2491 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2492 throw new IllegalArgumentException("File descriptors passed in Intent"); 2493 } 2494 2495 IIntentSender sender = intent.getTarget(); 2496 if (!(sender instanceof PendingIntentRecord)) { 2497 throw new IllegalArgumentException("Bad PendingIntent object"); 2498 } 2499 2500 PendingIntentRecord pir = (PendingIntentRecord)sender; 2501 2502 synchronized (this) { 2503 // If this is coming from the currently resumed activity, it is 2504 // effectively saying that app switches are allowed at this point. 2505 if (mMainStack.mResumedActivity != null 2506 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2507 Binder.getCallingUid()) { 2508 mAppSwitchesAllowedTime = 0; 2509 } 2510 } 2511 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2512 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2513 return ret; 2514 } 2515 2516 public boolean startNextMatchingActivity(IBinder callingActivity, 2517 Intent intent, Bundle options) { 2518 // Refuse possible leaked file descriptors 2519 if (intent != null && intent.hasFileDescriptors() == true) { 2520 throw new IllegalArgumentException("File descriptors passed in Intent"); 2521 } 2522 2523 synchronized (this) { 2524 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2525 if (r == null) { 2526 ActivityOptions.abort(options); 2527 return false; 2528 } 2529 if (r.app == null || r.app.thread == null) { 2530 // The caller is not running... d'oh! 2531 ActivityOptions.abort(options); 2532 return false; 2533 } 2534 intent = new Intent(intent); 2535 // The caller is not allowed to change the data. 2536 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2537 // And we are resetting to find the next component... 2538 intent.setComponent(null); 2539 2540 ActivityInfo aInfo = null; 2541 try { 2542 List<ResolveInfo> resolves = 2543 AppGlobals.getPackageManager().queryIntentActivities( 2544 intent, r.resolvedType, 2545 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2546 UserHandle.getCallingUserId()); 2547 2548 // Look for the original activity in the list... 2549 final int N = resolves != null ? resolves.size() : 0; 2550 for (int i=0; i<N; i++) { 2551 ResolveInfo rInfo = resolves.get(i); 2552 if (rInfo.activityInfo.packageName.equals(r.packageName) 2553 && rInfo.activityInfo.name.equals(r.info.name)) { 2554 // We found the current one... the next matching is 2555 // after it. 2556 i++; 2557 if (i<N) { 2558 aInfo = resolves.get(i).activityInfo; 2559 } 2560 break; 2561 } 2562 } 2563 } catch (RemoteException e) { 2564 } 2565 2566 if (aInfo == null) { 2567 // Nobody who is next! 2568 ActivityOptions.abort(options); 2569 return false; 2570 } 2571 2572 intent.setComponent(new ComponentName( 2573 aInfo.applicationInfo.packageName, aInfo.name)); 2574 intent.setFlags(intent.getFlags()&~( 2575 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2576 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2577 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2578 Intent.FLAG_ACTIVITY_NEW_TASK)); 2579 2580 // Okay now we need to start the new activity, replacing the 2581 // currently running activity. This is a little tricky because 2582 // we want to start the new one as if the current one is finished, 2583 // but not finish the current one first so that there is no flicker. 2584 // And thus... 2585 final boolean wasFinishing = r.finishing; 2586 r.finishing = true; 2587 2588 // Propagate reply information over to the new activity. 2589 final ActivityRecord resultTo = r.resultTo; 2590 final String resultWho = r.resultWho; 2591 final int requestCode = r.requestCode; 2592 r.resultTo = null; 2593 if (resultTo != null) { 2594 resultTo.removeResultsLocked(r, resultWho, requestCode); 2595 } 2596 2597 final long origId = Binder.clearCallingIdentity(); 2598 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2599 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2600 resultWho, requestCode, -1, r.launchedFromUid, 0, 2601 options, false, null); 2602 Binder.restoreCallingIdentity(origId); 2603 2604 r.finishing = wasFinishing; 2605 if (res != ActivityManager.START_SUCCESS) { 2606 return false; 2607 } 2608 return true; 2609 } 2610 } 2611 2612 final int startActivityInPackage(int uid, 2613 Intent intent, String resolvedType, IBinder resultTo, 2614 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2615 2616 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2617 false, true, "startActivityInPackage", null); 2618 2619 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2620 resultTo, resultWho, requestCode, startFlags, 2621 null, null, null, null, options, userId); 2622 return ret; 2623 } 2624 2625 public final int startActivities(IApplicationThread caller, 2626 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2627 enforceNotIsolatedCaller("startActivities"); 2628 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2629 options, UserHandle.getCallingUserId()); 2630 return ret; 2631 } 2632 2633 final int startActivitiesInPackage(int uid, 2634 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2635 Bundle options, int userId) { 2636 2637 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2638 false, true, "startActivityInPackage", null); 2639 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2640 options, userId); 2641 return ret; 2642 } 2643 2644 final void addRecentTaskLocked(TaskRecord task) { 2645 int N = mRecentTasks.size(); 2646 // Quick case: check if the top-most recent task is the same. 2647 if (N > 0 && mRecentTasks.get(0) == task) { 2648 return; 2649 } 2650 // Remove any existing entries that are the same kind of task. 2651 for (int i=0; i<N; i++) { 2652 TaskRecord tr = mRecentTasks.get(i); 2653 if (task.userId == tr.userId 2654 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2655 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2656 mRecentTasks.remove(i); 2657 i--; 2658 N--; 2659 if (task.intent == null) { 2660 // If the new recent task we are adding is not fully 2661 // specified, then replace it with the existing recent task. 2662 task = tr; 2663 } 2664 } 2665 } 2666 if (N >= MAX_RECENT_TASKS) { 2667 mRecentTasks.remove(N-1); 2668 } 2669 mRecentTasks.add(0, task); 2670 } 2671 2672 public void setRequestedOrientation(IBinder token, 2673 int requestedOrientation) { 2674 synchronized (this) { 2675 ActivityRecord r = mMainStack.isInStackLocked(token); 2676 if (r == null) { 2677 return; 2678 } 2679 final long origId = Binder.clearCallingIdentity(); 2680 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2681 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2682 mConfiguration, 2683 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2684 if (config != null) { 2685 r.frozenBeforeDestroy = true; 2686 if (!updateConfigurationLocked(config, r, false, false)) { 2687 mMainStack.resumeTopActivityLocked(null); 2688 } 2689 } 2690 Binder.restoreCallingIdentity(origId); 2691 } 2692 } 2693 2694 public int getRequestedOrientation(IBinder token) { 2695 synchronized (this) { 2696 ActivityRecord r = mMainStack.isInStackLocked(token); 2697 if (r == null) { 2698 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2699 } 2700 return mWindowManager.getAppOrientation(r.appToken); 2701 } 2702 } 2703 2704 /** 2705 * This is the internal entry point for handling Activity.finish(). 2706 * 2707 * @param token The Binder token referencing the Activity we want to finish. 2708 * @param resultCode Result code, if any, from this Activity. 2709 * @param resultData Result data (Intent), if any, from this Activity. 2710 * 2711 * @return Returns true if the activity successfully finished, or false if it is still running. 2712 */ 2713 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2714 // Refuse possible leaked file descriptors 2715 if (resultData != null && resultData.hasFileDescriptors() == true) { 2716 throw new IllegalArgumentException("File descriptors passed in Intent"); 2717 } 2718 2719 synchronized(this) { 2720 if (mController != null) { 2721 // Find the first activity that is not finishing. 2722 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2723 if (next != null) { 2724 // ask watcher if this is allowed 2725 boolean resumeOK = true; 2726 try { 2727 resumeOK = mController.activityResuming(next.packageName); 2728 } catch (RemoteException e) { 2729 mController = null; 2730 } 2731 2732 if (!resumeOK) { 2733 return false; 2734 } 2735 } 2736 } 2737 final long origId = Binder.clearCallingIdentity(); 2738 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2739 resultData, "app-request", true); 2740 Binder.restoreCallingIdentity(origId); 2741 return res; 2742 } 2743 } 2744 2745 public final void finishHeavyWeightApp() { 2746 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2747 != PackageManager.PERMISSION_GRANTED) { 2748 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2749 + Binder.getCallingPid() 2750 + ", uid=" + Binder.getCallingUid() 2751 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2752 Slog.w(TAG, msg); 2753 throw new SecurityException(msg); 2754 } 2755 2756 synchronized(this) { 2757 if (mHeavyWeightProcess == null) { 2758 return; 2759 } 2760 2761 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2762 mHeavyWeightProcess.activities); 2763 for (int i=0; i<activities.size(); i++) { 2764 ActivityRecord r = activities.get(i); 2765 if (!r.finishing) { 2766 int index = mMainStack.indexOfTokenLocked(r.appToken); 2767 if (index >= 0) { 2768 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2769 null, "finish-heavy", true); 2770 } 2771 } 2772 } 2773 2774 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2775 mHeavyWeightProcess.userId, 0)); 2776 mHeavyWeightProcess = null; 2777 } 2778 } 2779 2780 public void crashApplication(int uid, int initialPid, String packageName, 2781 String message) { 2782 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2783 != PackageManager.PERMISSION_GRANTED) { 2784 String msg = "Permission Denial: crashApplication() from pid=" 2785 + Binder.getCallingPid() 2786 + ", uid=" + Binder.getCallingUid() 2787 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2788 Slog.w(TAG, msg); 2789 throw new SecurityException(msg); 2790 } 2791 2792 synchronized(this) { 2793 ProcessRecord proc = null; 2794 2795 // Figure out which process to kill. We don't trust that initialPid 2796 // still has any relation to current pids, so must scan through the 2797 // list. 2798 synchronized (mPidsSelfLocked) { 2799 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2800 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2801 if (p.uid != uid) { 2802 continue; 2803 } 2804 if (p.pid == initialPid) { 2805 proc = p; 2806 break; 2807 } 2808 for (String str : p.pkgList) { 2809 if (str.equals(packageName)) { 2810 proc = p; 2811 } 2812 } 2813 } 2814 } 2815 2816 if (proc == null) { 2817 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2818 + " initialPid=" + initialPid 2819 + " packageName=" + packageName); 2820 return; 2821 } 2822 2823 if (proc.thread != null) { 2824 if (proc.pid == Process.myPid()) { 2825 Log.w(TAG, "crashApplication: trying to crash self!"); 2826 return; 2827 } 2828 long ident = Binder.clearCallingIdentity(); 2829 try { 2830 proc.thread.scheduleCrash(message); 2831 } catch (RemoteException e) { 2832 } 2833 Binder.restoreCallingIdentity(ident); 2834 } 2835 } 2836 } 2837 2838 public final void finishSubActivity(IBinder token, String resultWho, 2839 int requestCode) { 2840 synchronized(this) { 2841 final long origId = Binder.clearCallingIdentity(); 2842 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2843 Binder.restoreCallingIdentity(origId); 2844 } 2845 } 2846 2847 public boolean finishActivityAffinity(IBinder token) { 2848 synchronized(this) { 2849 final long origId = Binder.clearCallingIdentity(); 2850 boolean res = mMainStack.finishActivityAffinityLocked(token); 2851 Binder.restoreCallingIdentity(origId); 2852 return res; 2853 } 2854 } 2855 2856 public boolean willActivityBeVisible(IBinder token) { 2857 synchronized(this) { 2858 int i; 2859 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2860 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2861 if (r.appToken == token) { 2862 return true; 2863 } 2864 if (r.fullscreen && !r.finishing) { 2865 return false; 2866 } 2867 } 2868 return true; 2869 } 2870 } 2871 2872 public void overridePendingTransition(IBinder token, String packageName, 2873 int enterAnim, int exitAnim) { 2874 synchronized(this) { 2875 ActivityRecord self = mMainStack.isInStackLocked(token); 2876 if (self == null) { 2877 return; 2878 } 2879 2880 final long origId = Binder.clearCallingIdentity(); 2881 2882 if (self.state == ActivityState.RESUMED 2883 || self.state == ActivityState.PAUSING) { 2884 mWindowManager.overridePendingAppTransition(packageName, 2885 enterAnim, exitAnim, null); 2886 } 2887 2888 Binder.restoreCallingIdentity(origId); 2889 } 2890 } 2891 2892 /** 2893 * Main function for removing an existing process from the activity manager 2894 * as a result of that process going away. Clears out all connections 2895 * to the process. 2896 */ 2897 private final void handleAppDiedLocked(ProcessRecord app, 2898 boolean restarting, boolean allowRestart) { 2899 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2900 if (!restarting) { 2901 mLruProcesses.remove(app); 2902 } 2903 2904 if (mProfileProc == app) { 2905 clearProfilerLocked(); 2906 } 2907 2908 // Just in case... 2909 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2910 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2911 mMainStack.mPausingActivity = null; 2912 } 2913 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2914 mMainStack.mLastPausedActivity = null; 2915 } 2916 2917 // Remove this application's activities from active lists. 2918 mMainStack.removeHistoryRecordsForAppLocked(app); 2919 2920 boolean atTop = true; 2921 boolean hasVisibleActivities = false; 2922 2923 // Clean out the history list. 2924 int i = mMainStack.mHistory.size(); 2925 if (localLOGV) Slog.v( 2926 TAG, "Removing app " + app + " from history with " + i + " entries"); 2927 while (i > 0) { 2928 i--; 2929 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2930 if (localLOGV) Slog.v( 2931 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2932 if (r.app == app) { 2933 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2934 if (ActivityStack.DEBUG_ADD_REMOVE) { 2935 RuntimeException here = new RuntimeException("here"); 2936 here.fillInStackTrace(); 2937 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2938 + ": haveState=" + r.haveState 2939 + " stateNotNeeded=" + r.stateNotNeeded 2940 + " finishing=" + r.finishing 2941 + " state=" + r.state, here); 2942 } 2943 if (!r.finishing) { 2944 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2945 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2946 System.identityHashCode(r), 2947 r.task.taskId, r.shortComponentName, 2948 "proc died without state saved"); 2949 } 2950 mMainStack.removeActivityFromHistoryLocked(r); 2951 2952 } else { 2953 // We have the current state for this activity, so 2954 // it can be restarted later when needed. 2955 if (localLOGV) Slog.v( 2956 TAG, "Keeping entry, setting app to null"); 2957 if (r.visible) { 2958 hasVisibleActivities = true; 2959 } 2960 r.app = null; 2961 r.nowVisible = false; 2962 if (!r.haveState) { 2963 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2964 "App died, clearing saved state of " + r); 2965 r.icicle = null; 2966 } 2967 } 2968 2969 r.stack.cleanUpActivityLocked(r, true, true); 2970 } 2971 atTop = false; 2972 } 2973 2974 app.activities.clear(); 2975 2976 if (app.instrumentationClass != null) { 2977 Slog.w(TAG, "Crash of app " + app.processName 2978 + " running instrumentation " + app.instrumentationClass); 2979 Bundle info = new Bundle(); 2980 info.putString("shortMsg", "Process crashed."); 2981 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2982 } 2983 2984 if (!restarting) { 2985 if (!mMainStack.resumeTopActivityLocked(null)) { 2986 // If there was nothing to resume, and we are not already 2987 // restarting this process, but there is a visible activity that 2988 // is hosted by the process... then make sure all visible 2989 // activities are running, taking care of restarting this 2990 // process. 2991 if (hasVisibleActivities) { 2992 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2993 } 2994 } 2995 } 2996 } 2997 2998 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2999 IBinder threadBinder = thread.asBinder(); 3000 // Find the application record. 3001 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3002 ProcessRecord rec = mLruProcesses.get(i); 3003 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3004 return i; 3005 } 3006 } 3007 return -1; 3008 } 3009 3010 final ProcessRecord getRecordForAppLocked( 3011 IApplicationThread thread) { 3012 if (thread == null) { 3013 return null; 3014 } 3015 3016 int appIndex = getLRURecordIndexForAppLocked(thread); 3017 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3018 } 3019 3020 final void appDiedLocked(ProcessRecord app, int pid, 3021 IApplicationThread thread) { 3022 3023 mProcDeaths[0]++; 3024 3025 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3026 synchronized (stats) { 3027 stats.noteProcessDiedLocked(app.info.uid, pid); 3028 } 3029 3030 // Clean up already done if the process has been re-started. 3031 if (app.pid == pid && app.thread != null && 3032 app.thread.asBinder() == thread.asBinder()) { 3033 if (!app.killedBackground) { 3034 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3035 + ") has died."); 3036 } 3037 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3038 if (localLOGV) Slog.v( 3039 TAG, "Dying app: " + app + ", pid: " + pid 3040 + ", thread: " + thread.asBinder()); 3041 boolean doLowMem = app.instrumentationClass == null; 3042 handleAppDiedLocked(app, false, true); 3043 3044 if (doLowMem) { 3045 // If there are no longer any background processes running, 3046 // and the app that died was not running instrumentation, 3047 // then tell everyone we are now low on memory. 3048 boolean haveBg = false; 3049 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3050 ProcessRecord rec = mLruProcesses.get(i); 3051 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3052 haveBg = true; 3053 break; 3054 } 3055 } 3056 3057 if (!haveBg) { 3058 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3059 long now = SystemClock.uptimeMillis(); 3060 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3061 ProcessRecord rec = mLruProcesses.get(i); 3062 if (rec != app && rec.thread != null && 3063 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3064 // The low memory report is overriding any current 3065 // state for a GC request. Make sure to do 3066 // heavy/important/visible/foreground processes first. 3067 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3068 rec.lastRequestedGc = 0; 3069 } else { 3070 rec.lastRequestedGc = rec.lastLowMemory; 3071 } 3072 rec.reportLowMemory = true; 3073 rec.lastLowMemory = now; 3074 mProcessesToGc.remove(rec); 3075 addProcessToGcListLocked(rec); 3076 } 3077 } 3078 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3079 scheduleAppGcsLocked(); 3080 } 3081 } 3082 } else if (app.pid != pid) { 3083 // A new process has already been started. 3084 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3085 + ") has died and restarted (pid " + app.pid + ")."); 3086 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3087 } else if (DEBUG_PROCESSES) { 3088 Slog.d(TAG, "Received spurious death notification for thread " 3089 + thread.asBinder()); 3090 } 3091 } 3092 3093 /** 3094 * If a stack trace dump file is configured, dump process stack traces. 3095 * @param clearTraces causes the dump file to be erased prior to the new 3096 * traces being written, if true; when false, the new traces will be 3097 * appended to any existing file content. 3098 * @param firstPids of dalvik VM processes to dump stack traces for first 3099 * @param lastPids of dalvik VM processes to dump stack traces for last 3100 * @param nativeProcs optional list of native process names to dump stack crawls 3101 * @return file containing stack traces, or null if no dump file is configured 3102 */ 3103 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3104 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3105 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3106 if (tracesPath == null || tracesPath.length() == 0) { 3107 return null; 3108 } 3109 3110 File tracesFile = new File(tracesPath); 3111 try { 3112 File tracesDir = tracesFile.getParentFile(); 3113 if (!tracesDir.exists()) { 3114 tracesFile.mkdirs(); 3115 if (!SELinux.restorecon(tracesDir)) { 3116 return null; 3117 } 3118 } 3119 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3120 3121 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3122 tracesFile.createNewFile(); 3123 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3124 } catch (IOException e) { 3125 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3126 return null; 3127 } 3128 3129 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3130 return tracesFile; 3131 } 3132 3133 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3134 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3135 // Use a FileObserver to detect when traces finish writing. 3136 // The order of traces is considered important to maintain for legibility. 3137 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3138 public synchronized void onEvent(int event, String path) { notify(); } 3139 }; 3140 3141 try { 3142 observer.startWatching(); 3143 3144 // First collect all of the stacks of the most important pids. 3145 if (firstPids != null) { 3146 try { 3147 int num = firstPids.size(); 3148 for (int i = 0; i < num; i++) { 3149 synchronized (observer) { 3150 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3151 observer.wait(200); // Wait for write-close, give up after 200msec 3152 } 3153 } 3154 } catch (InterruptedException e) { 3155 Log.wtf(TAG, e); 3156 } 3157 } 3158 3159 // Next measure CPU usage. 3160 if (processStats != null) { 3161 processStats.init(); 3162 System.gc(); 3163 processStats.update(); 3164 try { 3165 synchronized (processStats) { 3166 processStats.wait(500); // measure over 1/2 second. 3167 } 3168 } catch (InterruptedException e) { 3169 } 3170 processStats.update(); 3171 3172 // We'll take the stack crawls of just the top apps using CPU. 3173 final int N = processStats.countWorkingStats(); 3174 int numProcs = 0; 3175 for (int i=0; i<N && numProcs<5; i++) { 3176 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3177 if (lastPids.indexOfKey(stats.pid) >= 0) { 3178 numProcs++; 3179 try { 3180 synchronized (observer) { 3181 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3182 observer.wait(200); // Wait for write-close, give up after 200msec 3183 } 3184 } catch (InterruptedException e) { 3185 Log.wtf(TAG, e); 3186 } 3187 3188 } 3189 } 3190 } 3191 3192 } finally { 3193 observer.stopWatching(); 3194 } 3195 3196 if (nativeProcs != null) { 3197 int[] pids = Process.getPidsForCommands(nativeProcs); 3198 if (pids != null) { 3199 for (int pid : pids) { 3200 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3201 } 3202 } 3203 } 3204 } 3205 3206 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3207 if (true || IS_USER_BUILD) { 3208 return; 3209 } 3210 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3211 if (tracesPath == null || tracesPath.length() == 0) { 3212 return; 3213 } 3214 3215 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3216 StrictMode.allowThreadDiskWrites(); 3217 try { 3218 final File tracesFile = new File(tracesPath); 3219 final File tracesDir = tracesFile.getParentFile(); 3220 final File tracesTmp = new File(tracesDir, "__tmp__"); 3221 try { 3222 if (!tracesDir.exists()) { 3223 tracesFile.mkdirs(); 3224 if (!SELinux.restorecon(tracesDir.getPath())) { 3225 return; 3226 } 3227 } 3228 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3229 3230 if (tracesFile.exists()) { 3231 tracesTmp.delete(); 3232 tracesFile.renameTo(tracesTmp); 3233 } 3234 StringBuilder sb = new StringBuilder(); 3235 Time tobj = new Time(); 3236 tobj.set(System.currentTimeMillis()); 3237 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3238 sb.append(": "); 3239 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3240 sb.append(" since "); 3241 sb.append(msg); 3242 FileOutputStream fos = new FileOutputStream(tracesFile); 3243 fos.write(sb.toString().getBytes()); 3244 if (app == null) { 3245 fos.write("\n*** No application process!".getBytes()); 3246 } 3247 fos.close(); 3248 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3249 } catch (IOException e) { 3250 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3251 return; 3252 } 3253 3254 if (app != null) { 3255 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3256 firstPids.add(app.pid); 3257 dumpStackTraces(tracesPath, firstPids, null, null, null); 3258 } 3259 3260 File lastTracesFile = null; 3261 File curTracesFile = null; 3262 for (int i=9; i>=0; i--) { 3263 String name = String.format("slow%02d.txt", i); 3264 curTracesFile = new File(tracesDir, name); 3265 if (curTracesFile.exists()) { 3266 if (lastTracesFile != null) { 3267 curTracesFile.renameTo(lastTracesFile); 3268 } else { 3269 curTracesFile.delete(); 3270 } 3271 } 3272 lastTracesFile = curTracesFile; 3273 } 3274 tracesFile.renameTo(curTracesFile); 3275 if (tracesTmp.exists()) { 3276 tracesTmp.renameTo(tracesFile); 3277 } 3278 } finally { 3279 StrictMode.setThreadPolicy(oldPolicy); 3280 } 3281 } 3282 3283 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3284 ActivityRecord parent, final String annotation) { 3285 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3286 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3287 3288 if (mController != null) { 3289 try { 3290 // 0 == continue, -1 = kill process immediately 3291 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3292 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3293 } catch (RemoteException e) { 3294 mController = null; 3295 } 3296 } 3297 3298 long anrTime = SystemClock.uptimeMillis(); 3299 if (MONITOR_CPU_USAGE) { 3300 updateCpuStatsNow(); 3301 } 3302 3303 synchronized (this) { 3304 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3305 if (mShuttingDown) { 3306 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3307 return; 3308 } else if (app.notResponding) { 3309 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3310 return; 3311 } else if (app.crashing) { 3312 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3313 return; 3314 } 3315 3316 // In case we come through here for the same app before completing 3317 // this one, mark as anring now so we will bail out. 3318 app.notResponding = true; 3319 3320 // Log the ANR to the event log. 3321 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3322 annotation); 3323 3324 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3325 firstPids.add(app.pid); 3326 3327 int parentPid = app.pid; 3328 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3329 if (parentPid != app.pid) firstPids.add(parentPid); 3330 3331 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3332 3333 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3334 ProcessRecord r = mLruProcesses.get(i); 3335 if (r != null && r.thread != null) { 3336 int pid = r.pid; 3337 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3338 if (r.persistent) { 3339 firstPids.add(pid); 3340 } else { 3341 lastPids.put(pid, Boolean.TRUE); 3342 } 3343 } 3344 } 3345 } 3346 } 3347 3348 // Log the ANR to the main log. 3349 StringBuilder info = new StringBuilder(); 3350 info.setLength(0); 3351 info.append("ANR in ").append(app.processName); 3352 if (activity != null && activity.shortComponentName != null) { 3353 info.append(" (").append(activity.shortComponentName).append(")"); 3354 } 3355 info.append("\n"); 3356 if (annotation != null) { 3357 info.append("Reason: ").append(annotation).append("\n"); 3358 } 3359 if (parent != null && parent != activity) { 3360 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3361 } 3362 3363 final ProcessStats processStats = new ProcessStats(true); 3364 3365 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3366 3367 String cpuInfo = null; 3368 if (MONITOR_CPU_USAGE) { 3369 updateCpuStatsNow(); 3370 synchronized (mProcessStatsThread) { 3371 cpuInfo = mProcessStats.printCurrentState(anrTime); 3372 } 3373 info.append(processStats.printCurrentLoad()); 3374 info.append(cpuInfo); 3375 } 3376 3377 info.append(processStats.printCurrentState(anrTime)); 3378 3379 Slog.e(TAG, info.toString()); 3380 if (tracesFile == null) { 3381 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3382 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3383 } 3384 3385 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3386 cpuInfo, tracesFile, null); 3387 3388 if (mController != null) { 3389 try { 3390 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3391 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3392 if (res != 0) { 3393 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3394 return; 3395 } 3396 } catch (RemoteException e) { 3397 mController = null; 3398 } 3399 } 3400 3401 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3402 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3403 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3404 3405 synchronized (this) { 3406 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3407 Slog.w(TAG, "Killing " + app + ": background ANR"); 3408 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3409 app.processName, app.setAdj, "background ANR"); 3410 Process.killProcessQuiet(app.pid); 3411 return; 3412 } 3413 3414 // Set the app's notResponding state, and look up the errorReportReceiver 3415 makeAppNotRespondingLocked(app, 3416 activity != null ? activity.shortComponentName : null, 3417 annotation != null ? "ANR " + annotation : "ANR", 3418 info.toString()); 3419 3420 // Bring up the infamous App Not Responding dialog 3421 Message msg = Message.obtain(); 3422 HashMap map = new HashMap(); 3423 msg.what = SHOW_NOT_RESPONDING_MSG; 3424 msg.obj = map; 3425 map.put("app", app); 3426 if (activity != null) { 3427 map.put("activity", activity); 3428 } 3429 3430 mHandler.sendMessage(msg); 3431 } 3432 } 3433 3434 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3435 if (!mLaunchWarningShown) { 3436 mLaunchWarningShown = true; 3437 mHandler.post(new Runnable() { 3438 @Override 3439 public void run() { 3440 synchronized (ActivityManagerService.this) { 3441 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3442 d.show(); 3443 mHandler.postDelayed(new Runnable() { 3444 @Override 3445 public void run() { 3446 synchronized (ActivityManagerService.this) { 3447 d.dismiss(); 3448 mLaunchWarningShown = false; 3449 } 3450 } 3451 }, 4000); 3452 } 3453 } 3454 }); 3455 } 3456 } 3457 3458 public boolean clearApplicationUserData(final String packageName, 3459 final IPackageDataObserver observer, int userId) { 3460 enforceNotIsolatedCaller("clearApplicationUserData"); 3461 int uid = Binder.getCallingUid(); 3462 int pid = Binder.getCallingPid(); 3463 userId = handleIncomingUserLocked(pid, uid, 3464 userId, false, true, "clearApplicationUserData", null); 3465 long callingId = Binder.clearCallingIdentity(); 3466 try { 3467 IPackageManager pm = AppGlobals.getPackageManager(); 3468 int pkgUid = -1; 3469 synchronized(this) { 3470 try { 3471 pkgUid = pm.getPackageUid(packageName, userId); 3472 } catch (RemoteException e) { 3473 } 3474 if (pkgUid == -1) { 3475 Slog.w(TAG, "Invalid packageName:" + packageName); 3476 return false; 3477 } 3478 if (uid == pkgUid || checkComponentPermission( 3479 android.Manifest.permission.CLEAR_APP_USER_DATA, 3480 pid, uid, -1, true) 3481 == PackageManager.PERMISSION_GRANTED) { 3482 forceStopPackageLocked(packageName, pkgUid); 3483 } else { 3484 throw new SecurityException(pid+" does not have permission:"+ 3485 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3486 "for process:"+packageName); 3487 } 3488 } 3489 3490 try { 3491 //clear application user data 3492 pm.clearApplicationUserData(packageName, observer, userId); 3493 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3494 Uri.fromParts("package", packageName, null)); 3495 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3496 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3497 null, null, 0, null, null, null, false, false, userId); 3498 } catch (RemoteException e) { 3499 } 3500 } finally { 3501 Binder.restoreCallingIdentity(callingId); 3502 } 3503 return true; 3504 } 3505 3506 public void killBackgroundProcesses(final String packageName, int userId) { 3507 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3508 != PackageManager.PERMISSION_GRANTED && 3509 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3510 != PackageManager.PERMISSION_GRANTED) { 3511 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3512 + Binder.getCallingPid() 3513 + ", uid=" + Binder.getCallingUid() 3514 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3515 Slog.w(TAG, msg); 3516 throw new SecurityException(msg); 3517 } 3518 3519 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3520 userId, true, true, "killBackgroundProcesses", null); 3521 long callingId = Binder.clearCallingIdentity(); 3522 try { 3523 IPackageManager pm = AppGlobals.getPackageManager(); 3524 synchronized(this) { 3525 int appId = -1; 3526 try { 3527 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3528 } catch (RemoteException e) { 3529 } 3530 if (appId == -1) { 3531 Slog.w(TAG, "Invalid packageName: " + packageName); 3532 return; 3533 } 3534 killPackageProcessesLocked(packageName, appId, userId, 3535 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3536 } 3537 } finally { 3538 Binder.restoreCallingIdentity(callingId); 3539 } 3540 } 3541 3542 public void killAllBackgroundProcesses() { 3543 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3544 != PackageManager.PERMISSION_GRANTED) { 3545 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3546 + Binder.getCallingPid() 3547 + ", uid=" + Binder.getCallingUid() 3548 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3549 Slog.w(TAG, msg); 3550 throw new SecurityException(msg); 3551 } 3552 3553 long callingId = Binder.clearCallingIdentity(); 3554 try { 3555 synchronized(this) { 3556 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3557 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3558 final int NA = apps.size(); 3559 for (int ia=0; ia<NA; ia++) { 3560 ProcessRecord app = apps.valueAt(ia); 3561 if (app.persistent) { 3562 // we don't kill persistent processes 3563 continue; 3564 } 3565 if (app.removed) { 3566 procs.add(app); 3567 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3568 app.removed = true; 3569 procs.add(app); 3570 } 3571 } 3572 } 3573 3574 int N = procs.size(); 3575 for (int i=0; i<N; i++) { 3576 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3577 } 3578 } 3579 } finally { 3580 Binder.restoreCallingIdentity(callingId); 3581 } 3582 } 3583 3584 public void forceStopPackage(final String packageName, int userId) { 3585 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3586 != PackageManager.PERMISSION_GRANTED) { 3587 String msg = "Permission Denial: forceStopPackage() from pid=" 3588 + Binder.getCallingPid() 3589 + ", uid=" + Binder.getCallingUid() 3590 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3591 Slog.w(TAG, msg); 3592 throw new SecurityException(msg); 3593 } 3594 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3595 userId, true, true, "forceStopPackage", null); 3596 long callingId = Binder.clearCallingIdentity(); 3597 try { 3598 IPackageManager pm = AppGlobals.getPackageManager(); 3599 synchronized(this) { 3600 int[] users = userId == UserHandle.USER_ALL 3601 ? getUsersLocked() : new int[] { userId }; 3602 for (int user : users) { 3603 int pkgUid = -1; 3604 try { 3605 pkgUid = pm.getPackageUid(packageName, user); 3606 } catch (RemoteException e) { 3607 } 3608 if (pkgUid == -1) { 3609 Slog.w(TAG, "Invalid packageName: " + packageName); 3610 continue; 3611 } 3612 try { 3613 pm.setPackageStoppedState(packageName, true, user); 3614 } catch (RemoteException e) { 3615 } catch (IllegalArgumentException e) { 3616 Slog.w(TAG, "Failed trying to unstop package " 3617 + packageName + ": " + e); 3618 } 3619 if (isUserRunningLocked(user)) { 3620 forceStopPackageLocked(packageName, pkgUid); 3621 } 3622 } 3623 } 3624 } finally { 3625 Binder.restoreCallingIdentity(callingId); 3626 } 3627 } 3628 3629 /* 3630 * The pkg name and app id have to be specified. 3631 */ 3632 public void killApplicationWithAppId(String pkg, int appid) { 3633 if (pkg == null) { 3634 return; 3635 } 3636 // Make sure the uid is valid. 3637 if (appid < 0) { 3638 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3639 return; 3640 } 3641 int callerUid = Binder.getCallingUid(); 3642 // Only the system server can kill an application 3643 if (callerUid == Process.SYSTEM_UID) { 3644 // Post an aysnc message to kill the application 3645 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3646 msg.arg1 = appid; 3647 msg.arg2 = 0; 3648 msg.obj = pkg; 3649 mHandler.sendMessage(msg); 3650 } else { 3651 throw new SecurityException(callerUid + " cannot kill pkg: " + 3652 pkg); 3653 } 3654 } 3655 3656 public void closeSystemDialogs(String reason) { 3657 enforceNotIsolatedCaller("closeSystemDialogs"); 3658 3659 final int pid = Binder.getCallingPid(); 3660 final int uid = Binder.getCallingUid(); 3661 final long origId = Binder.clearCallingIdentity(); 3662 try { 3663 synchronized (this) { 3664 // Only allow this from foreground processes, so that background 3665 // applications can't abuse it to prevent system UI from being shown. 3666 if (uid >= Process.FIRST_APPLICATION_UID) { 3667 ProcessRecord proc; 3668 synchronized (mPidsSelfLocked) { 3669 proc = mPidsSelfLocked.get(pid); 3670 } 3671 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3672 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3673 + " from background process " + proc); 3674 return; 3675 } 3676 } 3677 closeSystemDialogsLocked(reason); 3678 } 3679 } finally { 3680 Binder.restoreCallingIdentity(origId); 3681 } 3682 } 3683 3684 void closeSystemDialogsLocked(String reason) { 3685 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3686 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3687 if (reason != null) { 3688 intent.putExtra("reason", reason); 3689 } 3690 mWindowManager.closeSystemDialogs(reason); 3691 3692 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3693 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3694 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3695 r.stack.finishActivityLocked(r, i, 3696 Activity.RESULT_CANCELED, null, "close-sys", true); 3697 } 3698 } 3699 3700 broadcastIntentLocked(null, null, intent, null, 3701 null, 0, null, null, null, false, false, -1, 3702 Process.SYSTEM_UID, UserHandle.USER_ALL); 3703 } 3704 3705 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3706 throws RemoteException { 3707 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3708 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3709 for (int i=pids.length-1; i>=0; i--) { 3710 infos[i] = new Debug.MemoryInfo(); 3711 Debug.getMemoryInfo(pids[i], infos[i]); 3712 } 3713 return infos; 3714 } 3715 3716 public long[] getProcessPss(int[] pids) throws RemoteException { 3717 enforceNotIsolatedCaller("getProcessPss"); 3718 long[] pss = new long[pids.length]; 3719 for (int i=pids.length-1; i>=0; i--) { 3720 pss[i] = Debug.getPss(pids[i]); 3721 } 3722 return pss; 3723 } 3724 3725 public void killApplicationProcess(String processName, int uid) { 3726 if (processName == null) { 3727 return; 3728 } 3729 3730 int callerUid = Binder.getCallingUid(); 3731 // Only the system server can kill an application 3732 if (callerUid == Process.SYSTEM_UID) { 3733 synchronized (this) { 3734 ProcessRecord app = getProcessRecordLocked(processName, uid); 3735 if (app != null && app.thread != null) { 3736 try { 3737 app.thread.scheduleSuicide(); 3738 } catch (RemoteException e) { 3739 // If the other end already died, then our work here is done. 3740 } 3741 } else { 3742 Slog.w(TAG, "Process/uid not found attempting kill of " 3743 + processName + " / " + uid); 3744 } 3745 } 3746 } else { 3747 throw new SecurityException(callerUid + " cannot kill app process: " + 3748 processName); 3749 } 3750 } 3751 3752 private void forceStopPackageLocked(final String packageName, int uid) { 3753 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3754 false, true, false, UserHandle.getUserId(uid)); 3755 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3756 Uri.fromParts("package", packageName, null)); 3757 if (!mProcessesReady) { 3758 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3759 } 3760 intent.putExtra(Intent.EXTRA_UID, uid); 3761 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 3762 broadcastIntentLocked(null, null, intent, 3763 null, null, 0, null, null, null, 3764 false, false, 3765 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3766 } 3767 3768 private void forceStopUserLocked(int userId) { 3769 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3770 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3771 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3772 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3773 broadcastIntentLocked(null, null, intent, 3774 null, null, 0, null, null, null, 3775 false, false, 3776 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3777 } 3778 3779 private final boolean killPackageProcessesLocked(String packageName, int appId, 3780 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3781 boolean doit, boolean evenPersistent, String reason) { 3782 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3783 3784 // Remove all processes this package may have touched: all with the 3785 // same UID (except for the system or root user), and all whose name 3786 // matches the package name. 3787 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3788 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3789 final int NA = apps.size(); 3790 for (int ia=0; ia<NA; ia++) { 3791 ProcessRecord app = apps.valueAt(ia); 3792 if (app.persistent && !evenPersistent) { 3793 // we don't kill persistent processes 3794 continue; 3795 } 3796 if (app.removed) { 3797 if (doit) { 3798 procs.add(app); 3799 } 3800 continue; 3801 } 3802 3803 // Skip process if it doesn't meet our oom adj requirement. 3804 if (app.setAdj < minOomAdj) { 3805 continue; 3806 } 3807 3808 // If no package is specified, we call all processes under the 3809 // give user id. 3810 if (packageName == null) { 3811 if (app.userId != userId) { 3812 continue; 3813 } 3814 // Package has been specified, we want to hit all processes 3815 // that match it. We need to qualify this by the processes 3816 // that are running under the specified app and user ID. 3817 } else { 3818 if (UserHandle.getAppId(app.uid) != appId) { 3819 continue; 3820 } 3821 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3822 continue; 3823 } 3824 if (!app.pkgList.contains(packageName)) { 3825 continue; 3826 } 3827 } 3828 3829 // Process has passed all conditions, kill it! 3830 if (!doit) { 3831 return true; 3832 } 3833 app.removed = true; 3834 procs.add(app); 3835 } 3836 } 3837 3838 int N = procs.size(); 3839 for (int i=0; i<N; i++) { 3840 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3841 } 3842 return N > 0; 3843 } 3844 3845 private final boolean forceStopPackageLocked(String name, int appId, 3846 boolean callerWillRestart, boolean purgeCache, boolean doit, 3847 boolean evenPersistent, int userId) { 3848 int i; 3849 int N; 3850 3851 if (userId == UserHandle.USER_ALL && name == null) { 3852 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3853 } 3854 3855 if (appId < 0 && name != null) { 3856 try { 3857 appId = UserHandle.getAppId( 3858 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3859 } catch (RemoteException e) { 3860 } 3861 } 3862 3863 if (doit) { 3864 if (name != null) { 3865 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3866 + " user=" + userId); 3867 } else { 3868 Slog.i(TAG, "Force stopping user " + userId); 3869 } 3870 3871 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3872 while (badApps.hasNext()) { 3873 SparseArray<Long> ba = badApps.next(); 3874 for (i=ba.size()-1; i>=0; i--) { 3875 boolean remove = false; 3876 final int entUid = ba.keyAt(i); 3877 if (name != null) { 3878 if (userId == UserHandle.USER_ALL) { 3879 if (UserHandle.getAppId(entUid) == appId) { 3880 remove = true; 3881 } 3882 } else { 3883 if (entUid == UserHandle.getUid(userId, appId)) { 3884 remove = true; 3885 } 3886 } 3887 } else if (UserHandle.getUserId(entUid) == userId) { 3888 remove = true; 3889 } 3890 if (remove) { 3891 ba.removeAt(i); 3892 } 3893 } 3894 if (ba.size() == 0) { 3895 badApps.remove(); 3896 } 3897 } 3898 } 3899 3900 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3901 -100, callerWillRestart, false, doit, evenPersistent, 3902 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3903 3904 TaskRecord lastTask = null; 3905 for (i=0; i<mMainStack.mHistory.size(); i++) { 3906 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3907 final boolean samePackage = r.packageName.equals(name) 3908 || (name == null && r.userId == userId); 3909 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3910 && (samePackage || r.task == lastTask) 3911 && (r.app == null || evenPersistent || !r.app.persistent)) { 3912 if (!doit) { 3913 if (r.finishing) { 3914 // If this activity is just finishing, then it is not 3915 // interesting as far as something to stop. 3916 continue; 3917 } 3918 return true; 3919 } 3920 didSomething = true; 3921 Slog.i(TAG, " Force finishing activity " + r); 3922 if (samePackage) { 3923 if (r.app != null) { 3924 r.app.removed = true; 3925 } 3926 r.app = null; 3927 } 3928 lastTask = r.task; 3929 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3930 null, "force-stop", true)) { 3931 i--; 3932 } 3933 } 3934 } 3935 3936 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3937 if (!doit) { 3938 return true; 3939 } 3940 didSomething = true; 3941 } 3942 3943 if (name == null) { 3944 // Remove all sticky broadcasts from this user. 3945 mStickyBroadcasts.remove(userId); 3946 } 3947 3948 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3949 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3950 userId, providers)) { 3951 if (!doit) { 3952 return true; 3953 } 3954 didSomething = true; 3955 } 3956 N = providers.size(); 3957 for (i=0; i<N; i++) { 3958 removeDyingProviderLocked(null, providers.get(i), true); 3959 } 3960 3961 if (mIntentSenderRecords.size() > 0) { 3962 Iterator<WeakReference<PendingIntentRecord>> it 3963 = mIntentSenderRecords.values().iterator(); 3964 while (it.hasNext()) { 3965 WeakReference<PendingIntentRecord> wpir = it.next(); 3966 if (wpir == null) { 3967 it.remove(); 3968 continue; 3969 } 3970 PendingIntentRecord pir = wpir.get(); 3971 if (pir == null) { 3972 it.remove(); 3973 continue; 3974 } 3975 if (name == null) { 3976 // Stopping user, remove all objects for the user. 3977 if (pir.key.userId != userId) { 3978 // Not the same user, skip it. 3979 continue; 3980 } 3981 } else { 3982 if (UserHandle.getAppId(pir.uid) != appId) { 3983 // Different app id, skip it. 3984 continue; 3985 } 3986 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3987 // Different user, skip it. 3988 continue; 3989 } 3990 if (!pir.key.packageName.equals(name)) { 3991 // Different package, skip it. 3992 continue; 3993 } 3994 } 3995 if (!doit) { 3996 return true; 3997 } 3998 didSomething = true; 3999 it.remove(); 4000 pir.canceled = true; 4001 if (pir.key.activity != null) { 4002 pir.key.activity.pendingResults.remove(pir.ref); 4003 } 4004 } 4005 } 4006 4007 if (doit) { 4008 if (purgeCache && name != null) { 4009 AttributeCache ac = AttributeCache.instance(); 4010 if (ac != null) { 4011 ac.removePackage(name); 4012 } 4013 } 4014 if (mBooted) { 4015 mMainStack.resumeTopActivityLocked(null); 4016 mMainStack.scheduleIdleLocked(); 4017 } 4018 } 4019 4020 return didSomething; 4021 } 4022 4023 private final boolean removeProcessLocked(ProcessRecord app, 4024 boolean callerWillRestart, boolean allowRestart, String reason) { 4025 final String name = app.processName; 4026 final int uid = app.uid; 4027 if (DEBUG_PROCESSES) Slog.d( 4028 TAG, "Force removing proc " + app.toShortString() + " (" + name 4029 + "/" + uid + ")"); 4030 4031 mProcessNames.remove(name, uid); 4032 mIsolatedProcesses.remove(app.uid); 4033 if (mHeavyWeightProcess == app) { 4034 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4035 mHeavyWeightProcess.userId, 0)); 4036 mHeavyWeightProcess = null; 4037 } 4038 boolean needRestart = false; 4039 if (app.pid > 0 && app.pid != MY_PID) { 4040 int pid = app.pid; 4041 synchronized (mPidsSelfLocked) { 4042 mPidsSelfLocked.remove(pid); 4043 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4044 } 4045 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4046 handleAppDiedLocked(app, true, allowRestart); 4047 mLruProcesses.remove(app); 4048 Process.killProcessQuiet(pid); 4049 4050 if (app.persistent && !app.isolated) { 4051 if (!callerWillRestart) { 4052 addAppLocked(app.info, false); 4053 } else { 4054 needRestart = true; 4055 } 4056 } 4057 } else { 4058 mRemovedProcesses.add(app); 4059 } 4060 4061 return needRestart; 4062 } 4063 4064 private final void processStartTimedOutLocked(ProcessRecord app) { 4065 final int pid = app.pid; 4066 boolean gone = false; 4067 synchronized (mPidsSelfLocked) { 4068 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4069 if (knownApp != null && knownApp.thread == null) { 4070 mPidsSelfLocked.remove(pid); 4071 gone = true; 4072 } 4073 } 4074 4075 if (gone) { 4076 Slog.w(TAG, "Process " + app + " failed to attach"); 4077 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4078 app.processName); 4079 mProcessNames.remove(app.processName, app.uid); 4080 mIsolatedProcesses.remove(app.uid); 4081 if (mHeavyWeightProcess == app) { 4082 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4083 mHeavyWeightProcess.userId, 0)); 4084 mHeavyWeightProcess = null; 4085 } 4086 // Take care of any launching providers waiting for this process. 4087 checkAppInLaunchingProvidersLocked(app, true); 4088 // Take care of any services that are waiting for the process. 4089 mServices.processStartTimedOutLocked(app); 4090 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4091 app.processName, app.setAdj, "start timeout"); 4092 Process.killProcessQuiet(pid); 4093 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4094 Slog.w(TAG, "Unattached app died before backup, skipping"); 4095 try { 4096 IBackupManager bm = IBackupManager.Stub.asInterface( 4097 ServiceManager.getService(Context.BACKUP_SERVICE)); 4098 bm.agentDisconnected(app.info.packageName); 4099 } catch (RemoteException e) { 4100 // Can't happen; the backup manager is local 4101 } 4102 } 4103 if (isPendingBroadcastProcessLocked(pid)) { 4104 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4105 skipPendingBroadcastLocked(pid); 4106 } 4107 } else { 4108 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4109 } 4110 } 4111 4112 private final boolean attachApplicationLocked(IApplicationThread thread, 4113 int pid) { 4114 4115 // Find the application record that is being attached... either via 4116 // the pid if we are running in multiple processes, or just pull the 4117 // next app record if we are emulating process with anonymous threads. 4118 ProcessRecord app; 4119 if (pid != MY_PID && pid >= 0) { 4120 synchronized (mPidsSelfLocked) { 4121 app = mPidsSelfLocked.get(pid); 4122 } 4123 } else { 4124 app = null; 4125 } 4126 4127 if (app == null) { 4128 Slog.w(TAG, "No pending application record for pid " + pid 4129 + " (IApplicationThread " + thread + "); dropping process"); 4130 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4131 if (pid > 0 && pid != MY_PID) { 4132 Process.killProcessQuiet(pid); 4133 } else { 4134 try { 4135 thread.scheduleExit(); 4136 } catch (Exception e) { 4137 // Ignore exceptions. 4138 } 4139 } 4140 return false; 4141 } 4142 4143 // If this application record is still attached to a previous 4144 // process, clean it up now. 4145 if (app.thread != null) { 4146 handleAppDiedLocked(app, true, true); 4147 } 4148 4149 // Tell the process all about itself. 4150 4151 if (localLOGV) Slog.v( 4152 TAG, "Binding process pid " + pid + " to record " + app); 4153 4154 String processName = app.processName; 4155 try { 4156 AppDeathRecipient adr = new AppDeathRecipient( 4157 app, pid, thread); 4158 thread.asBinder().linkToDeath(adr, 0); 4159 app.deathRecipient = adr; 4160 } catch (RemoteException e) { 4161 app.resetPackageList(); 4162 startProcessLocked(app, "link fail", processName); 4163 return false; 4164 } 4165 4166 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4167 4168 app.thread = thread; 4169 app.curAdj = app.setAdj = -100; 4170 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4171 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4172 app.forcingToForeground = null; 4173 app.foregroundServices = false; 4174 app.hasShownUi = false; 4175 app.debugging = false; 4176 4177 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4178 4179 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4180 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4181 4182 if (!normalMode) { 4183 Slog.i(TAG, "Launching preboot mode app: " + app); 4184 } 4185 4186 if (localLOGV) Slog.v( 4187 TAG, "New app record " + app 4188 + " thread=" + thread.asBinder() + " pid=" + pid); 4189 try { 4190 int testMode = IApplicationThread.DEBUG_OFF; 4191 if (mDebugApp != null && mDebugApp.equals(processName)) { 4192 testMode = mWaitForDebugger 4193 ? IApplicationThread.DEBUG_WAIT 4194 : IApplicationThread.DEBUG_ON; 4195 app.debugging = true; 4196 if (mDebugTransient) { 4197 mDebugApp = mOrigDebugApp; 4198 mWaitForDebugger = mOrigWaitForDebugger; 4199 } 4200 } 4201 String profileFile = app.instrumentationProfileFile; 4202 ParcelFileDescriptor profileFd = null; 4203 boolean profileAutoStop = false; 4204 if (mProfileApp != null && mProfileApp.equals(processName)) { 4205 mProfileProc = app; 4206 profileFile = mProfileFile; 4207 profileFd = mProfileFd; 4208 profileAutoStop = mAutoStopProfiler; 4209 } 4210 boolean enableOpenGlTrace = false; 4211 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4212 enableOpenGlTrace = true; 4213 mOpenGlTraceApp = null; 4214 } 4215 4216 // If the app is being launched for restore or full backup, set it up specially 4217 boolean isRestrictedBackupMode = false; 4218 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4219 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4220 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4221 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4222 } 4223 4224 ensurePackageDexOpt(app.instrumentationInfo != null 4225 ? app.instrumentationInfo.packageName 4226 : app.info.packageName); 4227 if (app.instrumentationClass != null) { 4228 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4229 } 4230 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4231 + processName + " with config " + mConfiguration); 4232 ApplicationInfo appInfo = app.instrumentationInfo != null 4233 ? app.instrumentationInfo : app.info; 4234 app.compat = compatibilityInfoForPackageLocked(appInfo); 4235 if (profileFd != null) { 4236 profileFd = profileFd.dup(); 4237 } 4238 thread.bindApplication(processName, appInfo, providers, 4239 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4240 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4241 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4242 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4243 mCoreSettingsObserver.getCoreSettingsLocked()); 4244 updateLruProcessLocked(app, false, true); 4245 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4246 } catch (Exception e) { 4247 // todo: Yikes! What should we do? For now we will try to 4248 // start another process, but that could easily get us in 4249 // an infinite loop of restarting processes... 4250 Slog.w(TAG, "Exception thrown during bind!", e); 4251 4252 app.resetPackageList(); 4253 app.unlinkDeathRecipient(); 4254 startProcessLocked(app, "bind fail", processName); 4255 return false; 4256 } 4257 4258 // Remove this record from the list of starting applications. 4259 mPersistentStartingProcesses.remove(app); 4260 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4261 "Attach application locked removing on hold: " + app); 4262 mProcessesOnHold.remove(app); 4263 4264 boolean badApp = false; 4265 boolean didSomething = false; 4266 4267 // See if the top visible activity is waiting to run in this process... 4268 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4269 if (hr != null && normalMode) { 4270 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4271 && processName.equals(hr.processName)) { 4272 try { 4273 if (mHeadless) { 4274 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4275 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4276 didSomething = true; 4277 } 4278 } catch (Exception e) { 4279 Slog.w(TAG, "Exception in new application when starting activity " 4280 + hr.intent.getComponent().flattenToShortString(), e); 4281 badApp = true; 4282 } 4283 } else { 4284 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4285 } 4286 } 4287 4288 // Find any services that should be running in this process... 4289 if (!badApp) { 4290 try { 4291 didSomething |= mServices.attachApplicationLocked(app, processName); 4292 } catch (Exception e) { 4293 badApp = true; 4294 } 4295 } 4296 4297 // Check if a next-broadcast receiver is in this process... 4298 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4299 try { 4300 didSomething = sendPendingBroadcastsLocked(app); 4301 } catch (Exception e) { 4302 // If the app died trying to launch the receiver we declare it 'bad' 4303 badApp = true; 4304 } 4305 } 4306 4307 // Check whether the next backup agent is in this process... 4308 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4309 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4310 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4311 try { 4312 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4313 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4314 mBackupTarget.backupMode); 4315 } catch (Exception e) { 4316 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4317 e.printStackTrace(); 4318 } 4319 } 4320 4321 if (badApp) { 4322 // todo: Also need to kill application to deal with all 4323 // kinds of exceptions. 4324 handleAppDiedLocked(app, false, true); 4325 return false; 4326 } 4327 4328 if (!didSomething) { 4329 updateOomAdjLocked(); 4330 } 4331 4332 return true; 4333 } 4334 4335 public final void attachApplication(IApplicationThread thread) { 4336 synchronized (this) { 4337 int callingPid = Binder.getCallingPid(); 4338 final long origId = Binder.clearCallingIdentity(); 4339 attachApplicationLocked(thread, callingPid); 4340 Binder.restoreCallingIdentity(origId); 4341 } 4342 } 4343 4344 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4345 final long origId = Binder.clearCallingIdentity(); 4346 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4347 if (stopProfiling) { 4348 synchronized (this) { 4349 if (mProfileProc == r.app) { 4350 if (mProfileFd != null) { 4351 try { 4352 mProfileFd.close(); 4353 } catch (IOException e) { 4354 } 4355 clearProfilerLocked(); 4356 } 4357 } 4358 } 4359 } 4360 Binder.restoreCallingIdentity(origId); 4361 } 4362 4363 void enableScreenAfterBoot() { 4364 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4365 SystemClock.uptimeMillis()); 4366 mWindowManager.enableScreenAfterBoot(); 4367 4368 synchronized (this) { 4369 updateEventDispatchingLocked(); 4370 } 4371 } 4372 4373 public void showBootMessage(final CharSequence msg, final boolean always) { 4374 enforceNotIsolatedCaller("showBootMessage"); 4375 mWindowManager.showBootMessage(msg, always); 4376 } 4377 4378 public void dismissKeyguardOnNextActivity() { 4379 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4380 final long token = Binder.clearCallingIdentity(); 4381 try { 4382 synchronized (this) { 4383 if (mLockScreenShown) { 4384 mLockScreenShown = false; 4385 comeOutOfSleepIfNeededLocked(); 4386 } 4387 mMainStack.dismissKeyguardOnNextActivityLocked(); 4388 } 4389 } finally { 4390 Binder.restoreCallingIdentity(token); 4391 } 4392 } 4393 4394 final void finishBooting() { 4395 IntentFilter pkgFilter = new IntentFilter(); 4396 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4397 pkgFilter.addDataScheme("package"); 4398 mContext.registerReceiver(new BroadcastReceiver() { 4399 @Override 4400 public void onReceive(Context context, Intent intent) { 4401 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4402 if (pkgs != null) { 4403 for (String pkg : pkgs) { 4404 synchronized (ActivityManagerService.this) { 4405 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4406 setResultCode(Activity.RESULT_OK); 4407 return; 4408 } 4409 } 4410 } 4411 } 4412 } 4413 }, pkgFilter); 4414 4415 synchronized (this) { 4416 // Ensure that any processes we had put on hold are now started 4417 // up. 4418 final int NP = mProcessesOnHold.size(); 4419 if (NP > 0) { 4420 ArrayList<ProcessRecord> procs = 4421 new ArrayList<ProcessRecord>(mProcessesOnHold); 4422 for (int ip=0; ip<NP; ip++) { 4423 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4424 + procs.get(ip)); 4425 startProcessLocked(procs.get(ip), "on-hold", null); 4426 } 4427 } 4428 4429 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4430 // Start looking for apps that are abusing wake locks. 4431 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4432 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4433 // Tell anyone interested that we are done booting! 4434 SystemProperties.set("sys.boot_completed", "1"); 4435 SystemProperties.set("dev.bootcomplete", "1"); 4436 for (int i=0; i<mStartedUsers.size(); i++) { 4437 UserStartedState uss = mStartedUsers.valueAt(i); 4438 if (uss.mState == UserStartedState.STATE_BOOTING) { 4439 uss.mState = UserStartedState.STATE_RUNNING; 4440 final int userId = mStartedUsers.keyAt(i); 4441 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4442 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4443 broadcastIntentLocked(null, null, intent, 4444 null, null, 0, null, null, 4445 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4446 false, false, MY_PID, Process.SYSTEM_UID, userId); 4447 } 4448 } 4449 } 4450 } 4451 } 4452 4453 final void ensureBootCompleted() { 4454 boolean booting; 4455 boolean enableScreen; 4456 synchronized (this) { 4457 booting = mBooting; 4458 mBooting = false; 4459 enableScreen = !mBooted; 4460 mBooted = true; 4461 } 4462 4463 if (booting) { 4464 finishBooting(); 4465 } 4466 4467 if (enableScreen) { 4468 enableScreenAfterBoot(); 4469 } 4470 } 4471 4472 public final void activityResumed(IBinder token) { 4473 final long origId = Binder.clearCallingIdentity(); 4474 mMainStack.activityResumed(token); 4475 Binder.restoreCallingIdentity(origId); 4476 } 4477 4478 public final void activityPaused(IBinder token) { 4479 final long origId = Binder.clearCallingIdentity(); 4480 mMainStack.activityPaused(token, false); 4481 Binder.restoreCallingIdentity(origId); 4482 } 4483 4484 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4485 CharSequence description) { 4486 if (localLOGV) Slog.v( 4487 TAG, "Activity stopped: token=" + token); 4488 4489 // Refuse possible leaked file descriptors 4490 if (icicle != null && icicle.hasFileDescriptors()) { 4491 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4492 } 4493 4494 ActivityRecord r = null; 4495 4496 final long origId = Binder.clearCallingIdentity(); 4497 4498 synchronized (this) { 4499 r = mMainStack.isInStackLocked(token); 4500 if (r != null) { 4501 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4502 } 4503 } 4504 4505 if (r != null) { 4506 sendPendingThumbnail(r, null, null, null, false); 4507 } 4508 4509 trimApplications(); 4510 4511 Binder.restoreCallingIdentity(origId); 4512 } 4513 4514 public final void activityDestroyed(IBinder token) { 4515 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4516 mMainStack.activityDestroyed(token); 4517 } 4518 4519 public String getCallingPackage(IBinder token) { 4520 synchronized (this) { 4521 ActivityRecord r = getCallingRecordLocked(token); 4522 return r != null && r.app != null ? r.info.packageName : null; 4523 } 4524 } 4525 4526 public ComponentName getCallingActivity(IBinder token) { 4527 synchronized (this) { 4528 ActivityRecord r = getCallingRecordLocked(token); 4529 return r != null ? r.intent.getComponent() : null; 4530 } 4531 } 4532 4533 private ActivityRecord getCallingRecordLocked(IBinder token) { 4534 ActivityRecord r = mMainStack.isInStackLocked(token); 4535 if (r == null) { 4536 return null; 4537 } 4538 return r.resultTo; 4539 } 4540 4541 public ComponentName getActivityClassForToken(IBinder token) { 4542 synchronized(this) { 4543 ActivityRecord r = mMainStack.isInStackLocked(token); 4544 if (r == null) { 4545 return null; 4546 } 4547 return r.intent.getComponent(); 4548 } 4549 } 4550 4551 public String getPackageForToken(IBinder token) { 4552 synchronized(this) { 4553 ActivityRecord r = mMainStack.isInStackLocked(token); 4554 if (r == null) { 4555 return null; 4556 } 4557 return r.packageName; 4558 } 4559 } 4560 4561 public IIntentSender getIntentSender(int type, 4562 String packageName, IBinder token, String resultWho, 4563 int requestCode, Intent[] intents, String[] resolvedTypes, 4564 int flags, Bundle options, int userId) { 4565 enforceNotIsolatedCaller("getIntentSender"); 4566 // Refuse possible leaked file descriptors 4567 if (intents != null) { 4568 if (intents.length < 1) { 4569 throw new IllegalArgumentException("Intents array length must be >= 1"); 4570 } 4571 for (int i=0; i<intents.length; i++) { 4572 Intent intent = intents[i]; 4573 if (intent != null) { 4574 if (intent.hasFileDescriptors()) { 4575 throw new IllegalArgumentException("File descriptors passed in Intent"); 4576 } 4577 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4578 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4579 throw new IllegalArgumentException( 4580 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4581 } 4582 intents[i] = new Intent(intent); 4583 } 4584 } 4585 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4586 throw new IllegalArgumentException( 4587 "Intent array length does not match resolvedTypes length"); 4588 } 4589 } 4590 if (options != null) { 4591 if (options.hasFileDescriptors()) { 4592 throw new IllegalArgumentException("File descriptors passed in options"); 4593 } 4594 } 4595 4596 synchronized(this) { 4597 int callingUid = Binder.getCallingUid(); 4598 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4599 false, true, "getIntentSender", null); 4600 try { 4601 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4602 int uid = AppGlobals.getPackageManager() 4603 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4604 if (!UserHandle.isSameApp(callingUid, uid)) { 4605 String msg = "Permission Denial: getIntentSender() from pid=" 4606 + Binder.getCallingPid() 4607 + ", uid=" + Binder.getCallingUid() 4608 + ", (need uid=" + uid + ")" 4609 + " is not allowed to send as package " + packageName; 4610 Slog.w(TAG, msg); 4611 throw new SecurityException(msg); 4612 } 4613 } 4614 4615 return getIntentSenderLocked(type, packageName, callingUid, userId, 4616 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4617 4618 } catch (RemoteException e) { 4619 throw new SecurityException(e); 4620 } 4621 } 4622 } 4623 4624 IIntentSender getIntentSenderLocked(int type, String packageName, 4625 int callingUid, int userId, IBinder token, String resultWho, 4626 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4627 Bundle options) { 4628 if (DEBUG_MU) 4629 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4630 ActivityRecord activity = null; 4631 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4632 activity = mMainStack.isInStackLocked(token); 4633 if (activity == null) { 4634 return null; 4635 } 4636 if (activity.finishing) { 4637 return null; 4638 } 4639 } 4640 4641 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4642 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4643 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4644 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4645 |PendingIntent.FLAG_UPDATE_CURRENT); 4646 4647 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4648 type, packageName, activity, resultWho, 4649 requestCode, intents, resolvedTypes, flags, options, userId); 4650 WeakReference<PendingIntentRecord> ref; 4651 ref = mIntentSenderRecords.get(key); 4652 PendingIntentRecord rec = ref != null ? ref.get() : null; 4653 if (rec != null) { 4654 if (!cancelCurrent) { 4655 if (updateCurrent) { 4656 if (rec.key.requestIntent != null) { 4657 rec.key.requestIntent.replaceExtras(intents != null ? 4658 intents[intents.length - 1] : null); 4659 } 4660 if (intents != null) { 4661 intents[intents.length-1] = rec.key.requestIntent; 4662 rec.key.allIntents = intents; 4663 rec.key.allResolvedTypes = resolvedTypes; 4664 } else { 4665 rec.key.allIntents = null; 4666 rec.key.allResolvedTypes = null; 4667 } 4668 } 4669 return rec; 4670 } 4671 rec.canceled = true; 4672 mIntentSenderRecords.remove(key); 4673 } 4674 if (noCreate) { 4675 return rec; 4676 } 4677 rec = new PendingIntentRecord(this, key, callingUid); 4678 mIntentSenderRecords.put(key, rec.ref); 4679 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4680 if (activity.pendingResults == null) { 4681 activity.pendingResults 4682 = new HashSet<WeakReference<PendingIntentRecord>>(); 4683 } 4684 activity.pendingResults.add(rec.ref); 4685 } 4686 return rec; 4687 } 4688 4689 public void cancelIntentSender(IIntentSender sender) { 4690 if (!(sender instanceof PendingIntentRecord)) { 4691 return; 4692 } 4693 synchronized(this) { 4694 PendingIntentRecord rec = (PendingIntentRecord)sender; 4695 try { 4696 int uid = AppGlobals.getPackageManager() 4697 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4698 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4699 String msg = "Permission Denial: cancelIntentSender() from pid=" 4700 + Binder.getCallingPid() 4701 + ", uid=" + Binder.getCallingUid() 4702 + " is not allowed to cancel packges " 4703 + rec.key.packageName; 4704 Slog.w(TAG, msg); 4705 throw new SecurityException(msg); 4706 } 4707 } catch (RemoteException e) { 4708 throw new SecurityException(e); 4709 } 4710 cancelIntentSenderLocked(rec, true); 4711 } 4712 } 4713 4714 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4715 rec.canceled = true; 4716 mIntentSenderRecords.remove(rec.key); 4717 if (cleanActivity && rec.key.activity != null) { 4718 rec.key.activity.pendingResults.remove(rec.ref); 4719 } 4720 } 4721 4722 public String getPackageForIntentSender(IIntentSender pendingResult) { 4723 if (!(pendingResult instanceof PendingIntentRecord)) { 4724 return null; 4725 } 4726 try { 4727 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4728 return res.key.packageName; 4729 } catch (ClassCastException e) { 4730 } 4731 return null; 4732 } 4733 4734 public int getUidForIntentSender(IIntentSender sender) { 4735 if (sender instanceof PendingIntentRecord) { 4736 try { 4737 PendingIntentRecord res = (PendingIntentRecord)sender; 4738 return res.uid; 4739 } catch (ClassCastException e) { 4740 } 4741 } 4742 return -1; 4743 } 4744 4745 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4746 if (!(pendingResult instanceof PendingIntentRecord)) { 4747 return false; 4748 } 4749 try { 4750 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4751 if (res.key.allIntents == null) { 4752 return false; 4753 } 4754 for (int i=0; i<res.key.allIntents.length; i++) { 4755 Intent intent = res.key.allIntents[i]; 4756 if (intent.getPackage() != null && intent.getComponent() != null) { 4757 return false; 4758 } 4759 } 4760 return true; 4761 } catch (ClassCastException e) { 4762 } 4763 return false; 4764 } 4765 4766 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4767 if (!(pendingResult instanceof PendingIntentRecord)) { 4768 return false; 4769 } 4770 try { 4771 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4772 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4773 return true; 4774 } 4775 return false; 4776 } catch (ClassCastException e) { 4777 } 4778 return false; 4779 } 4780 4781 public void setProcessLimit(int max) { 4782 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4783 "setProcessLimit()"); 4784 synchronized (this) { 4785 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4786 mProcessLimitOverride = max; 4787 } 4788 trimApplications(); 4789 } 4790 4791 public int getProcessLimit() { 4792 synchronized (this) { 4793 return mProcessLimitOverride; 4794 } 4795 } 4796 4797 void foregroundTokenDied(ForegroundToken token) { 4798 synchronized (ActivityManagerService.this) { 4799 synchronized (mPidsSelfLocked) { 4800 ForegroundToken cur 4801 = mForegroundProcesses.get(token.pid); 4802 if (cur != token) { 4803 return; 4804 } 4805 mForegroundProcesses.remove(token.pid); 4806 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4807 if (pr == null) { 4808 return; 4809 } 4810 pr.forcingToForeground = null; 4811 pr.foregroundServices = false; 4812 } 4813 updateOomAdjLocked(); 4814 } 4815 } 4816 4817 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4818 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4819 "setProcessForeground()"); 4820 synchronized(this) { 4821 boolean changed = false; 4822 4823 synchronized (mPidsSelfLocked) { 4824 ProcessRecord pr = mPidsSelfLocked.get(pid); 4825 if (pr == null && isForeground) { 4826 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4827 return; 4828 } 4829 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4830 if (oldToken != null) { 4831 oldToken.token.unlinkToDeath(oldToken, 0); 4832 mForegroundProcesses.remove(pid); 4833 if (pr != null) { 4834 pr.forcingToForeground = null; 4835 } 4836 changed = true; 4837 } 4838 if (isForeground && token != null) { 4839 ForegroundToken newToken = new ForegroundToken() { 4840 public void binderDied() { 4841 foregroundTokenDied(this); 4842 } 4843 }; 4844 newToken.pid = pid; 4845 newToken.token = token; 4846 try { 4847 token.linkToDeath(newToken, 0); 4848 mForegroundProcesses.put(pid, newToken); 4849 pr.forcingToForeground = token; 4850 changed = true; 4851 } catch (RemoteException e) { 4852 // If the process died while doing this, we will later 4853 // do the cleanup with the process death link. 4854 } 4855 } 4856 } 4857 4858 if (changed) { 4859 updateOomAdjLocked(); 4860 } 4861 } 4862 } 4863 4864 // ========================================================= 4865 // PERMISSIONS 4866 // ========================================================= 4867 4868 static class PermissionController extends IPermissionController.Stub { 4869 ActivityManagerService mActivityManagerService; 4870 PermissionController(ActivityManagerService activityManagerService) { 4871 mActivityManagerService = activityManagerService; 4872 } 4873 4874 public boolean checkPermission(String permission, int pid, int uid) { 4875 return mActivityManagerService.checkPermission(permission, pid, 4876 uid) == PackageManager.PERMISSION_GRANTED; 4877 } 4878 } 4879 4880 /** 4881 * This can be called with or without the global lock held. 4882 */ 4883 int checkComponentPermission(String permission, int pid, int uid, 4884 int owningUid, boolean exported) { 4885 // We might be performing an operation on behalf of an indirect binder 4886 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4887 // client identity accordingly before proceeding. 4888 Identity tlsIdentity = sCallerIdentity.get(); 4889 if (tlsIdentity != null) { 4890 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4891 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4892 uid = tlsIdentity.uid; 4893 pid = tlsIdentity.pid; 4894 } 4895 4896 if (pid == MY_PID) { 4897 return PackageManager.PERMISSION_GRANTED; 4898 } 4899 4900 return ActivityManager.checkComponentPermission(permission, uid, 4901 owningUid, exported); 4902 } 4903 4904 /** 4905 * As the only public entry point for permissions checking, this method 4906 * can enforce the semantic that requesting a check on a null global 4907 * permission is automatically denied. (Internally a null permission 4908 * string is used when calling {@link #checkComponentPermission} in cases 4909 * when only uid-based security is needed.) 4910 * 4911 * This can be called with or without the global lock held. 4912 */ 4913 public int checkPermission(String permission, int pid, int uid) { 4914 if (permission == null) { 4915 return PackageManager.PERMISSION_DENIED; 4916 } 4917 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4918 } 4919 4920 /** 4921 * Binder IPC calls go through the public entry point. 4922 * This can be called with or without the global lock held. 4923 */ 4924 int checkCallingPermission(String permission) { 4925 return checkPermission(permission, 4926 Binder.getCallingPid(), 4927 UserHandle.getAppId(Binder.getCallingUid())); 4928 } 4929 4930 /** 4931 * This can be called with or without the global lock held. 4932 */ 4933 void enforceCallingPermission(String permission, String func) { 4934 if (checkCallingPermission(permission) 4935 == PackageManager.PERMISSION_GRANTED) { 4936 return; 4937 } 4938 4939 String msg = "Permission Denial: " + func + " from pid=" 4940 + Binder.getCallingPid() 4941 + ", uid=" + Binder.getCallingUid() 4942 + " requires " + permission; 4943 Slog.w(TAG, msg); 4944 throw new SecurityException(msg); 4945 } 4946 4947 /** 4948 * Determine if UID is holding permissions required to access {@link Uri} in 4949 * the given {@link ProviderInfo}. Final permission checking is always done 4950 * in {@link ContentProvider}. 4951 */ 4952 private final boolean checkHoldingPermissionsLocked( 4953 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4954 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4955 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4956 4957 if (pi.applicationInfo.uid == uid) { 4958 return true; 4959 } else if (!pi.exported) { 4960 return false; 4961 } 4962 4963 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4964 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4965 try { 4966 // check if target holds top-level <provider> permissions 4967 if (!readMet && pi.readPermission != null 4968 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4969 readMet = true; 4970 } 4971 if (!writeMet && pi.writePermission != null 4972 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4973 writeMet = true; 4974 } 4975 4976 // track if unprotected read/write is allowed; any denied 4977 // <path-permission> below removes this ability 4978 boolean allowDefaultRead = pi.readPermission == null; 4979 boolean allowDefaultWrite = pi.writePermission == null; 4980 4981 // check if target holds any <path-permission> that match uri 4982 final PathPermission[] pps = pi.pathPermissions; 4983 if (pps != null) { 4984 final String path = uri.getPath(); 4985 int i = pps.length; 4986 while (i > 0 && (!readMet || !writeMet)) { 4987 i--; 4988 PathPermission pp = pps[i]; 4989 if (pp.match(path)) { 4990 if (!readMet) { 4991 final String pprperm = pp.getReadPermission(); 4992 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4993 + pprperm + " for " + pp.getPath() 4994 + ": match=" + pp.match(path) 4995 + " check=" + pm.checkUidPermission(pprperm, uid)); 4996 if (pprperm != null) { 4997 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4998 readMet = true; 4999 } else { 5000 allowDefaultRead = false; 5001 } 5002 } 5003 } 5004 if (!writeMet) { 5005 final String ppwperm = pp.getWritePermission(); 5006 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5007 + ppwperm + " for " + pp.getPath() 5008 + ": match=" + pp.match(path) 5009 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5010 if (ppwperm != null) { 5011 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5012 writeMet = true; 5013 } else { 5014 allowDefaultWrite = false; 5015 } 5016 } 5017 } 5018 } 5019 } 5020 } 5021 5022 // grant unprotected <provider> read/write, if not blocked by 5023 // <path-permission> above 5024 if (allowDefaultRead) readMet = true; 5025 if (allowDefaultWrite) writeMet = true; 5026 5027 } catch (RemoteException e) { 5028 return false; 5029 } 5030 5031 return readMet && writeMet; 5032 } 5033 5034 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5035 int modeFlags) { 5036 // Root gets to do everything. 5037 if (uid == 0) { 5038 return true; 5039 } 5040 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5041 if (perms == null) return false; 5042 UriPermission perm = perms.get(uri); 5043 if (perm == null) return false; 5044 return (modeFlags&perm.modeFlags) == modeFlags; 5045 } 5046 5047 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5048 enforceNotIsolatedCaller("checkUriPermission"); 5049 5050 // Another redirected-binder-call permissions check as in 5051 // {@link checkComponentPermission}. 5052 Identity tlsIdentity = sCallerIdentity.get(); 5053 if (tlsIdentity != null) { 5054 uid = tlsIdentity.uid; 5055 pid = tlsIdentity.pid; 5056 } 5057 5058 // Our own process gets to do everything. 5059 if (pid == MY_PID) { 5060 return PackageManager.PERMISSION_GRANTED; 5061 } 5062 synchronized(this) { 5063 return checkUriPermissionLocked(uri, uid, modeFlags) 5064 ? PackageManager.PERMISSION_GRANTED 5065 : PackageManager.PERMISSION_DENIED; 5066 } 5067 } 5068 5069 /** 5070 * Check if the targetPkg can be granted permission to access uri by 5071 * the callingUid using the given modeFlags. Throws a security exception 5072 * if callingUid is not allowed to do this. Returns the uid of the target 5073 * if the URI permission grant should be performed; returns -1 if it is not 5074 * needed (for example targetPkg already has permission to access the URI). 5075 * If you already know the uid of the target, you can supply it in 5076 * lastTargetUid else set that to -1. 5077 */ 5078 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5079 Uri uri, int modeFlags, int lastTargetUid) { 5080 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5081 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5082 if (modeFlags == 0) { 5083 return -1; 5084 } 5085 5086 if (targetPkg != null) { 5087 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5088 "Checking grant " + targetPkg + " permission to " + uri); 5089 } 5090 5091 final IPackageManager pm = AppGlobals.getPackageManager(); 5092 5093 // If this is not a content: uri, we can't do anything with it. 5094 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5095 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5096 "Can't grant URI permission for non-content URI: " + uri); 5097 return -1; 5098 } 5099 5100 String name = uri.getAuthority(); 5101 ProviderInfo pi = null; 5102 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5103 UserHandle.getUserId(callingUid)); 5104 if (cpr != null) { 5105 pi = cpr.info; 5106 } else { 5107 try { 5108 pi = pm.resolveContentProvider(name, 5109 PackageManager.GET_URI_PERMISSION_PATTERNS, 5110 UserHandle.getUserId(callingUid)); 5111 } catch (RemoteException ex) { 5112 } 5113 } 5114 if (pi == null) { 5115 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5116 return -1; 5117 } 5118 5119 int targetUid = lastTargetUid; 5120 if (targetUid < 0 && targetPkg != null) { 5121 try { 5122 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5123 if (targetUid < 0) { 5124 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5125 "Can't grant URI permission no uid for: " + targetPkg); 5126 return -1; 5127 } 5128 } catch (RemoteException ex) { 5129 return -1; 5130 } 5131 } 5132 5133 if (targetUid >= 0) { 5134 // First... does the target actually need this permission? 5135 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5136 // No need to grant the target this permission. 5137 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5138 "Target " + targetPkg + " already has full permission to " + uri); 5139 return -1; 5140 } 5141 } else { 5142 // First... there is no target package, so can anyone access it? 5143 boolean allowed = pi.exported; 5144 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5145 if (pi.readPermission != null) { 5146 allowed = false; 5147 } 5148 } 5149 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5150 if (pi.writePermission != null) { 5151 allowed = false; 5152 } 5153 } 5154 if (allowed) { 5155 return -1; 5156 } 5157 } 5158 5159 // Second... is the provider allowing granting of URI permissions? 5160 if (!pi.grantUriPermissions) { 5161 throw new SecurityException("Provider " + pi.packageName 5162 + "/" + pi.name 5163 + " does not allow granting of Uri permissions (uri " 5164 + uri + ")"); 5165 } 5166 if (pi.uriPermissionPatterns != null) { 5167 final int N = pi.uriPermissionPatterns.length; 5168 boolean allowed = false; 5169 for (int i=0; i<N; i++) { 5170 if (pi.uriPermissionPatterns[i] != null 5171 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5172 allowed = true; 5173 break; 5174 } 5175 } 5176 if (!allowed) { 5177 throw new SecurityException("Provider " + pi.packageName 5178 + "/" + pi.name 5179 + " does not allow granting of permission to path of Uri " 5180 + uri); 5181 } 5182 } 5183 5184 // Third... does the caller itself have permission to access 5185 // this uri? 5186 if (callingUid != Process.myUid()) { 5187 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5188 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5189 throw new SecurityException("Uid " + callingUid 5190 + " does not have permission to uri " + uri); 5191 } 5192 } 5193 } 5194 5195 return targetUid; 5196 } 5197 5198 public int checkGrantUriPermission(int callingUid, String targetPkg, 5199 Uri uri, int modeFlags) { 5200 enforceNotIsolatedCaller("checkGrantUriPermission"); 5201 synchronized(this) { 5202 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5203 } 5204 } 5205 5206 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5207 Uri uri, int modeFlags, UriPermissionOwner owner) { 5208 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5209 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5210 if (modeFlags == 0) { 5211 return; 5212 } 5213 5214 // So here we are: the caller has the assumed permission 5215 // to the uri, and the target doesn't. Let's now give this to 5216 // the target. 5217 5218 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5219 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5220 5221 HashMap<Uri, UriPermission> targetUris 5222 = mGrantedUriPermissions.get(targetUid); 5223 if (targetUris == null) { 5224 targetUris = new HashMap<Uri, UriPermission>(); 5225 mGrantedUriPermissions.put(targetUid, targetUris); 5226 } 5227 5228 UriPermission perm = targetUris.get(uri); 5229 if (perm == null) { 5230 perm = new UriPermission(targetUid, uri); 5231 targetUris.put(uri, perm); 5232 } 5233 5234 perm.modeFlags |= modeFlags; 5235 if (owner == null) { 5236 perm.globalModeFlags |= modeFlags; 5237 } else { 5238 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5239 perm.readOwners.add(owner); 5240 owner.addReadPermission(perm); 5241 } 5242 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5243 perm.writeOwners.add(owner); 5244 owner.addWritePermission(perm); 5245 } 5246 } 5247 } 5248 5249 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5250 int modeFlags, UriPermissionOwner owner) { 5251 if (targetPkg == null) { 5252 throw new NullPointerException("targetPkg"); 5253 } 5254 5255 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5256 if (targetUid < 0) { 5257 return; 5258 } 5259 5260 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5261 } 5262 5263 static class NeededUriGrants extends ArrayList<Uri> { 5264 final String targetPkg; 5265 final int targetUid; 5266 final int flags; 5267 5268 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5269 targetPkg = _targetPkg; 5270 targetUid = _targetUid; 5271 flags = _flags; 5272 } 5273 } 5274 5275 /** 5276 * Like checkGrantUriPermissionLocked, but takes an Intent. 5277 */ 5278 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5279 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5280 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5281 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5282 + " clip=" + (intent != null ? intent.getClipData() : null) 5283 + " from " + intent + "; flags=0x" 5284 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5285 5286 if (targetPkg == null) { 5287 throw new NullPointerException("targetPkg"); 5288 } 5289 5290 if (intent == null) { 5291 return null; 5292 } 5293 Uri data = intent.getData(); 5294 ClipData clip = intent.getClipData(); 5295 if (data == null && clip == null) { 5296 return null; 5297 } 5298 if (data != null) { 5299 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5300 mode, needed != null ? needed.targetUid : -1); 5301 if (target > 0) { 5302 if (needed == null) { 5303 needed = new NeededUriGrants(targetPkg, target, mode); 5304 } 5305 needed.add(data); 5306 } 5307 } 5308 if (clip != null) { 5309 for (int i=0; i<clip.getItemCount(); i++) { 5310 Uri uri = clip.getItemAt(i).getUri(); 5311 if (uri != null) { 5312 int target = -1; 5313 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5314 mode, needed != null ? needed.targetUid : -1); 5315 if (target > 0) { 5316 if (needed == null) { 5317 needed = new NeededUriGrants(targetPkg, target, mode); 5318 } 5319 needed.add(uri); 5320 } 5321 } else { 5322 Intent clipIntent = clip.getItemAt(i).getIntent(); 5323 if (clipIntent != null) { 5324 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5325 callingUid, targetPkg, clipIntent, mode, needed); 5326 if (newNeeded != null) { 5327 needed = newNeeded; 5328 } 5329 } 5330 } 5331 } 5332 } 5333 5334 return needed; 5335 } 5336 5337 /** 5338 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5339 */ 5340 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5341 UriPermissionOwner owner) { 5342 if (needed != null) { 5343 for (int i=0; i<needed.size(); i++) { 5344 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5345 needed.get(i), needed.flags, owner); 5346 } 5347 } 5348 } 5349 5350 void grantUriPermissionFromIntentLocked(int callingUid, 5351 String targetPkg, Intent intent, UriPermissionOwner owner) { 5352 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5353 intent, intent != null ? intent.getFlags() : 0, null); 5354 if (needed == null) { 5355 return; 5356 } 5357 5358 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5359 } 5360 5361 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5362 Uri uri, int modeFlags) { 5363 enforceNotIsolatedCaller("grantUriPermission"); 5364 synchronized(this) { 5365 final ProcessRecord r = getRecordForAppLocked(caller); 5366 if (r == null) { 5367 throw new SecurityException("Unable to find app for caller " 5368 + caller 5369 + " when granting permission to uri " + uri); 5370 } 5371 if (targetPkg == null) { 5372 throw new IllegalArgumentException("null target"); 5373 } 5374 if (uri == null) { 5375 throw new IllegalArgumentException("null uri"); 5376 } 5377 5378 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5379 null); 5380 } 5381 } 5382 5383 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5384 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5385 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5386 HashMap<Uri, UriPermission> perms 5387 = mGrantedUriPermissions.get(perm.uid); 5388 if (perms != null) { 5389 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5390 "Removing " + perm.uid + " permission to " + perm.uri); 5391 perms.remove(perm.uri); 5392 if (perms.size() == 0) { 5393 mGrantedUriPermissions.remove(perm.uid); 5394 } 5395 } 5396 } 5397 } 5398 5399 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5400 int modeFlags) { 5401 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5402 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5403 if (modeFlags == 0) { 5404 return; 5405 } 5406 5407 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5408 "Revoking all granted permissions to " + uri); 5409 5410 final IPackageManager pm = AppGlobals.getPackageManager(); 5411 5412 final String authority = uri.getAuthority(); 5413 ProviderInfo pi = null; 5414 int userId = UserHandle.getUserId(callingUid); 5415 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5416 if (cpr != null) { 5417 pi = cpr.info; 5418 } else { 5419 try { 5420 pi = pm.resolveContentProvider(authority, 5421 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5422 } catch (RemoteException ex) { 5423 } 5424 } 5425 if (pi == null) { 5426 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5427 return; 5428 } 5429 5430 // Does the caller have this permission on the URI? 5431 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5432 // Right now, if you are not the original owner of the permission, 5433 // you are not allowed to revoke it. 5434 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5435 throw new SecurityException("Uid " + callingUid 5436 + " does not have permission to uri " + uri); 5437 //} 5438 } 5439 5440 // Go through all of the permissions and remove any that match. 5441 final List<String> SEGMENTS = uri.getPathSegments(); 5442 if (SEGMENTS != null) { 5443 final int NS = SEGMENTS.size(); 5444 int N = mGrantedUriPermissions.size(); 5445 for (int i=0; i<N; i++) { 5446 HashMap<Uri, UriPermission> perms 5447 = mGrantedUriPermissions.valueAt(i); 5448 Iterator<UriPermission> it = perms.values().iterator(); 5449 toploop: 5450 while (it.hasNext()) { 5451 UriPermission perm = it.next(); 5452 Uri targetUri = perm.uri; 5453 if (!authority.equals(targetUri.getAuthority())) { 5454 continue; 5455 } 5456 List<String> targetSegments = targetUri.getPathSegments(); 5457 if (targetSegments == null) { 5458 continue; 5459 } 5460 if (targetSegments.size() < NS) { 5461 continue; 5462 } 5463 for (int j=0; j<NS; j++) { 5464 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5465 continue toploop; 5466 } 5467 } 5468 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5469 "Revoking " + perm.uid + " permission to " + perm.uri); 5470 perm.clearModes(modeFlags); 5471 if (perm.modeFlags == 0) { 5472 it.remove(); 5473 } 5474 } 5475 if (perms.size() == 0) { 5476 mGrantedUriPermissions.remove( 5477 mGrantedUriPermissions.keyAt(i)); 5478 N--; 5479 i--; 5480 } 5481 } 5482 } 5483 } 5484 5485 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5486 int modeFlags) { 5487 enforceNotIsolatedCaller("revokeUriPermission"); 5488 synchronized(this) { 5489 final ProcessRecord r = getRecordForAppLocked(caller); 5490 if (r == null) { 5491 throw new SecurityException("Unable to find app for caller " 5492 + caller 5493 + " when revoking permission to uri " + uri); 5494 } 5495 if (uri == null) { 5496 Slog.w(TAG, "revokeUriPermission: null uri"); 5497 return; 5498 } 5499 5500 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5501 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5502 if (modeFlags == 0) { 5503 return; 5504 } 5505 5506 final IPackageManager pm = AppGlobals.getPackageManager(); 5507 5508 final String authority = uri.getAuthority(); 5509 ProviderInfo pi = null; 5510 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5511 if (cpr != null) { 5512 pi = cpr.info; 5513 } else { 5514 try { 5515 pi = pm.resolveContentProvider(authority, 5516 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5517 } catch (RemoteException ex) { 5518 } 5519 } 5520 if (pi == null) { 5521 Slog.w(TAG, "No content provider found for permission revoke: " 5522 + uri.toSafeString()); 5523 return; 5524 } 5525 5526 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5527 } 5528 } 5529 5530 @Override 5531 public IBinder newUriPermissionOwner(String name) { 5532 enforceNotIsolatedCaller("newUriPermissionOwner"); 5533 synchronized(this) { 5534 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5535 return owner.getExternalTokenLocked(); 5536 } 5537 } 5538 5539 @Override 5540 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5541 Uri uri, int modeFlags) { 5542 synchronized(this) { 5543 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5544 if (owner == null) { 5545 throw new IllegalArgumentException("Unknown owner: " + token); 5546 } 5547 if (fromUid != Binder.getCallingUid()) { 5548 if (Binder.getCallingUid() != Process.myUid()) { 5549 // Only system code can grant URI permissions on behalf 5550 // of other users. 5551 throw new SecurityException("nice try"); 5552 } 5553 } 5554 if (targetPkg == null) { 5555 throw new IllegalArgumentException("null target"); 5556 } 5557 if (uri == null) { 5558 throw new IllegalArgumentException("null uri"); 5559 } 5560 5561 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5562 } 5563 } 5564 5565 @Override 5566 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5567 synchronized(this) { 5568 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5569 if (owner == null) { 5570 throw new IllegalArgumentException("Unknown owner: " + token); 5571 } 5572 5573 if (uri == null) { 5574 owner.removeUriPermissionsLocked(mode); 5575 } else { 5576 owner.removeUriPermissionLocked(uri, mode); 5577 } 5578 } 5579 } 5580 5581 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5582 synchronized (this) { 5583 ProcessRecord app = 5584 who != null ? getRecordForAppLocked(who) : null; 5585 if (app == null) return; 5586 5587 Message msg = Message.obtain(); 5588 msg.what = WAIT_FOR_DEBUGGER_MSG; 5589 msg.obj = app; 5590 msg.arg1 = waiting ? 1 : 0; 5591 mHandler.sendMessage(msg); 5592 } 5593 } 5594 5595 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5596 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5597 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5598 outInfo.availMem = Process.getFreeMemory(); 5599 outInfo.totalMem = Process.getTotalMemory(); 5600 outInfo.threshold = homeAppMem; 5601 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5602 outInfo.hiddenAppThreshold = hiddenAppMem; 5603 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5604 ProcessList.SERVICE_ADJ); 5605 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5606 ProcessList.VISIBLE_APP_ADJ); 5607 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5608 ProcessList.FOREGROUND_APP_ADJ); 5609 } 5610 5611 // ========================================================= 5612 // TASK MANAGEMENT 5613 // ========================================================= 5614 5615 public List getTasks(int maxNum, int flags, 5616 IThumbnailReceiver receiver) { 5617 ArrayList list = new ArrayList(); 5618 5619 PendingThumbnailsRecord pending = null; 5620 IApplicationThread topThumbnail = null; 5621 ActivityRecord topRecord = null; 5622 5623 synchronized(this) { 5624 if (localLOGV) Slog.v( 5625 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5626 + ", receiver=" + receiver); 5627 5628 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5629 != PackageManager.PERMISSION_GRANTED) { 5630 if (receiver != null) { 5631 // If the caller wants to wait for pending thumbnails, 5632 // it ain't gonna get them. 5633 try { 5634 receiver.finished(); 5635 } catch (RemoteException ex) { 5636 } 5637 } 5638 String msg = "Permission Denial: getTasks() from pid=" 5639 + Binder.getCallingPid() 5640 + ", uid=" + Binder.getCallingUid() 5641 + " requires " + android.Manifest.permission.GET_TASKS; 5642 Slog.w(TAG, msg); 5643 throw new SecurityException(msg); 5644 } 5645 5646 int pos = mMainStack.mHistory.size()-1; 5647 ActivityRecord next = 5648 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5649 ActivityRecord top = null; 5650 TaskRecord curTask = null; 5651 int numActivities = 0; 5652 int numRunning = 0; 5653 while (pos >= 0 && maxNum > 0) { 5654 final ActivityRecord r = next; 5655 pos--; 5656 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5657 5658 // Initialize state for next task if needed. 5659 if (top == null || 5660 (top.state == ActivityState.INITIALIZING 5661 && top.task == r.task)) { 5662 top = r; 5663 curTask = r.task; 5664 numActivities = numRunning = 0; 5665 } 5666 5667 // Add 'r' into the current task. 5668 numActivities++; 5669 if (r.app != null && r.app.thread != null) { 5670 numRunning++; 5671 } 5672 5673 if (localLOGV) Slog.v( 5674 TAG, r.intent.getComponent().flattenToShortString() 5675 + ": task=" + r.task); 5676 5677 // If the next one is a different task, generate a new 5678 // TaskInfo entry for what we have. 5679 if (next == null || next.task != curTask) { 5680 ActivityManager.RunningTaskInfo ci 5681 = new ActivityManager.RunningTaskInfo(); 5682 ci.id = curTask.taskId; 5683 ci.baseActivity = r.intent.getComponent(); 5684 ci.topActivity = top.intent.getComponent(); 5685 if (top.thumbHolder != null) { 5686 ci.description = top.thumbHolder.lastDescription; 5687 } 5688 ci.numActivities = numActivities; 5689 ci.numRunning = numRunning; 5690 //System.out.println( 5691 // "#" + maxNum + ": " + " descr=" + ci.description); 5692 if (ci.thumbnail == null && receiver != null) { 5693 if (localLOGV) Slog.v( 5694 TAG, "State=" + top.state + "Idle=" + top.idle 5695 + " app=" + top.app 5696 + " thr=" + (top.app != null ? top.app.thread : null)); 5697 if (top.state == ActivityState.RESUMED 5698 || top.state == ActivityState.PAUSING) { 5699 if (top.idle && top.app != null 5700 && top.app.thread != null) { 5701 topRecord = top; 5702 topThumbnail = top.app.thread; 5703 } else { 5704 top.thumbnailNeeded = true; 5705 } 5706 } 5707 if (pending == null) { 5708 pending = new PendingThumbnailsRecord(receiver); 5709 } 5710 pending.pendingRecords.add(top); 5711 } 5712 list.add(ci); 5713 maxNum--; 5714 top = null; 5715 } 5716 } 5717 5718 if (pending != null) { 5719 mPendingThumbnails.add(pending); 5720 } 5721 } 5722 5723 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5724 5725 if (topThumbnail != null) { 5726 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5727 try { 5728 topThumbnail.requestThumbnail(topRecord.appToken); 5729 } catch (Exception e) { 5730 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5731 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5732 } 5733 } 5734 5735 if (pending == null && receiver != null) { 5736 // In this case all thumbnails were available and the client 5737 // is being asked to be told when the remaining ones come in... 5738 // which is unusually, since the top-most currently running 5739 // activity should never have a canned thumbnail! Oh well. 5740 try { 5741 receiver.finished(); 5742 } catch (RemoteException ex) { 5743 } 5744 } 5745 5746 return list; 5747 } 5748 5749 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5750 int flags, int userId) { 5751 final int callingUid = Binder.getCallingUid(); 5752 if (userId != UserHandle.getCallingUserId()) { 5753 // Check if the caller is holding permissions for cross-user requests. 5754 if (checkComponentPermission( 5755 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5756 Binder.getCallingPid(), callingUid, -1, true) 5757 != PackageManager.PERMISSION_GRANTED) { 5758 String msg = "Permission Denial: " 5759 + "Request to get recent tasks for user " + userId 5760 + " but is calling from user " + UserHandle.getUserId(callingUid) 5761 + "; this requires " 5762 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5763 Slog.w(TAG, msg); 5764 throw new SecurityException(msg); 5765 } else { 5766 if (userId == UserHandle.USER_CURRENT) { 5767 userId = mCurrentUserId; 5768 } 5769 } 5770 } 5771 5772 synchronized (this) { 5773 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5774 "getRecentTasks()"); 5775 final boolean detailed = checkCallingPermission( 5776 android.Manifest.permission.GET_DETAILED_TASKS) 5777 == PackageManager.PERMISSION_GRANTED; 5778 5779 IPackageManager pm = AppGlobals.getPackageManager(); 5780 5781 final int N = mRecentTasks.size(); 5782 ArrayList<ActivityManager.RecentTaskInfo> res 5783 = new ArrayList<ActivityManager.RecentTaskInfo>( 5784 maxNum < N ? maxNum : N); 5785 for (int i=0; i<N && maxNum > 0; i++) { 5786 TaskRecord tr = mRecentTasks.get(i); 5787 // Only add calling user's recent tasks 5788 if (tr.userId != userId) continue; 5789 // Return the entry if desired by the caller. We always return 5790 // the first entry, because callers always expect this to be the 5791 // foreground app. We may filter others if the caller has 5792 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5793 // we should exclude the entry. 5794 5795 if (i == 0 5796 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5797 || (tr.intent == null) 5798 || ((tr.intent.getFlags() 5799 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5800 ActivityManager.RecentTaskInfo rti 5801 = new ActivityManager.RecentTaskInfo(); 5802 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5803 rti.persistentId = tr.taskId; 5804 rti.baseIntent = new Intent( 5805 tr.intent != null ? tr.intent : tr.affinityIntent); 5806 if (!detailed) { 5807 rti.baseIntent.replaceExtras((Bundle)null); 5808 } 5809 rti.origActivity = tr.origActivity; 5810 rti.description = tr.lastDescription; 5811 5812 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5813 // Check whether this activity is currently available. 5814 try { 5815 if (rti.origActivity != null) { 5816 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5817 == null) { 5818 continue; 5819 } 5820 } else if (rti.baseIntent != null) { 5821 if (pm.queryIntentActivities(rti.baseIntent, 5822 null, 0, userId) == null) { 5823 continue; 5824 } 5825 } 5826 } catch (RemoteException e) { 5827 // Will never happen. 5828 } 5829 } 5830 5831 res.add(rti); 5832 maxNum--; 5833 } 5834 } 5835 return res; 5836 } 5837 } 5838 5839 private TaskRecord taskForIdLocked(int id) { 5840 final int N = mRecentTasks.size(); 5841 for (int i=0; i<N; i++) { 5842 TaskRecord tr = mRecentTasks.get(i); 5843 if (tr.taskId == id) { 5844 return tr; 5845 } 5846 } 5847 return null; 5848 } 5849 5850 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5851 synchronized (this) { 5852 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5853 "getTaskThumbnails()"); 5854 TaskRecord tr = taskForIdLocked(id); 5855 if (tr != null) { 5856 return mMainStack.getTaskThumbnailsLocked(tr); 5857 } 5858 } 5859 return null; 5860 } 5861 5862 public Bitmap getTaskTopThumbnail(int id) { 5863 synchronized (this) { 5864 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5865 "getTaskTopThumbnail()"); 5866 TaskRecord tr = taskForIdLocked(id); 5867 if (tr != null) { 5868 return mMainStack.getTaskTopThumbnailLocked(tr); 5869 } 5870 } 5871 return null; 5872 } 5873 5874 public boolean removeSubTask(int taskId, int subTaskIndex) { 5875 synchronized (this) { 5876 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5877 "removeSubTask()"); 5878 long ident = Binder.clearCallingIdentity(); 5879 try { 5880 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5881 true) != null; 5882 } finally { 5883 Binder.restoreCallingIdentity(ident); 5884 } 5885 } 5886 } 5887 5888 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5889 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5890 Intent baseIntent = new Intent( 5891 tr.intent != null ? tr.intent : tr.affinityIntent); 5892 ComponentName component = baseIntent.getComponent(); 5893 if (component == null) { 5894 Slog.w(TAG, "Now component for base intent of task: " + tr); 5895 return; 5896 } 5897 5898 // Find any running services associated with this app. 5899 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5900 5901 if (killProcesses) { 5902 // Find any running processes associated with this app. 5903 final String pkg = component.getPackageName(); 5904 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5905 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5906 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5907 for (int i=0; i<uids.size(); i++) { 5908 ProcessRecord proc = uids.valueAt(i); 5909 if (proc.userId != tr.userId) { 5910 continue; 5911 } 5912 if (!proc.pkgList.contains(pkg)) { 5913 continue; 5914 } 5915 procs.add(proc); 5916 } 5917 } 5918 5919 // Kill the running processes. 5920 for (int i=0; i<procs.size(); i++) { 5921 ProcessRecord pr = procs.get(i); 5922 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5923 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5924 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5925 pr.processName, pr.setAdj, "remove task"); 5926 pr.killedBackground = true; 5927 Process.killProcessQuiet(pr.pid); 5928 } else { 5929 pr.waitingToKill = "remove task"; 5930 } 5931 } 5932 } 5933 } 5934 5935 public boolean removeTask(int taskId, int flags) { 5936 synchronized (this) { 5937 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5938 "removeTask()"); 5939 long ident = Binder.clearCallingIdentity(); 5940 try { 5941 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5942 false); 5943 if (r != null) { 5944 mRecentTasks.remove(r.task); 5945 cleanUpRemovedTaskLocked(r.task, flags); 5946 return true; 5947 } else { 5948 TaskRecord tr = null; 5949 int i=0; 5950 while (i < mRecentTasks.size()) { 5951 TaskRecord t = mRecentTasks.get(i); 5952 if (t.taskId == taskId) { 5953 tr = t; 5954 break; 5955 } 5956 i++; 5957 } 5958 if (tr != null) { 5959 if (tr.numActivities <= 0) { 5960 // Caller is just removing a recent task that is 5961 // not actively running. That is easy! 5962 mRecentTasks.remove(i); 5963 cleanUpRemovedTaskLocked(tr, flags); 5964 return true; 5965 } else { 5966 Slog.w(TAG, "removeTask: task " + taskId 5967 + " does not have activities to remove, " 5968 + " but numActivities=" + tr.numActivities 5969 + ": " + tr); 5970 } 5971 } 5972 } 5973 } finally { 5974 Binder.restoreCallingIdentity(ident); 5975 } 5976 } 5977 return false; 5978 } 5979 5980 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5981 int j; 5982 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5983 TaskRecord jt = startTask; 5984 5985 // First look backwards 5986 for (j=startIndex-1; j>=0; j--) { 5987 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5988 if (r.task != jt) { 5989 jt = r.task; 5990 if (affinity.equals(jt.affinity)) { 5991 return j; 5992 } 5993 } 5994 } 5995 5996 // Now look forwards 5997 final int N = mMainStack.mHistory.size(); 5998 jt = startTask; 5999 for (j=startIndex+1; j<N; j++) { 6000 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 6001 if (r.task != jt) { 6002 if (affinity.equals(jt.affinity)) { 6003 return j; 6004 } 6005 jt = r.task; 6006 } 6007 } 6008 6009 // Might it be at the top? 6010 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 6011 return N-1; 6012 } 6013 6014 return -1; 6015 } 6016 6017 /** 6018 * TODO: Add mController hook 6019 */ 6020 public void moveTaskToFront(int task, int flags, Bundle options) { 6021 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6022 "moveTaskToFront()"); 6023 6024 synchronized(this) { 6025 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6026 Binder.getCallingUid(), "Task to front")) { 6027 ActivityOptions.abort(options); 6028 return; 6029 } 6030 final long origId = Binder.clearCallingIdentity(); 6031 try { 6032 TaskRecord tr = taskForIdLocked(task); 6033 if (tr != null) { 6034 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6035 mMainStack.mUserLeaving = true; 6036 } 6037 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6038 // Caller wants the home activity moved with it. To accomplish this, 6039 // we'll just move the home task to the top first. 6040 mMainStack.moveHomeToFrontLocked(); 6041 } 6042 mMainStack.moveTaskToFrontLocked(tr, null, options); 6043 return; 6044 } 6045 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6046 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6047 if (hr.task.taskId == task) { 6048 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6049 mMainStack.mUserLeaving = true; 6050 } 6051 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6052 // Caller wants the home activity moved with it. To accomplish this, 6053 // we'll just move the home task to the top first. 6054 mMainStack.moveHomeToFrontLocked(); 6055 } 6056 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6057 return; 6058 } 6059 } 6060 } finally { 6061 Binder.restoreCallingIdentity(origId); 6062 } 6063 ActivityOptions.abort(options); 6064 } 6065 } 6066 6067 public void moveTaskToBack(int task) { 6068 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6069 "moveTaskToBack()"); 6070 6071 synchronized(this) { 6072 if (mMainStack.mResumedActivity != null 6073 && mMainStack.mResumedActivity.task.taskId == task) { 6074 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6075 Binder.getCallingUid(), "Task to back")) { 6076 return; 6077 } 6078 } 6079 final long origId = Binder.clearCallingIdentity(); 6080 mMainStack.moveTaskToBackLocked(task, null); 6081 Binder.restoreCallingIdentity(origId); 6082 } 6083 } 6084 6085 /** 6086 * Moves an activity, and all of the other activities within the same task, to the bottom 6087 * of the history stack. The activity's order within the task is unchanged. 6088 * 6089 * @param token A reference to the activity we wish to move 6090 * @param nonRoot If false then this only works if the activity is the root 6091 * of a task; if true it will work for any activity in a task. 6092 * @return Returns true if the move completed, false if not. 6093 */ 6094 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6095 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6096 synchronized(this) { 6097 final long origId = Binder.clearCallingIdentity(); 6098 int taskId = getTaskForActivityLocked(token, !nonRoot); 6099 if (taskId >= 0) { 6100 return mMainStack.moveTaskToBackLocked(taskId, null); 6101 } 6102 Binder.restoreCallingIdentity(origId); 6103 } 6104 return false; 6105 } 6106 6107 public void moveTaskBackwards(int task) { 6108 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6109 "moveTaskBackwards()"); 6110 6111 synchronized(this) { 6112 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6113 Binder.getCallingUid(), "Task backwards")) { 6114 return; 6115 } 6116 final long origId = Binder.clearCallingIdentity(); 6117 moveTaskBackwardsLocked(task); 6118 Binder.restoreCallingIdentity(origId); 6119 } 6120 } 6121 6122 private final void moveTaskBackwardsLocked(int task) { 6123 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6124 } 6125 6126 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6127 synchronized(this) { 6128 return getTaskForActivityLocked(token, onlyRoot); 6129 } 6130 } 6131 6132 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6133 final int N = mMainStack.mHistory.size(); 6134 TaskRecord lastTask = null; 6135 for (int i=0; i<N; i++) { 6136 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6137 if (r.appToken == token) { 6138 if (!onlyRoot || lastTask != r.task) { 6139 return r.task.taskId; 6140 } 6141 return -1; 6142 } 6143 lastTask = r.task; 6144 } 6145 6146 return -1; 6147 } 6148 6149 // ========================================================= 6150 // THUMBNAILS 6151 // ========================================================= 6152 6153 public void reportThumbnail(IBinder token, 6154 Bitmap thumbnail, CharSequence description) { 6155 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6156 final long origId = Binder.clearCallingIdentity(); 6157 sendPendingThumbnail(null, token, thumbnail, description, true); 6158 Binder.restoreCallingIdentity(origId); 6159 } 6160 6161 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6162 Bitmap thumbnail, CharSequence description, boolean always) { 6163 TaskRecord task = null; 6164 ArrayList receivers = null; 6165 6166 //System.out.println("Send pending thumbnail: " + r); 6167 6168 synchronized(this) { 6169 if (r == null) { 6170 r = mMainStack.isInStackLocked(token); 6171 if (r == null) { 6172 return; 6173 } 6174 } 6175 if (thumbnail == null && r.thumbHolder != null) { 6176 thumbnail = r.thumbHolder.lastThumbnail; 6177 description = r.thumbHolder.lastDescription; 6178 } 6179 if (thumbnail == null && !always) { 6180 // If there is no thumbnail, and this entry is not actually 6181 // going away, then abort for now and pick up the next 6182 // thumbnail we get. 6183 return; 6184 } 6185 task = r.task; 6186 6187 int N = mPendingThumbnails.size(); 6188 int i=0; 6189 while (i<N) { 6190 PendingThumbnailsRecord pr = 6191 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6192 //System.out.println("Looking in " + pr.pendingRecords); 6193 if (pr.pendingRecords.remove(r)) { 6194 if (receivers == null) { 6195 receivers = new ArrayList(); 6196 } 6197 receivers.add(pr); 6198 if (pr.pendingRecords.size() == 0) { 6199 pr.finished = true; 6200 mPendingThumbnails.remove(i); 6201 N--; 6202 continue; 6203 } 6204 } 6205 i++; 6206 } 6207 } 6208 6209 if (receivers != null) { 6210 final int N = receivers.size(); 6211 for (int i=0; i<N; i++) { 6212 try { 6213 PendingThumbnailsRecord pr = 6214 (PendingThumbnailsRecord)receivers.get(i); 6215 pr.receiver.newThumbnail( 6216 task != null ? task.taskId : -1, thumbnail, description); 6217 if (pr.finished) { 6218 pr.receiver.finished(); 6219 } 6220 } catch (Exception e) { 6221 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6222 } 6223 } 6224 } 6225 } 6226 6227 // ========================================================= 6228 // CONTENT PROVIDERS 6229 // ========================================================= 6230 6231 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6232 List<ProviderInfo> providers = null; 6233 try { 6234 providers = AppGlobals.getPackageManager(). 6235 queryContentProviders(app.processName, app.uid, 6236 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6237 } catch (RemoteException ex) { 6238 } 6239 if (DEBUG_MU) 6240 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6241 int userId = app.userId; 6242 if (providers != null) { 6243 int N = providers.size(); 6244 for (int i=0; i<N; i++) { 6245 ProviderInfo cpi = 6246 (ProviderInfo)providers.get(i); 6247 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6248 cpi.name, cpi.flags); 6249 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6250 // This is a singleton provider, but a user besides the 6251 // default user is asking to initialize a process it runs 6252 // in... well, no, it doesn't actually run in this process, 6253 // it runs in the process of the default user. Get rid of it. 6254 providers.remove(i); 6255 N--; 6256 continue; 6257 } 6258 6259 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6260 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6261 if (cpr == null) { 6262 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6263 mProviderMap.putProviderByClass(comp, cpr); 6264 } 6265 if (DEBUG_MU) 6266 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6267 app.pubProviders.put(cpi.name, cpr); 6268 app.addPackage(cpi.applicationInfo.packageName); 6269 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6270 } 6271 } 6272 return providers; 6273 } 6274 6275 /** 6276 * Check if {@link ProcessRecord} has a possible chance at accessing the 6277 * given {@link ProviderInfo}. Final permission checking is always done 6278 * in {@link ContentProvider}. 6279 */ 6280 private final String checkContentProviderPermissionLocked( 6281 ProviderInfo cpi, ProcessRecord r) { 6282 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6283 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6284 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6285 cpi.applicationInfo.uid, cpi.exported) 6286 == PackageManager.PERMISSION_GRANTED) { 6287 return null; 6288 } 6289 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6290 cpi.applicationInfo.uid, cpi.exported) 6291 == PackageManager.PERMISSION_GRANTED) { 6292 return null; 6293 } 6294 6295 PathPermission[] pps = cpi.pathPermissions; 6296 if (pps != null) { 6297 int i = pps.length; 6298 while (i > 0) { 6299 i--; 6300 PathPermission pp = pps[i]; 6301 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6302 cpi.applicationInfo.uid, cpi.exported) 6303 == PackageManager.PERMISSION_GRANTED) { 6304 return null; 6305 } 6306 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6307 cpi.applicationInfo.uid, cpi.exported) 6308 == PackageManager.PERMISSION_GRANTED) { 6309 return null; 6310 } 6311 } 6312 } 6313 6314 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6315 if (perms != null) { 6316 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6317 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6318 return null; 6319 } 6320 } 6321 } 6322 6323 String msg; 6324 if (!cpi.exported) { 6325 msg = "Permission Denial: opening provider " + cpi.name 6326 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6327 + ", uid=" + callingUid + ") that is not exported from uid " 6328 + cpi.applicationInfo.uid; 6329 } else { 6330 msg = "Permission Denial: opening provider " + cpi.name 6331 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6332 + ", uid=" + callingUid + ") requires " 6333 + cpi.readPermission + " or " + cpi.writePermission; 6334 } 6335 Slog.w(TAG, msg); 6336 return msg; 6337 } 6338 6339 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6340 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6341 if (r != null) { 6342 for (int i=0; i<r.conProviders.size(); i++) { 6343 ContentProviderConnection conn = r.conProviders.get(i); 6344 if (conn.provider == cpr) { 6345 if (DEBUG_PROVIDER) Slog.v(TAG, 6346 "Adding provider requested by " 6347 + r.processName + " from process " 6348 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6349 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6350 if (stable) { 6351 conn.stableCount++; 6352 conn.numStableIncs++; 6353 } else { 6354 conn.unstableCount++; 6355 conn.numUnstableIncs++; 6356 } 6357 return conn; 6358 } 6359 } 6360 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6361 if (stable) { 6362 conn.stableCount = 1; 6363 conn.numStableIncs = 1; 6364 } else { 6365 conn.unstableCount = 1; 6366 conn.numUnstableIncs = 1; 6367 } 6368 cpr.connections.add(conn); 6369 r.conProviders.add(conn); 6370 return conn; 6371 } 6372 cpr.addExternalProcessHandleLocked(externalProcessToken); 6373 return null; 6374 } 6375 6376 boolean decProviderCountLocked(ContentProviderConnection conn, 6377 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6378 if (conn != null) { 6379 cpr = conn.provider; 6380 if (DEBUG_PROVIDER) Slog.v(TAG, 6381 "Removing provider requested by " 6382 + conn.client.processName + " from process " 6383 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6384 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6385 if (stable) { 6386 conn.stableCount--; 6387 } else { 6388 conn.unstableCount--; 6389 } 6390 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6391 cpr.connections.remove(conn); 6392 conn.client.conProviders.remove(conn); 6393 return true; 6394 } 6395 return false; 6396 } 6397 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6398 return false; 6399 } 6400 6401 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6402 String name, IBinder token, boolean stable, int userId) { 6403 ContentProviderRecord cpr; 6404 ContentProviderConnection conn = null; 6405 ProviderInfo cpi = null; 6406 6407 synchronized(this) { 6408 ProcessRecord r = null; 6409 if (caller != null) { 6410 r = getRecordForAppLocked(caller); 6411 if (r == null) { 6412 throw new SecurityException( 6413 "Unable to find app for caller " + caller 6414 + " (pid=" + Binder.getCallingPid() 6415 + ") when getting content provider " + name); 6416 } 6417 } 6418 6419 // First check if this content provider has been published... 6420 cpr = mProviderMap.getProviderByName(name, userId); 6421 boolean providerRunning = cpr != null; 6422 if (providerRunning) { 6423 cpi = cpr.info; 6424 String msg; 6425 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6426 throw new SecurityException(msg); 6427 } 6428 6429 if (r != null && cpr.canRunHere(r)) { 6430 // This provider has been published or is in the process 6431 // of being published... but it is also allowed to run 6432 // in the caller's process, so don't make a connection 6433 // and just let the caller instantiate its own instance. 6434 ContentProviderHolder holder = cpr.newHolder(null); 6435 // don't give caller the provider object, it needs 6436 // to make its own. 6437 holder.provider = null; 6438 return holder; 6439 } 6440 6441 final long origId = Binder.clearCallingIdentity(); 6442 6443 // In this case the provider instance already exists, so we can 6444 // return it right away. 6445 conn = incProviderCountLocked(r, cpr, token, stable); 6446 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6447 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6448 // If this is a perceptible app accessing the provider, 6449 // make sure to count it as being accessed and thus 6450 // back up on the LRU list. This is good because 6451 // content providers are often expensive to start. 6452 updateLruProcessLocked(cpr.proc, false, true); 6453 } 6454 } 6455 6456 if (cpr.proc != null) { 6457 if (false) { 6458 if (cpr.name.flattenToShortString().equals( 6459 "com.android.providers.calendar/.CalendarProvider2")) { 6460 Slog.v(TAG, "****************** KILLING " 6461 + cpr.name.flattenToShortString()); 6462 Process.killProcess(cpr.proc.pid); 6463 } 6464 } 6465 boolean success = updateOomAdjLocked(cpr.proc); 6466 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6467 // NOTE: there is still a race here where a signal could be 6468 // pending on the process even though we managed to update its 6469 // adj level. Not sure what to do about this, but at least 6470 // the race is now smaller. 6471 if (!success) { 6472 // Uh oh... it looks like the provider's process 6473 // has been killed on us. We need to wait for a new 6474 // process to be started, and make sure its death 6475 // doesn't kill our process. 6476 Slog.i(TAG, 6477 "Existing provider " + cpr.name.flattenToShortString() 6478 + " is crashing; detaching " + r); 6479 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6480 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6481 if (!lastRef) { 6482 // This wasn't the last ref our process had on 6483 // the provider... we have now been killed, bail. 6484 return null; 6485 } 6486 providerRunning = false; 6487 conn = null; 6488 } 6489 } 6490 6491 Binder.restoreCallingIdentity(origId); 6492 } 6493 6494 boolean singleton; 6495 if (!providerRunning) { 6496 try { 6497 cpi = AppGlobals.getPackageManager(). 6498 resolveContentProvider(name, 6499 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6500 } catch (RemoteException ex) { 6501 } 6502 if (cpi == null) { 6503 return null; 6504 } 6505 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6506 cpi.name, cpi.flags); 6507 if (singleton) { 6508 userId = 0; 6509 } 6510 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6511 6512 String msg; 6513 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6514 throw new SecurityException(msg); 6515 } 6516 6517 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6518 && !cpi.processName.equals("system")) { 6519 // If this content provider does not run in the system 6520 // process, and the system is not yet ready to run other 6521 // processes, then fail fast instead of hanging. 6522 throw new IllegalArgumentException( 6523 "Attempt to launch content provider before system ready"); 6524 } 6525 6526 // Make sure that the user who owns this provider is started. If not, 6527 // we don't want to allow it to run. 6528 if (mStartedUsers.get(userId) == null) { 6529 Slog.w(TAG, "Unable to launch app " 6530 + cpi.applicationInfo.packageName + "/" 6531 + cpi.applicationInfo.uid + " for provider " 6532 + name + ": user " + userId + " is stopped"); 6533 return null; 6534 } 6535 6536 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6537 cpr = mProviderMap.getProviderByClass(comp, userId); 6538 final boolean firstClass = cpr == null; 6539 if (firstClass) { 6540 try { 6541 ApplicationInfo ai = 6542 AppGlobals.getPackageManager(). 6543 getApplicationInfo( 6544 cpi.applicationInfo.packageName, 6545 STOCK_PM_FLAGS, userId); 6546 if (ai == null) { 6547 Slog.w(TAG, "No package info for content provider " 6548 + cpi.name); 6549 return null; 6550 } 6551 ai = getAppInfoForUser(ai, userId); 6552 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6553 } catch (RemoteException ex) { 6554 // pm is in same process, this will never happen. 6555 } 6556 } 6557 6558 if (r != null && cpr.canRunHere(r)) { 6559 // If this is a multiprocess provider, then just return its 6560 // info and allow the caller to instantiate it. Only do 6561 // this if the provider is the same user as the caller's 6562 // process, or can run as root (so can be in any process). 6563 return cpr.newHolder(null); 6564 } 6565 6566 if (DEBUG_PROVIDER) { 6567 RuntimeException e = new RuntimeException("here"); 6568 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6569 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6570 } 6571 6572 // This is single process, and our app is now connecting to it. 6573 // See if we are already in the process of launching this 6574 // provider. 6575 final int N = mLaunchingProviders.size(); 6576 int i; 6577 for (i=0; i<N; i++) { 6578 if (mLaunchingProviders.get(i) == cpr) { 6579 break; 6580 } 6581 } 6582 6583 // If the provider is not already being launched, then get it 6584 // started. 6585 if (i >= N) { 6586 final long origId = Binder.clearCallingIdentity(); 6587 6588 try { 6589 // Content provider is now in use, its package can't be stopped. 6590 try { 6591 AppGlobals.getPackageManager().setPackageStoppedState( 6592 cpr.appInfo.packageName, false, userId); 6593 } catch (RemoteException e) { 6594 } catch (IllegalArgumentException e) { 6595 Slog.w(TAG, "Failed trying to unstop package " 6596 + cpr.appInfo.packageName + ": " + e); 6597 } 6598 6599 ProcessRecord proc = startProcessLocked(cpi.processName, 6600 cpr.appInfo, false, 0, "content provider", 6601 new ComponentName(cpi.applicationInfo.packageName, 6602 cpi.name), false, false); 6603 if (proc == null) { 6604 Slog.w(TAG, "Unable to launch app " 6605 + cpi.applicationInfo.packageName + "/" 6606 + cpi.applicationInfo.uid + " for provider " 6607 + name + ": process is bad"); 6608 return null; 6609 } 6610 cpr.launchingApp = proc; 6611 mLaunchingProviders.add(cpr); 6612 } finally { 6613 Binder.restoreCallingIdentity(origId); 6614 } 6615 } 6616 6617 // Make sure the provider is published (the same provider class 6618 // may be published under multiple names). 6619 if (firstClass) { 6620 mProviderMap.putProviderByClass(comp, cpr); 6621 } 6622 6623 mProviderMap.putProviderByName(name, cpr); 6624 conn = incProviderCountLocked(r, cpr, token, stable); 6625 if (conn != null) { 6626 conn.waiting = true; 6627 } 6628 } 6629 } 6630 6631 // Wait for the provider to be published... 6632 synchronized (cpr) { 6633 while (cpr.provider == null) { 6634 if (cpr.launchingApp == null) { 6635 Slog.w(TAG, "Unable to launch app " 6636 + cpi.applicationInfo.packageName + "/" 6637 + cpi.applicationInfo.uid + " for provider " 6638 + name + ": launching app became null"); 6639 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6640 cpi.applicationInfo.packageName, 6641 cpi.applicationInfo.uid, name); 6642 return null; 6643 } 6644 try { 6645 if (DEBUG_MU) { 6646 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6647 + cpr.launchingApp); 6648 } 6649 if (conn != null) { 6650 conn.waiting = true; 6651 } 6652 cpr.wait(); 6653 } catch (InterruptedException ex) { 6654 } finally { 6655 if (conn != null) { 6656 conn.waiting = false; 6657 } 6658 } 6659 } 6660 } 6661 return cpr != null ? cpr.newHolder(conn) : null; 6662 } 6663 6664 public final ContentProviderHolder getContentProvider( 6665 IApplicationThread caller, String name, int userId, boolean stable) { 6666 enforceNotIsolatedCaller("getContentProvider"); 6667 if (caller == null) { 6668 String msg = "null IApplicationThread when getting content provider " 6669 + name; 6670 Slog.w(TAG, msg); 6671 throw new SecurityException(msg); 6672 } 6673 6674 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6675 false, true, "getContentProvider", null); 6676 return getContentProviderImpl(caller, name, null, stable, userId); 6677 } 6678 6679 public ContentProviderHolder getContentProviderExternal( 6680 String name, int userId, IBinder token) { 6681 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6682 "Do not have permission in call getContentProviderExternal()"); 6683 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6684 false, true, "getContentProvider", null); 6685 return getContentProviderExternalUnchecked(name, token, userId); 6686 } 6687 6688 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6689 IBinder token, int userId) { 6690 return getContentProviderImpl(null, name, token, true, userId); 6691 } 6692 6693 /** 6694 * Drop a content provider from a ProcessRecord's bookkeeping 6695 * @param cpr 6696 */ 6697 public void removeContentProvider(IBinder connection, boolean stable) { 6698 enforceNotIsolatedCaller("removeContentProvider"); 6699 synchronized (this) { 6700 ContentProviderConnection conn; 6701 try { 6702 conn = (ContentProviderConnection)connection; 6703 } catch (ClassCastException e) { 6704 String msg ="removeContentProvider: " + connection 6705 + " not a ContentProviderConnection"; 6706 Slog.w(TAG, msg); 6707 throw new IllegalArgumentException(msg); 6708 } 6709 if (conn == null) { 6710 throw new NullPointerException("connection is null"); 6711 } 6712 if (decProviderCountLocked(conn, null, null, stable)) { 6713 updateOomAdjLocked(); 6714 } 6715 } 6716 } 6717 6718 public void removeContentProviderExternal(String name, IBinder token) { 6719 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6720 "Do not have permission in call removeContentProviderExternal()"); 6721 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6722 } 6723 6724 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6725 synchronized (this) { 6726 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6727 if(cpr == null) { 6728 //remove from mProvidersByClass 6729 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6730 return; 6731 } 6732 6733 //update content provider record entry info 6734 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6735 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6736 if (localCpr.hasExternalProcessHandles()) { 6737 if (localCpr.removeExternalProcessHandleLocked(token)) { 6738 updateOomAdjLocked(); 6739 } else { 6740 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6741 + " with no external reference for token: " 6742 + token + "."); 6743 } 6744 } else { 6745 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6746 + " with no external references."); 6747 } 6748 } 6749 } 6750 6751 public final void publishContentProviders(IApplicationThread caller, 6752 List<ContentProviderHolder> providers) { 6753 if (providers == null) { 6754 return; 6755 } 6756 6757 enforceNotIsolatedCaller("publishContentProviders"); 6758 synchronized (this) { 6759 final ProcessRecord r = getRecordForAppLocked(caller); 6760 if (DEBUG_MU) 6761 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6762 if (r == null) { 6763 throw new SecurityException( 6764 "Unable to find app for caller " + caller 6765 + " (pid=" + Binder.getCallingPid() 6766 + ") when publishing content providers"); 6767 } 6768 6769 final long origId = Binder.clearCallingIdentity(); 6770 6771 final int N = providers.size(); 6772 for (int i=0; i<N; i++) { 6773 ContentProviderHolder src = providers.get(i); 6774 if (src == null || src.info == null || src.provider == null) { 6775 continue; 6776 } 6777 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6778 if (DEBUG_MU) 6779 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6780 if (dst != null) { 6781 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6782 mProviderMap.putProviderByClass(comp, dst); 6783 String names[] = dst.info.authority.split(";"); 6784 for (int j = 0; j < names.length; j++) { 6785 mProviderMap.putProviderByName(names[j], dst); 6786 } 6787 6788 int NL = mLaunchingProviders.size(); 6789 int j; 6790 for (j=0; j<NL; j++) { 6791 if (mLaunchingProviders.get(j) == dst) { 6792 mLaunchingProviders.remove(j); 6793 j--; 6794 NL--; 6795 } 6796 } 6797 synchronized (dst) { 6798 dst.provider = src.provider; 6799 dst.proc = r; 6800 dst.notifyAll(); 6801 } 6802 updateOomAdjLocked(r); 6803 } 6804 } 6805 6806 Binder.restoreCallingIdentity(origId); 6807 } 6808 } 6809 6810 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6811 ContentProviderConnection conn; 6812 try { 6813 conn = (ContentProviderConnection)connection; 6814 } catch (ClassCastException e) { 6815 String msg ="refContentProvider: " + connection 6816 + " not a ContentProviderConnection"; 6817 Slog.w(TAG, msg); 6818 throw new IllegalArgumentException(msg); 6819 } 6820 if (conn == null) { 6821 throw new NullPointerException("connection is null"); 6822 } 6823 6824 synchronized (this) { 6825 if (stable > 0) { 6826 conn.numStableIncs += stable; 6827 } 6828 stable = conn.stableCount + stable; 6829 if (stable < 0) { 6830 throw new IllegalStateException("stableCount < 0: " + stable); 6831 } 6832 6833 if (unstable > 0) { 6834 conn.numUnstableIncs += unstable; 6835 } 6836 unstable = conn.unstableCount + unstable; 6837 if (unstable < 0) { 6838 throw new IllegalStateException("unstableCount < 0: " + unstable); 6839 } 6840 6841 if ((stable+unstable) <= 0) { 6842 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6843 + stable + " unstable=" + unstable); 6844 } 6845 conn.stableCount = stable; 6846 conn.unstableCount = unstable; 6847 return !conn.dead; 6848 } 6849 } 6850 6851 public void unstableProviderDied(IBinder connection) { 6852 ContentProviderConnection conn; 6853 try { 6854 conn = (ContentProviderConnection)connection; 6855 } catch (ClassCastException e) { 6856 String msg ="refContentProvider: " + connection 6857 + " not a ContentProviderConnection"; 6858 Slog.w(TAG, msg); 6859 throw new IllegalArgumentException(msg); 6860 } 6861 if (conn == null) { 6862 throw new NullPointerException("connection is null"); 6863 } 6864 6865 // Safely retrieve the content provider associated with the connection. 6866 IContentProvider provider; 6867 synchronized (this) { 6868 provider = conn.provider.provider; 6869 } 6870 6871 if (provider == null) { 6872 // Um, yeah, we're way ahead of you. 6873 return; 6874 } 6875 6876 // Make sure the caller is being honest with us. 6877 if (provider.asBinder().pingBinder()) { 6878 // Er, no, still looks good to us. 6879 synchronized (this) { 6880 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6881 + " says " + conn + " died, but we don't agree"); 6882 return; 6883 } 6884 } 6885 6886 // Well look at that! It's dead! 6887 synchronized (this) { 6888 if (conn.provider.provider != provider) { 6889 // But something changed... good enough. 6890 return; 6891 } 6892 6893 ProcessRecord proc = conn.provider.proc; 6894 if (proc == null || proc.thread == null) { 6895 // Seems like the process is already cleaned up. 6896 return; 6897 } 6898 6899 // As far as we're concerned, this is just like receiving a 6900 // death notification... just a bit prematurely. 6901 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6902 + ") early provider death"); 6903 final long ident = Binder.clearCallingIdentity(); 6904 try { 6905 appDiedLocked(proc, proc.pid, proc.thread); 6906 } finally { 6907 Binder.restoreCallingIdentity(ident); 6908 } 6909 } 6910 } 6911 6912 public static final void installSystemProviders() { 6913 List<ProviderInfo> providers; 6914 synchronized (mSelf) { 6915 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6916 providers = mSelf.generateApplicationProvidersLocked(app); 6917 if (providers != null) { 6918 for (int i=providers.size()-1; i>=0; i--) { 6919 ProviderInfo pi = (ProviderInfo)providers.get(i); 6920 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6921 Slog.w(TAG, "Not installing system proc provider " + pi.name 6922 + ": not system .apk"); 6923 providers.remove(i); 6924 } 6925 } 6926 } 6927 } 6928 if (providers != null) { 6929 mSystemThread.installSystemProviders(providers); 6930 } 6931 6932 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6933 6934 mSelf.mUsageStatsService.monitorPackages(); 6935 } 6936 6937 /** 6938 * Allows app to retrieve the MIME type of a URI without having permission 6939 * to access its content provider. 6940 * 6941 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6942 * 6943 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6944 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6945 */ 6946 public String getProviderMimeType(Uri uri, int userId) { 6947 enforceNotIsolatedCaller("getProviderMimeType"); 6948 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6949 userId, false, true, "getProviderMimeType", null); 6950 final String name = uri.getAuthority(); 6951 final long ident = Binder.clearCallingIdentity(); 6952 ContentProviderHolder holder = null; 6953 6954 try { 6955 holder = getContentProviderExternalUnchecked(name, null, userId); 6956 if (holder != null) { 6957 return holder.provider.getType(uri); 6958 } 6959 } catch (RemoteException e) { 6960 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6961 return null; 6962 } finally { 6963 if (holder != null) { 6964 removeContentProviderExternalUnchecked(name, null, userId); 6965 } 6966 Binder.restoreCallingIdentity(ident); 6967 } 6968 6969 return null; 6970 } 6971 6972 // ========================================================= 6973 // GLOBAL MANAGEMENT 6974 // ========================================================= 6975 6976 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6977 ApplicationInfo info, String customProcess, boolean isolated) { 6978 String proc = customProcess != null ? customProcess : info.processName; 6979 BatteryStatsImpl.Uid.Proc ps = null; 6980 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6981 int uid = info.uid; 6982 if (isolated) { 6983 int userId = UserHandle.getUserId(uid); 6984 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6985 uid = 0; 6986 while (true) { 6987 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6988 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6989 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6990 } 6991 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6992 mNextIsolatedProcessUid++; 6993 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6994 // No process for this uid, use it. 6995 break; 6996 } 6997 stepsLeft--; 6998 if (stepsLeft <= 0) { 6999 return null; 7000 } 7001 } 7002 } 7003 synchronized (stats) { 7004 ps = stats.getProcessStatsLocked(info.uid, proc); 7005 } 7006 return new ProcessRecord(ps, thread, info, proc, uid); 7007 } 7008 7009 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 7010 ProcessRecord app; 7011 if (!isolated) { 7012 app = getProcessRecordLocked(info.processName, info.uid); 7013 } else { 7014 app = null; 7015 } 7016 7017 if (app == null) { 7018 app = newProcessRecordLocked(null, info, null, isolated); 7019 mProcessNames.put(info.processName, app.uid, app); 7020 if (isolated) { 7021 mIsolatedProcesses.put(app.uid, app); 7022 } 7023 updateLruProcessLocked(app, true, true); 7024 } 7025 7026 // This package really, really can not be stopped. 7027 try { 7028 AppGlobals.getPackageManager().setPackageStoppedState( 7029 info.packageName, false, UserHandle.getUserId(app.uid)); 7030 } catch (RemoteException e) { 7031 } catch (IllegalArgumentException e) { 7032 Slog.w(TAG, "Failed trying to unstop package " 7033 + info.packageName + ": " + e); 7034 } 7035 7036 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7037 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7038 app.persistent = true; 7039 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7040 } 7041 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7042 mPersistentStartingProcesses.add(app); 7043 startProcessLocked(app, "added application", app.processName); 7044 } 7045 7046 return app; 7047 } 7048 7049 public void unhandledBack() { 7050 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7051 "unhandledBack()"); 7052 7053 synchronized(this) { 7054 int count = mMainStack.mHistory.size(); 7055 if (DEBUG_SWITCH) Slog.d( 7056 TAG, "Performing unhandledBack(): stack size = " + count); 7057 if (count > 1) { 7058 final long origId = Binder.clearCallingIdentity(); 7059 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7060 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7061 Binder.restoreCallingIdentity(origId); 7062 } 7063 } 7064 } 7065 7066 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7067 enforceNotIsolatedCaller("openContentUri"); 7068 final int userId = UserHandle.getCallingUserId(); 7069 String name = uri.getAuthority(); 7070 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7071 ParcelFileDescriptor pfd = null; 7072 if (cph != null) { 7073 // We record the binder invoker's uid in thread-local storage before 7074 // going to the content provider to open the file. Later, in the code 7075 // that handles all permissions checks, we look for this uid and use 7076 // that rather than the Activity Manager's own uid. The effect is that 7077 // we do the check against the caller's permissions even though it looks 7078 // to the content provider like the Activity Manager itself is making 7079 // the request. 7080 sCallerIdentity.set(new Identity( 7081 Binder.getCallingPid(), Binder.getCallingUid())); 7082 try { 7083 pfd = cph.provider.openFile(uri, "r"); 7084 } catch (FileNotFoundException e) { 7085 // do nothing; pfd will be returned null 7086 } finally { 7087 // Ensure that whatever happens, we clean up the identity state 7088 sCallerIdentity.remove(); 7089 } 7090 7091 // We've got the fd now, so we're done with the provider. 7092 removeContentProviderExternalUnchecked(name, null, userId); 7093 } else { 7094 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7095 } 7096 return pfd; 7097 } 7098 7099 // Actually is sleeping or shutting down or whatever else in the future 7100 // is an inactive state. 7101 public boolean isSleeping() { 7102 return mSleeping || mShuttingDown; 7103 } 7104 7105 public void goingToSleep() { 7106 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7107 != PackageManager.PERMISSION_GRANTED) { 7108 throw new SecurityException("Requires permission " 7109 + android.Manifest.permission.DEVICE_POWER); 7110 } 7111 7112 synchronized(this) { 7113 mWentToSleep = true; 7114 updateEventDispatchingLocked(); 7115 7116 if (!mSleeping) { 7117 mSleeping = true; 7118 mMainStack.stopIfSleepingLocked(); 7119 7120 // Initialize the wake times of all processes. 7121 checkExcessivePowerUsageLocked(false); 7122 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7123 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7124 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7125 } 7126 } 7127 } 7128 7129 public boolean shutdown(int timeout) { 7130 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7131 != PackageManager.PERMISSION_GRANTED) { 7132 throw new SecurityException("Requires permission " 7133 + android.Manifest.permission.SHUTDOWN); 7134 } 7135 7136 boolean timedout = false; 7137 7138 synchronized(this) { 7139 mShuttingDown = true; 7140 updateEventDispatchingLocked(); 7141 7142 if (mMainStack.mResumedActivity != null) { 7143 mMainStack.stopIfSleepingLocked(); 7144 final long endTime = System.currentTimeMillis() + timeout; 7145 while (mMainStack.mResumedActivity != null 7146 || mMainStack.mPausingActivity != null) { 7147 long delay = endTime - System.currentTimeMillis(); 7148 if (delay <= 0) { 7149 Slog.w(TAG, "Activity manager shutdown timed out"); 7150 timedout = true; 7151 break; 7152 } 7153 try { 7154 this.wait(); 7155 } catch (InterruptedException e) { 7156 } 7157 } 7158 } 7159 } 7160 7161 mUsageStatsService.shutdown(); 7162 mBatteryStatsService.shutdown(); 7163 7164 return timedout; 7165 } 7166 7167 public final void activitySlept(IBinder token) { 7168 if (localLOGV) Slog.v( 7169 TAG, "Activity slept: token=" + token); 7170 7171 ActivityRecord r = null; 7172 7173 final long origId = Binder.clearCallingIdentity(); 7174 7175 synchronized (this) { 7176 r = mMainStack.isInStackLocked(token); 7177 if (r != null) { 7178 mMainStack.activitySleptLocked(r); 7179 } 7180 } 7181 7182 Binder.restoreCallingIdentity(origId); 7183 } 7184 7185 private void comeOutOfSleepIfNeededLocked() { 7186 if (!mWentToSleep && !mLockScreenShown) { 7187 if (mSleeping) { 7188 mSleeping = false; 7189 mMainStack.awakeFromSleepingLocked(); 7190 mMainStack.resumeTopActivityLocked(null); 7191 } 7192 } 7193 } 7194 7195 public void wakingUp() { 7196 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7197 != PackageManager.PERMISSION_GRANTED) { 7198 throw new SecurityException("Requires permission " 7199 + android.Manifest.permission.DEVICE_POWER); 7200 } 7201 7202 synchronized(this) { 7203 mWentToSleep = false; 7204 updateEventDispatchingLocked(); 7205 comeOutOfSleepIfNeededLocked(); 7206 } 7207 } 7208 7209 private void updateEventDispatchingLocked() { 7210 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7211 } 7212 7213 public void setLockScreenShown(boolean shown) { 7214 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7215 != PackageManager.PERMISSION_GRANTED) { 7216 throw new SecurityException("Requires permission " 7217 + android.Manifest.permission.DEVICE_POWER); 7218 } 7219 7220 synchronized(this) { 7221 mLockScreenShown = shown; 7222 comeOutOfSleepIfNeededLocked(); 7223 } 7224 } 7225 7226 public void stopAppSwitches() { 7227 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7228 != PackageManager.PERMISSION_GRANTED) { 7229 throw new SecurityException("Requires permission " 7230 + android.Manifest.permission.STOP_APP_SWITCHES); 7231 } 7232 7233 synchronized(this) { 7234 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7235 + APP_SWITCH_DELAY_TIME; 7236 mDidAppSwitch = false; 7237 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7238 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7239 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7240 } 7241 } 7242 7243 public void resumeAppSwitches() { 7244 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7245 != PackageManager.PERMISSION_GRANTED) { 7246 throw new SecurityException("Requires permission " 7247 + android.Manifest.permission.STOP_APP_SWITCHES); 7248 } 7249 7250 synchronized(this) { 7251 // Note that we don't execute any pending app switches... we will 7252 // let those wait until either the timeout, or the next start 7253 // activity request. 7254 mAppSwitchesAllowedTime = 0; 7255 } 7256 } 7257 7258 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7259 String name) { 7260 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7261 return true; 7262 } 7263 7264 final int perm = checkComponentPermission( 7265 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7266 callingUid, -1, true); 7267 if (perm == PackageManager.PERMISSION_GRANTED) { 7268 return true; 7269 } 7270 7271 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7272 return false; 7273 } 7274 7275 public void setDebugApp(String packageName, boolean waitForDebugger, 7276 boolean persistent) { 7277 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7278 "setDebugApp()"); 7279 7280 // Note that this is not really thread safe if there are multiple 7281 // callers into it at the same time, but that's not a situation we 7282 // care about. 7283 if (persistent) { 7284 final ContentResolver resolver = mContext.getContentResolver(); 7285 Settings.System.putString( 7286 resolver, Settings.System.DEBUG_APP, 7287 packageName); 7288 Settings.System.putInt( 7289 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7290 waitForDebugger ? 1 : 0); 7291 } 7292 7293 synchronized (this) { 7294 if (!persistent) { 7295 mOrigDebugApp = mDebugApp; 7296 mOrigWaitForDebugger = mWaitForDebugger; 7297 } 7298 mDebugApp = packageName; 7299 mWaitForDebugger = waitForDebugger; 7300 mDebugTransient = !persistent; 7301 if (packageName != null) { 7302 final long origId = Binder.clearCallingIdentity(); 7303 forceStopPackageLocked(packageName, -1, false, false, true, true, 7304 UserHandle.USER_ALL); 7305 Binder.restoreCallingIdentity(origId); 7306 } 7307 } 7308 } 7309 7310 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7311 synchronized (this) { 7312 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7313 if (!isDebuggable) { 7314 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7315 throw new SecurityException("Process not debuggable: " + app.packageName); 7316 } 7317 } 7318 7319 mOpenGlTraceApp = processName; 7320 } 7321 } 7322 7323 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7324 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7325 synchronized (this) { 7326 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7327 if (!isDebuggable) { 7328 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7329 throw new SecurityException("Process not debuggable: " + app.packageName); 7330 } 7331 } 7332 mProfileApp = processName; 7333 mProfileFile = profileFile; 7334 if (mProfileFd != null) { 7335 try { 7336 mProfileFd.close(); 7337 } catch (IOException e) { 7338 } 7339 mProfileFd = null; 7340 } 7341 mProfileFd = profileFd; 7342 mProfileType = 0; 7343 mAutoStopProfiler = autoStopProfiler; 7344 } 7345 } 7346 7347 public void setAlwaysFinish(boolean enabled) { 7348 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7349 "setAlwaysFinish()"); 7350 7351 Settings.System.putInt( 7352 mContext.getContentResolver(), 7353 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7354 7355 synchronized (this) { 7356 mAlwaysFinishActivities = enabled; 7357 } 7358 } 7359 7360 public void setActivityController(IActivityController controller) { 7361 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7362 "setActivityController()"); 7363 synchronized (this) { 7364 mController = controller; 7365 } 7366 } 7367 7368 public boolean isUserAMonkey() { 7369 // For now the fact that there is a controller implies 7370 // we have a monkey. 7371 synchronized (this) { 7372 return mController != null; 7373 } 7374 } 7375 7376 public void registerProcessObserver(IProcessObserver observer) { 7377 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7378 "registerProcessObserver()"); 7379 synchronized (this) { 7380 mProcessObservers.register(observer); 7381 } 7382 } 7383 7384 public void unregisterProcessObserver(IProcessObserver observer) { 7385 synchronized (this) { 7386 mProcessObservers.unregister(observer); 7387 } 7388 } 7389 7390 public void setImmersive(IBinder token, boolean immersive) { 7391 synchronized(this) { 7392 ActivityRecord r = mMainStack.isInStackLocked(token); 7393 if (r == null) { 7394 throw new IllegalArgumentException(); 7395 } 7396 r.immersive = immersive; 7397 } 7398 } 7399 7400 public boolean isImmersive(IBinder token) { 7401 synchronized (this) { 7402 ActivityRecord r = mMainStack.isInStackLocked(token); 7403 if (r == null) { 7404 throw new IllegalArgumentException(); 7405 } 7406 return r.immersive; 7407 } 7408 } 7409 7410 public boolean isTopActivityImmersive() { 7411 enforceNotIsolatedCaller("startActivity"); 7412 synchronized (this) { 7413 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7414 return (r != null) ? r.immersive : false; 7415 } 7416 } 7417 7418 public final void enterSafeMode() { 7419 synchronized(this) { 7420 // It only makes sense to do this before the system is ready 7421 // and started launching other packages. 7422 if (!mSystemReady) { 7423 try { 7424 AppGlobals.getPackageManager().enterSafeMode(); 7425 } catch (RemoteException e) { 7426 } 7427 } 7428 } 7429 } 7430 7431 public final void showSafeModeOverlay() { 7432 View v = LayoutInflater.from(mContext).inflate( 7433 com.android.internal.R.layout.safe_mode, null); 7434 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7435 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7436 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7437 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7438 lp.gravity = Gravity.BOTTOM | Gravity.START; 7439 lp.format = v.getBackground().getOpacity(); 7440 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7441 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7442 ((WindowManager)mContext.getSystemService( 7443 Context.WINDOW_SERVICE)).addView(v, lp); 7444 } 7445 7446 public void noteWakeupAlarm(IIntentSender sender) { 7447 if (!(sender instanceof PendingIntentRecord)) { 7448 return; 7449 } 7450 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7451 synchronized (stats) { 7452 if (mBatteryStatsService.isOnBattery()) { 7453 mBatteryStatsService.enforceCallingPermission(); 7454 PendingIntentRecord rec = (PendingIntentRecord)sender; 7455 int MY_UID = Binder.getCallingUid(); 7456 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7457 BatteryStatsImpl.Uid.Pkg pkg = 7458 stats.getPackageStatsLocked(uid, rec.key.packageName); 7459 pkg.incWakeupsLocked(); 7460 } 7461 } 7462 } 7463 7464 public boolean killPids(int[] pids, String pReason, boolean secure) { 7465 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7466 throw new SecurityException("killPids only available to the system"); 7467 } 7468 String reason = (pReason == null) ? "Unknown" : pReason; 7469 // XXX Note: don't acquire main activity lock here, because the window 7470 // manager calls in with its locks held. 7471 7472 boolean killed = false; 7473 synchronized (mPidsSelfLocked) { 7474 int[] types = new int[pids.length]; 7475 int worstType = 0; 7476 for (int i=0; i<pids.length; i++) { 7477 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7478 if (proc != null) { 7479 int type = proc.setAdj; 7480 types[i] = type; 7481 if (type > worstType) { 7482 worstType = type; 7483 } 7484 } 7485 } 7486 7487 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7488 // then constrain it so we will kill all hidden procs. 7489 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7490 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7491 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7492 } 7493 7494 // If this is not a secure call, don't let it kill processes that 7495 // are important. 7496 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7497 worstType = ProcessList.SERVICE_ADJ; 7498 } 7499 7500 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7501 for (int i=0; i<pids.length; i++) { 7502 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7503 if (proc == null) { 7504 continue; 7505 } 7506 int adj = proc.setAdj; 7507 if (adj >= worstType && !proc.killedBackground) { 7508 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7509 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7510 proc.processName, adj, reason); 7511 killed = true; 7512 proc.killedBackground = true; 7513 Process.killProcessQuiet(pids[i]); 7514 } 7515 } 7516 } 7517 return killed; 7518 } 7519 7520 @Override 7521 public boolean killProcessesBelowForeground(String reason) { 7522 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7523 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7524 } 7525 7526 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7527 } 7528 7529 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7530 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7531 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7532 } 7533 7534 boolean killed = false; 7535 synchronized (mPidsSelfLocked) { 7536 final int size = mPidsSelfLocked.size(); 7537 for (int i = 0; i < size; i++) { 7538 final int pid = mPidsSelfLocked.keyAt(i); 7539 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7540 if (proc == null) continue; 7541 7542 final int adj = proc.setAdj; 7543 if (adj > belowAdj && !proc.killedBackground) { 7544 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7545 EventLog.writeEvent( 7546 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7547 killed = true; 7548 proc.killedBackground = true; 7549 Process.killProcessQuiet(pid); 7550 } 7551 } 7552 } 7553 return killed; 7554 } 7555 7556 public final void startRunning(String pkg, String cls, String action, 7557 String data) { 7558 synchronized(this) { 7559 if (mStartRunning) { 7560 return; 7561 } 7562 mStartRunning = true; 7563 mTopComponent = pkg != null && cls != null 7564 ? new ComponentName(pkg, cls) : null; 7565 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7566 mTopData = data; 7567 if (!mSystemReady) { 7568 return; 7569 } 7570 } 7571 7572 systemReady(null); 7573 } 7574 7575 private void retrieveSettings() { 7576 final ContentResolver resolver = mContext.getContentResolver(); 7577 String debugApp = Settings.System.getString( 7578 resolver, Settings.System.DEBUG_APP); 7579 boolean waitForDebugger = Settings.System.getInt( 7580 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7581 boolean alwaysFinishActivities = Settings.System.getInt( 7582 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7583 7584 Configuration configuration = new Configuration(); 7585 Settings.System.getConfiguration(resolver, configuration); 7586 7587 synchronized (this) { 7588 mDebugApp = mOrigDebugApp = debugApp; 7589 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7590 mAlwaysFinishActivities = alwaysFinishActivities; 7591 // This happens before any activities are started, so we can 7592 // change mConfiguration in-place. 7593 updateConfigurationLocked(configuration, null, false, true); 7594 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7595 } 7596 } 7597 7598 public boolean testIsSystemReady() { 7599 // no need to synchronize(this) just to read & return the value 7600 return mSystemReady; 7601 } 7602 7603 private static File getCalledPreBootReceiversFile() { 7604 File dataDir = Environment.getDataDirectory(); 7605 File systemDir = new File(dataDir, "system"); 7606 File fname = new File(systemDir, "called_pre_boots.dat"); 7607 return fname; 7608 } 7609 7610 static final int LAST_DONE_VERSION = 10000; 7611 7612 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7613 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7614 File file = getCalledPreBootReceiversFile(); 7615 FileInputStream fis = null; 7616 try { 7617 fis = new FileInputStream(file); 7618 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7619 int fvers = dis.readInt(); 7620 if (fvers == LAST_DONE_VERSION) { 7621 String vers = dis.readUTF(); 7622 String codename = dis.readUTF(); 7623 String build = dis.readUTF(); 7624 if (android.os.Build.VERSION.RELEASE.equals(vers) 7625 && android.os.Build.VERSION.CODENAME.equals(codename) 7626 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7627 int num = dis.readInt(); 7628 while (num > 0) { 7629 num--; 7630 String pkg = dis.readUTF(); 7631 String cls = dis.readUTF(); 7632 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7633 } 7634 } 7635 } 7636 } catch (FileNotFoundException e) { 7637 } catch (IOException e) { 7638 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7639 } finally { 7640 if (fis != null) { 7641 try { 7642 fis.close(); 7643 } catch (IOException e) { 7644 } 7645 } 7646 } 7647 return lastDoneReceivers; 7648 } 7649 7650 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7651 File file = getCalledPreBootReceiversFile(); 7652 FileOutputStream fos = null; 7653 DataOutputStream dos = null; 7654 try { 7655 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7656 fos = new FileOutputStream(file); 7657 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7658 dos.writeInt(LAST_DONE_VERSION); 7659 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7660 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7661 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7662 dos.writeInt(list.size()); 7663 for (int i=0; i<list.size(); i++) { 7664 dos.writeUTF(list.get(i).getPackageName()); 7665 dos.writeUTF(list.get(i).getClassName()); 7666 } 7667 } catch (IOException e) { 7668 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7669 file.delete(); 7670 } finally { 7671 FileUtils.sync(fos); 7672 if (dos != null) { 7673 try { 7674 dos.close(); 7675 } catch (IOException e) { 7676 // TODO Auto-generated catch block 7677 e.printStackTrace(); 7678 } 7679 } 7680 } 7681 } 7682 7683 public void systemReady(final Runnable goingCallback) { 7684 synchronized(this) { 7685 if (mSystemReady) { 7686 if (goingCallback != null) goingCallback.run(); 7687 return; 7688 } 7689 7690 // Check to see if there are any update receivers to run. 7691 if (!mDidUpdate) { 7692 if (mWaitingUpdate) { 7693 return; 7694 } 7695 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7696 List<ResolveInfo> ris = null; 7697 try { 7698 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7699 intent, null, 0, 0); 7700 } catch (RemoteException e) { 7701 } 7702 if (ris != null) { 7703 for (int i=ris.size()-1; i>=0; i--) { 7704 if ((ris.get(i).activityInfo.applicationInfo.flags 7705 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7706 ris.remove(i); 7707 } 7708 } 7709 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7710 7711 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7712 7713 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7714 for (int i=0; i<ris.size(); i++) { 7715 ActivityInfo ai = ris.get(i).activityInfo; 7716 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7717 if (lastDoneReceivers.contains(comp)) { 7718 ris.remove(i); 7719 i--; 7720 } 7721 } 7722 7723 final int[] users = getUsersLocked(); 7724 for (int i=0; i<ris.size(); i++) { 7725 ActivityInfo ai = ris.get(i).activityInfo; 7726 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7727 doneReceivers.add(comp); 7728 intent.setComponent(comp); 7729 for (int j=0; j<users.length; j++) { 7730 IIntentReceiver finisher = null; 7731 if (i == ris.size()-1 && j == users.length-1) { 7732 finisher = new IIntentReceiver.Stub() { 7733 public void performReceive(Intent intent, int resultCode, 7734 String data, Bundle extras, boolean ordered, 7735 boolean sticky, int sendingUser) { 7736 // The raw IIntentReceiver interface is called 7737 // with the AM lock held, so redispatch to 7738 // execute our code without the lock. 7739 mHandler.post(new Runnable() { 7740 public void run() { 7741 synchronized (ActivityManagerService.this) { 7742 mDidUpdate = true; 7743 } 7744 writeLastDonePreBootReceivers(doneReceivers); 7745 showBootMessage(mContext.getText( 7746 R.string.android_upgrading_complete), 7747 false); 7748 systemReady(goingCallback); 7749 } 7750 }); 7751 } 7752 }; 7753 } 7754 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7755 + " for user " + users[j]); 7756 broadcastIntentLocked(null, null, intent, null, finisher, 7757 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7758 users[j]); 7759 if (finisher != null) { 7760 mWaitingUpdate = true; 7761 } 7762 } 7763 } 7764 } 7765 if (mWaitingUpdate) { 7766 return; 7767 } 7768 mDidUpdate = true; 7769 } 7770 7771 mSystemReady = true; 7772 if (!mStartRunning) { 7773 return; 7774 } 7775 } 7776 7777 ArrayList<ProcessRecord> procsToKill = null; 7778 synchronized(mPidsSelfLocked) { 7779 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7780 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7781 if (!isAllowedWhileBooting(proc.info)){ 7782 if (procsToKill == null) { 7783 procsToKill = new ArrayList<ProcessRecord>(); 7784 } 7785 procsToKill.add(proc); 7786 } 7787 } 7788 } 7789 7790 synchronized(this) { 7791 if (procsToKill != null) { 7792 for (int i=procsToKill.size()-1; i>=0; i--) { 7793 ProcessRecord proc = procsToKill.get(i); 7794 Slog.i(TAG, "Removing system update proc: " + proc); 7795 removeProcessLocked(proc, true, false, "system update done"); 7796 } 7797 } 7798 7799 // Now that we have cleaned up any update processes, we 7800 // are ready to start launching real processes and know that 7801 // we won't trample on them any more. 7802 mProcessesReady = true; 7803 } 7804 7805 Slog.i(TAG, "System now ready"); 7806 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7807 SystemClock.uptimeMillis()); 7808 7809 synchronized(this) { 7810 // Make sure we have no pre-ready processes sitting around. 7811 7812 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7813 ResolveInfo ri = mContext.getPackageManager() 7814 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7815 STOCK_PM_FLAGS); 7816 CharSequence errorMsg = null; 7817 if (ri != null) { 7818 ActivityInfo ai = ri.activityInfo; 7819 ApplicationInfo app = ai.applicationInfo; 7820 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7821 mTopAction = Intent.ACTION_FACTORY_TEST; 7822 mTopData = null; 7823 mTopComponent = new ComponentName(app.packageName, 7824 ai.name); 7825 } else { 7826 errorMsg = mContext.getResources().getText( 7827 com.android.internal.R.string.factorytest_not_system); 7828 } 7829 } else { 7830 errorMsg = mContext.getResources().getText( 7831 com.android.internal.R.string.factorytest_no_action); 7832 } 7833 if (errorMsg != null) { 7834 mTopAction = null; 7835 mTopData = null; 7836 mTopComponent = null; 7837 Message msg = Message.obtain(); 7838 msg.what = SHOW_FACTORY_ERROR_MSG; 7839 msg.getData().putCharSequence("msg", errorMsg); 7840 mHandler.sendMessage(msg); 7841 } 7842 } 7843 } 7844 7845 retrieveSettings(); 7846 7847 if (goingCallback != null) goingCallback.run(); 7848 7849 synchronized (this) { 7850 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7851 try { 7852 List apps = AppGlobals.getPackageManager(). 7853 getPersistentApplications(STOCK_PM_FLAGS); 7854 if (apps != null) { 7855 int N = apps.size(); 7856 int i; 7857 for (i=0; i<N; i++) { 7858 ApplicationInfo info 7859 = (ApplicationInfo)apps.get(i); 7860 if (info != null && 7861 !info.packageName.equals("android")) { 7862 addAppLocked(info, false); 7863 } 7864 } 7865 } 7866 } catch (RemoteException ex) { 7867 // pm is in same process, this will never happen. 7868 } 7869 } 7870 7871 // Start up initial activity. 7872 mBooting = true; 7873 7874 try { 7875 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7876 Message msg = Message.obtain(); 7877 msg.what = SHOW_UID_ERROR_MSG; 7878 mHandler.sendMessage(msg); 7879 } 7880 } catch (RemoteException e) { 7881 } 7882 7883 long ident = Binder.clearCallingIdentity(); 7884 try { 7885 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7886 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7887 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7888 broadcastIntentLocked(null, null, intent, 7889 null, null, 0, null, null, null, 7890 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7891 } finally { 7892 Binder.restoreCallingIdentity(ident); 7893 } 7894 mMainStack.resumeTopActivityLocked(null); 7895 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7896 } 7897 } 7898 7899 private boolean makeAppCrashingLocked(ProcessRecord app, 7900 String shortMsg, String longMsg, String stackTrace) { 7901 app.crashing = true; 7902 app.crashingReport = generateProcessError(app, 7903 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7904 startAppProblemLocked(app); 7905 app.stopFreezingAllLocked(); 7906 return handleAppCrashLocked(app); 7907 } 7908 7909 private void makeAppNotRespondingLocked(ProcessRecord app, 7910 String activity, String shortMsg, String longMsg) { 7911 app.notResponding = true; 7912 app.notRespondingReport = generateProcessError(app, 7913 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7914 activity, shortMsg, longMsg, null); 7915 startAppProblemLocked(app); 7916 app.stopFreezingAllLocked(); 7917 } 7918 7919 /** 7920 * Generate a process error record, suitable for attachment to a ProcessRecord. 7921 * 7922 * @param app The ProcessRecord in which the error occurred. 7923 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7924 * ActivityManager.AppErrorStateInfo 7925 * @param activity The activity associated with the crash, if known. 7926 * @param shortMsg Short message describing the crash. 7927 * @param longMsg Long message describing the crash. 7928 * @param stackTrace Full crash stack trace, may be null. 7929 * 7930 * @return Returns a fully-formed AppErrorStateInfo record. 7931 */ 7932 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7933 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7934 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7935 7936 report.condition = condition; 7937 report.processName = app.processName; 7938 report.pid = app.pid; 7939 report.uid = app.info.uid; 7940 report.tag = activity; 7941 report.shortMsg = shortMsg; 7942 report.longMsg = longMsg; 7943 report.stackTrace = stackTrace; 7944 7945 return report; 7946 } 7947 7948 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7949 synchronized (this) { 7950 app.crashing = false; 7951 app.crashingReport = null; 7952 app.notResponding = false; 7953 app.notRespondingReport = null; 7954 if (app.anrDialog == fromDialog) { 7955 app.anrDialog = null; 7956 } 7957 if (app.waitDialog == fromDialog) { 7958 app.waitDialog = null; 7959 } 7960 if (app.pid > 0 && app.pid != MY_PID) { 7961 handleAppCrashLocked(app); 7962 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7963 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7964 app.processName, app.setAdj, "user's request after error"); 7965 Process.killProcessQuiet(app.pid); 7966 } 7967 } 7968 } 7969 7970 private boolean handleAppCrashLocked(ProcessRecord app) { 7971 if (mHeadless) { 7972 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7973 return false; 7974 } 7975 long now = SystemClock.uptimeMillis(); 7976 7977 Long crashTime; 7978 if (!app.isolated) { 7979 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7980 } else { 7981 crashTime = null; 7982 } 7983 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7984 // This process loses! 7985 Slog.w(TAG, "Process " + app.info.processName 7986 + " has crashed too many times: killing!"); 7987 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7988 app.info.processName, app.uid); 7989 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7990 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7991 if (r.app == app) { 7992 Slog.w(TAG, " Force finishing activity " 7993 + r.intent.getComponent().flattenToShortString()); 7994 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7995 null, "crashed", false); 7996 } 7997 } 7998 if (!app.persistent) { 7999 // We don't want to start this process again until the user 8000 // explicitly does so... but for persistent process, we really 8001 // need to keep it running. If a persistent process is actually 8002 // repeatedly crashing, then badness for everyone. 8003 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 8004 app.info.processName); 8005 if (!app.isolated) { 8006 // XXX We don't have a way to mark isolated processes 8007 // as bad, since they don't have a peristent identity. 8008 mBadProcesses.put(app.info.processName, app.uid, now); 8009 mProcessCrashTimes.remove(app.info.processName, app.uid); 8010 } 8011 app.bad = true; 8012 app.removed = true; 8013 // Don't let services in this process be restarted and potentially 8014 // annoy the user repeatedly. Unless it is persistent, since those 8015 // processes run critical code. 8016 removeProcessLocked(app, false, false, "crash"); 8017 mMainStack.resumeTopActivityLocked(null); 8018 return false; 8019 } 8020 mMainStack.resumeTopActivityLocked(null); 8021 } else { 8022 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8023 if (r != null && r.app == app) { 8024 // If the top running activity is from this crashing 8025 // process, then terminate it to avoid getting in a loop. 8026 Slog.w(TAG, " Force finishing activity " 8027 + r.intent.getComponent().flattenToShortString()); 8028 int index = mMainStack.indexOfActivityLocked(r); 8029 r.stack.finishActivityLocked(r, index, 8030 Activity.RESULT_CANCELED, null, "crashed", false); 8031 // Also terminate any activities below it that aren't yet 8032 // stopped, to avoid a situation where one will get 8033 // re-start our crashing activity once it gets resumed again. 8034 index--; 8035 if (index >= 0) { 8036 r = (ActivityRecord)mMainStack.mHistory.get(index); 8037 if (r.state == ActivityState.RESUMED 8038 || r.state == ActivityState.PAUSING 8039 || r.state == ActivityState.PAUSED) { 8040 if (!r.isHomeActivity || mHomeProcess != r.app) { 8041 Slog.w(TAG, " Force finishing activity " 8042 + r.intent.getComponent().flattenToShortString()); 8043 r.stack.finishActivityLocked(r, index, 8044 Activity.RESULT_CANCELED, null, "crashed", false); 8045 } 8046 } 8047 } 8048 } 8049 } 8050 8051 // Bump up the crash count of any services currently running in the proc. 8052 if (app.services.size() != 0) { 8053 // Any services running in the application need to be placed 8054 // back in the pending list. 8055 Iterator<ServiceRecord> it = app.services.iterator(); 8056 while (it.hasNext()) { 8057 ServiceRecord sr = it.next(); 8058 sr.crashCount++; 8059 } 8060 } 8061 8062 // If the crashing process is what we consider to be the "home process" and it has been 8063 // replaced by a third-party app, clear the package preferred activities from packages 8064 // with a home activity running in the process to prevent a repeatedly crashing app 8065 // from blocking the user to manually clear the list. 8066 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8067 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8068 Iterator it = mHomeProcess.activities.iterator(); 8069 while (it.hasNext()) { 8070 ActivityRecord r = (ActivityRecord)it.next(); 8071 if (r.isHomeActivity) { 8072 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8073 try { 8074 ActivityThread.getPackageManager() 8075 .clearPackagePreferredActivities(r.packageName); 8076 } catch (RemoteException c) { 8077 // pm is in same process, this will never happen. 8078 } 8079 } 8080 } 8081 } 8082 8083 if (!app.isolated) { 8084 // XXX Can't keep track of crash times for isolated processes, 8085 // because they don't have a perisistent identity. 8086 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8087 } 8088 8089 return true; 8090 } 8091 8092 void startAppProblemLocked(ProcessRecord app) { 8093 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8094 mContext, app.info.packageName, app.info.flags); 8095 skipCurrentReceiverLocked(app); 8096 } 8097 8098 void skipCurrentReceiverLocked(ProcessRecord app) { 8099 for (BroadcastQueue queue : mBroadcastQueues) { 8100 queue.skipCurrentReceiverLocked(app); 8101 } 8102 } 8103 8104 /** 8105 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8106 * The application process will exit immediately after this call returns. 8107 * @param app object of the crashing app, null for the system server 8108 * @param crashInfo describing the exception 8109 */ 8110 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8111 ProcessRecord r = findAppProcess(app, "Crash"); 8112 final String processName = app == null ? "system_server" 8113 : (r == null ? "unknown" : r.processName); 8114 8115 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8116 processName, 8117 r == null ? -1 : r.info.flags, 8118 crashInfo.exceptionClassName, 8119 crashInfo.exceptionMessage, 8120 crashInfo.throwFileName, 8121 crashInfo.throwLineNumber); 8122 8123 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8124 8125 crashApplication(r, crashInfo); 8126 } 8127 8128 public void handleApplicationStrictModeViolation( 8129 IBinder app, 8130 int violationMask, 8131 StrictMode.ViolationInfo info) { 8132 ProcessRecord r = findAppProcess(app, "StrictMode"); 8133 if (r == null) { 8134 return; 8135 } 8136 8137 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8138 Integer stackFingerprint = info.hashCode(); 8139 boolean logIt = true; 8140 synchronized (mAlreadyLoggedViolatedStacks) { 8141 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8142 logIt = false; 8143 // TODO: sub-sample into EventLog for these, with 8144 // the info.durationMillis? Then we'd get 8145 // the relative pain numbers, without logging all 8146 // the stack traces repeatedly. We'd want to do 8147 // likewise in the client code, which also does 8148 // dup suppression, before the Binder call. 8149 } else { 8150 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8151 mAlreadyLoggedViolatedStacks.clear(); 8152 } 8153 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8154 } 8155 } 8156 if (logIt) { 8157 logStrictModeViolationToDropBox(r, info); 8158 } 8159 } 8160 8161 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8162 AppErrorResult result = new AppErrorResult(); 8163 synchronized (this) { 8164 final long origId = Binder.clearCallingIdentity(); 8165 8166 Message msg = Message.obtain(); 8167 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8168 HashMap<String, Object> data = new HashMap<String, Object>(); 8169 data.put("result", result); 8170 data.put("app", r); 8171 data.put("violationMask", violationMask); 8172 data.put("info", info); 8173 msg.obj = data; 8174 mHandler.sendMessage(msg); 8175 8176 Binder.restoreCallingIdentity(origId); 8177 } 8178 int res = result.get(); 8179 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8180 } 8181 } 8182 8183 // Depending on the policy in effect, there could be a bunch of 8184 // these in quick succession so we try to batch these together to 8185 // minimize disk writes, number of dropbox entries, and maximize 8186 // compression, by having more fewer, larger records. 8187 private void logStrictModeViolationToDropBox( 8188 ProcessRecord process, 8189 StrictMode.ViolationInfo info) { 8190 if (info == null) { 8191 return; 8192 } 8193 final boolean isSystemApp = process == null || 8194 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8195 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8196 final String processName = process == null ? "unknown" : process.processName; 8197 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8198 final DropBoxManager dbox = (DropBoxManager) 8199 mContext.getSystemService(Context.DROPBOX_SERVICE); 8200 8201 // Exit early if the dropbox isn't configured to accept this report type. 8202 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8203 8204 boolean bufferWasEmpty; 8205 boolean needsFlush; 8206 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8207 synchronized (sb) { 8208 bufferWasEmpty = sb.length() == 0; 8209 appendDropBoxProcessHeaders(process, processName, sb); 8210 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8211 sb.append("System-App: ").append(isSystemApp).append("\n"); 8212 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8213 if (info.violationNumThisLoop != 0) { 8214 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8215 } 8216 if (info.numAnimationsRunning != 0) { 8217 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8218 } 8219 if (info.broadcastIntentAction != null) { 8220 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8221 } 8222 if (info.durationMillis != -1) { 8223 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8224 } 8225 if (info.numInstances != -1) { 8226 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8227 } 8228 if (info.tags != null) { 8229 for (String tag : info.tags) { 8230 sb.append("Span-Tag: ").append(tag).append("\n"); 8231 } 8232 } 8233 sb.append("\n"); 8234 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8235 sb.append(info.crashInfo.stackTrace); 8236 } 8237 sb.append("\n"); 8238 8239 // Only buffer up to ~64k. Various logging bits truncate 8240 // things at 128k. 8241 needsFlush = (sb.length() > 64 * 1024); 8242 } 8243 8244 // Flush immediately if the buffer's grown too large, or this 8245 // is a non-system app. Non-system apps are isolated with a 8246 // different tag & policy and not batched. 8247 // 8248 // Batching is useful during internal testing with 8249 // StrictMode settings turned up high. Without batching, 8250 // thousands of separate files could be created on boot. 8251 if (!isSystemApp || needsFlush) { 8252 new Thread("Error dump: " + dropboxTag) { 8253 @Override 8254 public void run() { 8255 String report; 8256 synchronized (sb) { 8257 report = sb.toString(); 8258 sb.delete(0, sb.length()); 8259 sb.trimToSize(); 8260 } 8261 if (report.length() != 0) { 8262 dbox.addText(dropboxTag, report); 8263 } 8264 } 8265 }.start(); 8266 return; 8267 } 8268 8269 // System app batching: 8270 if (!bufferWasEmpty) { 8271 // An existing dropbox-writing thread is outstanding, so 8272 // we don't need to start it up. The existing thread will 8273 // catch the buffer appends we just did. 8274 return; 8275 } 8276 8277 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8278 // (After this point, we shouldn't access AMS internal data structures.) 8279 new Thread("Error dump: " + dropboxTag) { 8280 @Override 8281 public void run() { 8282 // 5 second sleep to let stacks arrive and be batched together 8283 try { 8284 Thread.sleep(5000); // 5 seconds 8285 } catch (InterruptedException e) {} 8286 8287 String errorReport; 8288 synchronized (mStrictModeBuffer) { 8289 errorReport = mStrictModeBuffer.toString(); 8290 if (errorReport.length() == 0) { 8291 return; 8292 } 8293 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8294 mStrictModeBuffer.trimToSize(); 8295 } 8296 dbox.addText(dropboxTag, errorReport); 8297 } 8298 }.start(); 8299 } 8300 8301 /** 8302 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8303 * @param app object of the crashing app, null for the system server 8304 * @param tag reported by the caller 8305 * @param crashInfo describing the context of the error 8306 * @return true if the process should exit immediately (WTF is fatal) 8307 */ 8308 public boolean handleApplicationWtf(IBinder app, String tag, 8309 ApplicationErrorReport.CrashInfo crashInfo) { 8310 ProcessRecord r = findAppProcess(app, "WTF"); 8311 final String processName = app == null ? "system_server" 8312 : (r == null ? "unknown" : r.processName); 8313 8314 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8315 processName, 8316 r == null ? -1 : r.info.flags, 8317 tag, crashInfo.exceptionMessage); 8318 8319 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8320 8321 if (r != null && r.pid != Process.myPid() && 8322 Settings.Secure.getInt(mContext.getContentResolver(), 8323 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8324 crashApplication(r, crashInfo); 8325 return true; 8326 } else { 8327 return false; 8328 } 8329 } 8330 8331 /** 8332 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8333 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8334 */ 8335 private ProcessRecord findAppProcess(IBinder app, String reason) { 8336 if (app == null) { 8337 return null; 8338 } 8339 8340 synchronized (this) { 8341 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8342 final int NA = apps.size(); 8343 for (int ia=0; ia<NA; ia++) { 8344 ProcessRecord p = apps.valueAt(ia); 8345 if (p.thread != null && p.thread.asBinder() == app) { 8346 return p; 8347 } 8348 } 8349 } 8350 8351 Slog.w(TAG, "Can't find mystery application for " + reason 8352 + " from pid=" + Binder.getCallingPid() 8353 + " uid=" + Binder.getCallingUid() + ": " + app); 8354 return null; 8355 } 8356 } 8357 8358 /** 8359 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8360 * to append various headers to the dropbox log text. 8361 */ 8362 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8363 StringBuilder sb) { 8364 // Watchdog thread ends up invoking this function (with 8365 // a null ProcessRecord) to add the stack file to dropbox. 8366 // Do not acquire a lock on this (am) in such cases, as it 8367 // could cause a potential deadlock, if and when watchdog 8368 // is invoked due to unavailability of lock on am and it 8369 // would prevent watchdog from killing system_server. 8370 if (process == null) { 8371 sb.append("Process: ").append(processName).append("\n"); 8372 return; 8373 } 8374 // Note: ProcessRecord 'process' is guarded by the service 8375 // instance. (notably process.pkgList, which could otherwise change 8376 // concurrently during execution of this method) 8377 synchronized (this) { 8378 sb.append("Process: ").append(processName).append("\n"); 8379 int flags = process.info.flags; 8380 IPackageManager pm = AppGlobals.getPackageManager(); 8381 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8382 for (String pkg : process.pkgList) { 8383 sb.append("Package: ").append(pkg); 8384 try { 8385 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8386 if (pi != null) { 8387 sb.append(" v").append(pi.versionCode); 8388 if (pi.versionName != null) { 8389 sb.append(" (").append(pi.versionName).append(")"); 8390 } 8391 } 8392 } catch (RemoteException e) { 8393 Slog.e(TAG, "Error getting package info: " + pkg, e); 8394 } 8395 sb.append("\n"); 8396 } 8397 } 8398 } 8399 8400 private static String processClass(ProcessRecord process) { 8401 if (process == null || process.pid == MY_PID) { 8402 return "system_server"; 8403 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8404 return "system_app"; 8405 } else { 8406 return "data_app"; 8407 } 8408 } 8409 8410 /** 8411 * Write a description of an error (crash, WTF, ANR) to the drop box. 8412 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8413 * @param process which caused the error, null means the system server 8414 * @param activity which triggered the error, null if unknown 8415 * @param parent activity related to the error, null if unknown 8416 * @param subject line related to the error, null if absent 8417 * @param report in long form describing the error, null if absent 8418 * @param logFile to include in the report, null if none 8419 * @param crashInfo giving an application stack trace, null if absent 8420 */ 8421 public void addErrorToDropBox(String eventType, 8422 ProcessRecord process, String processName, ActivityRecord activity, 8423 ActivityRecord parent, String subject, 8424 final String report, final File logFile, 8425 final ApplicationErrorReport.CrashInfo crashInfo) { 8426 // NOTE -- this must never acquire the ActivityManagerService lock, 8427 // otherwise the watchdog may be prevented from resetting the system. 8428 8429 final String dropboxTag = processClass(process) + "_" + eventType; 8430 final DropBoxManager dbox = (DropBoxManager) 8431 mContext.getSystemService(Context.DROPBOX_SERVICE); 8432 8433 // Exit early if the dropbox isn't configured to accept this report type. 8434 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8435 8436 final StringBuilder sb = new StringBuilder(1024); 8437 appendDropBoxProcessHeaders(process, processName, sb); 8438 if (activity != null) { 8439 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8440 } 8441 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8442 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8443 } 8444 if (parent != null && parent != activity) { 8445 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8446 } 8447 if (subject != null) { 8448 sb.append("Subject: ").append(subject).append("\n"); 8449 } 8450 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8451 if (Debug.isDebuggerConnected()) { 8452 sb.append("Debugger: Connected\n"); 8453 } 8454 sb.append("\n"); 8455 8456 // Do the rest in a worker thread to avoid blocking the caller on I/O 8457 // (After this point, we shouldn't access AMS internal data structures.) 8458 Thread worker = new Thread("Error dump: " + dropboxTag) { 8459 @Override 8460 public void run() { 8461 if (report != null) { 8462 sb.append(report); 8463 } 8464 if (logFile != null) { 8465 try { 8466 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8467 } catch (IOException e) { 8468 Slog.e(TAG, "Error reading " + logFile, e); 8469 } 8470 } 8471 if (crashInfo != null && crashInfo.stackTrace != null) { 8472 sb.append(crashInfo.stackTrace); 8473 } 8474 8475 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8476 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8477 if (lines > 0) { 8478 sb.append("\n"); 8479 8480 // Merge several logcat streams, and take the last N lines 8481 InputStreamReader input = null; 8482 try { 8483 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8484 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8485 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8486 8487 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8488 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8489 input = new InputStreamReader(logcat.getInputStream()); 8490 8491 int num; 8492 char[] buf = new char[8192]; 8493 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8494 } catch (IOException e) { 8495 Slog.e(TAG, "Error running logcat", e); 8496 } finally { 8497 if (input != null) try { input.close(); } catch (IOException e) {} 8498 } 8499 } 8500 8501 dbox.addText(dropboxTag, sb.toString()); 8502 } 8503 }; 8504 8505 if (process == null) { 8506 // If process is null, we are being called from some internal code 8507 // and may be about to die -- run this synchronously. 8508 worker.run(); 8509 } else { 8510 worker.start(); 8511 } 8512 } 8513 8514 /** 8515 * Bring up the "unexpected error" dialog box for a crashing app. 8516 * Deal with edge cases (intercepts from instrumented applications, 8517 * ActivityController, error intent receivers, that sort of thing). 8518 * @param r the application crashing 8519 * @param crashInfo describing the failure 8520 */ 8521 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8522 long timeMillis = System.currentTimeMillis(); 8523 String shortMsg = crashInfo.exceptionClassName; 8524 String longMsg = crashInfo.exceptionMessage; 8525 String stackTrace = crashInfo.stackTrace; 8526 if (shortMsg != null && longMsg != null) { 8527 longMsg = shortMsg + ": " + longMsg; 8528 } else if (shortMsg != null) { 8529 longMsg = shortMsg; 8530 } 8531 8532 AppErrorResult result = new AppErrorResult(); 8533 synchronized (this) { 8534 if (mController != null) { 8535 try { 8536 String name = r != null ? r.processName : null; 8537 int pid = r != null ? r.pid : Binder.getCallingPid(); 8538 if (!mController.appCrashed(name, pid, 8539 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8540 Slog.w(TAG, "Force-killing crashed app " + name 8541 + " at watcher's request"); 8542 Process.killProcess(pid); 8543 return; 8544 } 8545 } catch (RemoteException e) { 8546 mController = null; 8547 } 8548 } 8549 8550 final long origId = Binder.clearCallingIdentity(); 8551 8552 // If this process is running instrumentation, finish it. 8553 if (r != null && r.instrumentationClass != null) { 8554 Slog.w(TAG, "Error in app " + r.processName 8555 + " running instrumentation " + r.instrumentationClass + ":"); 8556 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8557 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8558 Bundle info = new Bundle(); 8559 info.putString("shortMsg", shortMsg); 8560 info.putString("longMsg", longMsg); 8561 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8562 Binder.restoreCallingIdentity(origId); 8563 return; 8564 } 8565 8566 // If we can't identify the process or it's already exceeded its crash quota, 8567 // quit right away without showing a crash dialog. 8568 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8569 Binder.restoreCallingIdentity(origId); 8570 return; 8571 } 8572 8573 Message msg = Message.obtain(); 8574 msg.what = SHOW_ERROR_MSG; 8575 HashMap data = new HashMap(); 8576 data.put("result", result); 8577 data.put("app", r); 8578 msg.obj = data; 8579 mHandler.sendMessage(msg); 8580 8581 Binder.restoreCallingIdentity(origId); 8582 } 8583 8584 int res = result.get(); 8585 8586 Intent appErrorIntent = null; 8587 synchronized (this) { 8588 if (r != null && !r.isolated) { 8589 // XXX Can't keep track of crash time for isolated processes, 8590 // since they don't have a persistent identity. 8591 mProcessCrashTimes.put(r.info.processName, r.uid, 8592 SystemClock.uptimeMillis()); 8593 } 8594 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8595 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8596 } 8597 } 8598 8599 if (appErrorIntent != null) { 8600 try { 8601 mContext.startActivity(appErrorIntent); 8602 } catch (ActivityNotFoundException e) { 8603 Slog.w(TAG, "bug report receiver dissappeared", e); 8604 } 8605 } 8606 } 8607 8608 Intent createAppErrorIntentLocked(ProcessRecord r, 8609 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8610 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8611 if (report == null) { 8612 return null; 8613 } 8614 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8615 result.setComponent(r.errorReportReceiver); 8616 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8617 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8618 return result; 8619 } 8620 8621 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8622 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8623 if (r.errorReportReceiver == null) { 8624 return null; 8625 } 8626 8627 if (!r.crashing && !r.notResponding) { 8628 return null; 8629 } 8630 8631 ApplicationErrorReport report = new ApplicationErrorReport(); 8632 report.packageName = r.info.packageName; 8633 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8634 report.processName = r.processName; 8635 report.time = timeMillis; 8636 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8637 8638 if (r.crashing) { 8639 report.type = ApplicationErrorReport.TYPE_CRASH; 8640 report.crashInfo = crashInfo; 8641 } else if (r.notResponding) { 8642 report.type = ApplicationErrorReport.TYPE_ANR; 8643 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8644 8645 report.anrInfo.activity = r.notRespondingReport.tag; 8646 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8647 report.anrInfo.info = r.notRespondingReport.longMsg; 8648 } 8649 8650 return report; 8651 } 8652 8653 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8654 enforceNotIsolatedCaller("getProcessesInErrorState"); 8655 // assume our apps are happy - lazy create the list 8656 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8657 8658 final boolean allUsers = ActivityManager.checkUidPermission( 8659 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8660 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8661 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8662 8663 synchronized (this) { 8664 8665 // iterate across all processes 8666 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8667 ProcessRecord app = mLruProcesses.get(i); 8668 if (!allUsers && app.userId != userId) { 8669 continue; 8670 } 8671 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8672 // This one's in trouble, so we'll generate a report for it 8673 // crashes are higher priority (in case there's a crash *and* an anr) 8674 ActivityManager.ProcessErrorStateInfo report = null; 8675 if (app.crashing) { 8676 report = app.crashingReport; 8677 } else if (app.notResponding) { 8678 report = app.notRespondingReport; 8679 } 8680 8681 if (report != null) { 8682 if (errList == null) { 8683 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8684 } 8685 errList.add(report); 8686 } else { 8687 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8688 " crashing = " + app.crashing + 8689 " notResponding = " + app.notResponding); 8690 } 8691 } 8692 } 8693 } 8694 8695 return errList; 8696 } 8697 8698 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8699 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8700 if (currApp != null) { 8701 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8702 } 8703 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8704 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8705 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8706 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8707 if (currApp != null) { 8708 currApp.lru = 0; 8709 } 8710 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8711 } else if (adj >= ProcessList.SERVICE_ADJ) { 8712 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8713 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8714 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8715 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8716 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8717 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8718 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8719 } else { 8720 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8721 } 8722 } 8723 8724 private void fillInProcMemInfo(ProcessRecord app, 8725 ActivityManager.RunningAppProcessInfo outInfo) { 8726 outInfo.pid = app.pid; 8727 outInfo.uid = app.info.uid; 8728 if (mHeavyWeightProcess == app) { 8729 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8730 } 8731 if (app.persistent) { 8732 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8733 } 8734 if (app.hasActivities) { 8735 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8736 } 8737 outInfo.lastTrimLevel = app.trimMemoryLevel; 8738 int adj = app.curAdj; 8739 outInfo.importance = oomAdjToImportance(adj, outInfo); 8740 outInfo.importanceReasonCode = app.adjTypeCode; 8741 } 8742 8743 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8744 enforceNotIsolatedCaller("getRunningAppProcesses"); 8745 // Lazy instantiation of list 8746 List<ActivityManager.RunningAppProcessInfo> runList = null; 8747 final boolean allUsers = ActivityManager.checkUidPermission( 8748 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8749 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8750 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8751 synchronized (this) { 8752 // Iterate across all processes 8753 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8754 ProcessRecord app = mLruProcesses.get(i); 8755 if (!allUsers && app.userId != userId) { 8756 continue; 8757 } 8758 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8759 // Generate process state info for running application 8760 ActivityManager.RunningAppProcessInfo currApp = 8761 new ActivityManager.RunningAppProcessInfo(app.processName, 8762 app.pid, app.getPackageList()); 8763 fillInProcMemInfo(app, currApp); 8764 if (app.adjSource instanceof ProcessRecord) { 8765 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8766 currApp.importanceReasonImportance = oomAdjToImportance( 8767 app.adjSourceOom, null); 8768 } else if (app.adjSource instanceof ActivityRecord) { 8769 ActivityRecord r = (ActivityRecord)app.adjSource; 8770 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8771 } 8772 if (app.adjTarget instanceof ComponentName) { 8773 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8774 } 8775 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8776 // + " lru=" + currApp.lru); 8777 if (runList == null) { 8778 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8779 } 8780 runList.add(currApp); 8781 } 8782 } 8783 } 8784 return runList; 8785 } 8786 8787 public List<ApplicationInfo> getRunningExternalApplications() { 8788 enforceNotIsolatedCaller("getRunningExternalApplications"); 8789 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8790 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8791 if (runningApps != null && runningApps.size() > 0) { 8792 Set<String> extList = new HashSet<String>(); 8793 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8794 if (app.pkgList != null) { 8795 for (String pkg : app.pkgList) { 8796 extList.add(pkg); 8797 } 8798 } 8799 } 8800 IPackageManager pm = AppGlobals.getPackageManager(); 8801 for (String pkg : extList) { 8802 try { 8803 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8804 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8805 retList.add(info); 8806 } 8807 } catch (RemoteException e) { 8808 } 8809 } 8810 } 8811 return retList; 8812 } 8813 8814 @Override 8815 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8816 enforceNotIsolatedCaller("getMyMemoryState"); 8817 synchronized (this) { 8818 ProcessRecord proc; 8819 synchronized (mPidsSelfLocked) { 8820 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8821 } 8822 fillInProcMemInfo(proc, outInfo); 8823 } 8824 } 8825 8826 @Override 8827 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8828 if (checkCallingPermission(android.Manifest.permission.DUMP) 8829 != PackageManager.PERMISSION_GRANTED) { 8830 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8831 + Binder.getCallingPid() 8832 + ", uid=" + Binder.getCallingUid() 8833 + " without permission " 8834 + android.Manifest.permission.DUMP); 8835 return; 8836 } 8837 8838 boolean dumpAll = false; 8839 boolean dumpClient = false; 8840 String dumpPackage = null; 8841 8842 int opti = 0; 8843 while (opti < args.length) { 8844 String opt = args[opti]; 8845 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8846 break; 8847 } 8848 opti++; 8849 if ("-a".equals(opt)) { 8850 dumpAll = true; 8851 } else if ("-c".equals(opt)) { 8852 dumpClient = true; 8853 } else if ("-h".equals(opt)) { 8854 pw.println("Activity manager dump options:"); 8855 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8856 pw.println(" cmd may be one of:"); 8857 pw.println(" a[ctivities]: activity stack state"); 8858 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8859 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8860 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8861 pw.println(" o[om]: out of memory management"); 8862 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8863 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8864 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8865 pw.println(" service [COMP_SPEC]: service client-side state"); 8866 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8867 pw.println(" all: dump all activities"); 8868 pw.println(" top: dump the top activity"); 8869 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8870 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8871 pw.println(" a partial substring in a component name, a"); 8872 pw.println(" hex object identifier."); 8873 pw.println(" -a: include all available server state."); 8874 pw.println(" -c: include client state."); 8875 return; 8876 } else { 8877 pw.println("Unknown argument: " + opt + "; use -h for help"); 8878 } 8879 } 8880 8881 long origId = Binder.clearCallingIdentity(); 8882 boolean more = false; 8883 // Is the caller requesting to dump a particular piece of data? 8884 if (opti < args.length) { 8885 String cmd = args[opti]; 8886 opti++; 8887 if ("activities".equals(cmd) || "a".equals(cmd)) { 8888 synchronized (this) { 8889 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8890 } 8891 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8892 String[] newArgs; 8893 String name; 8894 if (opti >= args.length) { 8895 name = null; 8896 newArgs = EMPTY_STRING_ARRAY; 8897 } else { 8898 name = args[opti]; 8899 opti++; 8900 newArgs = new String[args.length - opti]; 8901 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8902 args.length - opti); 8903 } 8904 synchronized (this) { 8905 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8906 } 8907 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8908 String[] newArgs; 8909 String name; 8910 if (opti >= args.length) { 8911 name = null; 8912 newArgs = EMPTY_STRING_ARRAY; 8913 } else { 8914 name = args[opti]; 8915 opti++; 8916 newArgs = new String[args.length - opti]; 8917 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8918 args.length - opti); 8919 } 8920 synchronized (this) { 8921 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8922 } 8923 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8924 String[] newArgs; 8925 String name; 8926 if (opti >= args.length) { 8927 name = null; 8928 newArgs = EMPTY_STRING_ARRAY; 8929 } else { 8930 name = args[opti]; 8931 opti++; 8932 newArgs = new String[args.length - opti]; 8933 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8934 args.length - opti); 8935 } 8936 synchronized (this) { 8937 dumpProcessesLocked(fd, pw, args, opti, true, name); 8938 } 8939 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8940 synchronized (this) { 8941 dumpOomLocked(fd, pw, args, opti, true); 8942 } 8943 } else if ("provider".equals(cmd)) { 8944 String[] newArgs; 8945 String name; 8946 if (opti >= args.length) { 8947 name = null; 8948 newArgs = EMPTY_STRING_ARRAY; 8949 } else { 8950 name = args[opti]; 8951 opti++; 8952 newArgs = new String[args.length - opti]; 8953 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8954 } 8955 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8956 pw.println("No providers match: " + name); 8957 pw.println("Use -h for help."); 8958 } 8959 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8960 synchronized (this) { 8961 dumpProvidersLocked(fd, pw, args, opti, true, null); 8962 } 8963 } else if ("service".equals(cmd)) { 8964 String[] newArgs; 8965 String name; 8966 if (opti >= args.length) { 8967 name = null; 8968 newArgs = EMPTY_STRING_ARRAY; 8969 } else { 8970 name = args[opti]; 8971 opti++; 8972 newArgs = new String[args.length - opti]; 8973 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8974 args.length - opti); 8975 } 8976 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8977 pw.println("No services match: " + name); 8978 pw.println("Use -h for help."); 8979 } 8980 } else if ("package".equals(cmd)) { 8981 String[] newArgs; 8982 if (opti >= args.length) { 8983 pw.println("package: no package name specified"); 8984 pw.println("Use -h for help."); 8985 } else { 8986 dumpPackage = args[opti]; 8987 opti++; 8988 newArgs = new String[args.length - opti]; 8989 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8990 args.length - opti); 8991 args = newArgs; 8992 opti = 0; 8993 more = true; 8994 } 8995 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8996 synchronized (this) { 8997 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8998 } 8999 } else { 9000 // Dumping a single activity? 9001 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 9002 pw.println("Bad activity command, or no activities match: " + cmd); 9003 pw.println("Use -h for help."); 9004 } 9005 } 9006 if (!more) { 9007 Binder.restoreCallingIdentity(origId); 9008 return; 9009 } 9010 } 9011 9012 // No piece of data specified, dump everything. 9013 synchronized (this) { 9014 boolean needSep; 9015 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9016 if (needSep) { 9017 pw.println(" "); 9018 } 9019 if (dumpAll) { 9020 pw.println("-------------------------------------------------------------------------------"); 9021 } 9022 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9023 if (needSep) { 9024 pw.println(" "); 9025 } 9026 if (dumpAll) { 9027 pw.println("-------------------------------------------------------------------------------"); 9028 } 9029 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9030 if (needSep) { 9031 pw.println(" "); 9032 } 9033 if (dumpAll) { 9034 pw.println("-------------------------------------------------------------------------------"); 9035 } 9036 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9037 if (needSep) { 9038 pw.println(" "); 9039 } 9040 if (dumpAll) { 9041 pw.println("-------------------------------------------------------------------------------"); 9042 } 9043 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9044 if (needSep) { 9045 pw.println(" "); 9046 } 9047 if (dumpAll) { 9048 pw.println("-------------------------------------------------------------------------------"); 9049 } 9050 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9051 } 9052 Binder.restoreCallingIdentity(origId); 9053 } 9054 9055 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9056 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9057 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9058 pw.println(" Main stack:"); 9059 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9060 dumpPackage); 9061 pw.println(" "); 9062 pw.println(" Running activities (most recent first):"); 9063 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9064 dumpPackage); 9065 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9066 pw.println(" "); 9067 pw.println(" Activities waiting for another to become visible:"); 9068 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9069 !dumpAll, false, dumpPackage); 9070 } 9071 if (mMainStack.mStoppingActivities.size() > 0) { 9072 pw.println(" "); 9073 pw.println(" Activities waiting to stop:"); 9074 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9075 !dumpAll, false, dumpPackage); 9076 } 9077 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9078 pw.println(" "); 9079 pw.println(" Activities waiting to sleep:"); 9080 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9081 !dumpAll, false, dumpPackage); 9082 } 9083 if (mMainStack.mFinishingActivities.size() > 0) { 9084 pw.println(" "); 9085 pw.println(" Activities waiting to finish:"); 9086 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9087 !dumpAll, false, dumpPackage); 9088 } 9089 9090 pw.println(" "); 9091 if (mMainStack.mPausingActivity != null) { 9092 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9093 } 9094 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9095 pw.println(" mFocusedActivity: " + mFocusedActivity); 9096 if (dumpAll) { 9097 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9098 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9099 pw.println(" mDismissKeyguardOnNextActivity: " 9100 + mMainStack.mDismissKeyguardOnNextActivity); 9101 } 9102 9103 if (mRecentTasks.size() > 0) { 9104 pw.println(); 9105 pw.println(" Recent tasks:"); 9106 9107 final int N = mRecentTasks.size(); 9108 for (int i=0; i<N; i++) { 9109 TaskRecord tr = mRecentTasks.get(i); 9110 if (dumpPackage != null) { 9111 if (tr.realActivity == null || 9112 !dumpPackage.equals(tr.realActivity)) { 9113 continue; 9114 } 9115 } 9116 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9117 pw.println(tr); 9118 if (dumpAll) { 9119 mRecentTasks.get(i).dump(pw, " "); 9120 } 9121 } 9122 } 9123 9124 if (dumpAll) { 9125 pw.println(" "); 9126 pw.println(" mCurTask: " + mCurTask); 9127 } 9128 9129 return true; 9130 } 9131 9132 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9133 int opti, boolean dumpAll, String dumpPackage) { 9134 boolean needSep = false; 9135 int numPers = 0; 9136 9137 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9138 9139 if (dumpAll) { 9140 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9141 final int NA = procs.size(); 9142 for (int ia=0; ia<NA; ia++) { 9143 ProcessRecord r = procs.valueAt(ia); 9144 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9145 continue; 9146 } 9147 if (!needSep) { 9148 pw.println(" All known processes:"); 9149 needSep = true; 9150 } 9151 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9152 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9153 pw.print(" "); pw.println(r); 9154 r.dump(pw, " "); 9155 if (r.persistent) { 9156 numPers++; 9157 } 9158 } 9159 } 9160 } 9161 9162 if (mIsolatedProcesses.size() > 0) { 9163 if (needSep) pw.println(" "); 9164 needSep = true; 9165 pw.println(" Isolated process list (sorted by uid):"); 9166 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9167 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9168 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9169 continue; 9170 } 9171 pw.println(String.format("%sIsolated #%2d: %s", 9172 " ", i, r.toString())); 9173 } 9174 } 9175 9176 if (mLruProcesses.size() > 0) { 9177 if (needSep) pw.println(" "); 9178 needSep = true; 9179 pw.println(" Process LRU list (sorted by oom_adj):"); 9180 dumpProcessOomList(pw, this, mLruProcesses, " ", 9181 "Proc", "PERS", false, dumpPackage); 9182 needSep = true; 9183 } 9184 9185 if (dumpAll) { 9186 synchronized (mPidsSelfLocked) { 9187 boolean printed = false; 9188 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9189 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9190 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9191 continue; 9192 } 9193 if (!printed) { 9194 if (needSep) pw.println(" "); 9195 needSep = true; 9196 pw.println(" PID mappings:"); 9197 printed = true; 9198 } 9199 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9200 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9201 } 9202 } 9203 } 9204 9205 if (mForegroundProcesses.size() > 0) { 9206 synchronized (mPidsSelfLocked) { 9207 boolean printed = false; 9208 for (int i=0; i<mForegroundProcesses.size(); i++) { 9209 ProcessRecord r = mPidsSelfLocked.get( 9210 mForegroundProcesses.valueAt(i).pid); 9211 if (dumpPackage != null && (r == null 9212 || !dumpPackage.equals(r.info.packageName))) { 9213 continue; 9214 } 9215 if (!printed) { 9216 if (needSep) pw.println(" "); 9217 needSep = true; 9218 pw.println(" Foreground Processes:"); 9219 printed = true; 9220 } 9221 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9222 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9223 } 9224 } 9225 } 9226 9227 if (mPersistentStartingProcesses.size() > 0) { 9228 if (needSep) pw.println(" "); 9229 needSep = true; 9230 pw.println(" Persisent processes that are starting:"); 9231 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9232 "Starting Norm", "Restarting PERS", dumpPackage); 9233 } 9234 9235 if (mRemovedProcesses.size() > 0) { 9236 if (needSep) pw.println(" "); 9237 needSep = true; 9238 pw.println(" Processes that are being removed:"); 9239 dumpProcessList(pw, this, mRemovedProcesses, " ", 9240 "Removed Norm", "Removed PERS", dumpPackage); 9241 } 9242 9243 if (mProcessesOnHold.size() > 0) { 9244 if (needSep) pw.println(" "); 9245 needSep = true; 9246 pw.println(" Processes that are on old until the system is ready:"); 9247 dumpProcessList(pw, this, mProcessesOnHold, " ", 9248 "OnHold Norm", "OnHold PERS", dumpPackage); 9249 } 9250 9251 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9252 9253 if (mProcessCrashTimes.getMap().size() > 0) { 9254 boolean printed = false; 9255 long now = SystemClock.uptimeMillis(); 9256 for (Map.Entry<String, SparseArray<Long>> procs 9257 : mProcessCrashTimes.getMap().entrySet()) { 9258 String pname = procs.getKey(); 9259 SparseArray<Long> uids = procs.getValue(); 9260 final int N = uids.size(); 9261 for (int i=0; i<N; i++) { 9262 int puid = uids.keyAt(i); 9263 ProcessRecord r = mProcessNames.get(pname, puid); 9264 if (dumpPackage != null && (r == null 9265 || !dumpPackage.equals(r.info.packageName))) { 9266 continue; 9267 } 9268 if (!printed) { 9269 if (needSep) pw.println(" "); 9270 needSep = true; 9271 pw.println(" Time since processes crashed:"); 9272 printed = true; 9273 } 9274 pw.print(" Process "); pw.print(pname); 9275 pw.print(" uid "); pw.print(puid); 9276 pw.print(": last crashed "); 9277 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9278 pw.println(" ago"); 9279 } 9280 } 9281 } 9282 9283 if (mBadProcesses.getMap().size() > 0) { 9284 boolean printed = false; 9285 for (Map.Entry<String, SparseArray<Long>> procs 9286 : mBadProcesses.getMap().entrySet()) { 9287 String pname = procs.getKey(); 9288 SparseArray<Long> uids = procs.getValue(); 9289 final int N = uids.size(); 9290 for (int i=0; i<N; i++) { 9291 int puid = uids.keyAt(i); 9292 ProcessRecord r = mProcessNames.get(pname, puid); 9293 if (dumpPackage != null && (r == null 9294 || !dumpPackage.equals(r.info.packageName))) { 9295 continue; 9296 } 9297 if (!printed) { 9298 if (needSep) pw.println(" "); 9299 needSep = true; 9300 pw.println(" Bad processes:"); 9301 } 9302 pw.print(" Bad process "); pw.print(pname); 9303 pw.print(" uid "); pw.print(puid); 9304 pw.print(": crashed at time "); 9305 pw.println(uids.valueAt(i)); 9306 } 9307 } 9308 } 9309 9310 pw.println(); 9311 pw.println(" mStartedUsers:"); 9312 for (int i=0; i<mStartedUsers.size(); i++) { 9313 UserStartedState uss = mStartedUsers.valueAt(i); 9314 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9315 pw.print(": "); uss.dump("", pw); 9316 } 9317 pw.print(" mUserLru: ["); 9318 for (int i=0; i<mUserLru.size(); i++) { 9319 if (i > 0) pw.print(", "); 9320 pw.print(mUserLru.get(i)); 9321 } 9322 pw.println("]"); 9323 if (dumpAll) { 9324 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 9325 } 9326 pw.println(" mHomeProcess: " + mHomeProcess); 9327 pw.println(" mPreviousProcess: " + mPreviousProcess); 9328 if (dumpAll) { 9329 StringBuilder sb = new StringBuilder(128); 9330 sb.append(" mPreviousProcessVisibleTime: "); 9331 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9332 pw.println(sb); 9333 } 9334 if (mHeavyWeightProcess != null) { 9335 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9336 } 9337 pw.println(" mConfiguration: " + mConfiguration); 9338 if (dumpAll) { 9339 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9340 if (mCompatModePackages.getPackages().size() > 0) { 9341 boolean printed = false; 9342 for (Map.Entry<String, Integer> entry 9343 : mCompatModePackages.getPackages().entrySet()) { 9344 String pkg = entry.getKey(); 9345 int mode = entry.getValue(); 9346 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9347 continue; 9348 } 9349 if (!printed) { 9350 pw.println(" mScreenCompatPackages:"); 9351 printed = true; 9352 } 9353 pw.print(" "); pw.print(pkg); pw.print(": "); 9354 pw.print(mode); pw.println(); 9355 } 9356 } 9357 } 9358 if (mSleeping || mWentToSleep || mLockScreenShown) { 9359 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9360 + " mLockScreenShown " + mLockScreenShown); 9361 } 9362 if (mShuttingDown) { 9363 pw.println(" mShuttingDown=" + mShuttingDown); 9364 } 9365 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9366 || mOrigWaitForDebugger) { 9367 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9368 + " mDebugTransient=" + mDebugTransient 9369 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9370 } 9371 if (mOpenGlTraceApp != null) { 9372 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9373 } 9374 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9375 || mProfileFd != null) { 9376 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9377 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9378 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9379 + mAutoStopProfiler); 9380 } 9381 if (mAlwaysFinishActivities || mController != null) { 9382 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9383 + " mController=" + mController); 9384 } 9385 if (dumpAll) { 9386 pw.println(" Total persistent processes: " + numPers); 9387 pw.println(" mStartRunning=" + mStartRunning 9388 + " mProcessesReady=" + mProcessesReady 9389 + " mSystemReady=" + mSystemReady); 9390 pw.println(" mBooting=" + mBooting 9391 + " mBooted=" + mBooted 9392 + " mFactoryTest=" + mFactoryTest); 9393 pw.print(" mLastPowerCheckRealtime="); 9394 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9395 pw.println(""); 9396 pw.print(" mLastPowerCheckUptime="); 9397 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9398 pw.println(""); 9399 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9400 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9401 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9402 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9403 + " mNumHiddenProcs=" + mNumHiddenProcs 9404 + " mNumServiceProcs=" + mNumServiceProcs 9405 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9406 } 9407 9408 return true; 9409 } 9410 9411 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9412 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9413 if (mProcessesToGc.size() > 0) { 9414 boolean printed = false; 9415 long now = SystemClock.uptimeMillis(); 9416 for (int i=0; i<mProcessesToGc.size(); i++) { 9417 ProcessRecord proc = mProcessesToGc.get(i); 9418 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9419 continue; 9420 } 9421 if (!printed) { 9422 if (needSep) pw.println(" "); 9423 needSep = true; 9424 pw.println(" Processes that are waiting to GC:"); 9425 printed = true; 9426 } 9427 pw.print(" Process "); pw.println(proc); 9428 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9429 pw.print(", last gced="); 9430 pw.print(now-proc.lastRequestedGc); 9431 pw.print(" ms ago, last lowMem="); 9432 pw.print(now-proc.lastLowMemory); 9433 pw.println(" ms ago"); 9434 9435 } 9436 } 9437 return needSep; 9438 } 9439 9440 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9441 int opti, boolean dumpAll) { 9442 boolean needSep = false; 9443 9444 if (mLruProcesses.size() > 0) { 9445 if (needSep) pw.println(" "); 9446 needSep = true; 9447 pw.println(" OOM levels:"); 9448 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9449 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9450 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9451 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9452 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9453 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9454 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9455 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9456 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9457 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9458 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9459 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9460 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9461 9462 if (needSep) pw.println(" "); 9463 needSep = true; 9464 pw.println(" Process OOM control:"); 9465 dumpProcessOomList(pw, this, mLruProcesses, " ", 9466 "Proc", "PERS", true, null); 9467 needSep = true; 9468 } 9469 9470 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9471 9472 pw.println(); 9473 pw.println(" mHomeProcess: " + mHomeProcess); 9474 pw.println(" mPreviousProcess: " + mPreviousProcess); 9475 if (mHeavyWeightProcess != null) { 9476 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9477 } 9478 9479 return true; 9480 } 9481 9482 /** 9483 * There are three ways to call this: 9484 * - no provider specified: dump all the providers 9485 * - a flattened component name that matched an existing provider was specified as the 9486 * first arg: dump that one provider 9487 * - the first arg isn't the flattened component name of an existing provider: 9488 * dump all providers whose component contains the first arg as a substring 9489 */ 9490 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9491 int opti, boolean dumpAll) { 9492 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9493 } 9494 9495 static class ItemMatcher { 9496 ArrayList<ComponentName> components; 9497 ArrayList<String> strings; 9498 ArrayList<Integer> objects; 9499 boolean all; 9500 9501 ItemMatcher() { 9502 all = true; 9503 } 9504 9505 void build(String name) { 9506 ComponentName componentName = ComponentName.unflattenFromString(name); 9507 if (componentName != null) { 9508 if (components == null) { 9509 components = new ArrayList<ComponentName>(); 9510 } 9511 components.add(componentName); 9512 all = false; 9513 } else { 9514 int objectId = 0; 9515 // Not a '/' separated full component name; maybe an object ID? 9516 try { 9517 objectId = Integer.parseInt(name, 16); 9518 if (objects == null) { 9519 objects = new ArrayList<Integer>(); 9520 } 9521 objects.add(objectId); 9522 all = false; 9523 } catch (RuntimeException e) { 9524 // Not an integer; just do string match. 9525 if (strings == null) { 9526 strings = new ArrayList<String>(); 9527 } 9528 strings.add(name); 9529 all = false; 9530 } 9531 } 9532 } 9533 9534 int build(String[] args, int opti) { 9535 for (; opti<args.length; opti++) { 9536 String name = args[opti]; 9537 if ("--".equals(name)) { 9538 return opti+1; 9539 } 9540 build(name); 9541 } 9542 return opti; 9543 } 9544 9545 boolean match(Object object, ComponentName comp) { 9546 if (all) { 9547 return true; 9548 } 9549 if (components != null) { 9550 for (int i=0; i<components.size(); i++) { 9551 if (components.get(i).equals(comp)) { 9552 return true; 9553 } 9554 } 9555 } 9556 if (objects != null) { 9557 for (int i=0; i<objects.size(); i++) { 9558 if (System.identityHashCode(object) == objects.get(i)) { 9559 return true; 9560 } 9561 } 9562 } 9563 if (strings != null) { 9564 String flat = comp.flattenToString(); 9565 for (int i=0; i<strings.size(); i++) { 9566 if (flat.contains(strings.get(i))) { 9567 return true; 9568 } 9569 } 9570 } 9571 return false; 9572 } 9573 } 9574 9575 /** 9576 * There are three things that cmd can be: 9577 * - a flattened component name that matches an existing activity 9578 * - the cmd arg isn't the flattened component name of an existing activity: 9579 * dump all activity whose component contains the cmd as a substring 9580 * - A hex number of the ActivityRecord object instance. 9581 */ 9582 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9583 int opti, boolean dumpAll) { 9584 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9585 9586 if ("all".equals(name)) { 9587 synchronized (this) { 9588 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9589 activities.add(r1); 9590 } 9591 } 9592 } else if ("top".equals(name)) { 9593 synchronized (this) { 9594 final int N = mMainStack.mHistory.size(); 9595 if (N > 0) { 9596 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9597 } 9598 } 9599 } else { 9600 ItemMatcher matcher = new ItemMatcher(); 9601 matcher.build(name); 9602 9603 synchronized (this) { 9604 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9605 if (matcher.match(r1, r1.intent.getComponent())) { 9606 activities.add(r1); 9607 } 9608 } 9609 } 9610 } 9611 9612 if (activities.size() <= 0) { 9613 return false; 9614 } 9615 9616 String[] newArgs = new String[args.length - opti]; 9617 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9618 9619 TaskRecord lastTask = null; 9620 boolean needSep = false; 9621 for (int i=activities.size()-1; i>=0; i--) { 9622 ActivityRecord r = (ActivityRecord)activities.get(i); 9623 if (needSep) { 9624 pw.println(); 9625 } 9626 needSep = true; 9627 synchronized (this) { 9628 if (lastTask != r.task) { 9629 lastTask = r.task; 9630 pw.print("TASK "); pw.print(lastTask.affinity); 9631 pw.print(" id="); pw.println(lastTask.taskId); 9632 if (dumpAll) { 9633 lastTask.dump(pw, " "); 9634 } 9635 } 9636 } 9637 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9638 } 9639 return true; 9640 } 9641 9642 /** 9643 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9644 * there is a thread associated with the activity. 9645 */ 9646 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9647 final ActivityRecord r, String[] args, boolean dumpAll) { 9648 String innerPrefix = prefix + " "; 9649 synchronized (this) { 9650 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9651 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9652 pw.print(" pid="); 9653 if (r.app != null) pw.println(r.app.pid); 9654 else pw.println("(not running)"); 9655 if (dumpAll) { 9656 r.dump(pw, innerPrefix); 9657 } 9658 } 9659 if (r.app != null && r.app.thread != null) { 9660 // flush anything that is already in the PrintWriter since the thread is going 9661 // to write to the file descriptor directly 9662 pw.flush(); 9663 try { 9664 TransferPipe tp = new TransferPipe(); 9665 try { 9666 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9667 r.appToken, innerPrefix, args); 9668 tp.go(fd); 9669 } finally { 9670 tp.kill(); 9671 } 9672 } catch (IOException e) { 9673 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9674 } catch (RemoteException e) { 9675 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9676 } 9677 } 9678 } 9679 9680 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9681 int opti, boolean dumpAll, String dumpPackage) { 9682 boolean needSep = false; 9683 boolean onlyHistory = false; 9684 9685 if ("history".equals(dumpPackage)) { 9686 onlyHistory = true; 9687 dumpPackage = null; 9688 } 9689 9690 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9691 if (!onlyHistory && dumpAll) { 9692 if (mRegisteredReceivers.size() > 0) { 9693 boolean printed = false; 9694 Iterator it = mRegisteredReceivers.values().iterator(); 9695 while (it.hasNext()) { 9696 ReceiverList r = (ReceiverList)it.next(); 9697 if (dumpPackage != null && (r.app == null || 9698 !dumpPackage.equals(r.app.info.packageName))) { 9699 continue; 9700 } 9701 if (!printed) { 9702 pw.println(" Registered Receivers:"); 9703 needSep = true; 9704 printed = true; 9705 } 9706 pw.print(" * "); pw.println(r); 9707 r.dump(pw, " "); 9708 } 9709 } 9710 9711 if (mReceiverResolver.dump(pw, needSep ? 9712 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9713 " ", dumpPackage, false)) { 9714 needSep = true; 9715 } 9716 } 9717 9718 for (BroadcastQueue q : mBroadcastQueues) { 9719 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9720 } 9721 9722 needSep = true; 9723 9724 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9725 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9726 if (needSep) { 9727 pw.println(); 9728 } 9729 needSep = true; 9730 pw.print(" Sticky broadcasts for user "); 9731 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9732 StringBuilder sb = new StringBuilder(128); 9733 for (Map.Entry<String, ArrayList<Intent>> ent 9734 : mStickyBroadcasts.valueAt(user).entrySet()) { 9735 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9736 if (dumpAll) { 9737 pw.println(":"); 9738 ArrayList<Intent> intents = ent.getValue(); 9739 final int N = intents.size(); 9740 for (int i=0; i<N; i++) { 9741 sb.setLength(0); 9742 sb.append(" Intent: "); 9743 intents.get(i).toShortString(sb, false, true, false, false); 9744 pw.println(sb.toString()); 9745 Bundle bundle = intents.get(i).getExtras(); 9746 if (bundle != null) { 9747 pw.print(" "); 9748 pw.println(bundle.toString()); 9749 } 9750 } 9751 } else { 9752 pw.println(""); 9753 } 9754 } 9755 } 9756 } 9757 9758 if (!onlyHistory && dumpAll) { 9759 pw.println(); 9760 for (BroadcastQueue queue : mBroadcastQueues) { 9761 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9762 + queue.mBroadcastsScheduled); 9763 } 9764 pw.println(" mHandler:"); 9765 mHandler.dump(new PrintWriterPrinter(pw), " "); 9766 needSep = true; 9767 } 9768 9769 return needSep; 9770 } 9771 9772 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9773 int opti, boolean dumpAll, String dumpPackage) { 9774 boolean needSep = true; 9775 9776 ItemMatcher matcher = new ItemMatcher(); 9777 matcher.build(args, opti); 9778 9779 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9780 9781 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9782 9783 if (mLaunchingProviders.size() > 0) { 9784 boolean printed = false; 9785 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9786 ContentProviderRecord r = mLaunchingProviders.get(i); 9787 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9788 continue; 9789 } 9790 if (!printed) { 9791 if (needSep) pw.println(" "); 9792 needSep = true; 9793 pw.println(" Launching content providers:"); 9794 printed = true; 9795 } 9796 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9797 pw.println(r); 9798 } 9799 } 9800 9801 if (mGrantedUriPermissions.size() > 0) { 9802 if (needSep) pw.println(); 9803 needSep = true; 9804 pw.println("Granted Uri Permissions:"); 9805 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9806 int uid = mGrantedUriPermissions.keyAt(i); 9807 HashMap<Uri, UriPermission> perms 9808 = mGrantedUriPermissions.valueAt(i); 9809 pw.print(" * UID "); pw.print(uid); 9810 pw.println(" holds:"); 9811 for (UriPermission perm : perms.values()) { 9812 pw.print(" "); pw.println(perm); 9813 if (dumpAll) { 9814 perm.dump(pw, " "); 9815 } 9816 } 9817 } 9818 needSep = true; 9819 } 9820 9821 return needSep; 9822 } 9823 9824 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9825 int opti, boolean dumpAll, String dumpPackage) { 9826 boolean needSep = false; 9827 9828 if (mIntentSenderRecords.size() > 0) { 9829 boolean printed = false; 9830 Iterator<WeakReference<PendingIntentRecord>> it 9831 = mIntentSenderRecords.values().iterator(); 9832 while (it.hasNext()) { 9833 WeakReference<PendingIntentRecord> ref = it.next(); 9834 PendingIntentRecord rec = ref != null ? ref.get(): null; 9835 if (dumpPackage != null && (rec == null 9836 || !dumpPackage.equals(rec.key.packageName))) { 9837 continue; 9838 } 9839 if (!printed) { 9840 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9841 printed = true; 9842 } 9843 needSep = true; 9844 if (rec != null) { 9845 pw.print(" * "); pw.println(rec); 9846 if (dumpAll) { 9847 rec.dump(pw, " "); 9848 } 9849 } else { 9850 pw.print(" * "); pw.println(ref); 9851 } 9852 } 9853 } 9854 9855 return needSep; 9856 } 9857 9858 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9859 String prefix, String label, boolean complete, boolean brief, boolean client, 9860 String dumpPackage) { 9861 TaskRecord lastTask = null; 9862 boolean needNL = false; 9863 final String innerPrefix = prefix + " "; 9864 final String[] args = new String[0]; 9865 for (int i=list.size()-1; i>=0; i--) { 9866 final ActivityRecord r = (ActivityRecord)list.get(i); 9867 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9868 continue; 9869 } 9870 final boolean full = !brief && (complete || !r.isInHistory()); 9871 if (needNL) { 9872 pw.println(" "); 9873 needNL = false; 9874 } 9875 if (lastTask != r.task) { 9876 lastTask = r.task; 9877 pw.print(prefix); 9878 pw.print(full ? "* " : " "); 9879 pw.println(lastTask); 9880 if (full) { 9881 lastTask.dump(pw, prefix + " "); 9882 } else if (complete) { 9883 // Complete + brief == give a summary. Isn't that obvious?!? 9884 if (lastTask.intent != null) { 9885 pw.print(prefix); pw.print(" "); 9886 pw.println(lastTask.intent.toInsecureStringWithClip()); 9887 } 9888 } 9889 } 9890 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9891 pw.print(" #"); pw.print(i); pw.print(": "); 9892 pw.println(r); 9893 if (full) { 9894 r.dump(pw, innerPrefix); 9895 } else if (complete) { 9896 // Complete + brief == give a summary. Isn't that obvious?!? 9897 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9898 if (r.app != null) { 9899 pw.print(innerPrefix); pw.println(r.app); 9900 } 9901 } 9902 if (client && r.app != null && r.app.thread != null) { 9903 // flush anything that is already in the PrintWriter since the thread is going 9904 // to write to the file descriptor directly 9905 pw.flush(); 9906 try { 9907 TransferPipe tp = new TransferPipe(); 9908 try { 9909 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9910 r.appToken, innerPrefix, args); 9911 // Short timeout, since blocking here can 9912 // deadlock with the application. 9913 tp.go(fd, 2000); 9914 } finally { 9915 tp.kill(); 9916 } 9917 } catch (IOException e) { 9918 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9919 } catch (RemoteException e) { 9920 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9921 } 9922 needNL = true; 9923 } 9924 } 9925 } 9926 9927 private static String buildOomTag(String prefix, String space, int val, int base) { 9928 if (val == base) { 9929 if (space == null) return prefix; 9930 return prefix + " "; 9931 } 9932 return prefix + "+" + Integer.toString(val-base); 9933 } 9934 9935 private static final int dumpProcessList(PrintWriter pw, 9936 ActivityManagerService service, List list, 9937 String prefix, String normalLabel, String persistentLabel, 9938 String dumpPackage) { 9939 int numPers = 0; 9940 final int N = list.size()-1; 9941 for (int i=N; i>=0; i--) { 9942 ProcessRecord r = (ProcessRecord)list.get(i); 9943 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9944 continue; 9945 } 9946 pw.println(String.format("%s%s #%2d: %s", 9947 prefix, (r.persistent ? persistentLabel : normalLabel), 9948 i, r.toString())); 9949 if (r.persistent) { 9950 numPers++; 9951 } 9952 } 9953 return numPers; 9954 } 9955 9956 private static final boolean dumpProcessOomList(PrintWriter pw, 9957 ActivityManagerService service, List<ProcessRecord> origList, 9958 String prefix, String normalLabel, String persistentLabel, 9959 boolean inclDetails, String dumpPackage) { 9960 9961 ArrayList<Pair<ProcessRecord, Integer>> list 9962 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9963 for (int i=0; i<origList.size(); i++) { 9964 ProcessRecord r = origList.get(i); 9965 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9966 continue; 9967 } 9968 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9969 } 9970 9971 if (list.size() <= 0) { 9972 return false; 9973 } 9974 9975 Comparator<Pair<ProcessRecord, Integer>> comparator 9976 = new Comparator<Pair<ProcessRecord, Integer>>() { 9977 @Override 9978 public int compare(Pair<ProcessRecord, Integer> object1, 9979 Pair<ProcessRecord, Integer> object2) { 9980 if (object1.first.setAdj != object2.first.setAdj) { 9981 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9982 } 9983 if (object1.second.intValue() != object2.second.intValue()) { 9984 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9985 } 9986 return 0; 9987 } 9988 }; 9989 9990 Collections.sort(list, comparator); 9991 9992 final long curRealtime = SystemClock.elapsedRealtime(); 9993 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9994 final long curUptime = SystemClock.uptimeMillis(); 9995 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9996 9997 for (int i=list.size()-1; i>=0; i--) { 9998 ProcessRecord r = list.get(i).first; 9999 String oomAdj; 10000 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10001 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10002 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10003 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10004 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10005 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10006 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10007 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10008 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10009 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10010 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10011 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10012 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10013 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10014 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10015 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10016 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10017 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10018 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10019 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10020 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10021 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10022 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10023 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10024 } else { 10025 oomAdj = Integer.toString(r.setAdj); 10026 } 10027 String schedGroup; 10028 switch (r.setSchedGroup) { 10029 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10030 schedGroup = "B"; 10031 break; 10032 case Process.THREAD_GROUP_DEFAULT: 10033 schedGroup = "F"; 10034 break; 10035 default: 10036 schedGroup = Integer.toString(r.setSchedGroup); 10037 break; 10038 } 10039 String foreground; 10040 if (r.foregroundActivities) { 10041 foreground = "A"; 10042 } else if (r.foregroundServices) { 10043 foreground = "S"; 10044 } else { 10045 foreground = " "; 10046 } 10047 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10048 prefix, (r.persistent ? persistentLabel : normalLabel), 10049 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10050 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10051 if (r.adjSource != null || r.adjTarget != null) { 10052 pw.print(prefix); 10053 pw.print(" "); 10054 if (r.adjTarget instanceof ComponentName) { 10055 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10056 } else if (r.adjTarget != null) { 10057 pw.print(r.adjTarget.toString()); 10058 } else { 10059 pw.print("{null}"); 10060 } 10061 pw.print("<="); 10062 if (r.adjSource instanceof ProcessRecord) { 10063 pw.print("Proc{"); 10064 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10065 pw.println("}"); 10066 } else if (r.adjSource != null) { 10067 pw.println(r.adjSource.toString()); 10068 } else { 10069 pw.println("{null}"); 10070 } 10071 } 10072 if (inclDetails) { 10073 pw.print(prefix); 10074 pw.print(" "); 10075 pw.print("oom: max="); pw.print(r.maxAdj); 10076 pw.print(" hidden="); pw.print(r.hiddenAdj); 10077 pw.print(" empty="); pw.print(r.emptyAdj); 10078 pw.print(" curRaw="); pw.print(r.curRawAdj); 10079 pw.print(" setRaw="); pw.print(r.setRawAdj); 10080 pw.print(" cur="); pw.print(r.curAdj); 10081 pw.print(" set="); pw.println(r.setAdj); 10082 pw.print(prefix); 10083 pw.print(" "); 10084 pw.print("keeping="); pw.print(r.keeping); 10085 pw.print(" hidden="); pw.print(r.hidden); 10086 pw.print(" empty="); pw.print(r.empty); 10087 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10088 10089 if (!r.keeping) { 10090 if (r.lastWakeTime != 0) { 10091 long wtime; 10092 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10093 synchronized (stats) { 10094 wtime = stats.getProcessWakeTime(r.info.uid, 10095 r.pid, curRealtime); 10096 } 10097 long timeUsed = wtime - r.lastWakeTime; 10098 pw.print(prefix); 10099 pw.print(" "); 10100 pw.print("keep awake over "); 10101 TimeUtils.formatDuration(realtimeSince, pw); 10102 pw.print(" used "); 10103 TimeUtils.formatDuration(timeUsed, pw); 10104 pw.print(" ("); 10105 pw.print((timeUsed*100)/realtimeSince); 10106 pw.println("%)"); 10107 } 10108 if (r.lastCpuTime != 0) { 10109 long timeUsed = r.curCpuTime - r.lastCpuTime; 10110 pw.print(prefix); 10111 pw.print(" "); 10112 pw.print("run cpu over "); 10113 TimeUtils.formatDuration(uptimeSince, pw); 10114 pw.print(" used "); 10115 TimeUtils.formatDuration(timeUsed, pw); 10116 pw.print(" ("); 10117 pw.print((timeUsed*100)/uptimeSince); 10118 pw.println("%)"); 10119 } 10120 } 10121 } 10122 } 10123 return true; 10124 } 10125 10126 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10127 ArrayList<ProcessRecord> procs; 10128 synchronized (this) { 10129 if (args != null && args.length > start 10130 && args[start].charAt(0) != '-') { 10131 procs = new ArrayList<ProcessRecord>(); 10132 int pid = -1; 10133 try { 10134 pid = Integer.parseInt(args[start]); 10135 } catch (NumberFormatException e) { 10136 10137 } 10138 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10139 ProcessRecord proc = mLruProcesses.get(i); 10140 if (proc.pid == pid) { 10141 procs.add(proc); 10142 } else if (proc.processName.equals(args[start])) { 10143 procs.add(proc); 10144 } 10145 } 10146 if (procs.size() <= 0) { 10147 pw.println("No process found for: " + args[start]); 10148 return null; 10149 } 10150 } else { 10151 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10152 } 10153 } 10154 return procs; 10155 } 10156 10157 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10158 PrintWriter pw, String[] args) { 10159 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10160 if (procs == null) { 10161 return; 10162 } 10163 10164 long uptime = SystemClock.uptimeMillis(); 10165 long realtime = SystemClock.elapsedRealtime(); 10166 pw.println("Applications Graphics Acceleration Info:"); 10167 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10168 10169 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10170 ProcessRecord r = procs.get(i); 10171 if (r.thread != null) { 10172 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10173 pw.flush(); 10174 try { 10175 TransferPipe tp = new TransferPipe(); 10176 try { 10177 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10178 tp.go(fd); 10179 } finally { 10180 tp.kill(); 10181 } 10182 } catch (IOException e) { 10183 pw.println("Failure while dumping the app: " + r); 10184 pw.flush(); 10185 } catch (RemoteException e) { 10186 pw.println("Got a RemoteException while dumping the app " + r); 10187 pw.flush(); 10188 } 10189 } 10190 } 10191 } 10192 10193 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10194 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10195 if (procs == null) { 10196 return; 10197 } 10198 10199 pw.println("Applications Database Info:"); 10200 10201 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10202 ProcessRecord r = procs.get(i); 10203 if (r.thread != null) { 10204 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10205 pw.flush(); 10206 try { 10207 TransferPipe tp = new TransferPipe(); 10208 try { 10209 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10210 tp.go(fd); 10211 } finally { 10212 tp.kill(); 10213 } 10214 } catch (IOException e) { 10215 pw.println("Failure while dumping the app: " + r); 10216 pw.flush(); 10217 } catch (RemoteException e) { 10218 pw.println("Got a RemoteException while dumping the app " + r); 10219 pw.flush(); 10220 } 10221 } 10222 } 10223 } 10224 10225 final static class MemItem { 10226 final String label; 10227 final String shortLabel; 10228 final long pss; 10229 final int id; 10230 ArrayList<MemItem> subitems; 10231 10232 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10233 label = _label; 10234 shortLabel = _shortLabel; 10235 pss = _pss; 10236 id = _id; 10237 } 10238 } 10239 10240 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10241 boolean sort) { 10242 if (sort) { 10243 Collections.sort(items, new Comparator<MemItem>() { 10244 @Override 10245 public int compare(MemItem lhs, MemItem rhs) { 10246 if (lhs.pss < rhs.pss) { 10247 return 1; 10248 } else if (lhs.pss > rhs.pss) { 10249 return -1; 10250 } 10251 return 0; 10252 } 10253 }); 10254 } 10255 10256 for (int i=0; i<items.size(); i++) { 10257 MemItem mi = items.get(i); 10258 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10259 if (mi.subitems != null) { 10260 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10261 } 10262 } 10263 } 10264 10265 // These are in KB. 10266 static final long[] DUMP_MEM_BUCKETS = new long[] { 10267 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10268 120*1024, 160*1024, 200*1024, 10269 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10270 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10271 }; 10272 10273 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10274 boolean stackLike) { 10275 int start = label.lastIndexOf('.'); 10276 if (start >= 0) start++; 10277 else start = 0; 10278 int end = label.length(); 10279 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10280 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10281 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10282 out.append(bucket); 10283 out.append(stackLike ? "MB." : "MB "); 10284 out.append(label, start, end); 10285 return; 10286 } 10287 } 10288 out.append(memKB/1024); 10289 out.append(stackLike ? "MB." : "MB "); 10290 out.append(label, start, end); 10291 } 10292 10293 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10294 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10295 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10296 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10297 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10298 }; 10299 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10300 "System", "Persistent", "Foreground", 10301 "Visible", "Perceptible", "Heavy Weight", 10302 "Backup", "A Services", "Home", "Previous", 10303 "B Services", "Background" 10304 }; 10305 10306 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10307 PrintWriter pw, String prefix, String[] args, boolean brief, 10308 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10309 boolean dumpAll = false; 10310 boolean oomOnly = false; 10311 10312 int opti = 0; 10313 while (opti < args.length) { 10314 String opt = args[opti]; 10315 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10316 break; 10317 } 10318 opti++; 10319 if ("-a".equals(opt)) { 10320 dumpAll = true; 10321 } else if ("--oom".equals(opt)) { 10322 oomOnly = true; 10323 } else if ("-h".equals(opt)) { 10324 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10325 pw.println(" -a: include all available information for each process."); 10326 pw.println(" --oom: only show processes organized by oom adj."); 10327 pw.println("If [process] is specified it can be the name or "); 10328 pw.println("pid of a specific process to dump."); 10329 return; 10330 } else { 10331 pw.println("Unknown argument: " + opt + "; use -h for help"); 10332 } 10333 } 10334 10335 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10336 if (procs == null) { 10337 return; 10338 } 10339 10340 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10341 long uptime = SystemClock.uptimeMillis(); 10342 long realtime = SystemClock.elapsedRealtime(); 10343 10344 if (procs.size() == 1 || isCheckinRequest) { 10345 dumpAll = true; 10346 } 10347 10348 if (isCheckinRequest) { 10349 // short checkin version 10350 pw.println(uptime + "," + realtime); 10351 pw.flush(); 10352 } else { 10353 pw.println("Applications Memory Usage (kB):"); 10354 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10355 } 10356 10357 String[] innerArgs = new String[args.length-opti]; 10358 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10359 10360 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10361 long nativePss=0, dalvikPss=0, otherPss=0; 10362 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10363 10364 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10365 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10366 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10367 10368 long totalPss = 0; 10369 10370 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10371 ProcessRecord r = procs.get(i); 10372 if (r.thread != null) { 10373 if (!isCheckinRequest && dumpAll) { 10374 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10375 pw.flush(); 10376 } 10377 Debug.MemoryInfo mi = null; 10378 if (dumpAll) { 10379 try { 10380 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10381 } catch (RemoteException e) { 10382 if (!isCheckinRequest) { 10383 pw.println("Got RemoteException!"); 10384 pw.flush(); 10385 } 10386 } 10387 } else { 10388 mi = new Debug.MemoryInfo(); 10389 Debug.getMemoryInfo(r.pid, mi); 10390 } 10391 10392 if (!isCheckinRequest && mi != null) { 10393 long myTotalPss = mi.getTotalPss(); 10394 totalPss += myTotalPss; 10395 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10396 r.processName, myTotalPss, 0); 10397 procMems.add(pssItem); 10398 10399 nativePss += mi.nativePss; 10400 dalvikPss += mi.dalvikPss; 10401 otherPss += mi.otherPss; 10402 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10403 long mem = mi.getOtherPss(j); 10404 miscPss[j] += mem; 10405 otherPss -= mem; 10406 } 10407 10408 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10409 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10410 || oomIndex == (oomPss.length-1)) { 10411 oomPss[oomIndex] += myTotalPss; 10412 if (oomProcs[oomIndex] == null) { 10413 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10414 } 10415 oomProcs[oomIndex].add(pssItem); 10416 break; 10417 } 10418 } 10419 } 10420 } 10421 } 10422 10423 if (!isCheckinRequest && procs.size() > 1) { 10424 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10425 10426 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10427 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10428 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10429 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10430 String label = Debug.MemoryInfo.getOtherLabel(j); 10431 catMems.add(new MemItem(label, label, miscPss[j], j)); 10432 } 10433 10434 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10435 for (int j=0; j<oomPss.length; j++) { 10436 if (oomPss[j] != 0) { 10437 String label = DUMP_MEM_OOM_LABEL[j]; 10438 MemItem item = new MemItem(label, label, oomPss[j], 10439 DUMP_MEM_OOM_ADJ[j]); 10440 item.subitems = oomProcs[j]; 10441 oomMems.add(item); 10442 } 10443 } 10444 10445 if (outTag != null || outStack != null) { 10446 if (outTag != null) { 10447 appendMemBucket(outTag, totalPss, "total", false); 10448 } 10449 if (outStack != null) { 10450 appendMemBucket(outStack, totalPss, "total", true); 10451 } 10452 boolean firstLine = true; 10453 for (int i=0; i<oomMems.size(); i++) { 10454 MemItem miCat = oomMems.get(i); 10455 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10456 continue; 10457 } 10458 if (miCat.id < ProcessList.SERVICE_ADJ 10459 || miCat.id == ProcessList.HOME_APP_ADJ 10460 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10461 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10462 outTag.append(" / "); 10463 } 10464 if (outStack != null) { 10465 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10466 if (firstLine) { 10467 outStack.append(":"); 10468 firstLine = false; 10469 } 10470 outStack.append("\n\t at "); 10471 } else { 10472 outStack.append("$"); 10473 } 10474 } 10475 for (int j=0; j<miCat.subitems.size(); j++) { 10476 MemItem mi = miCat.subitems.get(j); 10477 if (j > 0) { 10478 if (outTag != null) { 10479 outTag.append(" "); 10480 } 10481 if (outStack != null) { 10482 outStack.append("$"); 10483 } 10484 } 10485 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10486 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10487 } 10488 if (outStack != null) { 10489 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10490 } 10491 } 10492 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10493 outStack.append("("); 10494 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10495 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10496 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10497 outStack.append(":"); 10498 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10499 } 10500 } 10501 outStack.append(")"); 10502 } 10503 } 10504 } 10505 } 10506 10507 if (!brief && !oomOnly) { 10508 pw.println(); 10509 pw.println("Total PSS by process:"); 10510 dumpMemItems(pw, " ", procMems, true); 10511 pw.println(); 10512 } 10513 pw.println("Total PSS by OOM adjustment:"); 10514 dumpMemItems(pw, " ", oomMems, false); 10515 if (!oomOnly) { 10516 PrintWriter out = categoryPw != null ? categoryPw : pw; 10517 out.println(); 10518 out.println("Total PSS by category:"); 10519 dumpMemItems(out, " ", catMems, true); 10520 } 10521 pw.println(); 10522 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10523 final int[] SINGLE_LONG_FORMAT = new int[] { 10524 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10525 }; 10526 long[] longOut = new long[1]; 10527 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10528 SINGLE_LONG_FORMAT, null, longOut, null); 10529 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10530 longOut[0] = 0; 10531 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10532 SINGLE_LONG_FORMAT, null, longOut, null); 10533 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10534 longOut[0] = 0; 10535 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10536 SINGLE_LONG_FORMAT, null, longOut, null); 10537 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10538 longOut[0] = 0; 10539 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10540 SINGLE_LONG_FORMAT, null, longOut, null); 10541 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10542 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10543 pw.print(shared); pw.println(" kB"); 10544 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10545 pw.print(voltile); pw.println(" kB volatile"); 10546 } 10547 } 10548 10549 /** 10550 * Searches array of arguments for the specified string 10551 * @param args array of argument strings 10552 * @param value value to search for 10553 * @return true if the value is contained in the array 10554 */ 10555 private static boolean scanArgs(String[] args, String value) { 10556 if (args != null) { 10557 for (String arg : args) { 10558 if (value.equals(arg)) { 10559 return true; 10560 } 10561 } 10562 } 10563 return false; 10564 } 10565 10566 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10567 ContentProviderRecord cpr, boolean always) { 10568 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10569 10570 if (!inLaunching || always) { 10571 synchronized (cpr) { 10572 cpr.launchingApp = null; 10573 cpr.notifyAll(); 10574 } 10575 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10576 String names[] = cpr.info.authority.split(";"); 10577 for (int j = 0; j < names.length; j++) { 10578 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10579 } 10580 } 10581 10582 for (int i=0; i<cpr.connections.size(); i++) { 10583 ContentProviderConnection conn = cpr.connections.get(i); 10584 if (conn.waiting) { 10585 // If this connection is waiting for the provider, then we don't 10586 // need to mess with its process unless we are always removing 10587 // or for some reason the provider is not currently launching. 10588 if (inLaunching && !always) { 10589 continue; 10590 } 10591 } 10592 ProcessRecord capp = conn.client; 10593 conn.dead = true; 10594 if (conn.stableCount > 0) { 10595 if (!capp.persistent && capp.thread != null 10596 && capp.pid != 0 10597 && capp.pid != MY_PID) { 10598 Slog.i(TAG, "Kill " + capp.processName 10599 + " (pid " + capp.pid + "): provider " + cpr.info.name 10600 + " in dying process " + (proc != null ? proc.processName : "??")); 10601 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10602 capp.processName, capp.setAdj, "dying provider " 10603 + cpr.name.toShortString()); 10604 Process.killProcessQuiet(capp.pid); 10605 } 10606 } else if (capp.thread != null && conn.provider.provider != null) { 10607 try { 10608 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10609 } catch (RemoteException e) { 10610 } 10611 // In the protocol here, we don't expect the client to correctly 10612 // clean up this connection, we'll just remove it. 10613 cpr.connections.remove(i); 10614 conn.client.conProviders.remove(conn); 10615 } 10616 } 10617 10618 if (inLaunching && always) { 10619 mLaunchingProviders.remove(cpr); 10620 } 10621 return inLaunching; 10622 } 10623 10624 /** 10625 * Main code for cleaning up a process when it has gone away. This is 10626 * called both as a result of the process dying, or directly when stopping 10627 * a process when running in single process mode. 10628 */ 10629 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10630 boolean restarting, boolean allowRestart, int index) { 10631 if (index >= 0) { 10632 mLruProcesses.remove(index); 10633 } 10634 10635 mProcessesToGc.remove(app); 10636 10637 // Dismiss any open dialogs. 10638 if (app.crashDialog != null) { 10639 app.crashDialog.dismiss(); 10640 app.crashDialog = null; 10641 } 10642 if (app.anrDialog != null) { 10643 app.anrDialog.dismiss(); 10644 app.anrDialog = null; 10645 } 10646 if (app.waitDialog != null) { 10647 app.waitDialog.dismiss(); 10648 app.waitDialog = null; 10649 } 10650 10651 app.crashing = false; 10652 app.notResponding = false; 10653 10654 app.resetPackageList(); 10655 app.unlinkDeathRecipient(); 10656 app.thread = null; 10657 app.forcingToForeground = null; 10658 app.foregroundServices = false; 10659 app.foregroundActivities = false; 10660 app.hasShownUi = false; 10661 app.hasAboveClient = false; 10662 10663 mServices.killServicesLocked(app, allowRestart); 10664 10665 boolean restart = false; 10666 10667 // Remove published content providers. 10668 if (!app.pubProviders.isEmpty()) { 10669 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10670 while (it.hasNext()) { 10671 ContentProviderRecord cpr = it.next(); 10672 10673 final boolean always = app.bad || !allowRestart; 10674 if (removeDyingProviderLocked(app, cpr, always) || always) { 10675 // We left the provider in the launching list, need to 10676 // restart it. 10677 restart = true; 10678 } 10679 10680 cpr.provider = null; 10681 cpr.proc = null; 10682 } 10683 app.pubProviders.clear(); 10684 } 10685 10686 // Take care of any launching providers waiting for this process. 10687 if (checkAppInLaunchingProvidersLocked(app, false)) { 10688 restart = true; 10689 } 10690 10691 // Unregister from connected content providers. 10692 if (!app.conProviders.isEmpty()) { 10693 for (int i=0; i<app.conProviders.size(); i++) { 10694 ContentProviderConnection conn = app.conProviders.get(i); 10695 conn.provider.connections.remove(conn); 10696 } 10697 app.conProviders.clear(); 10698 } 10699 10700 // At this point there may be remaining entries in mLaunchingProviders 10701 // where we were the only one waiting, so they are no longer of use. 10702 // Look for these and clean up if found. 10703 // XXX Commented out for now. Trying to figure out a way to reproduce 10704 // the actual situation to identify what is actually going on. 10705 if (false) { 10706 for (int i=0; i<mLaunchingProviders.size(); i++) { 10707 ContentProviderRecord cpr = (ContentProviderRecord) 10708 mLaunchingProviders.get(i); 10709 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10710 synchronized (cpr) { 10711 cpr.launchingApp = null; 10712 cpr.notifyAll(); 10713 } 10714 } 10715 } 10716 } 10717 10718 skipCurrentReceiverLocked(app); 10719 10720 // Unregister any receivers. 10721 if (app.receivers.size() > 0) { 10722 Iterator<ReceiverList> it = app.receivers.iterator(); 10723 while (it.hasNext()) { 10724 removeReceiverLocked(it.next()); 10725 } 10726 app.receivers.clear(); 10727 } 10728 10729 // If the app is undergoing backup, tell the backup manager about it 10730 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10731 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10732 try { 10733 IBackupManager bm = IBackupManager.Stub.asInterface( 10734 ServiceManager.getService(Context.BACKUP_SERVICE)); 10735 bm.agentDisconnected(app.info.packageName); 10736 } catch (RemoteException e) { 10737 // can't happen; backup manager is local 10738 } 10739 } 10740 10741 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10742 ProcessChangeItem item = mPendingProcessChanges.get(i); 10743 if (item.pid == app.pid) { 10744 mPendingProcessChanges.remove(i); 10745 mAvailProcessChanges.add(item); 10746 } 10747 } 10748 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10749 10750 // If the caller is restarting this app, then leave it in its 10751 // current lists and let the caller take care of it. 10752 if (restarting) { 10753 return; 10754 } 10755 10756 if (!app.persistent || app.isolated) { 10757 if (DEBUG_PROCESSES) Slog.v(TAG, 10758 "Removing non-persistent process during cleanup: " + app); 10759 mProcessNames.remove(app.processName, app.uid); 10760 mIsolatedProcesses.remove(app.uid); 10761 if (mHeavyWeightProcess == app) { 10762 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10763 mHeavyWeightProcess.userId, 0)); 10764 mHeavyWeightProcess = null; 10765 } 10766 } else if (!app.removed) { 10767 // This app is persistent, so we need to keep its record around. 10768 // If it is not already on the pending app list, add it there 10769 // and start a new process for it. 10770 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10771 mPersistentStartingProcesses.add(app); 10772 restart = true; 10773 } 10774 } 10775 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10776 "Clean-up removing on hold: " + app); 10777 mProcessesOnHold.remove(app); 10778 10779 if (app == mHomeProcess) { 10780 mHomeProcess = null; 10781 } 10782 if (app == mPreviousProcess) { 10783 mPreviousProcess = null; 10784 } 10785 10786 if (restart && !app.isolated) { 10787 // We have components that still need to be running in the 10788 // process, so re-launch it. 10789 mProcessNames.put(app.processName, app.uid, app); 10790 startProcessLocked(app, "restart", app.processName); 10791 } else if (app.pid > 0 && app.pid != MY_PID) { 10792 // Goodbye! 10793 synchronized (mPidsSelfLocked) { 10794 mPidsSelfLocked.remove(app.pid); 10795 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10796 } 10797 app.setPid(0); 10798 } 10799 } 10800 10801 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10802 // Look through the content providers we are waiting to have launched, 10803 // and if any run in this process then either schedule a restart of 10804 // the process or kill the client waiting for it if this process has 10805 // gone bad. 10806 int NL = mLaunchingProviders.size(); 10807 boolean restart = false; 10808 for (int i=0; i<NL; i++) { 10809 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10810 if (cpr.launchingApp == app) { 10811 if (!alwaysBad && !app.bad) { 10812 restart = true; 10813 } else { 10814 removeDyingProviderLocked(app, cpr, true); 10815 // cpr should have been removed from mLaunchingProviders 10816 NL = mLaunchingProviders.size(); 10817 i--; 10818 } 10819 } 10820 } 10821 return restart; 10822 } 10823 10824 // ========================================================= 10825 // SERVICES 10826 // ========================================================= 10827 10828 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10829 int flags) { 10830 enforceNotIsolatedCaller("getServices"); 10831 synchronized (this) { 10832 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10833 } 10834 } 10835 10836 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10837 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10838 synchronized (this) { 10839 return mServices.getRunningServiceControlPanelLocked(name); 10840 } 10841 } 10842 10843 public ComponentName startService(IApplicationThread caller, Intent service, 10844 String resolvedType, int userId) { 10845 enforceNotIsolatedCaller("startService"); 10846 // Refuse possible leaked file descriptors 10847 if (service != null && service.hasFileDescriptors() == true) { 10848 throw new IllegalArgumentException("File descriptors passed in Intent"); 10849 } 10850 10851 if (DEBUG_SERVICE) 10852 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10853 synchronized(this) { 10854 final int callingPid = Binder.getCallingPid(); 10855 final int callingUid = Binder.getCallingUid(); 10856 checkValidCaller(callingUid, userId); 10857 final long origId = Binder.clearCallingIdentity(); 10858 ComponentName res = mServices.startServiceLocked(caller, service, 10859 resolvedType, callingPid, callingUid, userId); 10860 Binder.restoreCallingIdentity(origId); 10861 return res; 10862 } 10863 } 10864 10865 ComponentName startServiceInPackage(int uid, 10866 Intent service, String resolvedType, int userId) { 10867 synchronized(this) { 10868 if (DEBUG_SERVICE) 10869 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10870 final long origId = Binder.clearCallingIdentity(); 10871 ComponentName res = mServices.startServiceLocked(null, service, 10872 resolvedType, -1, uid, userId); 10873 Binder.restoreCallingIdentity(origId); 10874 return res; 10875 } 10876 } 10877 10878 public int stopService(IApplicationThread caller, Intent service, 10879 String resolvedType, int userId) { 10880 enforceNotIsolatedCaller("stopService"); 10881 // Refuse possible leaked file descriptors 10882 if (service != null && service.hasFileDescriptors() == true) { 10883 throw new IllegalArgumentException("File descriptors passed in Intent"); 10884 } 10885 10886 checkValidCaller(Binder.getCallingUid(), userId); 10887 10888 synchronized(this) { 10889 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10890 } 10891 } 10892 10893 public IBinder peekService(Intent service, String resolvedType) { 10894 enforceNotIsolatedCaller("peekService"); 10895 // Refuse possible leaked file descriptors 10896 if (service != null && service.hasFileDescriptors() == true) { 10897 throw new IllegalArgumentException("File descriptors passed in Intent"); 10898 } 10899 synchronized(this) { 10900 return mServices.peekServiceLocked(service, resolvedType); 10901 } 10902 } 10903 10904 public boolean stopServiceToken(ComponentName className, IBinder token, 10905 int startId) { 10906 synchronized(this) { 10907 return mServices.stopServiceTokenLocked(className, token, startId); 10908 } 10909 } 10910 10911 public void setServiceForeground(ComponentName className, IBinder token, 10912 int id, Notification notification, boolean removeNotification) { 10913 synchronized(this) { 10914 mServices.setServiceForegroundLocked(className, token, id, notification, 10915 removeNotification); 10916 } 10917 } 10918 10919 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10920 boolean requireFull, String name, String callerPackage) { 10921 synchronized(this) { 10922 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10923 requireFull, name, callerPackage); 10924 } 10925 } 10926 10927 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10928 boolean requireFull, String name, String callerPackage) { 10929 final int callingUserId = UserHandle.getUserId(callingUid); 10930 if (callingUserId != userId) { 10931 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10932 if ((requireFull || checkComponentPermission( 10933 android.Manifest.permission.INTERACT_ACROSS_USERS, 10934 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10935 && checkComponentPermission( 10936 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10937 callingPid, callingUid, -1, true) 10938 != PackageManager.PERMISSION_GRANTED) { 10939 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10940 // In this case, they would like to just execute as their 10941 // owner user instead of failing. 10942 userId = callingUserId; 10943 } else { 10944 StringBuilder builder = new StringBuilder(128); 10945 builder.append("Permission Denial: "); 10946 builder.append(name); 10947 if (callerPackage != null) { 10948 builder.append(" from "); 10949 builder.append(callerPackage); 10950 } 10951 builder.append(" asks to run as user "); 10952 builder.append(userId); 10953 builder.append(" but is calling from user "); 10954 builder.append(UserHandle.getUserId(callingUid)); 10955 builder.append("; this requires "); 10956 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10957 if (!requireFull) { 10958 builder.append(" or "); 10959 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10960 } 10961 String msg = builder.toString(); 10962 Slog.w(TAG, msg); 10963 throw new SecurityException(msg); 10964 } 10965 } 10966 } 10967 if (userId == UserHandle.USER_CURRENT 10968 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10969 userId = mCurrentUserId; 10970 } 10971 if (!allowAll && userId < 0) { 10972 throw new IllegalArgumentException( 10973 "Call does not support special user #" + userId); 10974 } 10975 } 10976 return userId; 10977 } 10978 10979 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10980 String className, int flags) { 10981 boolean result = false; 10982 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10983 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10984 if (ActivityManager.checkUidPermission( 10985 android.Manifest.permission.INTERACT_ACROSS_USERS, 10986 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10987 ComponentName comp = new ComponentName(aInfo.packageName, className); 10988 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10989 + " requests FLAG_SINGLE_USER, but app does not hold " 10990 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10991 Slog.w(TAG, msg); 10992 throw new SecurityException(msg); 10993 } 10994 result = true; 10995 } 10996 } else if (componentProcessName == aInfo.packageName) { 10997 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10998 } else if ("system".equals(componentProcessName)) { 10999 result = true; 11000 } 11001 if (DEBUG_MU) { 11002 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 11003 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 11004 } 11005 return result; 11006 } 11007 11008 public int bindService(IApplicationThread caller, IBinder token, 11009 Intent service, String resolvedType, 11010 IServiceConnection connection, int flags, int userId) { 11011 enforceNotIsolatedCaller("bindService"); 11012 // Refuse possible leaked file descriptors 11013 if (service != null && service.hasFileDescriptors() == true) { 11014 throw new IllegalArgumentException("File descriptors passed in Intent"); 11015 } 11016 11017 synchronized(this) { 11018 return mServices.bindServiceLocked(caller, token, service, resolvedType, 11019 connection, flags, userId); 11020 } 11021 } 11022 11023 public boolean unbindService(IServiceConnection connection) { 11024 synchronized (this) { 11025 return mServices.unbindServiceLocked(connection); 11026 } 11027 } 11028 11029 public void publishService(IBinder token, Intent intent, IBinder service) { 11030 // Refuse possible leaked file descriptors 11031 if (intent != null && intent.hasFileDescriptors() == true) { 11032 throw new IllegalArgumentException("File descriptors passed in Intent"); 11033 } 11034 11035 synchronized(this) { 11036 if (!(token instanceof ServiceRecord)) { 11037 throw new IllegalArgumentException("Invalid service token"); 11038 } 11039 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11040 } 11041 } 11042 11043 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11044 // Refuse possible leaked file descriptors 11045 if (intent != null && intent.hasFileDescriptors() == true) { 11046 throw new IllegalArgumentException("File descriptors passed in Intent"); 11047 } 11048 11049 synchronized(this) { 11050 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11051 } 11052 } 11053 11054 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11055 synchronized(this) { 11056 if (!(token instanceof ServiceRecord)) { 11057 throw new IllegalArgumentException("Invalid service token"); 11058 } 11059 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11060 } 11061 } 11062 11063 // ========================================================= 11064 // BACKUP AND RESTORE 11065 // ========================================================= 11066 11067 // Cause the target app to be launched if necessary and its backup agent 11068 // instantiated. The backup agent will invoke backupAgentCreated() on the 11069 // activity manager to announce its creation. 11070 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11071 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11072 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11073 11074 synchronized(this) { 11075 // !!! TODO: currently no check here that we're already bound 11076 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11077 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11078 synchronized (stats) { 11079 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11080 } 11081 11082 // Backup agent is now in use, its package can't be stopped. 11083 try { 11084 AppGlobals.getPackageManager().setPackageStoppedState( 11085 app.packageName, false, UserHandle.getUserId(app.uid)); 11086 } catch (RemoteException e) { 11087 } catch (IllegalArgumentException e) { 11088 Slog.w(TAG, "Failed trying to unstop package " 11089 + app.packageName + ": " + e); 11090 } 11091 11092 BackupRecord r = new BackupRecord(ss, app, backupMode); 11093 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11094 ? new ComponentName(app.packageName, app.backupAgentName) 11095 : new ComponentName("android", "FullBackupAgent"); 11096 // startProcessLocked() returns existing proc's record if it's already running 11097 ProcessRecord proc = startProcessLocked(app.processName, app, 11098 false, 0, "backup", hostingName, false, false); 11099 if (proc == null) { 11100 Slog.e(TAG, "Unable to start backup agent process " + r); 11101 return false; 11102 } 11103 11104 r.app = proc; 11105 mBackupTarget = r; 11106 mBackupAppName = app.packageName; 11107 11108 // Try not to kill the process during backup 11109 updateOomAdjLocked(proc); 11110 11111 // If the process is already attached, schedule the creation of the backup agent now. 11112 // If it is not yet live, this will be done when it attaches to the framework. 11113 if (proc.thread != null) { 11114 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11115 try { 11116 proc.thread.scheduleCreateBackupAgent(app, 11117 compatibilityInfoForPackageLocked(app), backupMode); 11118 } catch (RemoteException e) { 11119 // Will time out on the backup manager side 11120 } 11121 } else { 11122 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11123 } 11124 // Invariants: at this point, the target app process exists and the application 11125 // is either already running or in the process of coming up. mBackupTarget and 11126 // mBackupAppName describe the app, so that when it binds back to the AM we 11127 // know that it's scheduled for a backup-agent operation. 11128 } 11129 11130 return true; 11131 } 11132 11133 // A backup agent has just come up 11134 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11135 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11136 + " = " + agent); 11137 11138 synchronized(this) { 11139 if (!agentPackageName.equals(mBackupAppName)) { 11140 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11141 return; 11142 } 11143 } 11144 11145 long oldIdent = Binder.clearCallingIdentity(); 11146 try { 11147 IBackupManager bm = IBackupManager.Stub.asInterface( 11148 ServiceManager.getService(Context.BACKUP_SERVICE)); 11149 bm.agentConnected(agentPackageName, agent); 11150 } catch (RemoteException e) { 11151 // can't happen; the backup manager service is local 11152 } catch (Exception e) { 11153 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11154 e.printStackTrace(); 11155 } finally { 11156 Binder.restoreCallingIdentity(oldIdent); 11157 } 11158 } 11159 11160 // done with this agent 11161 public void unbindBackupAgent(ApplicationInfo appInfo) { 11162 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11163 if (appInfo == null) { 11164 Slog.w(TAG, "unbind backup agent for null app"); 11165 return; 11166 } 11167 11168 synchronized(this) { 11169 if (mBackupAppName == null) { 11170 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11171 return; 11172 } 11173 11174 if (!mBackupAppName.equals(appInfo.packageName)) { 11175 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11176 return; 11177 } 11178 11179 ProcessRecord proc = mBackupTarget.app; 11180 mBackupTarget = null; 11181 mBackupAppName = null; 11182 11183 // Not backing this app up any more; reset its OOM adjustment 11184 updateOomAdjLocked(proc); 11185 11186 // If the app crashed during backup, 'thread' will be null here 11187 if (proc.thread != null) { 11188 try { 11189 proc.thread.scheduleDestroyBackupAgent(appInfo, 11190 compatibilityInfoForPackageLocked(appInfo)); 11191 } catch (Exception e) { 11192 Slog.e(TAG, "Exception when unbinding backup agent:"); 11193 e.printStackTrace(); 11194 } 11195 } 11196 } 11197 } 11198 // ========================================================= 11199 // BROADCASTS 11200 // ========================================================= 11201 11202 private final List getStickiesLocked(String action, IntentFilter filter, 11203 List cur, int userId) { 11204 final ContentResolver resolver = mContext.getContentResolver(); 11205 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11206 if (stickies == null) { 11207 return cur; 11208 } 11209 final ArrayList<Intent> list = stickies.get(action); 11210 if (list == null) { 11211 return cur; 11212 } 11213 int N = list.size(); 11214 for (int i=0; i<N; i++) { 11215 Intent intent = list.get(i); 11216 if (filter.match(resolver, intent, true, TAG) >= 0) { 11217 if (cur == null) { 11218 cur = new ArrayList<Intent>(); 11219 } 11220 cur.add(intent); 11221 } 11222 } 11223 return cur; 11224 } 11225 11226 boolean isPendingBroadcastProcessLocked(int pid) { 11227 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11228 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11229 } 11230 11231 void skipPendingBroadcastLocked(int pid) { 11232 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11233 for (BroadcastQueue queue : mBroadcastQueues) { 11234 queue.skipPendingBroadcastLocked(pid); 11235 } 11236 } 11237 11238 // The app just attached; send any pending broadcasts that it should receive 11239 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11240 boolean didSomething = false; 11241 for (BroadcastQueue queue : mBroadcastQueues) { 11242 didSomething |= queue.sendPendingBroadcastsLocked(app); 11243 } 11244 return didSomething; 11245 } 11246 11247 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11248 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11249 enforceNotIsolatedCaller("registerReceiver"); 11250 int callingUid; 11251 int callingPid; 11252 synchronized(this) { 11253 ProcessRecord callerApp = null; 11254 if (caller != null) { 11255 callerApp = getRecordForAppLocked(caller); 11256 if (callerApp == null) { 11257 throw new SecurityException( 11258 "Unable to find app for caller " + caller 11259 + " (pid=" + Binder.getCallingPid() 11260 + ") when registering receiver " + receiver); 11261 } 11262 if (callerApp.info.uid != Process.SYSTEM_UID && 11263 !callerApp.pkgList.contains(callerPackage)) { 11264 throw new SecurityException("Given caller package " + callerPackage 11265 + " is not running in process " + callerApp); 11266 } 11267 callingUid = callerApp.info.uid; 11268 callingPid = callerApp.pid; 11269 } else { 11270 callerPackage = null; 11271 callingUid = Binder.getCallingUid(); 11272 callingPid = Binder.getCallingPid(); 11273 } 11274 11275 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11276 true, true, "registerReceiver", callerPackage); 11277 11278 List allSticky = null; 11279 11280 // Look for any matching sticky broadcasts... 11281 Iterator actions = filter.actionsIterator(); 11282 if (actions != null) { 11283 while (actions.hasNext()) { 11284 String action = (String)actions.next(); 11285 allSticky = getStickiesLocked(action, filter, allSticky, 11286 UserHandle.USER_ALL); 11287 allSticky = getStickiesLocked(action, filter, allSticky, 11288 UserHandle.getUserId(callingUid)); 11289 } 11290 } else { 11291 allSticky = getStickiesLocked(null, filter, allSticky, 11292 UserHandle.USER_ALL); 11293 allSticky = getStickiesLocked(null, filter, allSticky, 11294 UserHandle.getUserId(callingUid)); 11295 } 11296 11297 // The first sticky in the list is returned directly back to 11298 // the client. 11299 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11300 11301 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11302 + ": " + sticky); 11303 11304 if (receiver == null) { 11305 return sticky; 11306 } 11307 11308 ReceiverList rl 11309 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11310 if (rl == null) { 11311 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11312 userId, receiver); 11313 if (rl.app != null) { 11314 rl.app.receivers.add(rl); 11315 } else { 11316 try { 11317 receiver.asBinder().linkToDeath(rl, 0); 11318 } catch (RemoteException e) { 11319 return sticky; 11320 } 11321 rl.linkedToDeath = true; 11322 } 11323 mRegisteredReceivers.put(receiver.asBinder(), rl); 11324 } else if (rl.uid != callingUid) { 11325 throw new IllegalArgumentException( 11326 "Receiver requested to register for uid " + callingUid 11327 + " was previously registered for uid " + rl.uid); 11328 } else if (rl.pid != callingPid) { 11329 throw new IllegalArgumentException( 11330 "Receiver requested to register for pid " + callingPid 11331 + " was previously registered for pid " + rl.pid); 11332 } else if (rl.userId != userId) { 11333 throw new IllegalArgumentException( 11334 "Receiver requested to register for user " + userId 11335 + " was previously registered for user " + rl.userId); 11336 } 11337 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11338 permission, callingUid, userId); 11339 rl.add(bf); 11340 if (!bf.debugCheck()) { 11341 Slog.w(TAG, "==> For Dynamic broadast"); 11342 } 11343 mReceiverResolver.addFilter(bf); 11344 11345 // Enqueue broadcasts for all existing stickies that match 11346 // this filter. 11347 if (allSticky != null) { 11348 ArrayList receivers = new ArrayList(); 11349 receivers.add(bf); 11350 11351 int N = allSticky.size(); 11352 for (int i=0; i<N; i++) { 11353 Intent intent = (Intent)allSticky.get(i); 11354 BroadcastQueue queue = broadcastQueueForIntent(intent); 11355 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11356 null, -1, -1, null, receivers, null, 0, null, null, 11357 false, true, true, -1); 11358 queue.enqueueParallelBroadcastLocked(r); 11359 queue.scheduleBroadcastsLocked(); 11360 } 11361 } 11362 11363 return sticky; 11364 } 11365 } 11366 11367 public void unregisterReceiver(IIntentReceiver receiver) { 11368 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11369 11370 final long origId = Binder.clearCallingIdentity(); 11371 try { 11372 boolean doTrim = false; 11373 11374 synchronized(this) { 11375 ReceiverList rl 11376 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11377 if (rl != null) { 11378 if (rl.curBroadcast != null) { 11379 BroadcastRecord r = rl.curBroadcast; 11380 final boolean doNext = finishReceiverLocked( 11381 receiver.asBinder(), r.resultCode, r.resultData, 11382 r.resultExtras, r.resultAbort, true); 11383 if (doNext) { 11384 doTrim = true; 11385 r.queue.processNextBroadcast(false); 11386 } 11387 } 11388 11389 if (rl.app != null) { 11390 rl.app.receivers.remove(rl); 11391 } 11392 removeReceiverLocked(rl); 11393 if (rl.linkedToDeath) { 11394 rl.linkedToDeath = false; 11395 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11396 } 11397 } 11398 } 11399 11400 // If we actually concluded any broadcasts, we might now be able 11401 // to trim the recipients' apps from our working set 11402 if (doTrim) { 11403 trimApplications(); 11404 return; 11405 } 11406 11407 } finally { 11408 Binder.restoreCallingIdentity(origId); 11409 } 11410 } 11411 11412 void removeReceiverLocked(ReceiverList rl) { 11413 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11414 int N = rl.size(); 11415 for (int i=0; i<N; i++) { 11416 mReceiverResolver.removeFilter(rl.get(i)); 11417 } 11418 } 11419 11420 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11421 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11422 ProcessRecord r = mLruProcesses.get(i); 11423 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11424 try { 11425 r.thread.dispatchPackageBroadcast(cmd, packages); 11426 } catch (RemoteException ex) { 11427 } 11428 } 11429 } 11430 } 11431 11432 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11433 int[] users) { 11434 List<ResolveInfo> receivers = null; 11435 try { 11436 HashSet<ComponentName> singleUserReceivers = null; 11437 boolean scannedFirstReceivers = false; 11438 for (int user : users) { 11439 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11440 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11441 if (newReceivers != null && newReceivers.size() == 0) { 11442 newReceivers = null; 11443 } 11444 if (receivers == null) { 11445 receivers = newReceivers; 11446 } else if (newReceivers != null) { 11447 // We need to concatenate the additional receivers 11448 // found with what we have do far. This would be easy, 11449 // but we also need to de-dup any receivers that are 11450 // singleUser. 11451 if (!scannedFirstReceivers) { 11452 // Collect any single user receivers we had already retrieved. 11453 scannedFirstReceivers = true; 11454 for (int i=0; i<receivers.size(); i++) { 11455 ResolveInfo ri = receivers.get(i); 11456 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11457 ComponentName cn = new ComponentName( 11458 ri.activityInfo.packageName, ri.activityInfo.name); 11459 if (singleUserReceivers == null) { 11460 singleUserReceivers = new HashSet<ComponentName>(); 11461 } 11462 singleUserReceivers.add(cn); 11463 } 11464 } 11465 } 11466 // Add the new results to the existing results, tracking 11467 // and de-dupping single user receivers. 11468 for (int i=0; i<newReceivers.size(); i++) { 11469 ResolveInfo ri = newReceivers.get(i); 11470 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11471 ComponentName cn = new ComponentName( 11472 ri.activityInfo.packageName, ri.activityInfo.name); 11473 if (singleUserReceivers == null) { 11474 singleUserReceivers = new HashSet<ComponentName>(); 11475 } 11476 if (!singleUserReceivers.contains(cn)) { 11477 singleUserReceivers.add(cn); 11478 receivers.add(ri); 11479 } 11480 } else { 11481 receivers.add(ri); 11482 } 11483 } 11484 } 11485 } 11486 } catch (RemoteException ex) { 11487 // pm is in same process, this will never happen. 11488 } 11489 return receivers; 11490 } 11491 11492 private final int broadcastIntentLocked(ProcessRecord callerApp, 11493 String callerPackage, Intent intent, String resolvedType, 11494 IIntentReceiver resultTo, int resultCode, String resultData, 11495 Bundle map, String requiredPermission, 11496 boolean ordered, boolean sticky, int callingPid, int callingUid, 11497 int userId) { 11498 intent = new Intent(intent); 11499 11500 // By default broadcasts do not go to stopped apps. 11501 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11502 11503 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11504 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11505 + " ordered=" + ordered + " userid=" + userId); 11506 if ((resultTo != null) && !ordered) { 11507 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11508 } 11509 11510 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11511 true, false, "broadcast", callerPackage); 11512 11513 // Make sure that the user who is receiving this broadcast is started. 11514 // If not, we will just skip it. 11515 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11516 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11517 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11518 Slog.w(TAG, "Skipping broadcast of " + intent 11519 + ": user " + userId + " is stopped"); 11520 return ActivityManager.BROADCAST_SUCCESS; 11521 } 11522 } 11523 11524 /* 11525 * Prevent non-system code (defined here to be non-persistent 11526 * processes) from sending protected broadcasts. 11527 */ 11528 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11529 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11530 callingUid == 0) { 11531 // Always okay. 11532 } else if (callerApp == null || !callerApp.persistent) { 11533 try { 11534 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11535 intent.getAction())) { 11536 String msg = "Permission Denial: not allowed to send broadcast " 11537 + intent.getAction() + " from pid=" 11538 + callingPid + ", uid=" + callingUid; 11539 Slog.w(TAG, msg); 11540 throw new SecurityException(msg); 11541 } 11542 } catch (RemoteException e) { 11543 Slog.w(TAG, "Remote exception", e); 11544 return ActivityManager.BROADCAST_SUCCESS; 11545 } 11546 } 11547 11548 // Handle special intents: if this broadcast is from the package 11549 // manager about a package being removed, we need to remove all of 11550 // its activities from the history stack. 11551 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11552 intent.getAction()); 11553 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11554 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11555 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11556 || uidRemoved) { 11557 if (checkComponentPermission( 11558 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11559 callingPid, callingUid, -1, true) 11560 == PackageManager.PERMISSION_GRANTED) { 11561 if (uidRemoved) { 11562 final Bundle intentExtras = intent.getExtras(); 11563 final int uid = intentExtras != null 11564 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11565 if (uid >= 0) { 11566 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11567 synchronized (bs) { 11568 bs.removeUidStatsLocked(uid); 11569 } 11570 } 11571 } else { 11572 // If resources are unavailable just force stop all 11573 // those packages and flush the attribute cache as well. 11574 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11575 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11576 if (list != null && (list.length > 0)) { 11577 for (String pkg : list) { 11578 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11579 } 11580 sendPackageBroadcastLocked( 11581 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11582 } 11583 } else { 11584 Uri data = intent.getData(); 11585 String ssp; 11586 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11587 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11588 forceStopPackageLocked(ssp, 11589 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11590 false, userId); 11591 } 11592 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11593 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11594 new String[] {ssp}, userId); 11595 } 11596 } 11597 } 11598 } 11599 } else { 11600 String msg = "Permission Denial: " + intent.getAction() 11601 + " broadcast from " + callerPackage + " (pid=" + callingPid 11602 + ", uid=" + callingUid + ")" 11603 + " requires " 11604 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11605 Slog.w(TAG, msg); 11606 throw new SecurityException(msg); 11607 } 11608 11609 // Special case for adding a package: by default turn on compatibility 11610 // mode. 11611 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11612 Uri data = intent.getData(); 11613 String ssp; 11614 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11615 mCompatModePackages.handlePackageAddedLocked(ssp, 11616 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11617 } 11618 } 11619 11620 /* 11621 * If this is the time zone changed action, queue up a message that will reset the timezone 11622 * of all currently running processes. This message will get queued up before the broadcast 11623 * happens. 11624 */ 11625 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11626 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11627 } 11628 11629 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11630 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11631 } 11632 11633 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11634 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11635 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11636 } 11637 11638 // Add to the sticky list if requested. 11639 if (sticky) { 11640 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11641 callingPid, callingUid) 11642 != PackageManager.PERMISSION_GRANTED) { 11643 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11644 + callingPid + ", uid=" + callingUid 11645 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11646 Slog.w(TAG, msg); 11647 throw new SecurityException(msg); 11648 } 11649 if (requiredPermission != null) { 11650 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11651 + " and enforce permission " + requiredPermission); 11652 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11653 } 11654 if (intent.getComponent() != null) { 11655 throw new SecurityException( 11656 "Sticky broadcasts can't target a specific component"); 11657 } 11658 // We use userId directly here, since the "all" target is maintained 11659 // as a separate set of sticky broadcasts. 11660 if (userId != UserHandle.USER_ALL) { 11661 // But first, if this is not a broadcast to all users, then 11662 // make sure it doesn't conflict with an existing broadcast to 11663 // all users. 11664 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11665 UserHandle.USER_ALL); 11666 if (stickies != null) { 11667 ArrayList<Intent> list = stickies.get(intent.getAction()); 11668 if (list != null) { 11669 int N = list.size(); 11670 int i; 11671 for (i=0; i<N; i++) { 11672 if (intent.filterEquals(list.get(i))) { 11673 throw new IllegalArgumentException( 11674 "Sticky broadcast " + intent + " for user " 11675 + userId + " conflicts with existing global broadcast"); 11676 } 11677 } 11678 } 11679 } 11680 } 11681 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11682 if (stickies == null) { 11683 stickies = new HashMap<String, ArrayList<Intent>>(); 11684 mStickyBroadcasts.put(userId, stickies); 11685 } 11686 ArrayList<Intent> list = stickies.get(intent.getAction()); 11687 if (list == null) { 11688 list = new ArrayList<Intent>(); 11689 stickies.put(intent.getAction(), list); 11690 } 11691 int N = list.size(); 11692 int i; 11693 for (i=0; i<N; i++) { 11694 if (intent.filterEquals(list.get(i))) { 11695 // This sticky already exists, replace it. 11696 list.set(i, new Intent(intent)); 11697 break; 11698 } 11699 } 11700 if (i >= N) { 11701 list.add(new Intent(intent)); 11702 } 11703 } 11704 11705 int[] users; 11706 if (userId == UserHandle.USER_ALL) { 11707 // Caller wants broadcast to go to all started users. 11708 users = mStartedUserArray; 11709 } else { 11710 // Caller wants broadcast to go to one specific user. 11711 users = mCurrentUserArray; 11712 } 11713 11714 // Figure out who all will receive this broadcast. 11715 List receivers = null; 11716 List<BroadcastFilter> registeredReceivers = null; 11717 // Need to resolve the intent to interested receivers... 11718 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11719 == 0) { 11720 receivers = collectReceiverComponents(intent, resolvedType, users); 11721 } 11722 if (intent.getComponent() == null) { 11723 registeredReceivers = mReceiverResolver.queryIntent(intent, 11724 resolvedType, false, userId); 11725 } 11726 11727 final boolean replacePending = 11728 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11729 11730 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11731 + " replacePending=" + replacePending); 11732 11733 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11734 if (!ordered && NR > 0) { 11735 // If we are not serializing this broadcast, then send the 11736 // registered receivers separately so they don't wait for the 11737 // components to be launched. 11738 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11739 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11740 callerPackage, callingPid, callingUid, requiredPermission, 11741 registeredReceivers, resultTo, resultCode, resultData, map, 11742 ordered, sticky, false, userId); 11743 if (DEBUG_BROADCAST) Slog.v( 11744 TAG, "Enqueueing parallel broadcast " + r); 11745 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11746 if (!replaced) { 11747 queue.enqueueParallelBroadcastLocked(r); 11748 queue.scheduleBroadcastsLocked(); 11749 } 11750 registeredReceivers = null; 11751 NR = 0; 11752 } 11753 11754 // Merge into one list. 11755 int ir = 0; 11756 if (receivers != null) { 11757 // A special case for PACKAGE_ADDED: do not allow the package 11758 // being added to see this broadcast. This prevents them from 11759 // using this as a back door to get run as soon as they are 11760 // installed. Maybe in the future we want to have a special install 11761 // broadcast or such for apps, but we'd like to deliberately make 11762 // this decision. 11763 String skipPackages[] = null; 11764 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11765 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11766 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11767 Uri data = intent.getData(); 11768 if (data != null) { 11769 String pkgName = data.getSchemeSpecificPart(); 11770 if (pkgName != null) { 11771 skipPackages = new String[] { pkgName }; 11772 } 11773 } 11774 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11775 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11776 } 11777 if (skipPackages != null && (skipPackages.length > 0)) { 11778 for (String skipPackage : skipPackages) { 11779 if (skipPackage != null) { 11780 int NT = receivers.size(); 11781 for (int it=0; it<NT; it++) { 11782 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11783 if (curt.activityInfo.packageName.equals(skipPackage)) { 11784 receivers.remove(it); 11785 it--; 11786 NT--; 11787 } 11788 } 11789 } 11790 } 11791 } 11792 11793 int NT = receivers != null ? receivers.size() : 0; 11794 int it = 0; 11795 ResolveInfo curt = null; 11796 BroadcastFilter curr = null; 11797 while (it < NT && ir < NR) { 11798 if (curt == null) { 11799 curt = (ResolveInfo)receivers.get(it); 11800 } 11801 if (curr == null) { 11802 curr = registeredReceivers.get(ir); 11803 } 11804 if (curr.getPriority() >= curt.priority) { 11805 // Insert this broadcast record into the final list. 11806 receivers.add(it, curr); 11807 ir++; 11808 curr = null; 11809 it++; 11810 NT++; 11811 } else { 11812 // Skip to the next ResolveInfo in the final list. 11813 it++; 11814 curt = null; 11815 } 11816 } 11817 } 11818 while (ir < NR) { 11819 if (receivers == null) { 11820 receivers = new ArrayList(); 11821 } 11822 receivers.add(registeredReceivers.get(ir)); 11823 ir++; 11824 } 11825 11826 if ((receivers != null && receivers.size() > 0) 11827 || resultTo != null) { 11828 BroadcastQueue queue = broadcastQueueForIntent(intent); 11829 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11830 callerPackage, callingPid, callingUid, requiredPermission, 11831 receivers, resultTo, resultCode, resultData, map, ordered, 11832 sticky, false, userId); 11833 if (DEBUG_BROADCAST) Slog.v( 11834 TAG, "Enqueueing ordered broadcast " + r 11835 + ": prev had " + queue.mOrderedBroadcasts.size()); 11836 if (DEBUG_BROADCAST) { 11837 int seq = r.intent.getIntExtra("seq", -1); 11838 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11839 } 11840 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11841 if (!replaced) { 11842 queue.enqueueOrderedBroadcastLocked(r); 11843 queue.scheduleBroadcastsLocked(); 11844 } 11845 } 11846 11847 return ActivityManager.BROADCAST_SUCCESS; 11848 } 11849 11850 final Intent verifyBroadcastLocked(Intent intent) { 11851 // Refuse possible leaked file descriptors 11852 if (intent != null && intent.hasFileDescriptors() == true) { 11853 throw new IllegalArgumentException("File descriptors passed in Intent"); 11854 } 11855 11856 int flags = intent.getFlags(); 11857 11858 if (!mProcessesReady) { 11859 // if the caller really truly claims to know what they're doing, go 11860 // ahead and allow the broadcast without launching any receivers 11861 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11862 intent = new Intent(intent); 11863 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11864 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11865 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11866 + " before boot completion"); 11867 throw new IllegalStateException("Cannot broadcast before boot completed"); 11868 } 11869 } 11870 11871 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11872 throw new IllegalArgumentException( 11873 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11874 } 11875 11876 return intent; 11877 } 11878 11879 public final int broadcastIntent(IApplicationThread caller, 11880 Intent intent, String resolvedType, IIntentReceiver resultTo, 11881 int resultCode, String resultData, Bundle map, 11882 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11883 enforceNotIsolatedCaller("broadcastIntent"); 11884 synchronized(this) { 11885 intent = verifyBroadcastLocked(intent); 11886 11887 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11888 final int callingPid = Binder.getCallingPid(); 11889 final int callingUid = Binder.getCallingUid(); 11890 final long origId = Binder.clearCallingIdentity(); 11891 int res = broadcastIntentLocked(callerApp, 11892 callerApp != null ? callerApp.info.packageName : null, 11893 intent, resolvedType, resultTo, 11894 resultCode, resultData, map, requiredPermission, serialized, sticky, 11895 callingPid, callingUid, userId); 11896 Binder.restoreCallingIdentity(origId); 11897 return res; 11898 } 11899 } 11900 11901 int broadcastIntentInPackage(String packageName, int uid, 11902 Intent intent, String resolvedType, IIntentReceiver resultTo, 11903 int resultCode, String resultData, Bundle map, 11904 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11905 synchronized(this) { 11906 intent = verifyBroadcastLocked(intent); 11907 11908 final long origId = Binder.clearCallingIdentity(); 11909 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11910 resultTo, resultCode, resultData, map, requiredPermission, 11911 serialized, sticky, -1, uid, userId); 11912 Binder.restoreCallingIdentity(origId); 11913 return res; 11914 } 11915 } 11916 11917 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11918 // Refuse possible leaked file descriptors 11919 if (intent != null && intent.hasFileDescriptors() == true) { 11920 throw new IllegalArgumentException("File descriptors passed in Intent"); 11921 } 11922 11923 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11924 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11925 11926 synchronized(this) { 11927 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11928 != PackageManager.PERMISSION_GRANTED) { 11929 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11930 + Binder.getCallingPid() 11931 + ", uid=" + Binder.getCallingUid() 11932 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11933 Slog.w(TAG, msg); 11934 throw new SecurityException(msg); 11935 } 11936 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11937 if (stickies != null) { 11938 ArrayList<Intent> list = stickies.get(intent.getAction()); 11939 if (list != null) { 11940 int N = list.size(); 11941 int i; 11942 for (i=0; i<N; i++) { 11943 if (intent.filterEquals(list.get(i))) { 11944 list.remove(i); 11945 break; 11946 } 11947 } 11948 if (list.size() <= 0) { 11949 stickies.remove(intent.getAction()); 11950 } 11951 } 11952 if (stickies.size() <= 0) { 11953 mStickyBroadcasts.remove(userId); 11954 } 11955 } 11956 } 11957 } 11958 11959 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11960 String resultData, Bundle resultExtras, boolean resultAbort, 11961 boolean explicit) { 11962 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11963 if (r == null) { 11964 Slog.w(TAG, "finishReceiver called but not found on queue"); 11965 return false; 11966 } 11967 11968 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11969 explicit); 11970 } 11971 11972 public void finishReceiver(IBinder who, int resultCode, String resultData, 11973 Bundle resultExtras, boolean resultAbort) { 11974 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11975 11976 // Refuse possible leaked file descriptors 11977 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11978 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11979 } 11980 11981 final long origId = Binder.clearCallingIdentity(); 11982 try { 11983 boolean doNext = false; 11984 BroadcastRecord r = null; 11985 11986 synchronized(this) { 11987 r = broadcastRecordForReceiverLocked(who); 11988 if (r != null) { 11989 doNext = r.queue.finishReceiverLocked(r, resultCode, 11990 resultData, resultExtras, resultAbort, true); 11991 } 11992 } 11993 11994 if (doNext) { 11995 r.queue.processNextBroadcast(false); 11996 } 11997 trimApplications(); 11998 } finally { 11999 Binder.restoreCallingIdentity(origId); 12000 } 12001 } 12002 12003 // ========================================================= 12004 // INSTRUMENTATION 12005 // ========================================================= 12006 12007 public boolean startInstrumentation(ComponentName className, 12008 String profileFile, int flags, Bundle arguments, 12009 IInstrumentationWatcher watcher, int userId) { 12010 enforceNotIsolatedCaller("startInstrumentation"); 12011 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 12012 userId, false, true, "startInstrumentation", null); 12013 // Refuse possible leaked file descriptors 12014 if (arguments != null && arguments.hasFileDescriptors()) { 12015 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12016 } 12017 12018 synchronized(this) { 12019 InstrumentationInfo ii = null; 12020 ApplicationInfo ai = null; 12021 try { 12022 ii = mContext.getPackageManager().getInstrumentationInfo( 12023 className, STOCK_PM_FLAGS); 12024 ai = AppGlobals.getPackageManager().getApplicationInfo( 12025 ii.targetPackage, STOCK_PM_FLAGS, userId); 12026 } catch (PackageManager.NameNotFoundException e) { 12027 } catch (RemoteException e) { 12028 } 12029 if (ii == null) { 12030 reportStartInstrumentationFailure(watcher, className, 12031 "Unable to find instrumentation info for: " + className); 12032 return false; 12033 } 12034 if (ai == null) { 12035 reportStartInstrumentationFailure(watcher, className, 12036 "Unable to find instrumentation target package: " + ii.targetPackage); 12037 return false; 12038 } 12039 12040 int match = mContext.getPackageManager().checkSignatures( 12041 ii.targetPackage, ii.packageName); 12042 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12043 String msg = "Permission Denial: starting instrumentation " 12044 + className + " from pid=" 12045 + Binder.getCallingPid() 12046 + ", uid=" + Binder.getCallingPid() 12047 + " not allowed because package " + ii.packageName 12048 + " does not have a signature matching the target " 12049 + ii.targetPackage; 12050 reportStartInstrumentationFailure(watcher, className, msg); 12051 throw new SecurityException(msg); 12052 } 12053 12054 final long origId = Binder.clearCallingIdentity(); 12055 // Instrumentation can kill and relaunch even persistent processes 12056 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12057 ProcessRecord app = addAppLocked(ai, false); 12058 app.instrumentationClass = className; 12059 app.instrumentationInfo = ai; 12060 app.instrumentationProfileFile = profileFile; 12061 app.instrumentationArguments = arguments; 12062 app.instrumentationWatcher = watcher; 12063 app.instrumentationResultClass = className; 12064 Binder.restoreCallingIdentity(origId); 12065 } 12066 12067 return true; 12068 } 12069 12070 /** 12071 * Report errors that occur while attempting to start Instrumentation. Always writes the 12072 * error to the logs, but if somebody is watching, send the report there too. This enables 12073 * the "am" command to report errors with more information. 12074 * 12075 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12076 * @param cn The component name of the instrumentation. 12077 * @param report The error report. 12078 */ 12079 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12080 ComponentName cn, String report) { 12081 Slog.w(TAG, report); 12082 try { 12083 if (watcher != null) { 12084 Bundle results = new Bundle(); 12085 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12086 results.putString("Error", report); 12087 watcher.instrumentationStatus(cn, -1, results); 12088 } 12089 } catch (RemoteException e) { 12090 Slog.w(TAG, e); 12091 } 12092 } 12093 12094 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12095 if (app.instrumentationWatcher != null) { 12096 try { 12097 // NOTE: IInstrumentationWatcher *must* be oneway here 12098 app.instrumentationWatcher.instrumentationFinished( 12099 app.instrumentationClass, 12100 resultCode, 12101 results); 12102 } catch (RemoteException e) { 12103 } 12104 } 12105 app.instrumentationWatcher = null; 12106 app.instrumentationClass = null; 12107 app.instrumentationInfo = null; 12108 app.instrumentationProfileFile = null; 12109 app.instrumentationArguments = null; 12110 12111 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12112 } 12113 12114 public void finishInstrumentation(IApplicationThread target, 12115 int resultCode, Bundle results) { 12116 int userId = UserHandle.getCallingUserId(); 12117 // Refuse possible leaked file descriptors 12118 if (results != null && results.hasFileDescriptors()) { 12119 throw new IllegalArgumentException("File descriptors passed in Intent"); 12120 } 12121 12122 synchronized(this) { 12123 ProcessRecord app = getRecordForAppLocked(target); 12124 if (app == null) { 12125 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12126 return; 12127 } 12128 final long origId = Binder.clearCallingIdentity(); 12129 finishInstrumentationLocked(app, resultCode, results); 12130 Binder.restoreCallingIdentity(origId); 12131 } 12132 } 12133 12134 // ========================================================= 12135 // CONFIGURATION 12136 // ========================================================= 12137 12138 public ConfigurationInfo getDeviceConfigurationInfo() { 12139 ConfigurationInfo config = new ConfigurationInfo(); 12140 synchronized (this) { 12141 config.reqTouchScreen = mConfiguration.touchscreen; 12142 config.reqKeyboardType = mConfiguration.keyboard; 12143 config.reqNavigation = mConfiguration.navigation; 12144 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12145 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12146 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12147 } 12148 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12149 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12150 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12151 } 12152 config.reqGlEsVersion = GL_ES_VERSION; 12153 } 12154 return config; 12155 } 12156 12157 public Configuration getConfiguration() { 12158 Configuration ci; 12159 synchronized(this) { 12160 ci = new Configuration(mConfiguration); 12161 } 12162 return ci; 12163 } 12164 12165 public void updatePersistentConfiguration(Configuration values) { 12166 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12167 "updateConfiguration()"); 12168 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12169 "updateConfiguration()"); 12170 if (values == null) { 12171 throw new NullPointerException("Configuration must not be null"); 12172 } 12173 12174 synchronized(this) { 12175 final long origId = Binder.clearCallingIdentity(); 12176 updateConfigurationLocked(values, null, true, false); 12177 Binder.restoreCallingIdentity(origId); 12178 } 12179 } 12180 12181 public void updateConfiguration(Configuration values) { 12182 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12183 "updateConfiguration()"); 12184 12185 synchronized(this) { 12186 if (values == null && mWindowManager != null) { 12187 // sentinel: fetch the current configuration from the window manager 12188 values = mWindowManager.computeNewConfiguration(); 12189 } 12190 12191 if (mWindowManager != null) { 12192 mProcessList.applyDisplaySize(mWindowManager); 12193 } 12194 12195 final long origId = Binder.clearCallingIdentity(); 12196 if (values != null) { 12197 Settings.System.clearConfiguration(values); 12198 } 12199 updateConfigurationLocked(values, null, false, false); 12200 Binder.restoreCallingIdentity(origId); 12201 } 12202 } 12203 12204 /** 12205 * Do either or both things: (1) change the current configuration, and (2) 12206 * make sure the given activity is running with the (now) current 12207 * configuration. Returns true if the activity has been left running, or 12208 * false if <var>starting</var> is being destroyed to match the new 12209 * configuration. 12210 * @param persistent TODO 12211 */ 12212 boolean updateConfigurationLocked(Configuration values, 12213 ActivityRecord starting, boolean persistent, boolean initLocale) { 12214 // do nothing if we are headless 12215 if (mHeadless) return true; 12216 12217 int changes = 0; 12218 12219 boolean kept = true; 12220 12221 if (values != null) { 12222 Configuration newConfig = new Configuration(mConfiguration); 12223 changes = newConfig.updateFrom(values); 12224 if (changes != 0) { 12225 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12226 Slog.i(TAG, "Updating configuration to: " + values); 12227 } 12228 12229 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12230 12231 if (values.locale != null && !initLocale) { 12232 saveLocaleLocked(values.locale, 12233 !values.locale.equals(mConfiguration.locale), 12234 values.userSetLocale); 12235 } 12236 12237 mConfigurationSeq++; 12238 if (mConfigurationSeq <= 0) { 12239 mConfigurationSeq = 1; 12240 } 12241 newConfig.seq = mConfigurationSeq; 12242 mConfiguration = newConfig; 12243 Slog.i(TAG, "Config changed: " + newConfig); 12244 12245 final Configuration configCopy = new Configuration(mConfiguration); 12246 12247 // TODO: If our config changes, should we auto dismiss any currently 12248 // showing dialogs? 12249 mShowDialogs = shouldShowDialogs(newConfig); 12250 12251 AttributeCache ac = AttributeCache.instance(); 12252 if (ac != null) { 12253 ac.updateConfiguration(configCopy); 12254 } 12255 12256 // Make sure all resources in our process are updated 12257 // right now, so that anyone who is going to retrieve 12258 // resource values after we return will be sure to get 12259 // the new ones. This is especially important during 12260 // boot, where the first config change needs to guarantee 12261 // all resources have that config before following boot 12262 // code is executed. 12263 mSystemThread.applyConfigurationToResources(configCopy); 12264 12265 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12266 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12267 msg.obj = new Configuration(configCopy); 12268 mHandler.sendMessage(msg); 12269 } 12270 12271 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12272 ProcessRecord app = mLruProcesses.get(i); 12273 try { 12274 if (app.thread != null) { 12275 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12276 + app.processName + " new config " + mConfiguration); 12277 app.thread.scheduleConfigurationChanged(configCopy); 12278 } 12279 } catch (Exception e) { 12280 } 12281 } 12282 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12283 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12284 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12285 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12286 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12287 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12288 broadcastIntentLocked(null, null, 12289 new Intent(Intent.ACTION_LOCALE_CHANGED), 12290 null, null, 0, null, null, 12291 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12292 } 12293 } 12294 } 12295 12296 if (changes != 0 && starting == null) { 12297 // If the configuration changed, and the caller is not already 12298 // in the process of starting an activity, then find the top 12299 // activity to check if its configuration needs to change. 12300 starting = mMainStack.topRunningActivityLocked(null); 12301 } 12302 12303 if (starting != null) { 12304 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12305 // And we need to make sure at this point that all other activities 12306 // are made visible with the correct configuration. 12307 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12308 } 12309 12310 if (values != null && mWindowManager != null) { 12311 mWindowManager.setNewConfiguration(mConfiguration); 12312 } 12313 12314 return kept; 12315 } 12316 12317 /** 12318 * Decide based on the configuration whether we should shouw the ANR, 12319 * crash, etc dialogs. The idea is that if there is no affordnace to 12320 * press the on-screen buttons, we shouldn't show the dialog. 12321 * 12322 * A thought: SystemUI might also want to get told about this, the Power 12323 * dialog / global actions also might want different behaviors. 12324 */ 12325 private static final boolean shouldShowDialogs(Configuration config) { 12326 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12327 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12328 } 12329 12330 /** 12331 * Save the locale. You must be inside a synchronized (this) block. 12332 */ 12333 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12334 if(isDiff) { 12335 SystemProperties.set("user.language", l.getLanguage()); 12336 SystemProperties.set("user.region", l.getCountry()); 12337 } 12338 12339 if(isPersist) { 12340 SystemProperties.set("persist.sys.language", l.getLanguage()); 12341 SystemProperties.set("persist.sys.country", l.getCountry()); 12342 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12343 } 12344 } 12345 12346 @Override 12347 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12348 ActivityRecord srec = ActivityRecord.forToken(token); 12349 return srec != null && srec.task.affinity != null && 12350 srec.task.affinity.equals(destAffinity); 12351 } 12352 12353 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12354 Intent resultData) { 12355 ComponentName dest = destIntent.getComponent(); 12356 12357 synchronized (this) { 12358 ActivityRecord srec = ActivityRecord.forToken(token); 12359 if (srec == null) { 12360 return false; 12361 } 12362 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12363 final int start = history.indexOf(srec); 12364 if (start < 0) { 12365 // Current activity is not in history stack; do nothing. 12366 return false; 12367 } 12368 int finishTo = start - 1; 12369 ActivityRecord parent = null; 12370 boolean foundParentInTask = false; 12371 if (dest != null) { 12372 TaskRecord tr = srec.task; 12373 for (int i = start - 1; i >= 0; i--) { 12374 ActivityRecord r = history.get(i); 12375 if (tr != r.task) { 12376 // Couldn't find parent in the same task; stop at the one above this. 12377 // (Root of current task; in-app "home" behavior) 12378 // Always at least finish the current activity. 12379 finishTo = Math.min(start - 1, i + 1); 12380 parent = history.get(finishTo); 12381 break; 12382 } else if (r.info.packageName.equals(dest.getPackageName()) && 12383 r.info.name.equals(dest.getClassName())) { 12384 finishTo = i; 12385 parent = r; 12386 foundParentInTask = true; 12387 break; 12388 } 12389 } 12390 } 12391 12392 if (mController != null) { 12393 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12394 if (next != null) { 12395 // ask watcher if this is allowed 12396 boolean resumeOK = true; 12397 try { 12398 resumeOK = mController.activityResuming(next.packageName); 12399 } catch (RemoteException e) { 12400 mController = null; 12401 } 12402 12403 if (!resumeOK) { 12404 return false; 12405 } 12406 } 12407 } 12408 final long origId = Binder.clearCallingIdentity(); 12409 for (int i = start; i > finishTo; i--) { 12410 ActivityRecord r = history.get(i); 12411 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12412 "navigate-up", true); 12413 // Only return the supplied result for the first activity finished 12414 resultCode = Activity.RESULT_CANCELED; 12415 resultData = null; 12416 } 12417 12418 if (parent != null && foundParentInTask) { 12419 final int parentLaunchMode = parent.info.launchMode; 12420 final int destIntentFlags = destIntent.getFlags(); 12421 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12422 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12423 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12424 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12425 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12426 } else { 12427 try { 12428 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12429 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12430 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12431 null, aInfo, parent.appToken, null, 12432 0, -1, parent.launchedFromUid, 0, null, true, null); 12433 foundParentInTask = res == ActivityManager.START_SUCCESS; 12434 } catch (RemoteException e) { 12435 foundParentInTask = false; 12436 } 12437 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12438 resultData, "navigate-up", true); 12439 } 12440 } 12441 Binder.restoreCallingIdentity(origId); 12442 return foundParentInTask; 12443 } 12444 } 12445 12446 public int getLaunchedFromUid(IBinder activityToken) { 12447 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12448 if (srec == null) { 12449 return -1; 12450 } 12451 return srec.launchedFromUid; 12452 } 12453 12454 // ========================================================= 12455 // LIFETIME MANAGEMENT 12456 // ========================================================= 12457 12458 // Returns which broadcast queue the app is the current [or imminent] receiver 12459 // on, or 'null' if the app is not an active broadcast recipient. 12460 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12461 BroadcastRecord r = app.curReceiver; 12462 if (r != null) { 12463 return r.queue; 12464 } 12465 12466 // It's not the current receiver, but it might be starting up to become one 12467 synchronized (this) { 12468 for (BroadcastQueue queue : mBroadcastQueues) { 12469 r = queue.mPendingBroadcast; 12470 if (r != null && r.curApp == app) { 12471 // found it; report which queue it's in 12472 return queue; 12473 } 12474 } 12475 } 12476 12477 return null; 12478 } 12479 12480 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12481 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12482 if (mAdjSeq == app.adjSeq) { 12483 // This adjustment has already been computed. If we are calling 12484 // from the top, we may have already computed our adjustment with 12485 // an earlier hidden adjustment that isn't really for us... if 12486 // so, use the new hidden adjustment. 12487 if (!recursed && app.hidden) { 12488 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12489 app.hasActivities ? hiddenAdj : emptyAdj; 12490 } 12491 return app.curRawAdj; 12492 } 12493 12494 if (app.thread == null) { 12495 app.adjSeq = mAdjSeq; 12496 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12497 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12498 } 12499 12500 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12501 app.adjSource = null; 12502 app.adjTarget = null; 12503 app.empty = false; 12504 app.hidden = false; 12505 12506 final int activitiesSize = app.activities.size(); 12507 12508 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12509 // The max adjustment doesn't allow this app to be anything 12510 // below foreground, so it is not worth doing work for it. 12511 app.adjType = "fixed"; 12512 app.adjSeq = mAdjSeq; 12513 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12514 app.hasActivities = false; 12515 app.foregroundActivities = false; 12516 app.keeping = true; 12517 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12518 // System process can do UI, and when they do we want to have 12519 // them trim their memory after the user leaves the UI. To 12520 // facilitate this, here we need to determine whether or not it 12521 // is currently showing UI. 12522 app.systemNoUi = true; 12523 if (app == TOP_APP) { 12524 app.systemNoUi = false; 12525 app.hasActivities = true; 12526 } else if (activitiesSize > 0) { 12527 for (int j = 0; j < activitiesSize; j++) { 12528 final ActivityRecord r = app.activities.get(j); 12529 if (r.visible) { 12530 app.systemNoUi = false; 12531 } 12532 if (r.app == app) { 12533 app.hasActivities = true; 12534 } 12535 } 12536 } 12537 return (app.curAdj=app.maxAdj); 12538 } 12539 12540 app.keeping = false; 12541 app.systemNoUi = false; 12542 app.hasActivities = false; 12543 12544 // Determine the importance of the process, starting with most 12545 // important to least, and assign an appropriate OOM adjustment. 12546 int adj; 12547 int schedGroup; 12548 boolean foregroundActivities = false; 12549 boolean interesting = false; 12550 BroadcastQueue queue; 12551 if (app == TOP_APP) { 12552 // The last app on the list is the foreground app. 12553 adj = ProcessList.FOREGROUND_APP_ADJ; 12554 schedGroup = Process.THREAD_GROUP_DEFAULT; 12555 app.adjType = "top-activity"; 12556 foregroundActivities = true; 12557 interesting = true; 12558 app.hasActivities = true; 12559 } else if (app.instrumentationClass != null) { 12560 // Don't want to kill running instrumentation. 12561 adj = ProcessList.FOREGROUND_APP_ADJ; 12562 schedGroup = Process.THREAD_GROUP_DEFAULT; 12563 app.adjType = "instrumentation"; 12564 interesting = true; 12565 } else if ((queue = isReceivingBroadcast(app)) != null) { 12566 // An app that is currently receiving a broadcast also 12567 // counts as being in the foreground for OOM killer purposes. 12568 // It's placed in a sched group based on the nature of the 12569 // broadcast as reflected by which queue it's active in. 12570 adj = ProcessList.FOREGROUND_APP_ADJ; 12571 schedGroup = (queue == mFgBroadcastQueue) 12572 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12573 app.adjType = "broadcast"; 12574 } else if (app.executingServices.size() > 0) { 12575 // An app that is currently executing a service callback also 12576 // counts as being in the foreground. 12577 adj = ProcessList.FOREGROUND_APP_ADJ; 12578 schedGroup = Process.THREAD_GROUP_DEFAULT; 12579 app.adjType = "exec-service"; 12580 } else { 12581 // Assume process is hidden (has activities); we will correct 12582 // later if this is not the case. 12583 adj = hiddenAdj; 12584 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12585 app.hidden = true; 12586 app.adjType = "bg-activities"; 12587 } 12588 12589 boolean hasStoppingActivities = false; 12590 12591 // Examine all activities if not already foreground. 12592 if (!foregroundActivities && activitiesSize > 0) { 12593 for (int j = 0; j < activitiesSize; j++) { 12594 final ActivityRecord r = app.activities.get(j); 12595 if (r.visible) { 12596 // App has a visible activity; only upgrade adjustment. 12597 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12598 adj = ProcessList.VISIBLE_APP_ADJ; 12599 app.adjType = "visible"; 12600 } 12601 schedGroup = Process.THREAD_GROUP_DEFAULT; 12602 app.hidden = false; 12603 app.hasActivities = true; 12604 foregroundActivities = true; 12605 break; 12606 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12607 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12608 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12609 app.adjType = "pausing"; 12610 } 12611 app.hidden = false; 12612 foregroundActivities = true; 12613 } else if (r.state == ActivityState.STOPPING) { 12614 // We will apply the actual adjustment later, because 12615 // we want to allow this process to immediately go through 12616 // any memory trimming that is in effect. 12617 app.hidden = false; 12618 foregroundActivities = true; 12619 hasStoppingActivities = true; 12620 } 12621 if (r.app == app) { 12622 app.hasActivities = true; 12623 } 12624 } 12625 } 12626 12627 if (adj == hiddenAdj && !app.hasActivities) { 12628 // Whoops, this process is completely empty as far as we know 12629 // at this point. 12630 adj = emptyAdj; 12631 app.empty = true; 12632 app.adjType = "bg-empty"; 12633 } 12634 12635 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12636 if (app.foregroundServices) { 12637 // The user is aware of this app, so make it visible. 12638 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12639 app.hidden = false; 12640 app.adjType = "foreground-service"; 12641 schedGroup = Process.THREAD_GROUP_DEFAULT; 12642 } else if (app.forcingToForeground != null) { 12643 // The user is aware of this app, so make it visible. 12644 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12645 app.hidden = false; 12646 app.adjType = "force-foreground"; 12647 app.adjSource = app.forcingToForeground; 12648 schedGroup = Process.THREAD_GROUP_DEFAULT; 12649 } 12650 } 12651 12652 if (app.foregroundServices) { 12653 interesting = true; 12654 } 12655 12656 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12657 // We don't want to kill the current heavy-weight process. 12658 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12659 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12660 app.hidden = false; 12661 app.adjType = "heavy"; 12662 } 12663 12664 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12665 // This process is hosting what we currently consider to be the 12666 // home app, so we don't want to let it go into the background. 12667 adj = ProcessList.HOME_APP_ADJ; 12668 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12669 app.hidden = false; 12670 app.adjType = "home"; 12671 } 12672 12673 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12674 && app.activities.size() > 0) { 12675 // This was the previous process that showed UI to the user. 12676 // We want to try to keep it around more aggressively, to give 12677 // a good experience around switching between two apps. 12678 adj = ProcessList.PREVIOUS_APP_ADJ; 12679 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12680 app.hidden = false; 12681 app.adjType = "previous"; 12682 } 12683 12684 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12685 + " reason=" + app.adjType); 12686 12687 // By default, we use the computed adjustment. It may be changed if 12688 // there are applications dependent on our services or providers, but 12689 // this gives us a baseline and makes sure we don't get into an 12690 // infinite recursion. 12691 app.adjSeq = mAdjSeq; 12692 app.curRawAdj = app.nonStoppingAdj = adj; 12693 12694 if (mBackupTarget != null && app == mBackupTarget.app) { 12695 // If possible we want to avoid killing apps while they're being backed up 12696 if (adj > ProcessList.BACKUP_APP_ADJ) { 12697 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12698 adj = ProcessList.BACKUP_APP_ADJ; 12699 app.adjType = "backup"; 12700 app.hidden = false; 12701 } 12702 } 12703 12704 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12705 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12706 final long now = SystemClock.uptimeMillis(); 12707 // This process is more important if the top activity is 12708 // bound to the service. 12709 Iterator<ServiceRecord> jt = app.services.iterator(); 12710 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12711 ServiceRecord s = jt.next(); 12712 if (s.startRequested) { 12713 if (app.hasShownUi && app != mHomeProcess) { 12714 // If this process has shown some UI, let it immediately 12715 // go to the LRU list because it may be pretty heavy with 12716 // UI stuff. We'll tag it with a label just to help 12717 // debug and understand what is going on. 12718 if (adj > ProcessList.SERVICE_ADJ) { 12719 app.adjType = "started-bg-ui-services"; 12720 } 12721 } else { 12722 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12723 // This service has seen some activity within 12724 // recent memory, so we will keep its process ahead 12725 // of the background processes. 12726 if (adj > ProcessList.SERVICE_ADJ) { 12727 adj = ProcessList.SERVICE_ADJ; 12728 app.adjType = "started-services"; 12729 app.hidden = false; 12730 } 12731 } 12732 // If we have let the service slide into the background 12733 // state, still have some text describing what it is doing 12734 // even though the service no longer has an impact. 12735 if (adj > ProcessList.SERVICE_ADJ) { 12736 app.adjType = "started-bg-services"; 12737 } 12738 } 12739 // Don't kill this process because it is doing work; it 12740 // has said it is doing work. 12741 app.keeping = true; 12742 } 12743 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12744 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12745 Iterator<ArrayList<ConnectionRecord>> kt 12746 = s.connections.values().iterator(); 12747 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12748 ArrayList<ConnectionRecord> clist = kt.next(); 12749 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12750 // XXX should compute this based on the max of 12751 // all connected clients. 12752 ConnectionRecord cr = clist.get(i); 12753 if (cr.binding.client == app) { 12754 // Binding to ourself is not interesting. 12755 continue; 12756 } 12757 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12758 ProcessRecord client = cr.binding.client; 12759 int clientAdj = adj; 12760 int myHiddenAdj = hiddenAdj; 12761 if (myHiddenAdj > client.hiddenAdj) { 12762 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12763 myHiddenAdj = client.hiddenAdj; 12764 } else { 12765 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12766 } 12767 } 12768 int myEmptyAdj = emptyAdj; 12769 if (myEmptyAdj > client.emptyAdj) { 12770 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12771 myEmptyAdj = client.emptyAdj; 12772 } else { 12773 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12774 } 12775 } 12776 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12777 myEmptyAdj, TOP_APP, true, doingAll); 12778 String adjType = null; 12779 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12780 // Not doing bind OOM management, so treat 12781 // this guy more like a started service. 12782 if (app.hasShownUi && app != mHomeProcess) { 12783 // If this process has shown some UI, let it immediately 12784 // go to the LRU list because it may be pretty heavy with 12785 // UI stuff. We'll tag it with a label just to help 12786 // debug and understand what is going on. 12787 if (adj > clientAdj) { 12788 adjType = "bound-bg-ui-services"; 12789 } 12790 app.hidden = false; 12791 clientAdj = adj; 12792 } else { 12793 if (now >= (s.lastActivity 12794 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12795 // This service has not seen activity within 12796 // recent memory, so allow it to drop to the 12797 // LRU list if there is no other reason to keep 12798 // it around. We'll also tag it with a label just 12799 // to help debug and undertand what is going on. 12800 if (adj > clientAdj) { 12801 adjType = "bound-bg-services"; 12802 } 12803 clientAdj = adj; 12804 } 12805 } 12806 } 12807 if (adj > clientAdj) { 12808 // If this process has recently shown UI, and 12809 // the process that is binding to it is less 12810 // important than being visible, then we don't 12811 // care about the binding as much as we care 12812 // about letting this process get into the LRU 12813 // list to be killed and restarted if needed for 12814 // memory. 12815 if (app.hasShownUi && app != mHomeProcess 12816 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12817 adjType = "bound-bg-ui-services"; 12818 } else { 12819 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12820 |Context.BIND_IMPORTANT)) != 0) { 12821 adj = clientAdj; 12822 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12823 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12824 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12825 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12826 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12827 adj = clientAdj; 12828 } else { 12829 app.pendingUiClean = true; 12830 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12831 adj = ProcessList.VISIBLE_APP_ADJ; 12832 } 12833 } 12834 if (!client.hidden) { 12835 app.hidden = false; 12836 } 12837 if (client.keeping) { 12838 app.keeping = true; 12839 } 12840 adjType = "service"; 12841 } 12842 } 12843 if (adjType != null) { 12844 app.adjType = adjType; 12845 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12846 .REASON_SERVICE_IN_USE; 12847 app.adjSource = cr.binding.client; 12848 app.adjSourceOom = clientAdj; 12849 app.adjTarget = s.name; 12850 } 12851 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12852 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12853 schedGroup = Process.THREAD_GROUP_DEFAULT; 12854 } 12855 } 12856 } 12857 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12858 ActivityRecord a = cr.activity; 12859 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12860 (a.visible || a.state == ActivityState.RESUMED 12861 || a.state == ActivityState.PAUSING)) { 12862 adj = ProcessList.FOREGROUND_APP_ADJ; 12863 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12864 schedGroup = Process.THREAD_GROUP_DEFAULT; 12865 } 12866 app.hidden = false; 12867 app.adjType = "service"; 12868 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12869 .REASON_SERVICE_IN_USE; 12870 app.adjSource = a; 12871 app.adjSourceOom = adj; 12872 app.adjTarget = s.name; 12873 } 12874 } 12875 } 12876 } 12877 } 12878 } 12879 12880 // Finally, if this process has active services running in it, we 12881 // would like to avoid killing it unless it would prevent the current 12882 // application from running. By default we put the process in 12883 // with the rest of the background processes; as we scan through 12884 // its services we may bump it up from there. 12885 if (adj > hiddenAdj) { 12886 adj = hiddenAdj; 12887 app.hidden = false; 12888 app.adjType = "bg-services"; 12889 } 12890 } 12891 12892 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12893 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12894 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12895 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12896 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12897 ContentProviderRecord cpr = jt.next(); 12898 for (int i = cpr.connections.size()-1; 12899 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12900 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12901 i--) { 12902 ContentProviderConnection conn = cpr.connections.get(i); 12903 ProcessRecord client = conn.client; 12904 if (client == app) { 12905 // Being our own client is not interesting. 12906 continue; 12907 } 12908 int myHiddenAdj = hiddenAdj; 12909 if (myHiddenAdj > client.hiddenAdj) { 12910 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12911 myHiddenAdj = client.hiddenAdj; 12912 } else { 12913 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12914 } 12915 } 12916 int myEmptyAdj = emptyAdj; 12917 if (myEmptyAdj > client.emptyAdj) { 12918 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12919 myEmptyAdj = client.emptyAdj; 12920 } else { 12921 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12922 } 12923 } 12924 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12925 myEmptyAdj, TOP_APP, true, doingAll); 12926 if (adj > clientAdj) { 12927 if (app.hasShownUi && app != mHomeProcess 12928 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12929 app.adjType = "bg-ui-provider"; 12930 } else { 12931 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12932 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12933 app.adjType = "provider"; 12934 } 12935 if (!client.hidden) { 12936 app.hidden = false; 12937 } 12938 if (client.keeping) { 12939 app.keeping = true; 12940 } 12941 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12942 .REASON_PROVIDER_IN_USE; 12943 app.adjSource = client; 12944 app.adjSourceOom = clientAdj; 12945 app.adjTarget = cpr.name; 12946 } 12947 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12948 schedGroup = Process.THREAD_GROUP_DEFAULT; 12949 } 12950 } 12951 // If the provider has external (non-framework) process 12952 // dependencies, ensure that its adjustment is at least 12953 // FOREGROUND_APP_ADJ. 12954 if (cpr.hasExternalProcessHandles()) { 12955 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12956 adj = ProcessList.FOREGROUND_APP_ADJ; 12957 schedGroup = Process.THREAD_GROUP_DEFAULT; 12958 app.hidden = false; 12959 app.keeping = true; 12960 app.adjType = "provider"; 12961 app.adjTarget = cpr.name; 12962 } 12963 } 12964 } 12965 } 12966 12967 if (adj == ProcessList.SERVICE_ADJ) { 12968 if (doingAll) { 12969 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12970 mNewNumServiceProcs++; 12971 } 12972 if (app.serviceb) { 12973 adj = ProcessList.SERVICE_B_ADJ; 12974 } 12975 } else { 12976 app.serviceb = false; 12977 } 12978 12979 app.nonStoppingAdj = adj; 12980 12981 if (hasStoppingActivities) { 12982 // Only upgrade adjustment. 12983 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12984 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12985 app.adjType = "stopping"; 12986 } 12987 } 12988 12989 app.curRawAdj = adj; 12990 12991 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12992 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12993 if (adj > app.maxAdj) { 12994 adj = app.maxAdj; 12995 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12996 schedGroup = Process.THREAD_GROUP_DEFAULT; 12997 } 12998 } 12999 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13000 app.keeping = true; 13001 } 13002 13003 if (app.hasAboveClient) { 13004 // If this process has bound to any services with BIND_ABOVE_CLIENT, 13005 // then we need to drop its adjustment to be lower than the service's 13006 // in order to honor the request. We want to drop it by one adjustment 13007 // level... but there is special meaning applied to various levels so 13008 // we will skip some of them. 13009 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 13010 // System process will not get dropped, ever 13011 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 13012 adj = ProcessList.VISIBLE_APP_ADJ; 13013 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 13014 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13015 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13016 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 13017 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 13018 adj++; 13019 } 13020 } 13021 13022 int importance = app.memImportance; 13023 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13024 app.curAdj = adj; 13025 app.curSchedGroup = schedGroup; 13026 if (!interesting) { 13027 // For this reporting, if there is not something explicitly 13028 // interesting in this process then we will push it to the 13029 // background importance. 13030 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13031 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13032 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13033 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13034 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13035 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13036 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13037 } else if (adj >= ProcessList.SERVICE_ADJ) { 13038 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13039 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13040 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13041 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13042 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13043 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13044 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13045 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13046 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13047 } else { 13048 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13049 } 13050 } 13051 13052 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13053 if (foregroundActivities != app.foregroundActivities) { 13054 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13055 } 13056 if (changes != 0) { 13057 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13058 app.memImportance = importance; 13059 app.foregroundActivities = foregroundActivities; 13060 int i = mPendingProcessChanges.size()-1; 13061 ProcessChangeItem item = null; 13062 while (i >= 0) { 13063 item = mPendingProcessChanges.get(i); 13064 if (item.pid == app.pid) { 13065 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13066 break; 13067 } 13068 i--; 13069 } 13070 if (i < 0) { 13071 // No existing item in pending changes; need a new one. 13072 final int NA = mAvailProcessChanges.size(); 13073 if (NA > 0) { 13074 item = mAvailProcessChanges.remove(NA-1); 13075 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13076 } else { 13077 item = new ProcessChangeItem(); 13078 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13079 } 13080 item.changes = 0; 13081 item.pid = app.pid; 13082 item.uid = app.info.uid; 13083 if (mPendingProcessChanges.size() == 0) { 13084 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13085 "*** Enqueueing dispatch processes changed!"); 13086 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13087 } 13088 mPendingProcessChanges.add(item); 13089 } 13090 item.changes |= changes; 13091 item.importance = importance; 13092 item.foregroundActivities = foregroundActivities; 13093 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13094 + Integer.toHexString(System.identityHashCode(item)) 13095 + " " + app.toShortString() + ": changes=" + item.changes 13096 + " importance=" + item.importance 13097 + " foreground=" + item.foregroundActivities 13098 + " type=" + app.adjType + " source=" + app.adjSource 13099 + " target=" + app.adjTarget); 13100 } 13101 13102 return app.curRawAdj; 13103 } 13104 13105 /** 13106 * Ask a given process to GC right now. 13107 */ 13108 final void performAppGcLocked(ProcessRecord app) { 13109 try { 13110 app.lastRequestedGc = SystemClock.uptimeMillis(); 13111 if (app.thread != null) { 13112 if (app.reportLowMemory) { 13113 app.reportLowMemory = false; 13114 app.thread.scheduleLowMemory(); 13115 } else { 13116 app.thread.processInBackground(); 13117 } 13118 } 13119 } catch (Exception e) { 13120 // whatever. 13121 } 13122 } 13123 13124 /** 13125 * Returns true if things are idle enough to perform GCs. 13126 */ 13127 private final boolean canGcNowLocked() { 13128 boolean processingBroadcasts = false; 13129 for (BroadcastQueue q : mBroadcastQueues) { 13130 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13131 processingBroadcasts = true; 13132 } 13133 } 13134 return !processingBroadcasts 13135 && (mSleeping || (mMainStack.mResumedActivity != null && 13136 mMainStack.mResumedActivity.idle)); 13137 } 13138 13139 /** 13140 * Perform GCs on all processes that are waiting for it, but only 13141 * if things are idle. 13142 */ 13143 final void performAppGcsLocked() { 13144 final int N = mProcessesToGc.size(); 13145 if (N <= 0) { 13146 return; 13147 } 13148 if (canGcNowLocked()) { 13149 while (mProcessesToGc.size() > 0) { 13150 ProcessRecord proc = mProcessesToGc.remove(0); 13151 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13152 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13153 <= SystemClock.uptimeMillis()) { 13154 // To avoid spamming the system, we will GC processes one 13155 // at a time, waiting a few seconds between each. 13156 performAppGcLocked(proc); 13157 scheduleAppGcsLocked(); 13158 return; 13159 } else { 13160 // It hasn't been long enough since we last GCed this 13161 // process... put it in the list to wait for its time. 13162 addProcessToGcListLocked(proc); 13163 break; 13164 } 13165 } 13166 } 13167 13168 scheduleAppGcsLocked(); 13169 } 13170 } 13171 13172 /** 13173 * If all looks good, perform GCs on all processes waiting for them. 13174 */ 13175 final void performAppGcsIfAppropriateLocked() { 13176 if (canGcNowLocked()) { 13177 performAppGcsLocked(); 13178 return; 13179 } 13180 // Still not idle, wait some more. 13181 scheduleAppGcsLocked(); 13182 } 13183 13184 /** 13185 * Schedule the execution of all pending app GCs. 13186 */ 13187 final void scheduleAppGcsLocked() { 13188 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13189 13190 if (mProcessesToGc.size() > 0) { 13191 // Schedule a GC for the time to the next process. 13192 ProcessRecord proc = mProcessesToGc.get(0); 13193 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13194 13195 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13196 long now = SystemClock.uptimeMillis(); 13197 if (when < (now+GC_TIMEOUT)) { 13198 when = now + GC_TIMEOUT; 13199 } 13200 mHandler.sendMessageAtTime(msg, when); 13201 } 13202 } 13203 13204 /** 13205 * Add a process to the array of processes waiting to be GCed. Keeps the 13206 * list in sorted order by the last GC time. The process can't already be 13207 * on the list. 13208 */ 13209 final void addProcessToGcListLocked(ProcessRecord proc) { 13210 boolean added = false; 13211 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13212 if (mProcessesToGc.get(i).lastRequestedGc < 13213 proc.lastRequestedGc) { 13214 added = true; 13215 mProcessesToGc.add(i+1, proc); 13216 break; 13217 } 13218 } 13219 if (!added) { 13220 mProcessesToGc.add(0, proc); 13221 } 13222 } 13223 13224 /** 13225 * Set up to ask a process to GC itself. This will either do it 13226 * immediately, or put it on the list of processes to gc the next 13227 * time things are idle. 13228 */ 13229 final void scheduleAppGcLocked(ProcessRecord app) { 13230 long now = SystemClock.uptimeMillis(); 13231 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13232 return; 13233 } 13234 if (!mProcessesToGc.contains(app)) { 13235 addProcessToGcListLocked(app); 13236 scheduleAppGcsLocked(); 13237 } 13238 } 13239 13240 final void checkExcessivePowerUsageLocked(boolean doKills) { 13241 updateCpuStatsNow(); 13242 13243 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13244 boolean doWakeKills = doKills; 13245 boolean doCpuKills = doKills; 13246 if (mLastPowerCheckRealtime == 0) { 13247 doWakeKills = false; 13248 } 13249 if (mLastPowerCheckUptime == 0) { 13250 doCpuKills = false; 13251 } 13252 if (stats.isScreenOn()) { 13253 doWakeKills = false; 13254 } 13255 final long curRealtime = SystemClock.elapsedRealtime(); 13256 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13257 final long curUptime = SystemClock.uptimeMillis(); 13258 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13259 mLastPowerCheckRealtime = curRealtime; 13260 mLastPowerCheckUptime = curUptime; 13261 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13262 doWakeKills = false; 13263 } 13264 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13265 doCpuKills = false; 13266 } 13267 int i = mLruProcesses.size(); 13268 while (i > 0) { 13269 i--; 13270 ProcessRecord app = mLruProcesses.get(i); 13271 if (!app.keeping) { 13272 long wtime; 13273 synchronized (stats) { 13274 wtime = stats.getProcessWakeTime(app.info.uid, 13275 app.pid, curRealtime); 13276 } 13277 long wtimeUsed = wtime - app.lastWakeTime; 13278 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13279 if (DEBUG_POWER) { 13280 StringBuilder sb = new StringBuilder(128); 13281 sb.append("Wake for "); 13282 app.toShortString(sb); 13283 sb.append(": over "); 13284 TimeUtils.formatDuration(realtimeSince, sb); 13285 sb.append(" used "); 13286 TimeUtils.formatDuration(wtimeUsed, sb); 13287 sb.append(" ("); 13288 sb.append((wtimeUsed*100)/realtimeSince); 13289 sb.append("%)"); 13290 Slog.i(TAG, sb.toString()); 13291 sb.setLength(0); 13292 sb.append("CPU for "); 13293 app.toShortString(sb); 13294 sb.append(": over "); 13295 TimeUtils.formatDuration(uptimeSince, sb); 13296 sb.append(" used "); 13297 TimeUtils.formatDuration(cputimeUsed, sb); 13298 sb.append(" ("); 13299 sb.append((cputimeUsed*100)/uptimeSince); 13300 sb.append("%)"); 13301 Slog.i(TAG, sb.toString()); 13302 } 13303 // If a process has held a wake lock for more 13304 // than 50% of the time during this period, 13305 // that sounds bad. Kill! 13306 if (doWakeKills && realtimeSince > 0 13307 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13308 synchronized (stats) { 13309 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13310 realtimeSince, wtimeUsed); 13311 } 13312 Slog.w(TAG, "Excessive wake lock in " + app.processName 13313 + " (pid " + app.pid + "): held " + wtimeUsed 13314 + " during " + realtimeSince); 13315 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13316 app.processName, app.setAdj, "excessive wake lock"); 13317 Process.killProcessQuiet(app.pid); 13318 } else if (doCpuKills && uptimeSince > 0 13319 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13320 synchronized (stats) { 13321 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13322 uptimeSince, cputimeUsed); 13323 } 13324 Slog.w(TAG, "Excessive CPU in " + app.processName 13325 + " (pid " + app.pid + "): used " + cputimeUsed 13326 + " during " + uptimeSince); 13327 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13328 app.processName, app.setAdj, "excessive cpu"); 13329 Process.killProcessQuiet(app.pid); 13330 } else { 13331 app.lastWakeTime = wtime; 13332 app.lastCpuTime = app.curCpuTime; 13333 } 13334 } 13335 } 13336 } 13337 13338 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13339 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13340 app.hiddenAdj = hiddenAdj; 13341 app.emptyAdj = emptyAdj; 13342 13343 if (app.thread == null) { 13344 return false; 13345 } 13346 13347 final boolean wasKeeping = app.keeping; 13348 13349 boolean success = true; 13350 13351 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13352 13353 if (app.curRawAdj != app.setRawAdj) { 13354 if (wasKeeping && !app.keeping) { 13355 // This app is no longer something we want to keep. Note 13356 // its current wake lock time to later know to kill it if 13357 // it is not behaving well. 13358 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13359 synchronized (stats) { 13360 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13361 app.pid, SystemClock.elapsedRealtime()); 13362 } 13363 app.lastCpuTime = app.curCpuTime; 13364 } 13365 13366 app.setRawAdj = app.curRawAdj; 13367 } 13368 13369 if (app.curAdj != app.setAdj) { 13370 if (Process.setOomAdj(app.pid, app.curAdj)) { 13371 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13372 TAG, "Set " + app.pid + " " + app.processName + 13373 " adj " + app.curAdj + ": " + app.adjType); 13374 app.setAdj = app.curAdj; 13375 } else { 13376 success = false; 13377 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13378 } 13379 } 13380 if (app.setSchedGroup != app.curSchedGroup) { 13381 app.setSchedGroup = app.curSchedGroup; 13382 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13383 "Setting process group of " + app.processName 13384 + " to " + app.curSchedGroup); 13385 if (app.waitingToKill != null && 13386 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13387 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13388 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13389 app.processName, app.setAdj, app.waitingToKill); 13390 app.killedBackground = true; 13391 Process.killProcessQuiet(app.pid); 13392 success = false; 13393 } else { 13394 if (true) { 13395 long oldId = Binder.clearCallingIdentity(); 13396 try { 13397 Process.setProcessGroup(app.pid, app.curSchedGroup); 13398 } catch (Exception e) { 13399 Slog.w(TAG, "Failed setting process group of " + app.pid 13400 + " to " + app.curSchedGroup); 13401 e.printStackTrace(); 13402 } finally { 13403 Binder.restoreCallingIdentity(oldId); 13404 } 13405 } else { 13406 if (app.thread != null) { 13407 try { 13408 app.thread.setSchedulingGroup(app.curSchedGroup); 13409 } catch (RemoteException e) { 13410 } 13411 } 13412 } 13413 } 13414 } 13415 return success; 13416 } 13417 13418 private final ActivityRecord resumedAppLocked() { 13419 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13420 if (resumedActivity == null || resumedActivity.app == null) { 13421 resumedActivity = mMainStack.mPausingActivity; 13422 if (resumedActivity == null || resumedActivity.app == null) { 13423 resumedActivity = mMainStack.topRunningActivityLocked(null); 13424 } 13425 } 13426 return resumedActivity; 13427 } 13428 13429 final boolean updateOomAdjLocked(ProcessRecord app) { 13430 final ActivityRecord TOP_ACT = resumedAppLocked(); 13431 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13432 int curAdj = app.curAdj; 13433 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13434 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13435 13436 mAdjSeq++; 13437 13438 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13439 TOP_APP, false); 13440 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13441 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13442 if (nowHidden != wasHidden) { 13443 // Changed to/from hidden state, so apps after it in the LRU 13444 // list may also be changed. 13445 updateOomAdjLocked(); 13446 } 13447 return success; 13448 } 13449 13450 final void updateOomAdjLocked() { 13451 final ActivityRecord TOP_ACT = resumedAppLocked(); 13452 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13453 13454 if (false) { 13455 RuntimeException e = new RuntimeException(); 13456 e.fillInStackTrace(); 13457 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13458 } 13459 13460 mAdjSeq++; 13461 mNewNumServiceProcs = 0; 13462 13463 // Let's determine how many processes we have running vs. 13464 // how many slots we have for background processes; we may want 13465 // to put multiple processes in a slot of there are enough of 13466 // them. 13467 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13468 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13469 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13470 if (emptyFactor < 1) emptyFactor = 1; 13471 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13472 if (hiddenFactor < 1) hiddenFactor = 1; 13473 int stepHidden = 0; 13474 int stepEmpty = 0; 13475 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13476 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13477 int numHidden = 0; 13478 int numEmpty = 0; 13479 int numTrimming = 0; 13480 13481 mNumNonHiddenProcs = 0; 13482 mNumHiddenProcs = 0; 13483 13484 // First update the OOM adjustment for each of the 13485 // application processes based on their current state. 13486 int i = mLruProcesses.size(); 13487 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13488 int nextHiddenAdj = curHiddenAdj+1; 13489 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13490 int nextEmptyAdj = curEmptyAdj+2; 13491 while (i > 0) { 13492 i--; 13493 ProcessRecord app = mLruProcesses.get(i); 13494 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13495 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13496 if (!app.killedBackground) { 13497 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13498 // This process was assigned as a hidden process... step the 13499 // hidden level. 13500 mNumHiddenProcs++; 13501 if (curHiddenAdj != nextHiddenAdj) { 13502 stepHidden++; 13503 if (stepHidden >= hiddenFactor) { 13504 stepHidden = 0; 13505 curHiddenAdj = nextHiddenAdj; 13506 nextHiddenAdj += 2; 13507 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13508 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13509 } 13510 } 13511 } 13512 numHidden++; 13513 if (numHidden > hiddenProcessLimit) { 13514 Slog.i(TAG, "No longer want " + app.processName 13515 + " (pid " + app.pid + "): hidden #" + numHidden); 13516 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13517 app.processName, app.setAdj, "too many background"); 13518 app.killedBackground = true; 13519 Process.killProcessQuiet(app.pid); 13520 } 13521 } else { 13522 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13523 // This process was assigned as an empty process... step the 13524 // empty level. 13525 if (curEmptyAdj != nextEmptyAdj) { 13526 stepEmpty++; 13527 if (stepEmpty >= emptyFactor) { 13528 stepEmpty = 0; 13529 curEmptyAdj = nextEmptyAdj; 13530 nextEmptyAdj += 2; 13531 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13532 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13533 } 13534 } 13535 } 13536 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13537 mNumNonHiddenProcs++; 13538 } 13539 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13540 numEmpty++; 13541 if (numEmpty > emptyProcessLimit) { 13542 Slog.i(TAG, "No longer want " + app.processName 13543 + " (pid " + app.pid + "): empty #" + numEmpty); 13544 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13545 app.processName, app.setAdj, "too many background"); 13546 app.killedBackground = true; 13547 Process.killProcessQuiet(app.pid); 13548 } 13549 } 13550 } 13551 if (app.isolated && app.services.size() <= 0) { 13552 // If this is an isolated process, and there are no 13553 // services running in it, then the process is no longer 13554 // needed. We agressively kill these because we can by 13555 // definition not re-use the same process again, and it is 13556 // good to avoid having whatever code was running in them 13557 // left sitting around after no longer needed. 13558 Slog.i(TAG, "Isolated process " + app.processName 13559 + " (pid " + app.pid + ") no longer needed"); 13560 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13561 app.processName, app.setAdj, "isolated not needed"); 13562 app.killedBackground = true; 13563 Process.killProcessQuiet(app.pid); 13564 } 13565 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13566 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13567 && !app.killedBackground) { 13568 numTrimming++; 13569 } 13570 } 13571 } 13572 13573 mNumServiceProcs = mNewNumServiceProcs; 13574 13575 // Now determine the memory trimming level of background processes. 13576 // Unfortunately we need to start at the back of the list to do this 13577 // properly. We only do this if the number of background apps we 13578 // are managing to keep around is less than half the maximum we desire; 13579 // if we are keeping a good number around, we'll let them use whatever 13580 // memory they want. 13581 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13582 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13583 final int numHiddenAndEmpty = numHidden + numEmpty; 13584 final int N = mLruProcesses.size(); 13585 int factor = numTrimming/3; 13586 int minFactor = 2; 13587 if (mHomeProcess != null) minFactor++; 13588 if (mPreviousProcess != null) minFactor++; 13589 if (factor < minFactor) factor = minFactor; 13590 int step = 0; 13591 int fgTrimLevel; 13592 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13593 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13594 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13595 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13596 } else { 13597 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13598 } 13599 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13600 for (i=0; i<N; i++) { 13601 ProcessRecord app = mLruProcesses.get(i); 13602 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13603 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13604 && !app.killedBackground) { 13605 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13606 try { 13607 app.thread.scheduleTrimMemory(curLevel); 13608 } catch (RemoteException e) { 13609 } 13610 if (false) { 13611 // For now we won't do this; our memory trimming seems 13612 // to be good enough at this point that destroying 13613 // activities causes more harm than good. 13614 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13615 && app != mHomeProcess && app != mPreviousProcess) { 13616 // Need to do this on its own message because the stack may not 13617 // be in a consistent state at this point. 13618 // For these apps we will also finish their activities 13619 // to help them free memory. 13620 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13621 } 13622 } 13623 } 13624 app.trimMemoryLevel = curLevel; 13625 step++; 13626 if (step >= factor) { 13627 step = 0; 13628 switch (curLevel) { 13629 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13630 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13631 break; 13632 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13633 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13634 break; 13635 } 13636 } 13637 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13638 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13639 && app.thread != null) { 13640 try { 13641 app.thread.scheduleTrimMemory( 13642 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13643 } catch (RemoteException e) { 13644 } 13645 } 13646 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13647 } else { 13648 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13649 && app.pendingUiClean) { 13650 // If this application is now in the background and it 13651 // had done UI, then give it the special trim level to 13652 // have it free UI resources. 13653 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13654 if (app.trimMemoryLevel < level && app.thread != null) { 13655 try { 13656 app.thread.scheduleTrimMemory(level); 13657 } catch (RemoteException e) { 13658 } 13659 } 13660 app.pendingUiClean = false; 13661 } 13662 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13663 try { 13664 app.thread.scheduleTrimMemory(fgTrimLevel); 13665 } catch (RemoteException e) { 13666 } 13667 } 13668 app.trimMemoryLevel = fgTrimLevel; 13669 } 13670 } 13671 } else { 13672 final int N = mLruProcesses.size(); 13673 for (i=0; i<N; i++) { 13674 ProcessRecord app = mLruProcesses.get(i); 13675 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13676 && app.pendingUiClean) { 13677 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13678 && app.thread != null) { 13679 try { 13680 app.thread.scheduleTrimMemory( 13681 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13682 } catch (RemoteException e) { 13683 } 13684 } 13685 app.pendingUiClean = false; 13686 } 13687 app.trimMemoryLevel = 0; 13688 } 13689 } 13690 13691 if (mAlwaysFinishActivities) { 13692 // Need to do this on its own message because the stack may not 13693 // be in a consistent state at this point. 13694 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13695 } 13696 } 13697 13698 final void trimApplications() { 13699 synchronized (this) { 13700 int i; 13701 13702 // First remove any unused application processes whose package 13703 // has been removed. 13704 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13705 final ProcessRecord app = mRemovedProcesses.get(i); 13706 if (app.activities.size() == 0 13707 && app.curReceiver == null && app.services.size() == 0) { 13708 Slog.i( 13709 TAG, "Exiting empty application process " 13710 + app.processName + " (" 13711 + (app.thread != null ? app.thread.asBinder() : null) 13712 + ")\n"); 13713 if (app.pid > 0 && app.pid != MY_PID) { 13714 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13715 app.processName, app.setAdj, "empty"); 13716 Process.killProcessQuiet(app.pid); 13717 } else { 13718 try { 13719 app.thread.scheduleExit(); 13720 } catch (Exception e) { 13721 // Ignore exceptions. 13722 } 13723 } 13724 cleanUpApplicationRecordLocked(app, false, true, -1); 13725 mRemovedProcesses.remove(i); 13726 13727 if (app.persistent) { 13728 if (app.persistent) { 13729 addAppLocked(app.info, false); 13730 } 13731 } 13732 } 13733 } 13734 13735 // Now update the oom adj for all processes. 13736 updateOomAdjLocked(); 13737 } 13738 } 13739 13740 /** This method sends the specified signal to each of the persistent apps */ 13741 public void signalPersistentProcesses(int sig) throws RemoteException { 13742 if (sig != Process.SIGNAL_USR1) { 13743 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13744 } 13745 13746 synchronized (this) { 13747 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13748 != PackageManager.PERMISSION_GRANTED) { 13749 throw new SecurityException("Requires permission " 13750 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13751 } 13752 13753 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13754 ProcessRecord r = mLruProcesses.get(i); 13755 if (r.thread != null && r.persistent) { 13756 Process.sendSignal(r.pid, sig); 13757 } 13758 } 13759 } 13760 } 13761 13762 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13763 if (proc == null || proc == mProfileProc) { 13764 proc = mProfileProc; 13765 path = mProfileFile; 13766 profileType = mProfileType; 13767 clearProfilerLocked(); 13768 } 13769 if (proc == null) { 13770 return; 13771 } 13772 try { 13773 proc.thread.profilerControl(false, path, null, profileType); 13774 } catch (RemoteException e) { 13775 throw new IllegalStateException("Process disappeared"); 13776 } 13777 } 13778 13779 private void clearProfilerLocked() { 13780 if (mProfileFd != null) { 13781 try { 13782 mProfileFd.close(); 13783 } catch (IOException e) { 13784 } 13785 } 13786 mProfileApp = null; 13787 mProfileProc = null; 13788 mProfileFile = null; 13789 mProfileType = 0; 13790 mAutoStopProfiler = false; 13791 } 13792 13793 public boolean profileControl(String process, int userId, boolean start, 13794 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13795 13796 try { 13797 synchronized (this) { 13798 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13799 // its own permission. 13800 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13801 != PackageManager.PERMISSION_GRANTED) { 13802 throw new SecurityException("Requires permission " 13803 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13804 } 13805 13806 if (start && fd == null) { 13807 throw new IllegalArgumentException("null fd"); 13808 } 13809 13810 ProcessRecord proc = null; 13811 if (process != null) { 13812 proc = findProcessLocked(process, userId, "profileControl"); 13813 } 13814 13815 if (start && (proc == null || proc.thread == null)) { 13816 throw new IllegalArgumentException("Unknown process: " + process); 13817 } 13818 13819 if (start) { 13820 stopProfilerLocked(null, null, 0); 13821 setProfileApp(proc.info, proc.processName, path, fd, false); 13822 mProfileProc = proc; 13823 mProfileType = profileType; 13824 try { 13825 fd = fd.dup(); 13826 } catch (IOException e) { 13827 fd = null; 13828 } 13829 proc.thread.profilerControl(start, path, fd, profileType); 13830 fd = null; 13831 mProfileFd = null; 13832 } else { 13833 stopProfilerLocked(proc, path, profileType); 13834 if (fd != null) { 13835 try { 13836 fd.close(); 13837 } catch (IOException e) { 13838 } 13839 } 13840 } 13841 13842 return true; 13843 } 13844 } catch (RemoteException e) { 13845 throw new IllegalStateException("Process disappeared"); 13846 } finally { 13847 if (fd != null) { 13848 try { 13849 fd.close(); 13850 } catch (IOException e) { 13851 } 13852 } 13853 } 13854 } 13855 13856 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13857 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 13858 userId, true, true, callName, null); 13859 ProcessRecord proc = null; 13860 try { 13861 int pid = Integer.parseInt(process); 13862 synchronized (mPidsSelfLocked) { 13863 proc = mPidsSelfLocked.get(pid); 13864 } 13865 } catch (NumberFormatException e) { 13866 } 13867 13868 if (proc == null) { 13869 HashMap<String, SparseArray<ProcessRecord>> all 13870 = mProcessNames.getMap(); 13871 SparseArray<ProcessRecord> procs = all.get(process); 13872 if (procs != null && procs.size() > 0) { 13873 proc = procs.valueAt(0); 13874 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13875 for (int i=1; i<procs.size(); i++) { 13876 ProcessRecord thisProc = procs.valueAt(i); 13877 if (thisProc.userId == userId) { 13878 proc = thisProc; 13879 break; 13880 } 13881 } 13882 } 13883 } 13884 } 13885 13886 return proc; 13887 } 13888 13889 public boolean dumpHeap(String process, int userId, boolean managed, 13890 String path, ParcelFileDescriptor fd) throws RemoteException { 13891 13892 try { 13893 synchronized (this) { 13894 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13895 // its own permission (same as profileControl). 13896 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13897 != PackageManager.PERMISSION_GRANTED) { 13898 throw new SecurityException("Requires permission " 13899 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13900 } 13901 13902 if (fd == null) { 13903 throw new IllegalArgumentException("null fd"); 13904 } 13905 13906 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13907 if (proc == null || proc.thread == null) { 13908 throw new IllegalArgumentException("Unknown process: " + process); 13909 } 13910 13911 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13912 if (!isDebuggable) { 13913 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13914 throw new SecurityException("Process not debuggable: " + proc); 13915 } 13916 } 13917 13918 proc.thread.dumpHeap(managed, path, fd); 13919 fd = null; 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 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13935 public void monitor() { 13936 synchronized (this) { } 13937 } 13938 13939 void onCoreSettingsChange(Bundle settings) { 13940 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13941 ProcessRecord processRecord = mLruProcesses.get(i); 13942 try { 13943 if (processRecord.thread != null) { 13944 processRecord.thread.setCoreSettings(settings); 13945 } 13946 } catch (RemoteException re) { 13947 /* ignore */ 13948 } 13949 } 13950 } 13951 13952 // Multi-user methods 13953 13954 @Override 13955 public boolean switchUser(int userId) { 13956 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13957 != PackageManager.PERMISSION_GRANTED) { 13958 String msg = "Permission Denial: switchUser() from pid=" 13959 + Binder.getCallingPid() 13960 + ", uid=" + Binder.getCallingUid() 13961 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13962 Slog.w(TAG, msg); 13963 throw new SecurityException(msg); 13964 } 13965 13966 final long ident = Binder.clearCallingIdentity(); 13967 try { 13968 synchronized (this) { 13969 final int oldUserId = mCurrentUserId; 13970 if (oldUserId == userId) { 13971 return true; 13972 } 13973 13974 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 13975 if (userInfo == null) { 13976 Slog.w(TAG, "No user info for user #" + userId); 13977 return false; 13978 } 13979 13980 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 13981 R.anim.screen_user_enter); 13982 13983 // If the user we are switching to is not currently started, then 13984 // we need to start it now. 13985 if (mStartedUsers.get(userId) == null) { 13986 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13987 updateStartedUserArrayLocked(); 13988 } 13989 13990 mCurrentUserId = userId; 13991 mCurrentUserArray = new int[] { userId }; 13992 final Integer userIdInt = Integer.valueOf(userId); 13993 mUserLru.remove(userIdInt); 13994 mUserLru.add(userIdInt); 13995 13996 mWindowManager.setCurrentUser(userId); 13997 13998 final UserStartedState uss = mStartedUsers.get(userId); 13999 14000 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 14001 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14002 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 14003 oldUserId, userId, uss)); 14004 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 14005 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 14006 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14007 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14008 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14009 broadcastIntentLocked(null, null, intent, 14010 null, null, 0, null, null, null, 14011 false, false, MY_PID, Process.SYSTEM_UID, userId); 14012 14013 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 14014 if (userId != 0) { 14015 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 14016 broadcastIntentLocked(null, null, intent, null, 14017 new IIntentReceiver.Stub() { 14018 public void performReceive(Intent intent, int resultCode, 14019 String data, Bundle extras, boolean ordered, 14020 boolean sticky, int sendingUser) { 14021 synchronized (ActivityManagerService.this) { 14022 getUserManagerLocked().makeInitialized(userInfo.id); 14023 } 14024 } 14025 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14026 userId); 14027 } else { 14028 getUserManagerLocked().makeInitialized(userInfo.id); 14029 } 14030 } 14031 14032 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14033 if (!haveActivities) { 14034 startHomeActivityLocked(userId); 14035 } 14036 14037 getUserManagerLocked().userForeground(userId); 14038 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14039 } 14040 } finally { 14041 Binder.restoreCallingIdentity(ident); 14042 } 14043 14044 return true; 14045 } 14046 14047 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14048 long ident = Binder.clearCallingIdentity(); 14049 try { 14050 Intent intent; 14051 if (oldUserId >= 0) { 14052 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14053 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14054 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14055 broadcastIntentLocked(null, null, intent, 14056 null, null, 0, null, null, null, 14057 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14058 } 14059 if (newUserId >= 0) { 14060 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14061 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14062 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14063 broadcastIntentLocked(null, null, intent, 14064 null, null, 0, null, null, null, 14065 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14066 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14067 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14068 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14069 broadcastIntentLocked(null, null, intent, 14070 null, null, 0, null, null, 14071 android.Manifest.permission.MANAGE_USERS, 14072 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14073 } 14074 } finally { 14075 Binder.restoreCallingIdentity(ident); 14076 } 14077 } 14078 14079 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14080 final int newUserId) { 14081 final int N = mUserSwitchObservers.beginBroadcast(); 14082 if (N > 0) { 14083 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14084 int mCount = 0; 14085 @Override 14086 public void sendResult(Bundle data) throws RemoteException { 14087 synchronized (ActivityManagerService.this) { 14088 if (mCurUserSwitchCallback == this) { 14089 mCount++; 14090 if (mCount == N) { 14091 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14092 } 14093 } 14094 } 14095 } 14096 }; 14097 synchronized (this) { 14098 mCurUserSwitchCallback = callback; 14099 } 14100 for (int i=0; i<N; i++) { 14101 try { 14102 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14103 newUserId, callback); 14104 } catch (RemoteException e) { 14105 } 14106 } 14107 } else { 14108 synchronized (this) { 14109 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14110 } 14111 } 14112 mUserSwitchObservers.finishBroadcast(); 14113 } 14114 14115 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14116 synchronized (this) { 14117 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14118 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14119 } 14120 } 14121 14122 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14123 mCurUserSwitchCallback = null; 14124 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14125 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14126 oldUserId, newUserId, uss)); 14127 } 14128 14129 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14130 final int N = mUserSwitchObservers.beginBroadcast(); 14131 for (int i=0; i<N; i++) { 14132 try { 14133 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14134 } catch (RemoteException e) { 14135 } 14136 } 14137 mUserSwitchObservers.finishBroadcast(); 14138 synchronized (this) { 14139 mWindowManager.stopFreezingScreen(); 14140 } 14141 } 14142 14143 void finishUserSwitch(UserStartedState uss) { 14144 synchronized (this) { 14145 if (uss.mState == UserStartedState.STATE_BOOTING 14146 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14147 uss.mState = UserStartedState.STATE_RUNNING; 14148 final int userId = uss.mHandle.getIdentifier(); 14149 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14150 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14151 broadcastIntentLocked(null, null, intent, 14152 null, null, 0, null, null, 14153 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14154 false, false, MY_PID, Process.SYSTEM_UID, userId); 14155 } 14156 int num = mUserLru.size(); 14157 int i = 0; 14158 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14159 Integer oldUserId = mUserLru.get(i); 14160 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14161 if (oldUss == null) { 14162 // Shouldn't happen, but be sane if it does. 14163 mUserLru.remove(i); 14164 num--; 14165 continue; 14166 } 14167 if (oldUss.mState == UserStartedState.STATE_STOPPING) { 14168 // This user is already stopping, doesn't count. 14169 num--; 14170 i++; 14171 continue; 14172 } 14173 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14174 // Owner and current can't be stopped, but count as running. 14175 i++; 14176 continue; 14177 } 14178 // This is a user to be stopped. 14179 stopUserLocked(oldUserId, null); 14180 num--; 14181 i++; 14182 } 14183 } 14184 } 14185 14186 @Override 14187 public int stopUser(final int userId, final IStopUserCallback callback) { 14188 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14189 != PackageManager.PERMISSION_GRANTED) { 14190 String msg = "Permission Denial: switchUser() from pid=" 14191 + Binder.getCallingPid() 14192 + ", uid=" + Binder.getCallingUid() 14193 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14194 Slog.w(TAG, msg); 14195 throw new SecurityException(msg); 14196 } 14197 if (userId <= 0) { 14198 throw new IllegalArgumentException("Can't stop primary user " + userId); 14199 } 14200 synchronized (this) { 14201 return stopUserLocked(userId, callback); 14202 } 14203 } 14204 14205 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14206 if (mCurrentUserId == userId) { 14207 return ActivityManager.USER_OP_IS_CURRENT; 14208 } 14209 14210 final UserStartedState uss = mStartedUsers.get(userId); 14211 if (uss == null) { 14212 // User is not started, nothing to do... but we do need to 14213 // callback if requested. 14214 if (callback != null) { 14215 mHandler.post(new Runnable() { 14216 @Override 14217 public void run() { 14218 try { 14219 callback.userStopped(userId); 14220 } catch (RemoteException e) { 14221 } 14222 } 14223 }); 14224 } 14225 return ActivityManager.USER_OP_SUCCESS; 14226 } 14227 14228 if (callback != null) { 14229 uss.mStopCallbacks.add(callback); 14230 } 14231 14232 if (uss.mState != UserStartedState.STATE_STOPPING) { 14233 uss.mState = UserStartedState.STATE_STOPPING; 14234 14235 long ident = Binder.clearCallingIdentity(); 14236 try { 14237 // Inform of user switch 14238 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14239 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14240 @Override 14241 public void performReceive(Intent intent, int resultCode, String data, 14242 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14243 finishUserStop(uss); 14244 } 14245 }; 14246 broadcastIntentLocked(null, null, intent, 14247 null, resultReceiver, 0, null, null, null, 14248 true, false, MY_PID, Process.SYSTEM_UID, userId); 14249 } finally { 14250 Binder.restoreCallingIdentity(ident); 14251 } 14252 } 14253 14254 return ActivityManager.USER_OP_SUCCESS; 14255 } 14256 14257 void finishUserStop(UserStartedState uss) { 14258 final int userId = uss.mHandle.getIdentifier(); 14259 boolean stopped; 14260 ArrayList<IStopUserCallback> callbacks; 14261 synchronized (this) { 14262 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14263 if (uss.mState != UserStartedState.STATE_STOPPING 14264 || mStartedUsers.get(userId) != uss) { 14265 stopped = false; 14266 } else { 14267 stopped = true; 14268 // User can no longer run. 14269 mStartedUsers.remove(userId); 14270 mUserLru.remove(Integer.valueOf(userId)); 14271 updateStartedUserArrayLocked(); 14272 14273 // Clean up all state and processes associated with the user. 14274 // Kill all the processes for the user. 14275 forceStopUserLocked(userId); 14276 } 14277 } 14278 14279 for (int i=0; i<callbacks.size(); i++) { 14280 try { 14281 if (stopped) callbacks.get(i).userStopped(userId); 14282 else callbacks.get(i).userStopAborted(userId); 14283 } catch (RemoteException e) { 14284 } 14285 } 14286 } 14287 14288 @Override 14289 public UserInfo getCurrentUser() { 14290 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14291 != PackageManager.PERMISSION_GRANTED) && ( 14292 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14293 != PackageManager.PERMISSION_GRANTED)) { 14294 String msg = "Permission Denial: getCurrentUser() from pid=" 14295 + Binder.getCallingPid() 14296 + ", uid=" + Binder.getCallingUid() 14297 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14298 Slog.w(TAG, msg); 14299 throw new SecurityException(msg); 14300 } 14301 synchronized (this) { 14302 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14303 } 14304 } 14305 14306 @Override 14307 public boolean isUserRunning(int userId) { 14308 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14309 != PackageManager.PERMISSION_GRANTED) { 14310 String msg = "Permission Denial: isUserRunning() from pid=" 14311 + Binder.getCallingPid() 14312 + ", uid=" + Binder.getCallingUid() 14313 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14314 Slog.w(TAG, msg); 14315 throw new SecurityException(msg); 14316 } 14317 synchronized (this) { 14318 return isUserRunningLocked(userId); 14319 } 14320 } 14321 14322 boolean isUserRunningLocked(int userId) { 14323 UserStartedState state = mStartedUsers.get(userId); 14324 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14325 } 14326 14327 @Override 14328 public int[] getRunningUserIds() { 14329 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14330 != PackageManager.PERMISSION_GRANTED) { 14331 String msg = "Permission Denial: isUserRunning() from pid=" 14332 + Binder.getCallingPid() 14333 + ", uid=" + Binder.getCallingUid() 14334 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14335 Slog.w(TAG, msg); 14336 throw new SecurityException(msg); 14337 } 14338 synchronized (this) { 14339 return mStartedUserArray; 14340 } 14341 } 14342 14343 private void updateStartedUserArrayLocked() { 14344 mStartedUserArray = new int[mStartedUsers.size()]; 14345 for (int i=0; i<mStartedUsers.size(); i++) { 14346 mStartedUserArray[i] = mStartedUsers.keyAt(i); 14347 } 14348 } 14349 14350 @Override 14351 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14352 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14353 != PackageManager.PERMISSION_GRANTED) { 14354 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14355 + Binder.getCallingPid() 14356 + ", uid=" + Binder.getCallingUid() 14357 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14358 Slog.w(TAG, msg); 14359 throw new SecurityException(msg); 14360 } 14361 14362 mUserSwitchObservers.register(observer); 14363 } 14364 14365 @Override 14366 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14367 mUserSwitchObservers.unregister(observer); 14368 } 14369 14370 private boolean userExists(int userId) { 14371 if (userId == 0) { 14372 return true; 14373 } 14374 UserManagerService ums = getUserManagerLocked(); 14375 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14376 } 14377 14378 int[] getUsersLocked() { 14379 UserManagerService ums = getUserManagerLocked(); 14380 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14381 } 14382 14383 UserManagerService getUserManagerLocked() { 14384 if (mUserManager == null) { 14385 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14386 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14387 } 14388 return mUserManager; 14389 } 14390 14391 private void checkValidCaller(int uid, int userId) { 14392 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14393 14394 throw new SecurityException("Caller uid=" + uid 14395 + " is not privileged to communicate with user=" + userId); 14396 } 14397 14398 private int applyUserId(int uid, int userId) { 14399 return UserHandle.getUid(userId, uid); 14400 } 14401 14402 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14403 if (info == null) return null; 14404 ApplicationInfo newInfo = new ApplicationInfo(info); 14405 newInfo.uid = applyUserId(info.uid, userId); 14406 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14407 + info.packageName; 14408 return newInfo; 14409 } 14410 14411 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14412 if (aInfo == null 14413 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14414 return aInfo; 14415 } 14416 14417 ActivityInfo info = new ActivityInfo(aInfo); 14418 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14419 return info; 14420 } 14421} 14422