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