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