ActivityManagerService.java revision 6cbd33fc25fa48dcb673edc150d2315bec4ade3a
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21import com.android.internal.R; 22import com.android.internal.os.BatteryStatsImpl; 23import com.android.internal.os.ProcessStats; 24import com.android.server.AttributeCache; 25import com.android.server.IntentResolver; 26import com.android.server.ProcessMap; 27import com.android.server.SystemServer; 28import com.android.server.Watchdog; 29import com.android.server.am.ActivityStack.ActivityState; 30import com.android.server.pm.UserManagerService; 31import com.android.server.wm.WindowManagerService; 32 33import dalvik.system.Zygote; 34 35import android.app.Activity; 36import android.app.ActivityManager; 37import android.app.ActivityManagerNative; 38import android.app.ActivityOptions; 39import android.app.ActivityThread; 40import android.app.AlertDialog; 41import android.app.AppGlobals; 42import android.app.ApplicationErrorReport; 43import android.app.Dialog; 44import android.app.IActivityController; 45import android.app.IApplicationThread; 46import android.app.IInstrumentationWatcher; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.IServiceConnection; 50import android.app.IStopUserCallback; 51import android.app.IThumbnailReceiver; 52import android.app.IUserSwitchObserver; 53import android.app.Instrumentation; 54import android.app.Notification; 55import android.app.NotificationManager; 56import android.app.PendingIntent; 57import android.app.backup.IBackupManager; 58import android.content.ActivityNotFoundException; 59import android.content.BroadcastReceiver; 60import android.content.ClipData; 61import android.content.ComponentCallbacks2; 62import android.content.ComponentName; 63import android.content.ContentProvider; 64import android.content.ContentResolver; 65import android.content.Context; 66import android.content.DialogInterface; 67import android.content.IContentProvider; 68import android.content.IIntentReceiver; 69import android.content.IIntentSender; 70import android.content.Intent; 71import android.content.IntentFilter; 72import android.content.IntentSender; 73import android.content.pm.ActivityInfo; 74import android.content.pm.ApplicationInfo; 75import android.content.pm.ConfigurationInfo; 76import android.content.pm.IPackageDataObserver; 77import android.content.pm.IPackageManager; 78import android.content.pm.InstrumentationInfo; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageManager; 81import android.content.pm.UserInfo; 82import android.content.pm.PackageManager.NameNotFoundException; 83import android.content.pm.PathPermission; 84import android.content.pm.ProviderInfo; 85import android.content.pm.ResolveInfo; 86import android.content.pm.ServiceInfo; 87import android.content.res.CompatibilityInfo; 88import android.content.res.Configuration; 89import android.graphics.Bitmap; 90import android.net.Proxy; 91import android.net.ProxyProperties; 92import android.net.Uri; 93import android.os.Binder; 94import android.os.Build; 95import android.os.Bundle; 96import android.os.Debug; 97import android.os.DropBoxManager; 98import android.os.Environment; 99import android.os.FileObserver; 100import android.os.FileUtils; 101import android.os.Handler; 102import android.os.IBinder; 103import android.os.IPermissionController; 104import android.os.IRemoteCallback; 105import android.os.IUserManager; 106import android.os.Looper; 107import android.os.Message; 108import android.os.Parcel; 109import android.os.ParcelFileDescriptor; 110import android.os.Process; 111import android.os.RemoteCallbackList; 112import android.os.RemoteException; 113import android.os.SELinux; 114import android.os.ServiceManager; 115import android.os.StrictMode; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.provider.Settings; 120import android.text.format.Time; 121import android.util.EventLog; 122import android.util.Log; 123import android.util.Pair; 124import android.util.PrintWriterPrinter; 125import android.util.Slog; 126import android.util.SparseArray; 127import android.util.TimeUtils; 128import android.view.Gravity; 129import android.view.LayoutInflater; 130import android.view.View; 131import android.view.WindowManager; 132import android.view.WindowManagerPolicy; 133 134import java.io.BufferedInputStream; 135import java.io.BufferedOutputStream; 136import java.io.BufferedReader; 137import java.io.DataInputStream; 138import java.io.DataOutputStream; 139import java.io.File; 140import java.io.FileDescriptor; 141import java.io.FileInputStream; 142import java.io.FileNotFoundException; 143import java.io.FileOutputStream; 144import java.io.IOException; 145import java.io.InputStreamReader; 146import java.io.PrintWriter; 147import java.io.StringWriter; 148import java.lang.ref.WeakReference; 149import java.util.ArrayList; 150import java.util.Collections; 151import java.util.Comparator; 152import java.util.HashMap; 153import java.util.HashSet; 154import java.util.Iterator; 155import java.util.List; 156import java.util.Locale; 157import java.util.Map; 158import java.util.Set; 159import java.util.concurrent.atomic.AtomicBoolean; 160import java.util.concurrent.atomic.AtomicLong; 161 162public final class ActivityManagerService extends ActivityManagerNative 163 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 164 private static final String USER_DATA_DIR = "/data/user/"; 165 static final String TAG = "ActivityManager"; 166 static final String TAG_MU = "ActivityManagerServiceMU"; 167 static final boolean DEBUG = false; 168 static final boolean localLOGV = DEBUG; 169 static final boolean DEBUG_SWITCH = localLOGV || false; 170 static final boolean DEBUG_TASKS = localLOGV || false; 171 static final boolean DEBUG_PAUSE = localLOGV || false; 172 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 173 static final boolean DEBUG_TRANSITION = localLOGV || false; 174 static final boolean DEBUG_BROADCAST = localLOGV || false; 175 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 176 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 177 static final boolean DEBUG_SERVICE = localLOGV || false; 178 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 179 static final boolean DEBUG_VISBILITY = localLOGV || false; 180 static final boolean DEBUG_PROCESSES = localLOGV || false; 181 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 182 static final boolean DEBUG_PROVIDER = localLOGV || false; 183 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 184 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 185 static final boolean DEBUG_RESULTS = localLOGV || false; 186 static final boolean DEBUG_BACKUP = localLOGV || false; 187 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 188 static final boolean DEBUG_POWER = localLOGV || false; 189 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 190 static final boolean DEBUG_MU = localLOGV || false; 191 static final boolean VALIDATE_TOKENS = false; 192 static final boolean SHOW_ACTIVITY_START_TIME = true; 193 194 // Control over CPU and battery monitoring. 195 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 196 static final boolean MONITOR_CPU_USAGE = true; 197 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 198 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 199 static final boolean MONITOR_THREAD_CPU_USAGE = false; 200 201 // The flags that are set for all calls we make to the package manager. 202 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 203 204 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 205 206 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 207 208 // Maximum number of recent tasks that we can remember. 209 static final int MAX_RECENT_TASKS = 20; 210 211 // Amount of time after a call to stopAppSwitches() during which we will 212 // prevent further untrusted switches from happening. 213 static final long APP_SWITCH_DELAY_TIME = 5*1000; 214 215 // How long we wait for a launched process to attach to the activity manager 216 // before we decide it's never going to come up for real. 217 static final int PROC_START_TIMEOUT = 10*1000; 218 219 // How long we wait for a launched process to attach to the activity manager 220 // before we decide it's never going to come up for real, when the process was 221 // started with a wrapper for instrumentation (such as Valgrind) because it 222 // could take much longer than usual. 223 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 224 225 // How long to wait after going idle before forcing apps to GC. 226 static final int GC_TIMEOUT = 5*1000; 227 228 // The minimum amount of time between successive GC requests for a process. 229 static final int GC_MIN_INTERVAL = 60*1000; 230 231 // The rate at which we check for apps using excessive power -- 15 mins. 232 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 233 234 // The minimum sample duration we will allow before deciding we have 235 // enough data on wake locks to start killing things. 236 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 237 238 // The minimum sample duration we will allow before deciding we have 239 // enough data on CPU usage to start killing things. 240 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 241 242 // How long we allow a receiver to run before giving up on it. 243 static final int BROADCAST_FG_TIMEOUT = 10*1000; 244 static final int BROADCAST_BG_TIMEOUT = 60*1000; 245 246 // How long we wait until we timeout on key dispatching. 247 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 248 249 // How long we wait until we timeout on key dispatching during instrumentation. 250 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 251 252 // Amount of time we wait for observers to handle a user switch before 253 // giving up on them and unfreezing the screen. 254 static final int USER_SWITCH_TIMEOUT = 2*1000; 255 256 static final int MY_PID = Process.myPid(); 257 258 static final String[] EMPTY_STRING_ARRAY = new String[0]; 259 260 public ActivityStack mMainStack; 261 262 private final boolean mHeadless; 263 264 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 265 // default actuion automatically. Important for devices without direct input 266 // devices. 267 private boolean mShowDialogs = true; 268 269 /** 270 * Description of a request to start a new activity, which has been held 271 * due to app switches being disabled. 272 */ 273 static class PendingActivityLaunch { 274 ActivityRecord r; 275 ActivityRecord sourceRecord; 276 int startFlags; 277 } 278 279 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 280 = new ArrayList<PendingActivityLaunch>(); 281 282 283 BroadcastQueue mFgBroadcastQueue; 284 BroadcastQueue mBgBroadcastQueue; 285 // Convenient for easy iteration over the queues. Foreground is first 286 // so that dispatch of foreground broadcasts gets precedence. 287 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 288 289 BroadcastQueue broadcastQueueForIntent(Intent intent) { 290 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 291 if (DEBUG_BACKGROUND_BROADCAST) { 292 Slog.i(TAG, "Broadcast intent " + intent + " on " 293 + (isFg ? "foreground" : "background") 294 + " queue"); 295 } 296 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 297 } 298 299 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 300 for (BroadcastQueue queue : mBroadcastQueues) { 301 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 302 if (r != null) { 303 return r; 304 } 305 } 306 return null; 307 } 308 309 /** 310 * Activity we have told the window manager to have key focus. 311 */ 312 ActivityRecord mFocusedActivity = null; 313 /** 314 * List of intents that were used to start the most recent tasks. 315 */ 316 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 317 318 /** 319 * Process management. 320 */ 321 final ProcessList mProcessList = new ProcessList(); 322 323 /** 324 * All of the applications we currently have running organized by name. 325 * The keys are strings of the application package name (as 326 * returned by the package manager), and the keys are ApplicationRecord 327 * objects. 328 */ 329 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 330 331 /** 332 * The currently running isolated processes. 333 */ 334 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 335 336 /** 337 * Counter for assigning isolated process uids, to avoid frequently reusing the 338 * same ones. 339 */ 340 int mNextIsolatedProcessUid = 0; 341 342 /** 343 * The currently running heavy-weight process, if any. 344 */ 345 ProcessRecord mHeavyWeightProcess = null; 346 347 /** 348 * The last time that various processes have crashed. 349 */ 350 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 351 352 /** 353 * Set of applications that we consider to be bad, and will reject 354 * incoming broadcasts from (which the user has no control over). 355 * Processes are added to this set when they have crashed twice within 356 * a minimum amount of time; they are removed from it when they are 357 * later restarted (hopefully due to some user action). The value is the 358 * time it was added to the list. 359 */ 360 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 361 362 /** 363 * All of the processes we currently have running organized by pid. 364 * The keys are the pid running the application. 365 * 366 * <p>NOTE: This object is protected by its own lock, NOT the global 367 * activity manager lock! 368 */ 369 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 370 371 /** 372 * All of the processes that have been forced to be foreground. The key 373 * is the pid of the caller who requested it (we hold a death 374 * link on it). 375 */ 376 abstract class ForegroundToken implements IBinder.DeathRecipient { 377 int pid; 378 IBinder token; 379 } 380 final SparseArray<ForegroundToken> mForegroundProcesses 381 = new SparseArray<ForegroundToken>(); 382 383 /** 384 * List of records for processes that someone had tried to start before the 385 * system was ready. We don't start them at that point, but ensure they 386 * are started by the time booting is complete. 387 */ 388 final ArrayList<ProcessRecord> mProcessesOnHold 389 = new ArrayList<ProcessRecord>(); 390 391 /** 392 * List of persistent applications that are in the process 393 * of being started. 394 */ 395 final ArrayList<ProcessRecord> mPersistentStartingProcesses 396 = new ArrayList<ProcessRecord>(); 397 398 /** 399 * Processes that are being forcibly torn down. 400 */ 401 final ArrayList<ProcessRecord> mRemovedProcesses 402 = new ArrayList<ProcessRecord>(); 403 404 /** 405 * List of running applications, sorted by recent usage. 406 * The first entry in the list is the least recently used. 407 * It contains ApplicationRecord objects. This list does NOT include 408 * any persistent application records (since we never want to exit them). 409 */ 410 final ArrayList<ProcessRecord> mLruProcesses 411 = new ArrayList<ProcessRecord>(); 412 413 /** 414 * List of processes that should gc as soon as things are idle. 415 */ 416 final ArrayList<ProcessRecord> mProcessesToGc 417 = new ArrayList<ProcessRecord>(); 418 419 /** 420 * This is the process holding what we currently consider to be 421 * the "home" activity. 422 */ 423 ProcessRecord mHomeProcess; 424 425 /** 426 * This is the process holding the activity the user last visited that 427 * is in a different process from the one they are currently in. 428 */ 429 ProcessRecord mPreviousProcess; 430 431 /** 432 * The time at which the previous process was last visible. 433 */ 434 long mPreviousProcessVisibleTime; 435 436 /** 437 * Which uses have been started, so are allowed to run code. 438 */ 439 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 440 441 /** 442 * LRU list of history of current users. Most recently current is at the end. 443 */ 444 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 445 446 /** 447 * Registered observers of the user switching mechanics. 448 */ 449 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 450 = new RemoteCallbackList<IUserSwitchObserver>(); 451 452 /** 453 * Currently active user switch. 454 */ 455 Object mCurUserSwitchCallback; 456 457 /** 458 * Packages that the user has asked to have run in screen size 459 * compatibility mode instead of filling the screen. 460 */ 461 final CompatModePackages mCompatModePackages; 462 463 /** 464 * Set of PendingResultRecord objects that are currently active. 465 */ 466 final HashSet mPendingResultRecords = new HashSet(); 467 468 /** 469 * Set of IntentSenderRecord objects that are currently active. 470 */ 471 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 472 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 473 474 /** 475 * Fingerprints (hashCode()) of stack traces that we've 476 * already logged DropBox entries for. Guarded by itself. If 477 * something (rogue user app) forces this over 478 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 479 */ 480 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 481 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 482 483 /** 484 * Strict Mode background batched logging state. 485 * 486 * The string buffer is guarded by itself, and its lock is also 487 * used to determine if another batched write is already 488 * in-flight. 489 */ 490 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 491 492 /** 493 * Keeps track of all IIntentReceivers that have been registered for 494 * broadcasts. Hash keys are the receiver IBinder, hash value is 495 * a ReceiverList. 496 */ 497 final HashMap mRegisteredReceivers = new HashMap(); 498 499 /** 500 * Resolver for broadcast intents to registered receivers. 501 * Holds BroadcastFilter (subclass of IntentFilter). 502 */ 503 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 504 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 505 @Override 506 protected boolean allowFilterResult( 507 BroadcastFilter filter, List<BroadcastFilter> dest) { 508 IBinder target = filter.receiverList.receiver.asBinder(); 509 for (int i=dest.size()-1; i>=0; i--) { 510 if (dest.get(i).receiverList.receiver.asBinder() == target) { 511 return false; 512 } 513 } 514 return true; 515 } 516 517 @Override 518 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 519 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 520 || userId == filter.owningUserId) { 521 return super.newResult(filter, match, userId); 522 } 523 return null; 524 } 525 526 @Override 527 protected BroadcastFilter[] newArray(int size) { 528 return new BroadcastFilter[size]; 529 } 530 531 @Override 532 protected String packageForFilter(BroadcastFilter filter) { 533 return filter.packageName; 534 } 535 }; 536 537 /** 538 * State of all active sticky broadcasts per user. Keys are the action of the 539 * sticky Intent, values are an ArrayList of all broadcasted intents with 540 * that action (which should usually be one). The SparseArray is keyed 541 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 542 * for stickies that are sent to all users. 543 */ 544 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 545 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 546 547 final ActiveServices mServices; 548 549 /** 550 * Backup/restore process management 551 */ 552 String mBackupAppName = null; 553 BackupRecord mBackupTarget = null; 554 555 /** 556 * List of PendingThumbnailsRecord objects of clients who are still 557 * waiting to receive all of the thumbnails for a task. 558 */ 559 final ArrayList mPendingThumbnails = new ArrayList(); 560 561 /** 562 * List of HistoryRecord objects that have been finished and must 563 * still report back to a pending thumbnail receiver. 564 */ 565 final ArrayList mCancelledThumbnails = new ArrayList(); 566 567 final ProviderMap mProviderMap; 568 569 /** 570 * List of content providers who have clients waiting for them. The 571 * application is currently being launched and the provider will be 572 * removed from this list once it is published. 573 */ 574 final ArrayList<ContentProviderRecord> mLaunchingProviders 575 = new ArrayList<ContentProviderRecord>(); 576 577 /** 578 * Global set of specific Uri permissions that have been granted. 579 */ 580 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 581 = new SparseArray<HashMap<Uri, UriPermission>>(); 582 583 CoreSettingsObserver mCoreSettingsObserver; 584 585 /** 586 * Thread-local storage used to carry caller permissions over through 587 * indirect content-provider access. 588 * @see #ActivityManagerService.openContentUri() 589 */ 590 private class Identity { 591 public int pid; 592 public int uid; 593 594 Identity(int _pid, int _uid) { 595 pid = _pid; 596 uid = _uid; 597 } 598 } 599 600 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 601 602 /** 603 * All information we have collected about the runtime performance of 604 * any user id that can impact battery performance. 605 */ 606 final BatteryStatsService mBatteryStatsService; 607 608 /** 609 * information about component usage 610 */ 611 final UsageStatsService mUsageStatsService; 612 613 /** 614 * Current configuration information. HistoryRecord objects are given 615 * a reference to this object to indicate which configuration they are 616 * currently running in, so this object must be kept immutable. 617 */ 618 Configuration mConfiguration = new Configuration(); 619 620 /** 621 * Current sequencing integer of the configuration, for skipping old 622 * configurations. 623 */ 624 int mConfigurationSeq = 0; 625 626 /** 627 * Hardware-reported OpenGLES version. 628 */ 629 final int GL_ES_VERSION; 630 631 /** 632 * List of initialization arguments to pass to all processes when binding applications to them. 633 * For example, references to the commonly used services. 634 */ 635 HashMap<String, IBinder> mAppBindArgs; 636 637 /** 638 * Temporary to avoid allocations. Protected by main lock. 639 */ 640 final StringBuilder mStringBuilder = new StringBuilder(256); 641 642 /** 643 * Used to control how we initialize the service. 644 */ 645 boolean mStartRunning = false; 646 ComponentName mTopComponent; 647 String mTopAction; 648 String mTopData; 649 boolean mProcessesReady = false; 650 boolean mSystemReady = false; 651 boolean mBooting = false; 652 boolean mWaitingUpdate = false; 653 boolean mDidUpdate = false; 654 boolean mOnBattery = false; 655 boolean mLaunchWarningShown = false; 656 657 Context mContext; 658 659 int mFactoryTest; 660 661 boolean mCheckedForSetup; 662 663 /** 664 * The time at which we will allow normal application switches again, 665 * after a call to {@link #stopAppSwitches()}. 666 */ 667 long mAppSwitchesAllowedTime; 668 669 /** 670 * This is set to true after the first switch after mAppSwitchesAllowedTime 671 * is set; any switches after that will clear the time. 672 */ 673 boolean mDidAppSwitch; 674 675 /** 676 * Last time (in realtime) at which we checked for power usage. 677 */ 678 long mLastPowerCheckRealtime; 679 680 /** 681 * Last time (in uptime) at which we checked for power usage. 682 */ 683 long mLastPowerCheckUptime; 684 685 /** 686 * Set while we are wanting to sleep, to prevent any 687 * activities from being started/resumed. 688 */ 689 boolean mSleeping = false; 690 691 /** 692 * State of external calls telling us if the device is asleep. 693 */ 694 boolean mWentToSleep = false; 695 696 /** 697 * State of external call telling us if the lock screen is shown. 698 */ 699 boolean mLockScreenShown = false; 700 701 /** 702 * Set if we are shutting down the system, similar to sleeping. 703 */ 704 boolean mShuttingDown = false; 705 706 /** 707 * Task identifier that activities are currently being started 708 * in. Incremented each time a new task is created. 709 * todo: Replace this with a TokenSpace class that generates non-repeating 710 * integers that won't wrap. 711 */ 712 int mCurTask = 1; 713 714 /** 715 * Current sequence id for oom_adj computation traversal. 716 */ 717 int mAdjSeq = 0; 718 719 /** 720 * Current sequence id for process LRU updating. 721 */ 722 int mLruSeq = 0; 723 724 /** 725 * Keep track of the non-hidden/empty process we last found, to help 726 * determine how to distribute hidden/empty processes next time. 727 */ 728 int mNumNonHiddenProcs = 0; 729 730 /** 731 * Keep track of the number of hidden procs, to balance oom adj 732 * distribution between those and empty procs. 733 */ 734 int mNumHiddenProcs = 0; 735 736 /** 737 * Keep track of the number of service processes we last found, to 738 * determine on the next iteration which should be B services. 739 */ 740 int mNumServiceProcs = 0; 741 int mNewNumServiceProcs = 0; 742 743 /** 744 * System monitoring: number of processes that died since the last 745 * N procs were started. 746 */ 747 int[] mProcDeaths = new int[20]; 748 749 /** 750 * This is set if we had to do a delayed dexopt of an app before launching 751 * it, to increasing the ANR timeouts in that case. 752 */ 753 boolean mDidDexOpt; 754 755 String mDebugApp = null; 756 boolean mWaitForDebugger = false; 757 boolean mDebugTransient = false; 758 String mOrigDebugApp = null; 759 boolean mOrigWaitForDebugger = false; 760 boolean mAlwaysFinishActivities = false; 761 IActivityController mController = null; 762 String mProfileApp = null; 763 ProcessRecord mProfileProc = null; 764 String mProfileFile; 765 ParcelFileDescriptor mProfileFd; 766 int mProfileType = 0; 767 boolean mAutoStopProfiler = false; 768 String mOpenGlTraceApp = null; 769 770 static class ProcessChangeItem { 771 static final int CHANGE_ACTIVITIES = 1<<0; 772 static final int CHANGE_IMPORTANCE= 1<<1; 773 int changes; 774 int uid; 775 int pid; 776 int importance; 777 boolean foregroundActivities; 778 } 779 780 final RemoteCallbackList<IProcessObserver> mProcessObservers 781 = new RemoteCallbackList<IProcessObserver>(); 782 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 783 784 final ArrayList<ProcessChangeItem> mPendingProcessChanges 785 = new ArrayList<ProcessChangeItem>(); 786 final ArrayList<ProcessChangeItem> mAvailProcessChanges 787 = new ArrayList<ProcessChangeItem>(); 788 789 /** 790 * Callback of last caller to {@link #requestPss}. 791 */ 792 Runnable mRequestPssCallback; 793 794 /** 795 * Remaining processes for which we are waiting results from the last 796 * call to {@link #requestPss}. 797 */ 798 final ArrayList<ProcessRecord> mRequestPssList 799 = new ArrayList<ProcessRecord>(); 800 801 /** 802 * Runtime statistics collection thread. This object's lock is used to 803 * protect all related state. 804 */ 805 final Thread mProcessStatsThread; 806 807 /** 808 * Used to collect process stats when showing not responding dialog. 809 * Protected by mProcessStatsThread. 810 */ 811 final ProcessStats mProcessStats = new ProcessStats( 812 MONITOR_THREAD_CPU_USAGE); 813 final AtomicLong mLastCpuTime = new AtomicLong(0); 814 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 815 816 long mLastWriteTime = 0; 817 818 /** 819 * Set to true after the system has finished booting. 820 */ 821 boolean mBooted = false; 822 823 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 824 int mProcessLimitOverride = -1; 825 826 WindowManagerService mWindowManager; 827 828 static ActivityManagerService mSelf; 829 static ActivityThread mSystemThread; 830 831 private int mCurrentUserId; 832 private UserManagerService mUserManager; 833 834 private final class AppDeathRecipient implements IBinder.DeathRecipient { 835 final ProcessRecord mApp; 836 final int mPid; 837 final IApplicationThread mAppThread; 838 839 AppDeathRecipient(ProcessRecord app, int pid, 840 IApplicationThread thread) { 841 if (localLOGV) Slog.v( 842 TAG, "New death recipient " + this 843 + " for thread " + thread.asBinder()); 844 mApp = app; 845 mPid = pid; 846 mAppThread = thread; 847 } 848 849 public void binderDied() { 850 if (localLOGV) Slog.v( 851 TAG, "Death received in " + this 852 + " for thread " + mAppThread.asBinder()); 853 synchronized(ActivityManagerService.this) { 854 appDiedLocked(mApp, mPid, mAppThread); 855 } 856 } 857 } 858 859 static final int SHOW_ERROR_MSG = 1; 860 static final int SHOW_NOT_RESPONDING_MSG = 2; 861 static final int SHOW_FACTORY_ERROR_MSG = 3; 862 static final int UPDATE_CONFIGURATION_MSG = 4; 863 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 864 static final int WAIT_FOR_DEBUGGER_MSG = 6; 865 static final int SERVICE_TIMEOUT_MSG = 12; 866 static final int UPDATE_TIME_ZONE = 13; 867 static final int SHOW_UID_ERROR_MSG = 14; 868 static final int IM_FEELING_LUCKY_MSG = 15; 869 static final int PROC_START_TIMEOUT_MSG = 20; 870 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 871 static final int KILL_APPLICATION_MSG = 22; 872 static final int FINALIZE_PENDING_INTENT_MSG = 23; 873 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 874 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 875 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 876 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 877 static final int CLEAR_DNS_CACHE = 28; 878 static final int UPDATE_HTTP_PROXY = 29; 879 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 880 static final int DISPATCH_PROCESSES_CHANGED = 31; 881 static final int DISPATCH_PROCESS_DIED = 32; 882 static final int REPORT_MEM_USAGE = 33; 883 static final int REPORT_USER_SWITCH_MSG = 34; 884 static final int CONTINUE_USER_SWITCH_MSG = 35; 885 static final int USER_SWITCH_TIMEOUT_MSG = 36; 886 887 static final int FIRST_ACTIVITY_STACK_MSG = 100; 888 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 889 static final int FIRST_COMPAT_MODE_MSG = 300; 890 891 AlertDialog mUidAlert; 892 CompatModeDialog mCompatModeDialog; 893 long mLastMemUsageReportTime = 0; 894 895 final Handler mHandler = new Handler() { 896 //public Handler() { 897 // if (localLOGV) Slog.v(TAG, "Handler started!"); 898 //} 899 900 public void handleMessage(Message msg) { 901 switch (msg.what) { 902 case SHOW_ERROR_MSG: { 903 HashMap data = (HashMap) msg.obj; 904 synchronized (ActivityManagerService.this) { 905 ProcessRecord proc = (ProcessRecord)data.get("app"); 906 if (proc != null && proc.crashDialog != null) { 907 Slog.e(TAG, "App already has crash dialog: " + proc); 908 return; 909 } 910 AppErrorResult res = (AppErrorResult) data.get("result"); 911 if (mShowDialogs && !mSleeping && !mShuttingDown) { 912 Dialog d = new AppErrorDialog(mContext, res, proc); 913 d.show(); 914 proc.crashDialog = d; 915 } else { 916 // The device is asleep, so just pretend that the user 917 // saw a crash dialog and hit "force quit". 918 res.set(0); 919 } 920 } 921 922 ensureBootCompleted(); 923 } break; 924 case SHOW_NOT_RESPONDING_MSG: { 925 synchronized (ActivityManagerService.this) { 926 HashMap data = (HashMap) msg.obj; 927 ProcessRecord proc = (ProcessRecord)data.get("app"); 928 if (proc != null && proc.anrDialog != null) { 929 Slog.e(TAG, "App already has anr dialog: " + proc); 930 return; 931 } 932 933 Intent intent = new Intent("android.intent.action.ANR"); 934 if (!mProcessesReady) { 935 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 936 | Intent.FLAG_RECEIVER_FOREGROUND); 937 } 938 broadcastIntentLocked(null, null, intent, 939 null, null, 0, null, null, null, 940 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 941 942 if (mShowDialogs) { 943 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 944 mContext, proc, (ActivityRecord)data.get("activity")); 945 d.show(); 946 proc.anrDialog = d; 947 } else { 948 // Just kill the app if there is no dialog to be shown. 949 killAppAtUsersRequest(proc, null); 950 } 951 } 952 953 ensureBootCompleted(); 954 } break; 955 case SHOW_STRICT_MODE_VIOLATION_MSG: { 956 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 957 synchronized (ActivityManagerService.this) { 958 ProcessRecord proc = (ProcessRecord) data.get("app"); 959 if (proc == null) { 960 Slog.e(TAG, "App not found when showing strict mode dialog."); 961 break; 962 } 963 if (proc.crashDialog != null) { 964 Slog.e(TAG, "App already has strict mode dialog: " + proc); 965 return; 966 } 967 AppErrorResult res = (AppErrorResult) data.get("result"); 968 if (mShowDialogs && !mSleeping && !mShuttingDown) { 969 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 970 d.show(); 971 proc.crashDialog = d; 972 } else { 973 // The device is asleep, so just pretend that the user 974 // saw a crash dialog and hit "force quit". 975 res.set(0); 976 } 977 } 978 ensureBootCompleted(); 979 } break; 980 case SHOW_FACTORY_ERROR_MSG: { 981 Dialog d = new FactoryErrorDialog( 982 mContext, msg.getData().getCharSequence("msg")); 983 d.show(); 984 ensureBootCompleted(); 985 } break; 986 case UPDATE_CONFIGURATION_MSG: { 987 final ContentResolver resolver = mContext.getContentResolver(); 988 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 989 } break; 990 case GC_BACKGROUND_PROCESSES_MSG: { 991 synchronized (ActivityManagerService.this) { 992 performAppGcsIfAppropriateLocked(); 993 } 994 } break; 995 case WAIT_FOR_DEBUGGER_MSG: { 996 synchronized (ActivityManagerService.this) { 997 ProcessRecord app = (ProcessRecord)msg.obj; 998 if (msg.arg1 != 0) { 999 if (!app.waitedForDebugger) { 1000 Dialog d = new AppWaitingForDebuggerDialog( 1001 ActivityManagerService.this, 1002 mContext, app); 1003 app.waitDialog = d; 1004 app.waitedForDebugger = true; 1005 d.show(); 1006 } 1007 } else { 1008 if (app.waitDialog != null) { 1009 app.waitDialog.dismiss(); 1010 app.waitDialog = null; 1011 } 1012 } 1013 } 1014 } break; 1015 case SERVICE_TIMEOUT_MSG: { 1016 if (mDidDexOpt) { 1017 mDidDexOpt = false; 1018 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1019 nmsg.obj = msg.obj; 1020 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1021 return; 1022 } 1023 mServices.serviceTimeout((ProcessRecord)msg.obj); 1024 } break; 1025 case UPDATE_TIME_ZONE: { 1026 synchronized (ActivityManagerService.this) { 1027 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1028 ProcessRecord r = mLruProcesses.get(i); 1029 if (r.thread != null) { 1030 try { 1031 r.thread.updateTimeZone(); 1032 } catch (RemoteException ex) { 1033 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1034 } 1035 } 1036 } 1037 } 1038 } break; 1039 case CLEAR_DNS_CACHE: { 1040 synchronized (ActivityManagerService.this) { 1041 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1042 ProcessRecord r = mLruProcesses.get(i); 1043 if (r.thread != null) { 1044 try { 1045 r.thread.clearDnsCache(); 1046 } catch (RemoteException ex) { 1047 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1048 } 1049 } 1050 } 1051 } 1052 } break; 1053 case UPDATE_HTTP_PROXY: { 1054 ProxyProperties proxy = (ProxyProperties)msg.obj; 1055 String host = ""; 1056 String port = ""; 1057 String exclList = ""; 1058 if (proxy != null) { 1059 host = proxy.getHost(); 1060 port = Integer.toString(proxy.getPort()); 1061 exclList = proxy.getExclusionList(); 1062 } 1063 synchronized (ActivityManagerService.this) { 1064 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1065 ProcessRecord r = mLruProcesses.get(i); 1066 if (r.thread != null) { 1067 try { 1068 r.thread.setHttpProxy(host, port, exclList); 1069 } catch (RemoteException ex) { 1070 Slog.w(TAG, "Failed to update http proxy for: " + 1071 r.info.processName); 1072 } 1073 } 1074 } 1075 } 1076 } break; 1077 case SHOW_UID_ERROR_MSG: { 1078 String title = "System UIDs Inconsistent"; 1079 String text = "UIDs on the system are inconsistent, you need to wipe your" 1080 + " data partition or your device will be unstable."; 1081 Log.e(TAG, title + ": " + text); 1082 if (mShowDialogs) { 1083 // XXX This is a temporary dialog, no need to localize. 1084 AlertDialog d = new BaseErrorDialog(mContext); 1085 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1086 d.setCancelable(false); 1087 d.setTitle(title); 1088 d.setMessage(text); 1089 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1090 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1091 mUidAlert = d; 1092 d.show(); 1093 } 1094 } break; 1095 case IM_FEELING_LUCKY_MSG: { 1096 if (mUidAlert != null) { 1097 mUidAlert.dismiss(); 1098 mUidAlert = null; 1099 } 1100 } break; 1101 case PROC_START_TIMEOUT_MSG: { 1102 if (mDidDexOpt) { 1103 mDidDexOpt = false; 1104 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1105 nmsg.obj = msg.obj; 1106 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1107 return; 1108 } 1109 ProcessRecord app = (ProcessRecord)msg.obj; 1110 synchronized (ActivityManagerService.this) { 1111 processStartTimedOutLocked(app); 1112 } 1113 } break; 1114 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1115 synchronized (ActivityManagerService.this) { 1116 doPendingActivityLaunchesLocked(true); 1117 } 1118 } break; 1119 case KILL_APPLICATION_MSG: { 1120 synchronized (ActivityManagerService.this) { 1121 int appid = msg.arg1; 1122 boolean restart = (msg.arg2 == 1); 1123 String pkg = (String) msg.obj; 1124 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1125 UserHandle.USER_ALL); 1126 } 1127 } break; 1128 case FINALIZE_PENDING_INTENT_MSG: { 1129 ((PendingIntentRecord)msg.obj).completeFinalize(); 1130 } break; 1131 case POST_HEAVY_NOTIFICATION_MSG: { 1132 INotificationManager inm = NotificationManager.getService(); 1133 if (inm == null) { 1134 return; 1135 } 1136 1137 ActivityRecord root = (ActivityRecord)msg.obj; 1138 ProcessRecord process = root.app; 1139 if (process == null) { 1140 return; 1141 } 1142 1143 try { 1144 Context context = mContext.createPackageContext(process.info.packageName, 0); 1145 String text = mContext.getString(R.string.heavy_weight_notification, 1146 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1147 Notification notification = new Notification(); 1148 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1149 notification.when = 0; 1150 notification.flags = Notification.FLAG_ONGOING_EVENT; 1151 notification.tickerText = text; 1152 notification.defaults = 0; // please be quiet 1153 notification.sound = null; 1154 notification.vibrate = null; 1155 notification.setLatestEventInfo(context, text, 1156 mContext.getText(R.string.heavy_weight_notification_detail), 1157 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1158 PendingIntent.FLAG_CANCEL_CURRENT, null, 1159 new UserHandle(root.userId))); 1160 1161 try { 1162 int[] outId = new int[1]; 1163 inm.enqueueNotificationWithTag("android", null, 1164 R.string.heavy_weight_notification, 1165 notification, outId, root.userId); 1166 } catch (RuntimeException e) { 1167 Slog.w(ActivityManagerService.TAG, 1168 "Error showing notification for heavy-weight app", e); 1169 } catch (RemoteException e) { 1170 } 1171 } catch (NameNotFoundException e) { 1172 Slog.w(TAG, "Unable to create context for heavy notification", e); 1173 } 1174 } break; 1175 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1176 INotificationManager inm = NotificationManager.getService(); 1177 if (inm == null) { 1178 return; 1179 } 1180 try { 1181 inm.cancelNotificationWithTag("android", null, 1182 R.string.heavy_weight_notification, msg.arg1); 1183 } catch (RuntimeException e) { 1184 Slog.w(ActivityManagerService.TAG, 1185 "Error canceling notification for service", e); 1186 } catch (RemoteException e) { 1187 } 1188 } break; 1189 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1190 synchronized (ActivityManagerService.this) { 1191 checkExcessivePowerUsageLocked(true); 1192 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1193 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1194 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1195 } 1196 } break; 1197 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1198 synchronized (ActivityManagerService.this) { 1199 ActivityRecord ar = (ActivityRecord)msg.obj; 1200 if (mCompatModeDialog != null) { 1201 if (mCompatModeDialog.mAppInfo.packageName.equals( 1202 ar.info.applicationInfo.packageName)) { 1203 return; 1204 } 1205 mCompatModeDialog.dismiss(); 1206 mCompatModeDialog = null; 1207 } 1208 if (ar != null && false) { 1209 if (mCompatModePackages.getPackageAskCompatModeLocked( 1210 ar.packageName)) { 1211 int mode = mCompatModePackages.computeCompatModeLocked( 1212 ar.info.applicationInfo); 1213 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1214 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1215 mCompatModeDialog = new CompatModeDialog( 1216 ActivityManagerService.this, mContext, 1217 ar.info.applicationInfo); 1218 mCompatModeDialog.show(); 1219 } 1220 } 1221 } 1222 } 1223 break; 1224 } 1225 case DISPATCH_PROCESSES_CHANGED: { 1226 dispatchProcessesChanged(); 1227 break; 1228 } 1229 case DISPATCH_PROCESS_DIED: { 1230 final int pid = msg.arg1; 1231 final int uid = msg.arg2; 1232 dispatchProcessDied(pid, uid); 1233 break; 1234 } 1235 case REPORT_MEM_USAGE: { 1236 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1237 if (!isDebuggable) { 1238 return; 1239 } 1240 synchronized (ActivityManagerService.this) { 1241 long now = SystemClock.uptimeMillis(); 1242 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1243 // Don't report more than every 5 minutes to somewhat 1244 // avoid spamming. 1245 return; 1246 } 1247 mLastMemUsageReportTime = now; 1248 } 1249 Thread thread = new Thread() { 1250 @Override public void run() { 1251 StringBuilder dropBuilder = new StringBuilder(1024); 1252 StringBuilder logBuilder = new StringBuilder(1024); 1253 StringWriter oomSw = new StringWriter(); 1254 PrintWriter oomPw = new PrintWriter(oomSw); 1255 StringWriter catSw = new StringWriter(); 1256 PrintWriter catPw = new PrintWriter(catSw); 1257 String[] emptyArgs = new String[] { }; 1258 StringBuilder tag = new StringBuilder(128); 1259 StringBuilder stack = new StringBuilder(128); 1260 tag.append("Low on memory -- "); 1261 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1262 tag, stack); 1263 dropBuilder.append(stack); 1264 dropBuilder.append('\n'); 1265 dropBuilder.append('\n'); 1266 String oomString = oomSw.toString(); 1267 dropBuilder.append(oomString); 1268 dropBuilder.append('\n'); 1269 logBuilder.append(oomString); 1270 try { 1271 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1272 "procrank", }); 1273 final InputStreamReader converter = new InputStreamReader( 1274 proc.getInputStream()); 1275 BufferedReader in = new BufferedReader(converter); 1276 String line; 1277 while (true) { 1278 line = in.readLine(); 1279 if (line == null) { 1280 break; 1281 } 1282 if (line.length() > 0) { 1283 logBuilder.append(line); 1284 logBuilder.append('\n'); 1285 } 1286 dropBuilder.append(line); 1287 dropBuilder.append('\n'); 1288 } 1289 converter.close(); 1290 } catch (IOException e) { 1291 } 1292 synchronized (ActivityManagerService.this) { 1293 catPw.println(); 1294 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1295 catPw.println(); 1296 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1297 false, false, null); 1298 catPw.println(); 1299 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1300 } 1301 dropBuilder.append(catSw.toString()); 1302 addErrorToDropBox("lowmem", null, "system_server", null, 1303 null, tag.toString(), dropBuilder.toString(), null, null); 1304 Slog.i(TAG, logBuilder.toString()); 1305 synchronized (ActivityManagerService.this) { 1306 long now = SystemClock.uptimeMillis(); 1307 if (mLastMemUsageReportTime < now) { 1308 mLastMemUsageReportTime = now; 1309 } 1310 } 1311 } 1312 }; 1313 thread.start(); 1314 break; 1315 } 1316 case REPORT_USER_SWITCH_MSG: { 1317 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1318 break; 1319 } 1320 case CONTINUE_USER_SWITCH_MSG: { 1321 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1322 break; 1323 } 1324 case USER_SWITCH_TIMEOUT_MSG: { 1325 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1326 break; 1327 } 1328 } 1329 } 1330 }; 1331 1332 public static void setSystemProcess() { 1333 try { 1334 ActivityManagerService m = mSelf; 1335 1336 ServiceManager.addService("activity", m, true); 1337 ServiceManager.addService("meminfo", new MemBinder(m)); 1338 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1339 ServiceManager.addService("dbinfo", new DbBinder(m)); 1340 if (MONITOR_CPU_USAGE) { 1341 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1342 } 1343 ServiceManager.addService("permission", new PermissionController(m)); 1344 1345 ApplicationInfo info = 1346 mSelf.mContext.getPackageManager().getApplicationInfo( 1347 "android", STOCK_PM_FLAGS); 1348 mSystemThread.installSystemApplicationInfo(info); 1349 1350 synchronized (mSelf) { 1351 ProcessRecord app = mSelf.newProcessRecordLocked( 1352 mSystemThread.getApplicationThread(), info, 1353 info.processName, false); 1354 app.persistent = true; 1355 app.pid = MY_PID; 1356 app.maxAdj = ProcessList.SYSTEM_ADJ; 1357 mSelf.mProcessNames.put(app.processName, app.uid, app); 1358 synchronized (mSelf.mPidsSelfLocked) { 1359 mSelf.mPidsSelfLocked.put(app.pid, app); 1360 } 1361 mSelf.updateLruProcessLocked(app, true, true); 1362 } 1363 } catch (PackageManager.NameNotFoundException e) { 1364 throw new RuntimeException( 1365 "Unable to find android system package", e); 1366 } 1367 } 1368 1369 public void setWindowManager(WindowManagerService wm) { 1370 mWindowManager = wm; 1371 } 1372 1373 public static final Context main(int factoryTest) { 1374 AThread thr = new AThread(); 1375 thr.start(); 1376 1377 synchronized (thr) { 1378 while (thr.mService == null) { 1379 try { 1380 thr.wait(); 1381 } catch (InterruptedException e) { 1382 } 1383 } 1384 } 1385 1386 ActivityManagerService m = thr.mService; 1387 mSelf = m; 1388 ActivityThread at = ActivityThread.systemMain(); 1389 mSystemThread = at; 1390 Context context = at.getSystemContext(); 1391 context.setTheme(android.R.style.Theme_Holo); 1392 m.mContext = context; 1393 m.mFactoryTest = factoryTest; 1394 m.mMainStack = new ActivityStack(m, context, true); 1395 1396 m.mBatteryStatsService.publish(context); 1397 m.mUsageStatsService.publish(context); 1398 1399 synchronized (thr) { 1400 thr.mReady = true; 1401 thr.notifyAll(); 1402 } 1403 1404 m.startRunning(null, null, null, null); 1405 1406 return context; 1407 } 1408 1409 public static ActivityManagerService self() { 1410 return mSelf; 1411 } 1412 1413 static class AThread extends Thread { 1414 ActivityManagerService mService; 1415 boolean mReady = false; 1416 1417 public AThread() { 1418 super("ActivityManager"); 1419 } 1420 1421 public void run() { 1422 Looper.prepare(); 1423 1424 android.os.Process.setThreadPriority( 1425 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1426 android.os.Process.setCanSelfBackground(false); 1427 1428 ActivityManagerService m = new ActivityManagerService(); 1429 1430 synchronized (this) { 1431 mService = m; 1432 notifyAll(); 1433 } 1434 1435 synchronized (this) { 1436 while (!mReady) { 1437 try { 1438 wait(); 1439 } catch (InterruptedException e) { 1440 } 1441 } 1442 } 1443 1444 // For debug builds, log event loop stalls to dropbox for analysis. 1445 if (StrictMode.conditionallyEnableDebugLogging()) { 1446 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1447 } 1448 1449 Looper.loop(); 1450 } 1451 } 1452 1453 static class MemBinder extends Binder { 1454 ActivityManagerService mActivityManagerService; 1455 MemBinder(ActivityManagerService activityManagerService) { 1456 mActivityManagerService = activityManagerService; 1457 } 1458 1459 @Override 1460 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1461 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1462 != PackageManager.PERMISSION_GRANTED) { 1463 pw.println("Permission Denial: can't dump meminfo from from pid=" 1464 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1465 + " without permission " + android.Manifest.permission.DUMP); 1466 return; 1467 } 1468 1469 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1470 false, null, null, null); 1471 } 1472 } 1473 1474 static class GraphicsBinder extends Binder { 1475 ActivityManagerService mActivityManagerService; 1476 GraphicsBinder(ActivityManagerService activityManagerService) { 1477 mActivityManagerService = activityManagerService; 1478 } 1479 1480 @Override 1481 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1482 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1483 != PackageManager.PERMISSION_GRANTED) { 1484 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1485 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1486 + " without permission " + android.Manifest.permission.DUMP); 1487 return; 1488 } 1489 1490 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1491 } 1492 } 1493 1494 static class DbBinder extends Binder { 1495 ActivityManagerService mActivityManagerService; 1496 DbBinder(ActivityManagerService activityManagerService) { 1497 mActivityManagerService = activityManagerService; 1498 } 1499 1500 @Override 1501 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1502 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1503 != PackageManager.PERMISSION_GRANTED) { 1504 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1505 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1506 + " without permission " + android.Manifest.permission.DUMP); 1507 return; 1508 } 1509 1510 mActivityManagerService.dumpDbInfo(fd, pw, args); 1511 } 1512 } 1513 1514 static class CpuBinder extends Binder { 1515 ActivityManagerService mActivityManagerService; 1516 CpuBinder(ActivityManagerService activityManagerService) { 1517 mActivityManagerService = activityManagerService; 1518 } 1519 1520 @Override 1521 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1522 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1523 != PackageManager.PERMISSION_GRANTED) { 1524 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1525 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1526 + " without permission " + android.Manifest.permission.DUMP); 1527 return; 1528 } 1529 1530 synchronized (mActivityManagerService.mProcessStatsThread) { 1531 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1532 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1533 SystemClock.uptimeMillis())); 1534 } 1535 } 1536 } 1537 1538 private ActivityManagerService() { 1539 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1540 1541 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1542 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1543 mBroadcastQueues[0] = mFgBroadcastQueue; 1544 mBroadcastQueues[1] = mBgBroadcastQueue; 1545 1546 mServices = new ActiveServices(this); 1547 mProviderMap = new ProviderMap(this); 1548 1549 File dataDir = Environment.getDataDirectory(); 1550 File systemDir = new File(dataDir, "system"); 1551 systemDir.mkdirs(); 1552 mBatteryStatsService = new BatteryStatsService(new File( 1553 systemDir, "batterystats.bin").toString()); 1554 mBatteryStatsService.getActiveStatistics().readLocked(); 1555 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1556 mOnBattery = DEBUG_POWER ? true 1557 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1558 mBatteryStatsService.getActiveStatistics().setCallback(this); 1559 1560 mUsageStatsService = new UsageStatsService(new File( 1561 systemDir, "usagestats").toString()); 1562 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1563 1564 // User 0 is the first and only user that runs at boot. 1565 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1566 mUserLru.add(Integer.valueOf(0)); 1567 1568 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1569 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1570 1571 mConfiguration.setToDefaults(); 1572 mConfiguration.setLocale(Locale.getDefault()); 1573 1574 mConfigurationSeq = mConfiguration.seq = 1; 1575 mProcessStats.init(); 1576 1577 mCompatModePackages = new CompatModePackages(this, systemDir); 1578 1579 // Add ourself to the Watchdog monitors. 1580 Watchdog.getInstance().addMonitor(this); 1581 1582 mProcessStatsThread = new Thread("ProcessStats") { 1583 public void run() { 1584 while (true) { 1585 try { 1586 try { 1587 synchronized(this) { 1588 final long now = SystemClock.uptimeMillis(); 1589 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1590 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1591 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1592 // + ", write delay=" + nextWriteDelay); 1593 if (nextWriteDelay < nextCpuDelay) { 1594 nextCpuDelay = nextWriteDelay; 1595 } 1596 if (nextCpuDelay > 0) { 1597 mProcessStatsMutexFree.set(true); 1598 this.wait(nextCpuDelay); 1599 } 1600 } 1601 } catch (InterruptedException e) { 1602 } 1603 updateCpuStatsNow(); 1604 } catch (Exception e) { 1605 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1606 } 1607 } 1608 } 1609 }; 1610 mProcessStatsThread.start(); 1611 } 1612 1613 @Override 1614 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1615 throws RemoteException { 1616 if (code == SYSPROPS_TRANSACTION) { 1617 // We need to tell all apps about the system property change. 1618 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1619 synchronized(this) { 1620 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1621 final int NA = apps.size(); 1622 for (int ia=0; ia<NA; ia++) { 1623 ProcessRecord app = apps.valueAt(ia); 1624 if (app.thread != null) { 1625 procs.add(app.thread.asBinder()); 1626 } 1627 } 1628 } 1629 } 1630 1631 int N = procs.size(); 1632 for (int i=0; i<N; i++) { 1633 Parcel data2 = Parcel.obtain(); 1634 try { 1635 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1636 } catch (RemoteException e) { 1637 } 1638 data2.recycle(); 1639 } 1640 } 1641 try { 1642 return super.onTransact(code, data, reply, flags); 1643 } catch (RuntimeException e) { 1644 // The activity manager only throws security exceptions, so let's 1645 // log all others. 1646 if (!(e instanceof SecurityException)) { 1647 Slog.e(TAG, "Activity Manager Crash", e); 1648 } 1649 throw e; 1650 } 1651 } 1652 1653 void updateCpuStats() { 1654 final long now = SystemClock.uptimeMillis(); 1655 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1656 return; 1657 } 1658 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1659 synchronized (mProcessStatsThread) { 1660 mProcessStatsThread.notify(); 1661 } 1662 } 1663 } 1664 1665 void updateCpuStatsNow() { 1666 synchronized (mProcessStatsThread) { 1667 mProcessStatsMutexFree.set(false); 1668 final long now = SystemClock.uptimeMillis(); 1669 boolean haveNewCpuStats = false; 1670 1671 if (MONITOR_CPU_USAGE && 1672 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1673 mLastCpuTime.set(now); 1674 haveNewCpuStats = true; 1675 mProcessStats.update(); 1676 //Slog.i(TAG, mProcessStats.printCurrentState()); 1677 //Slog.i(TAG, "Total CPU usage: " 1678 // + mProcessStats.getTotalCpuPercent() + "%"); 1679 1680 // Slog the cpu usage if the property is set. 1681 if ("true".equals(SystemProperties.get("events.cpu"))) { 1682 int user = mProcessStats.getLastUserTime(); 1683 int system = mProcessStats.getLastSystemTime(); 1684 int iowait = mProcessStats.getLastIoWaitTime(); 1685 int irq = mProcessStats.getLastIrqTime(); 1686 int softIrq = mProcessStats.getLastSoftIrqTime(); 1687 int idle = mProcessStats.getLastIdleTime(); 1688 1689 int total = user + system + iowait + irq + softIrq + idle; 1690 if (total == 0) total = 1; 1691 1692 EventLog.writeEvent(EventLogTags.CPU, 1693 ((user+system+iowait+irq+softIrq) * 100) / total, 1694 (user * 100) / total, 1695 (system * 100) / total, 1696 (iowait * 100) / total, 1697 (irq * 100) / total, 1698 (softIrq * 100) / total); 1699 } 1700 } 1701 1702 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1703 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1704 synchronized(bstats) { 1705 synchronized(mPidsSelfLocked) { 1706 if (haveNewCpuStats) { 1707 if (mOnBattery) { 1708 int perc = bstats.startAddingCpuLocked(); 1709 int totalUTime = 0; 1710 int totalSTime = 0; 1711 final int N = mProcessStats.countStats(); 1712 for (int i=0; i<N; i++) { 1713 ProcessStats.Stats st = mProcessStats.getStats(i); 1714 if (!st.working) { 1715 continue; 1716 } 1717 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1718 int otherUTime = (st.rel_utime*perc)/100; 1719 int otherSTime = (st.rel_stime*perc)/100; 1720 totalUTime += otherUTime; 1721 totalSTime += otherSTime; 1722 if (pr != null) { 1723 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1724 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1725 st.rel_stime-otherSTime); 1726 ps.addSpeedStepTimes(cpuSpeedTimes); 1727 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1728 } else { 1729 BatteryStatsImpl.Uid.Proc ps = 1730 bstats.getProcessStatsLocked(st.name, st.pid); 1731 if (ps != null) { 1732 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1733 st.rel_stime-otherSTime); 1734 ps.addSpeedStepTimes(cpuSpeedTimes); 1735 } 1736 } 1737 } 1738 bstats.finishAddingCpuLocked(perc, totalUTime, 1739 totalSTime, cpuSpeedTimes); 1740 } 1741 } 1742 } 1743 1744 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1745 mLastWriteTime = now; 1746 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1747 } 1748 } 1749 } 1750 } 1751 1752 @Override 1753 public void batteryNeedsCpuUpdate() { 1754 updateCpuStatsNow(); 1755 } 1756 1757 @Override 1758 public void batteryPowerChanged(boolean onBattery) { 1759 // When plugging in, update the CPU stats first before changing 1760 // the plug state. 1761 updateCpuStatsNow(); 1762 synchronized (this) { 1763 synchronized(mPidsSelfLocked) { 1764 mOnBattery = DEBUG_POWER ? true : onBattery; 1765 } 1766 } 1767 } 1768 1769 /** 1770 * Initialize the application bind args. These are passed to each 1771 * process when the bindApplication() IPC is sent to the process. They're 1772 * lazily setup to make sure the services are running when they're asked for. 1773 */ 1774 private HashMap<String, IBinder> getCommonServicesLocked() { 1775 if (mAppBindArgs == null) { 1776 mAppBindArgs = new HashMap<String, IBinder>(); 1777 1778 // Setup the application init args 1779 mAppBindArgs.put("package", ServiceManager.getService("package")); 1780 mAppBindArgs.put("window", ServiceManager.getService("window")); 1781 mAppBindArgs.put(Context.ALARM_SERVICE, 1782 ServiceManager.getService(Context.ALARM_SERVICE)); 1783 } 1784 return mAppBindArgs; 1785 } 1786 1787 final void setFocusedActivityLocked(ActivityRecord r) { 1788 if (mFocusedActivity != r) { 1789 mFocusedActivity = r; 1790 if (r != null) { 1791 mWindowManager.setFocusedApp(r.appToken, true); 1792 } 1793 } 1794 } 1795 1796 private final void updateLruProcessInternalLocked(ProcessRecord app, 1797 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1798 // put it on the LRU to keep track of when it should be exited. 1799 int lrui = mLruProcesses.indexOf(app); 1800 if (lrui >= 0) mLruProcesses.remove(lrui); 1801 1802 int i = mLruProcesses.size()-1; 1803 int skipTop = 0; 1804 1805 app.lruSeq = mLruSeq; 1806 1807 // compute the new weight for this process. 1808 if (updateActivityTime) { 1809 app.lastActivityTime = SystemClock.uptimeMillis(); 1810 } 1811 if (app.activities.size() > 0) { 1812 // If this process has activities, we more strongly want to keep 1813 // it around. 1814 app.lruWeight = app.lastActivityTime; 1815 } else if (app.pubProviders.size() > 0) { 1816 // If this process contains content providers, we want to keep 1817 // it a little more strongly. 1818 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1819 // Also don't let it kick out the first few "real" hidden processes. 1820 skipTop = ProcessList.MIN_HIDDEN_APPS; 1821 } else { 1822 // If this process doesn't have activities, we less strongly 1823 // want to keep it around, and generally want to avoid getting 1824 // in front of any very recently used activities. 1825 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1826 // Also don't let it kick out the first few "real" hidden processes. 1827 skipTop = ProcessList.MIN_HIDDEN_APPS; 1828 } 1829 1830 while (i >= 0) { 1831 ProcessRecord p = mLruProcesses.get(i); 1832 // If this app shouldn't be in front of the first N background 1833 // apps, then skip over that many that are currently hidden. 1834 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1835 skipTop--; 1836 } 1837 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1838 mLruProcesses.add(i+1, app); 1839 break; 1840 } 1841 i--; 1842 } 1843 if (i < 0) { 1844 mLruProcesses.add(0, app); 1845 } 1846 1847 // If the app is currently using a content provider or service, 1848 // bump those processes as well. 1849 if (app.connections.size() > 0) { 1850 for (ConnectionRecord cr : app.connections) { 1851 if (cr.binding != null && cr.binding.service != null 1852 && cr.binding.service.app != null 1853 && cr.binding.service.app.lruSeq != mLruSeq) { 1854 updateLruProcessInternalLocked(cr.binding.service.app, false, 1855 updateActivityTime, i+1); 1856 } 1857 } 1858 } 1859 for (int j=app.conProviders.size()-1; j>=0; j--) { 1860 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1861 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1862 updateLruProcessInternalLocked(cpr.proc, false, 1863 updateActivityTime, i+1); 1864 } 1865 } 1866 1867 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1868 if (oomAdj) { 1869 updateOomAdjLocked(); 1870 } 1871 } 1872 1873 final void updateLruProcessLocked(ProcessRecord app, 1874 boolean oomAdj, boolean updateActivityTime) { 1875 mLruSeq++; 1876 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1877 } 1878 1879 final ProcessRecord getProcessRecordLocked( 1880 String processName, int uid) { 1881 if (uid == Process.SYSTEM_UID) { 1882 // The system gets to run in any process. If there are multiple 1883 // processes with the same uid, just pick the first (this 1884 // should never happen). 1885 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1886 processName); 1887 if (procs == null) return null; 1888 final int N = procs.size(); 1889 for (int i = 0; i < N; i++) { 1890 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1891 } 1892 } 1893 ProcessRecord proc = mProcessNames.get(processName, uid); 1894 return proc; 1895 } 1896 1897 void ensurePackageDexOpt(String packageName) { 1898 IPackageManager pm = AppGlobals.getPackageManager(); 1899 try { 1900 if (pm.performDexOpt(packageName)) { 1901 mDidDexOpt = true; 1902 } 1903 } catch (RemoteException e) { 1904 } 1905 } 1906 1907 boolean isNextTransitionForward() { 1908 int transit = mWindowManager.getPendingAppTransition(); 1909 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1910 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1911 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1912 } 1913 1914 final ProcessRecord startProcessLocked(String processName, 1915 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1916 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1917 boolean isolated) { 1918 ProcessRecord app; 1919 if (!isolated) { 1920 app = getProcessRecordLocked(processName, info.uid); 1921 } else { 1922 // If this is an isolated process, it can't re-use an existing process. 1923 app = null; 1924 } 1925 // We don't have to do anything more if: 1926 // (1) There is an existing application record; and 1927 // (2) The caller doesn't think it is dead, OR there is no thread 1928 // object attached to it so we know it couldn't have crashed; and 1929 // (3) There is a pid assigned to it, so it is either starting or 1930 // already running. 1931 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1932 + " app=" + app + " knownToBeDead=" + knownToBeDead 1933 + " thread=" + (app != null ? app.thread : null) 1934 + " pid=" + (app != null ? app.pid : -1)); 1935 if (app != null && app.pid > 0) { 1936 if (!knownToBeDead || app.thread == null) { 1937 // We already have the app running, or are waiting for it to 1938 // come up (we have a pid but not yet its thread), so keep it. 1939 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1940 // If this is a new package in the process, add the package to the list 1941 app.addPackage(info.packageName); 1942 return app; 1943 } else { 1944 // An application record is attached to a previous process, 1945 // clean it up now. 1946 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1947 handleAppDiedLocked(app, true, true); 1948 } 1949 } 1950 1951 String hostingNameStr = hostingName != null 1952 ? hostingName.flattenToShortString() : null; 1953 1954 if (!isolated) { 1955 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1956 // If we are in the background, then check to see if this process 1957 // is bad. If so, we will just silently fail. 1958 if (mBadProcesses.get(info.processName, info.uid) != null) { 1959 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1960 + "/" + info.processName); 1961 return null; 1962 } 1963 } else { 1964 // When the user is explicitly starting a process, then clear its 1965 // crash count so that we won't make it bad until they see at 1966 // least one crash dialog again, and make the process good again 1967 // if it had been bad. 1968 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1969 + "/" + info.processName); 1970 mProcessCrashTimes.remove(info.processName, info.uid); 1971 if (mBadProcesses.get(info.processName, info.uid) != null) { 1972 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1973 info.processName); 1974 mBadProcesses.remove(info.processName, info.uid); 1975 if (app != null) { 1976 app.bad = false; 1977 } 1978 } 1979 } 1980 } 1981 1982 if (app == null) { 1983 app = newProcessRecordLocked(null, info, processName, isolated); 1984 if (app == null) { 1985 Slog.w(TAG, "Failed making new process record for " 1986 + processName + "/" + info.uid + " isolated=" + isolated); 1987 return null; 1988 } 1989 mProcessNames.put(processName, app.uid, app); 1990 if (isolated) { 1991 mIsolatedProcesses.put(app.uid, app); 1992 } 1993 } else { 1994 // If this is a new package in the process, add the package to the list 1995 app.addPackage(info.packageName); 1996 } 1997 1998 // If the system is not ready yet, then hold off on starting this 1999 // process until it is. 2000 if (!mProcessesReady 2001 && !isAllowedWhileBooting(info) 2002 && !allowWhileBooting) { 2003 if (!mProcessesOnHold.contains(app)) { 2004 mProcessesOnHold.add(app); 2005 } 2006 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2007 return app; 2008 } 2009 2010 startProcessLocked(app, hostingType, hostingNameStr); 2011 return (app.pid != 0) ? app : null; 2012 } 2013 2014 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2015 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2016 } 2017 2018 private final void startProcessLocked(ProcessRecord app, 2019 String hostingType, String hostingNameStr) { 2020 if (app.pid > 0 && app.pid != MY_PID) { 2021 synchronized (mPidsSelfLocked) { 2022 mPidsSelfLocked.remove(app.pid); 2023 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2024 } 2025 app.setPid(0); 2026 } 2027 2028 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2029 "startProcessLocked removing on hold: " + app); 2030 mProcessesOnHold.remove(app); 2031 2032 updateCpuStats(); 2033 2034 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2035 mProcDeaths[0] = 0; 2036 2037 try { 2038 int uid = app.uid; 2039 2040 int[] gids = null; 2041 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2042 if (!app.isolated) { 2043 int[] permGids = null; 2044 try { 2045 final PackageManager pm = mContext.getPackageManager(); 2046 permGids = pm.getPackageGids(app.info.packageName); 2047 2048 if (Environment.isExternalStorageEmulated()) { 2049 if (pm.checkPermission( 2050 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2051 app.info.packageName) == PERMISSION_GRANTED) { 2052 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2053 } else { 2054 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2055 } 2056 } 2057 } catch (PackageManager.NameNotFoundException e) { 2058 Slog.w(TAG, "Unable to retrieve gids", e); 2059 } 2060 2061 /* 2062 * Add shared application GID so applications can share some 2063 * resources like shared libraries 2064 */ 2065 if (permGids == null) { 2066 gids = new int[1]; 2067 } else { 2068 gids = new int[permGids.length + 1]; 2069 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2070 } 2071 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2072 } 2073 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2074 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2075 && mTopComponent != null 2076 && app.processName.equals(mTopComponent.getPackageName())) { 2077 uid = 0; 2078 } 2079 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2080 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2081 uid = 0; 2082 } 2083 } 2084 int debugFlags = 0; 2085 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2086 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2087 // Also turn on CheckJNI for debuggable apps. It's quite 2088 // awkward to turn on otherwise. 2089 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2090 } 2091 // Run the app in safe mode if its manifest requests so or the 2092 // system is booted in safe mode. 2093 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2094 Zygote.systemInSafeMode == true) { 2095 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2096 } 2097 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2098 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2099 } 2100 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2101 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2102 } 2103 if ("1".equals(SystemProperties.get("debug.assert"))) { 2104 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2105 } 2106 2107 // Start the process. It will either succeed and return a result containing 2108 // the PID of the new process, or else throw a RuntimeException. 2109 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2110 app.processName, uid, uid, gids, debugFlags, mountExternal, 2111 app.info.targetSdkVersion, null, null); 2112 2113 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2114 synchronized (bs) { 2115 if (bs.isOnBattery()) { 2116 app.batteryStats.incStartsLocked(); 2117 } 2118 } 2119 2120 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2121 app.processName, hostingType, 2122 hostingNameStr != null ? hostingNameStr : ""); 2123 2124 if (app.persistent) { 2125 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2126 } 2127 2128 StringBuilder buf = mStringBuilder; 2129 buf.setLength(0); 2130 buf.append("Start proc "); 2131 buf.append(app.processName); 2132 buf.append(" for "); 2133 buf.append(hostingType); 2134 if (hostingNameStr != null) { 2135 buf.append(" "); 2136 buf.append(hostingNameStr); 2137 } 2138 buf.append(": pid="); 2139 buf.append(startResult.pid); 2140 buf.append(" uid="); 2141 buf.append(uid); 2142 buf.append(" gids={"); 2143 if (gids != null) { 2144 for (int gi=0; gi<gids.length; gi++) { 2145 if (gi != 0) buf.append(", "); 2146 buf.append(gids[gi]); 2147 2148 } 2149 } 2150 buf.append("}"); 2151 Slog.i(TAG, buf.toString()); 2152 app.setPid(startResult.pid); 2153 app.usingWrapper = startResult.usingWrapper; 2154 app.removed = false; 2155 synchronized (mPidsSelfLocked) { 2156 this.mPidsSelfLocked.put(startResult.pid, app); 2157 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2158 msg.obj = app; 2159 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2160 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2161 } 2162 } catch (RuntimeException e) { 2163 // XXX do better error recovery. 2164 app.setPid(0); 2165 Slog.e(TAG, "Failure starting process " + app.processName, e); 2166 } 2167 } 2168 2169 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2170 if (resumed) { 2171 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2172 } else { 2173 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2174 } 2175 } 2176 2177 boolean startHomeActivityLocked(int userId) { 2178 if (mHeadless) { 2179 // Added because none of the other calls to ensureBootCompleted seem to fire 2180 // when running headless. 2181 ensureBootCompleted(); 2182 return false; 2183 } 2184 2185 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2186 && mTopAction == null) { 2187 // We are running in factory test mode, but unable to find 2188 // the factory test app, so just sit around displaying the 2189 // error message and don't try to start anything. 2190 return false; 2191 } 2192 Intent intent = new Intent( 2193 mTopAction, 2194 mTopData != null ? Uri.parse(mTopData) : null); 2195 intent.setComponent(mTopComponent); 2196 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2197 intent.addCategory(Intent.CATEGORY_HOME); 2198 } 2199 ActivityInfo aInfo = 2200 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2201 if (aInfo != null) { 2202 intent.setComponent(new ComponentName( 2203 aInfo.applicationInfo.packageName, aInfo.name)); 2204 // Don't do this if the home app is currently being 2205 // instrumented. 2206 aInfo = new ActivityInfo(aInfo); 2207 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2208 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2209 aInfo.applicationInfo.uid); 2210 if (app == null || app.instrumentationClass == null) { 2211 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2212 mMainStack.startActivityLocked(null, intent, null, aInfo, 2213 null, null, 0, 0, 0, 0, null, false, null); 2214 } 2215 } 2216 2217 return true; 2218 } 2219 2220 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2221 ActivityInfo ai = null; 2222 ComponentName comp = intent.getComponent(); 2223 try { 2224 if (comp != null) { 2225 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2226 } else { 2227 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2228 intent, 2229 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2230 flags, userId); 2231 2232 if (info != null) { 2233 ai = info.activityInfo; 2234 } 2235 } 2236 } catch (RemoteException e) { 2237 // ignore 2238 } 2239 2240 return ai; 2241 } 2242 2243 /** 2244 * Starts the "new version setup screen" if appropriate. 2245 */ 2246 void startSetupActivityLocked() { 2247 // Only do this once per boot. 2248 if (mCheckedForSetup) { 2249 return; 2250 } 2251 2252 // We will show this screen if the current one is a different 2253 // version than the last one shown, and we are not running in 2254 // low-level factory test mode. 2255 final ContentResolver resolver = mContext.getContentResolver(); 2256 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2257 Settings.Secure.getInt(resolver, 2258 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2259 mCheckedForSetup = true; 2260 2261 // See if we should be showing the platform update setup UI. 2262 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2263 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2264 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2265 2266 // We don't allow third party apps to replace this. 2267 ResolveInfo ri = null; 2268 for (int i=0; ris != null && i<ris.size(); i++) { 2269 if ((ris.get(i).activityInfo.applicationInfo.flags 2270 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2271 ri = ris.get(i); 2272 break; 2273 } 2274 } 2275 2276 if (ri != null) { 2277 String vers = ri.activityInfo.metaData != null 2278 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2279 : null; 2280 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2281 vers = ri.activityInfo.applicationInfo.metaData.getString( 2282 Intent.METADATA_SETUP_VERSION); 2283 } 2284 String lastVers = Settings.Secure.getString( 2285 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2286 if (vers != null && !vers.equals(lastVers)) { 2287 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2288 intent.setComponent(new ComponentName( 2289 ri.activityInfo.packageName, ri.activityInfo.name)); 2290 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2291 null, null, 0, 0, 0, 0, null, false, null); 2292 } 2293 } 2294 } 2295 } 2296 2297 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2298 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2299 } 2300 2301 void enforceNotIsolatedCaller(String caller) { 2302 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2303 throw new SecurityException("Isolated process not allowed to call " + caller); 2304 } 2305 } 2306 2307 public int getFrontActivityScreenCompatMode() { 2308 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2309 synchronized (this) { 2310 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2311 } 2312 } 2313 2314 public void setFrontActivityScreenCompatMode(int mode) { 2315 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2316 "setFrontActivityScreenCompatMode"); 2317 synchronized (this) { 2318 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2319 } 2320 } 2321 2322 public int getPackageScreenCompatMode(String packageName) { 2323 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2324 synchronized (this) { 2325 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2326 } 2327 } 2328 2329 public void setPackageScreenCompatMode(String packageName, int mode) { 2330 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2331 "setPackageScreenCompatMode"); 2332 synchronized (this) { 2333 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2334 } 2335 } 2336 2337 public boolean getPackageAskScreenCompat(String packageName) { 2338 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2339 synchronized (this) { 2340 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2341 } 2342 } 2343 2344 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2345 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2346 "setPackageAskScreenCompat"); 2347 synchronized (this) { 2348 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2349 } 2350 } 2351 2352 void reportResumedActivityLocked(ActivityRecord r) { 2353 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2354 updateUsageStats(r, true); 2355 } 2356 2357 private void dispatchProcessesChanged() { 2358 int N; 2359 synchronized (this) { 2360 N = mPendingProcessChanges.size(); 2361 if (mActiveProcessChanges.length < N) { 2362 mActiveProcessChanges = new ProcessChangeItem[N]; 2363 } 2364 mPendingProcessChanges.toArray(mActiveProcessChanges); 2365 mAvailProcessChanges.addAll(mPendingProcessChanges); 2366 mPendingProcessChanges.clear(); 2367 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2368 } 2369 int i = mProcessObservers.beginBroadcast(); 2370 while (i > 0) { 2371 i--; 2372 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2373 if (observer != null) { 2374 try { 2375 for (int j=0; j<N; j++) { 2376 ProcessChangeItem item = mActiveProcessChanges[j]; 2377 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2378 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2379 + item.pid + " uid=" + item.uid + ": " 2380 + item.foregroundActivities); 2381 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2382 item.foregroundActivities); 2383 } 2384 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2385 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2386 + item.pid + " uid=" + item.uid + ": " + item.importance); 2387 observer.onImportanceChanged(item.pid, item.uid, 2388 item.importance); 2389 } 2390 } 2391 } catch (RemoteException e) { 2392 } 2393 } 2394 } 2395 mProcessObservers.finishBroadcast(); 2396 } 2397 2398 private void dispatchProcessDied(int pid, int uid) { 2399 int i = mProcessObservers.beginBroadcast(); 2400 while (i > 0) { 2401 i--; 2402 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2403 if (observer != null) { 2404 try { 2405 observer.onProcessDied(pid, uid); 2406 } catch (RemoteException e) { 2407 } 2408 } 2409 } 2410 mProcessObservers.finishBroadcast(); 2411 } 2412 2413 final void doPendingActivityLaunchesLocked(boolean doResume) { 2414 final int N = mPendingActivityLaunches.size(); 2415 if (N <= 0) { 2416 return; 2417 } 2418 for (int i=0; i<N; i++) { 2419 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2420 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2421 pal.startFlags, doResume && i == (N-1), null); 2422 } 2423 mPendingActivityLaunches.clear(); 2424 } 2425 2426 public final int startActivity(IApplicationThread caller, 2427 Intent intent, String resolvedType, IBinder resultTo, 2428 String resultWho, int requestCode, int startFlags, 2429 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2430 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2431 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2432 } 2433 2434 public final int startActivityAsUser(IApplicationThread caller, 2435 Intent intent, String resolvedType, IBinder resultTo, 2436 String resultWho, int requestCode, int startFlags, 2437 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2438 enforceNotIsolatedCaller("startActivity"); 2439 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2440 false, true, "startActivity", null); 2441 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2442 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2443 null, null, options, userId); 2444 } 2445 2446 public final WaitResult startActivityAndWait(IApplicationThread caller, 2447 Intent intent, String resolvedType, IBinder resultTo, 2448 String resultWho, int requestCode, int startFlags, String profileFile, 2449 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2450 enforceNotIsolatedCaller("startActivityAndWait"); 2451 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2452 false, true, "startActivityAndWait", null); 2453 WaitResult res = new WaitResult(); 2454 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2455 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2456 res, null, options, UserHandle.getCallingUserId()); 2457 return res; 2458 } 2459 2460 public final int startActivityWithConfig(IApplicationThread caller, 2461 Intent intent, String resolvedType, IBinder resultTo, 2462 String resultWho, int requestCode, int startFlags, Configuration config, 2463 Bundle options, int userId) { 2464 enforceNotIsolatedCaller("startActivityWithConfig"); 2465 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2466 false, true, "startActivityWithConfig", null); 2467 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2468 resultTo, resultWho, requestCode, startFlags, 2469 null, null, null, config, options, userId); 2470 return ret; 2471 } 2472 2473 public int startActivityIntentSender(IApplicationThread caller, 2474 IntentSender intent, Intent fillInIntent, String resolvedType, 2475 IBinder resultTo, String resultWho, int requestCode, 2476 int flagsMask, int flagsValues, Bundle options) { 2477 enforceNotIsolatedCaller("startActivityIntentSender"); 2478 // Refuse possible leaked file descriptors 2479 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2480 throw new IllegalArgumentException("File descriptors passed in Intent"); 2481 } 2482 2483 IIntentSender sender = intent.getTarget(); 2484 if (!(sender instanceof PendingIntentRecord)) { 2485 throw new IllegalArgumentException("Bad PendingIntent object"); 2486 } 2487 2488 PendingIntentRecord pir = (PendingIntentRecord)sender; 2489 2490 synchronized (this) { 2491 // If this is coming from the currently resumed activity, it is 2492 // effectively saying that app switches are allowed at this point. 2493 if (mMainStack.mResumedActivity != null 2494 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2495 Binder.getCallingUid()) { 2496 mAppSwitchesAllowedTime = 0; 2497 } 2498 } 2499 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2500 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2501 return ret; 2502 } 2503 2504 public boolean startNextMatchingActivity(IBinder callingActivity, 2505 Intent intent, Bundle options) { 2506 // Refuse possible leaked file descriptors 2507 if (intent != null && intent.hasFileDescriptors() == true) { 2508 throw new IllegalArgumentException("File descriptors passed in Intent"); 2509 } 2510 2511 synchronized (this) { 2512 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2513 if (r == null) { 2514 ActivityOptions.abort(options); 2515 return false; 2516 } 2517 if (r.app == null || r.app.thread == null) { 2518 // The caller is not running... d'oh! 2519 ActivityOptions.abort(options); 2520 return false; 2521 } 2522 intent = new Intent(intent); 2523 // The caller is not allowed to change the data. 2524 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2525 // And we are resetting to find the next component... 2526 intent.setComponent(null); 2527 2528 ActivityInfo aInfo = null; 2529 try { 2530 List<ResolveInfo> resolves = 2531 AppGlobals.getPackageManager().queryIntentActivities( 2532 intent, r.resolvedType, 2533 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2534 UserHandle.getCallingUserId()); 2535 2536 // Look for the original activity in the list... 2537 final int N = resolves != null ? resolves.size() : 0; 2538 for (int i=0; i<N; i++) { 2539 ResolveInfo rInfo = resolves.get(i); 2540 if (rInfo.activityInfo.packageName.equals(r.packageName) 2541 && rInfo.activityInfo.name.equals(r.info.name)) { 2542 // We found the current one... the next matching is 2543 // after it. 2544 i++; 2545 if (i<N) { 2546 aInfo = resolves.get(i).activityInfo; 2547 } 2548 break; 2549 } 2550 } 2551 } catch (RemoteException e) { 2552 } 2553 2554 if (aInfo == null) { 2555 // Nobody who is next! 2556 ActivityOptions.abort(options); 2557 return false; 2558 } 2559 2560 intent.setComponent(new ComponentName( 2561 aInfo.applicationInfo.packageName, aInfo.name)); 2562 intent.setFlags(intent.getFlags()&~( 2563 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2564 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2565 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2566 Intent.FLAG_ACTIVITY_NEW_TASK)); 2567 2568 // Okay now we need to start the new activity, replacing the 2569 // currently running activity. This is a little tricky because 2570 // we want to start the new one as if the current one is finished, 2571 // but not finish the current one first so that there is no flicker. 2572 // And thus... 2573 final boolean wasFinishing = r.finishing; 2574 r.finishing = true; 2575 2576 // Propagate reply information over to the new activity. 2577 final ActivityRecord resultTo = r.resultTo; 2578 final String resultWho = r.resultWho; 2579 final int requestCode = r.requestCode; 2580 r.resultTo = null; 2581 if (resultTo != null) { 2582 resultTo.removeResultsLocked(r, resultWho, requestCode); 2583 } 2584 2585 final long origId = Binder.clearCallingIdentity(); 2586 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2587 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2588 resultWho, requestCode, -1, r.launchedFromUid, 0, 2589 options, false, null); 2590 Binder.restoreCallingIdentity(origId); 2591 2592 r.finishing = wasFinishing; 2593 if (res != ActivityManager.START_SUCCESS) { 2594 return false; 2595 } 2596 return true; 2597 } 2598 } 2599 2600 final int startActivityInPackage(int uid, 2601 Intent intent, String resolvedType, IBinder resultTo, 2602 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2603 2604 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2605 false, true, "startActivityInPackage", null); 2606 2607 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2608 resultTo, resultWho, requestCode, startFlags, 2609 null, null, null, null, options, userId); 2610 return ret; 2611 } 2612 2613 public final int startActivities(IApplicationThread caller, 2614 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2615 enforceNotIsolatedCaller("startActivities"); 2616 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2617 options, UserHandle.getCallingUserId()); 2618 return ret; 2619 } 2620 2621 final int startActivitiesInPackage(int uid, 2622 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2623 Bundle options, int userId) { 2624 2625 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2626 false, true, "startActivityInPackage", null); 2627 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2628 options, userId); 2629 return ret; 2630 } 2631 2632 final void addRecentTaskLocked(TaskRecord task) { 2633 int N = mRecentTasks.size(); 2634 // Quick case: check if the top-most recent task is the same. 2635 if (N > 0 && mRecentTasks.get(0) == task) { 2636 return; 2637 } 2638 // Remove any existing entries that are the same kind of task. 2639 for (int i=0; i<N; i++) { 2640 TaskRecord tr = mRecentTasks.get(i); 2641 if (task.userId == tr.userId 2642 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2643 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2644 mRecentTasks.remove(i); 2645 i--; 2646 N--; 2647 if (task.intent == null) { 2648 // If the new recent task we are adding is not fully 2649 // specified, then replace it with the existing recent task. 2650 task = tr; 2651 } 2652 } 2653 } 2654 if (N >= MAX_RECENT_TASKS) { 2655 mRecentTasks.remove(N-1); 2656 } 2657 mRecentTasks.add(0, task); 2658 } 2659 2660 public void setRequestedOrientation(IBinder token, 2661 int requestedOrientation) { 2662 synchronized (this) { 2663 ActivityRecord r = mMainStack.isInStackLocked(token); 2664 if (r == null) { 2665 return; 2666 } 2667 final long origId = Binder.clearCallingIdentity(); 2668 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2669 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2670 mConfiguration, 2671 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2672 if (config != null) { 2673 r.frozenBeforeDestroy = true; 2674 if (!updateConfigurationLocked(config, r, false, false)) { 2675 mMainStack.resumeTopActivityLocked(null); 2676 } 2677 } 2678 Binder.restoreCallingIdentity(origId); 2679 } 2680 } 2681 2682 public int getRequestedOrientation(IBinder token) { 2683 synchronized (this) { 2684 ActivityRecord r = mMainStack.isInStackLocked(token); 2685 if (r == null) { 2686 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2687 } 2688 return mWindowManager.getAppOrientation(r.appToken); 2689 } 2690 } 2691 2692 /** 2693 * This is the internal entry point for handling Activity.finish(). 2694 * 2695 * @param token The Binder token referencing the Activity we want to finish. 2696 * @param resultCode Result code, if any, from this Activity. 2697 * @param resultData Result data (Intent), if any, from this Activity. 2698 * 2699 * @return Returns true if the activity successfully finished, or false if it is still running. 2700 */ 2701 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2702 // Refuse possible leaked file descriptors 2703 if (resultData != null && resultData.hasFileDescriptors() == true) { 2704 throw new IllegalArgumentException("File descriptors passed in Intent"); 2705 } 2706 2707 synchronized(this) { 2708 if (mController != null) { 2709 // Find the first activity that is not finishing. 2710 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2711 if (next != null) { 2712 // ask watcher if this is allowed 2713 boolean resumeOK = true; 2714 try { 2715 resumeOK = mController.activityResuming(next.packageName); 2716 } catch (RemoteException e) { 2717 mController = null; 2718 } 2719 2720 if (!resumeOK) { 2721 return false; 2722 } 2723 } 2724 } 2725 final long origId = Binder.clearCallingIdentity(); 2726 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2727 resultData, "app-request", true); 2728 Binder.restoreCallingIdentity(origId); 2729 return res; 2730 } 2731 } 2732 2733 public final void finishHeavyWeightApp() { 2734 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2735 != PackageManager.PERMISSION_GRANTED) { 2736 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2737 + Binder.getCallingPid() 2738 + ", uid=" + Binder.getCallingUid() 2739 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2740 Slog.w(TAG, msg); 2741 throw new SecurityException(msg); 2742 } 2743 2744 synchronized(this) { 2745 if (mHeavyWeightProcess == null) { 2746 return; 2747 } 2748 2749 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2750 mHeavyWeightProcess.activities); 2751 for (int i=0; i<activities.size(); i++) { 2752 ActivityRecord r = activities.get(i); 2753 if (!r.finishing) { 2754 int index = mMainStack.indexOfTokenLocked(r.appToken); 2755 if (index >= 0) { 2756 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2757 null, "finish-heavy", true); 2758 } 2759 } 2760 } 2761 2762 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2763 mHeavyWeightProcess.userId, 0)); 2764 mHeavyWeightProcess = null; 2765 } 2766 } 2767 2768 public void crashApplication(int uid, int initialPid, String packageName, 2769 String message) { 2770 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2771 != PackageManager.PERMISSION_GRANTED) { 2772 String msg = "Permission Denial: crashApplication() from pid=" 2773 + Binder.getCallingPid() 2774 + ", uid=" + Binder.getCallingUid() 2775 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2776 Slog.w(TAG, msg); 2777 throw new SecurityException(msg); 2778 } 2779 2780 synchronized(this) { 2781 ProcessRecord proc = null; 2782 2783 // Figure out which process to kill. We don't trust that initialPid 2784 // still has any relation to current pids, so must scan through the 2785 // list. 2786 synchronized (mPidsSelfLocked) { 2787 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2788 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2789 if (p.uid != uid) { 2790 continue; 2791 } 2792 if (p.pid == initialPid) { 2793 proc = p; 2794 break; 2795 } 2796 for (String str : p.pkgList) { 2797 if (str.equals(packageName)) { 2798 proc = p; 2799 } 2800 } 2801 } 2802 } 2803 2804 if (proc == null) { 2805 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2806 + " initialPid=" + initialPid 2807 + " packageName=" + packageName); 2808 return; 2809 } 2810 2811 if (proc.thread != null) { 2812 if (proc.pid == Process.myPid()) { 2813 Log.w(TAG, "crashApplication: trying to crash self!"); 2814 return; 2815 } 2816 long ident = Binder.clearCallingIdentity(); 2817 try { 2818 proc.thread.scheduleCrash(message); 2819 } catch (RemoteException e) { 2820 } 2821 Binder.restoreCallingIdentity(ident); 2822 } 2823 } 2824 } 2825 2826 public final void finishSubActivity(IBinder token, String resultWho, 2827 int requestCode) { 2828 synchronized(this) { 2829 final long origId = Binder.clearCallingIdentity(); 2830 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2831 Binder.restoreCallingIdentity(origId); 2832 } 2833 } 2834 2835 public boolean finishActivityAffinity(IBinder token) { 2836 synchronized(this) { 2837 final long origId = Binder.clearCallingIdentity(); 2838 boolean res = mMainStack.finishActivityAffinityLocked(token); 2839 Binder.restoreCallingIdentity(origId); 2840 return res; 2841 } 2842 } 2843 2844 public boolean willActivityBeVisible(IBinder token) { 2845 synchronized(this) { 2846 int i; 2847 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2848 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2849 if (r.appToken == token) { 2850 return true; 2851 } 2852 if (r.fullscreen && !r.finishing) { 2853 return false; 2854 } 2855 } 2856 return true; 2857 } 2858 } 2859 2860 public void overridePendingTransition(IBinder token, String packageName, 2861 int enterAnim, int exitAnim) { 2862 synchronized(this) { 2863 ActivityRecord self = mMainStack.isInStackLocked(token); 2864 if (self == null) { 2865 return; 2866 } 2867 2868 final long origId = Binder.clearCallingIdentity(); 2869 2870 if (self.state == ActivityState.RESUMED 2871 || self.state == ActivityState.PAUSING) { 2872 mWindowManager.overridePendingAppTransition(packageName, 2873 enterAnim, exitAnim, null); 2874 } 2875 2876 Binder.restoreCallingIdentity(origId); 2877 } 2878 } 2879 2880 /** 2881 * Main function for removing an existing process from the activity manager 2882 * as a result of that process going away. Clears out all connections 2883 * to the process. 2884 */ 2885 private final void handleAppDiedLocked(ProcessRecord app, 2886 boolean restarting, boolean allowRestart) { 2887 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2888 if (!restarting) { 2889 mLruProcesses.remove(app); 2890 } 2891 2892 if (mProfileProc == app) { 2893 clearProfilerLocked(); 2894 } 2895 2896 // Just in case... 2897 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2898 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2899 mMainStack.mPausingActivity = null; 2900 } 2901 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2902 mMainStack.mLastPausedActivity = null; 2903 } 2904 2905 // Remove this application's activities from active lists. 2906 mMainStack.removeHistoryRecordsForAppLocked(app); 2907 2908 boolean atTop = true; 2909 boolean hasVisibleActivities = false; 2910 2911 // Clean out the history list. 2912 int i = mMainStack.mHistory.size(); 2913 if (localLOGV) Slog.v( 2914 TAG, "Removing app " + app + " from history with " + i + " entries"); 2915 while (i > 0) { 2916 i--; 2917 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2918 if (localLOGV) Slog.v( 2919 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2920 if (r.app == app) { 2921 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2922 if (ActivityStack.DEBUG_ADD_REMOVE) { 2923 RuntimeException here = new RuntimeException("here"); 2924 here.fillInStackTrace(); 2925 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2926 + ": haveState=" + r.haveState 2927 + " stateNotNeeded=" + r.stateNotNeeded 2928 + " finishing=" + r.finishing 2929 + " state=" + r.state, here); 2930 } 2931 if (!r.finishing) { 2932 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2933 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2934 System.identityHashCode(r), 2935 r.task.taskId, r.shortComponentName, 2936 "proc died without state saved"); 2937 } 2938 mMainStack.removeActivityFromHistoryLocked(r); 2939 2940 } else { 2941 // We have the current state for this activity, so 2942 // it can be restarted later when needed. 2943 if (localLOGV) Slog.v( 2944 TAG, "Keeping entry, setting app to null"); 2945 if (r.visible) { 2946 hasVisibleActivities = true; 2947 } 2948 r.app = null; 2949 r.nowVisible = false; 2950 if (!r.haveState) { 2951 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2952 "App died, clearing saved state of " + r); 2953 r.icicle = null; 2954 } 2955 } 2956 2957 r.stack.cleanUpActivityLocked(r, true, true); 2958 } 2959 atTop = false; 2960 } 2961 2962 app.activities.clear(); 2963 2964 if (app.instrumentationClass != null) { 2965 Slog.w(TAG, "Crash of app " + app.processName 2966 + " running instrumentation " + app.instrumentationClass); 2967 Bundle info = new Bundle(); 2968 info.putString("shortMsg", "Process crashed."); 2969 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2970 } 2971 2972 if (!restarting) { 2973 if (!mMainStack.resumeTopActivityLocked(null)) { 2974 // If there was nothing to resume, and we are not already 2975 // restarting this process, but there is a visible activity that 2976 // is hosted by the process... then make sure all visible 2977 // activities are running, taking care of restarting this 2978 // process. 2979 if (hasVisibleActivities) { 2980 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2981 } 2982 } 2983 } 2984 } 2985 2986 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2987 IBinder threadBinder = thread.asBinder(); 2988 // Find the application record. 2989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2990 ProcessRecord rec = mLruProcesses.get(i); 2991 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2992 return i; 2993 } 2994 } 2995 return -1; 2996 } 2997 2998 final ProcessRecord getRecordForAppLocked( 2999 IApplicationThread thread) { 3000 if (thread == null) { 3001 return null; 3002 } 3003 3004 int appIndex = getLRURecordIndexForAppLocked(thread); 3005 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3006 } 3007 3008 final void appDiedLocked(ProcessRecord app, int pid, 3009 IApplicationThread thread) { 3010 3011 mProcDeaths[0]++; 3012 3013 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3014 synchronized (stats) { 3015 stats.noteProcessDiedLocked(app.info.uid, pid); 3016 } 3017 3018 // Clean up already done if the process has been re-started. 3019 if (app.pid == pid && app.thread != null && 3020 app.thread.asBinder() == thread.asBinder()) { 3021 if (!app.killedBackground) { 3022 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3023 + ") has died."); 3024 } 3025 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3026 if (localLOGV) Slog.v( 3027 TAG, "Dying app: " + app + ", pid: " + pid 3028 + ", thread: " + thread.asBinder()); 3029 boolean doLowMem = app.instrumentationClass == null; 3030 handleAppDiedLocked(app, false, true); 3031 3032 if (doLowMem) { 3033 // If there are no longer any background processes running, 3034 // and the app that died was not running instrumentation, 3035 // then tell everyone we are now low on memory. 3036 boolean haveBg = false; 3037 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3038 ProcessRecord rec = mLruProcesses.get(i); 3039 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3040 haveBg = true; 3041 break; 3042 } 3043 } 3044 3045 if (!haveBg) { 3046 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3047 long now = SystemClock.uptimeMillis(); 3048 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3049 ProcessRecord rec = mLruProcesses.get(i); 3050 if (rec != app && rec.thread != null && 3051 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3052 // The low memory report is overriding any current 3053 // state for a GC request. Make sure to do 3054 // heavy/important/visible/foreground processes first. 3055 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3056 rec.lastRequestedGc = 0; 3057 } else { 3058 rec.lastRequestedGc = rec.lastLowMemory; 3059 } 3060 rec.reportLowMemory = true; 3061 rec.lastLowMemory = now; 3062 mProcessesToGc.remove(rec); 3063 addProcessToGcListLocked(rec); 3064 } 3065 } 3066 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3067 scheduleAppGcsLocked(); 3068 } 3069 } 3070 } else if (app.pid != pid) { 3071 // A new process has already been started. 3072 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3073 + ") has died and restarted (pid " + app.pid + ")."); 3074 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3075 } else if (DEBUG_PROCESSES) { 3076 Slog.d(TAG, "Received spurious death notification for thread " 3077 + thread.asBinder()); 3078 } 3079 } 3080 3081 /** 3082 * If a stack trace dump file is configured, dump process stack traces. 3083 * @param clearTraces causes the dump file to be erased prior to the new 3084 * traces being written, if true; when false, the new traces will be 3085 * appended to any existing file content. 3086 * @param firstPids of dalvik VM processes to dump stack traces for first 3087 * @param lastPids of dalvik VM processes to dump stack traces for last 3088 * @param nativeProcs optional list of native process names to dump stack crawls 3089 * @return file containing stack traces, or null if no dump file is configured 3090 */ 3091 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3092 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3093 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3094 if (tracesPath == null || tracesPath.length() == 0) { 3095 return null; 3096 } 3097 3098 File tracesFile = new File(tracesPath); 3099 try { 3100 File tracesDir = tracesFile.getParentFile(); 3101 if (!tracesDir.exists()) { 3102 tracesFile.mkdirs(); 3103 if (!SELinux.restorecon(tracesDir)) { 3104 return null; 3105 } 3106 } 3107 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3108 3109 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3110 tracesFile.createNewFile(); 3111 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3112 } catch (IOException e) { 3113 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3114 return null; 3115 } 3116 3117 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3118 return tracesFile; 3119 } 3120 3121 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3122 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3123 // Use a FileObserver to detect when traces finish writing. 3124 // The order of traces is considered important to maintain for legibility. 3125 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3126 public synchronized void onEvent(int event, String path) { notify(); } 3127 }; 3128 3129 try { 3130 observer.startWatching(); 3131 3132 // First collect all of the stacks of the most important pids. 3133 if (firstPids != null) { 3134 try { 3135 int num = firstPids.size(); 3136 for (int i = 0; i < num; i++) { 3137 synchronized (observer) { 3138 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3139 observer.wait(200); // Wait for write-close, give up after 200msec 3140 } 3141 } 3142 } catch (InterruptedException e) { 3143 Log.wtf(TAG, e); 3144 } 3145 } 3146 3147 // Next measure CPU usage. 3148 if (processStats != null) { 3149 processStats.init(); 3150 System.gc(); 3151 processStats.update(); 3152 try { 3153 synchronized (processStats) { 3154 processStats.wait(500); // measure over 1/2 second. 3155 } 3156 } catch (InterruptedException e) { 3157 } 3158 processStats.update(); 3159 3160 // We'll take the stack crawls of just the top apps using CPU. 3161 final int N = processStats.countWorkingStats(); 3162 int numProcs = 0; 3163 for (int i=0; i<N && numProcs<5; i++) { 3164 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3165 if (lastPids.indexOfKey(stats.pid) >= 0) { 3166 numProcs++; 3167 try { 3168 synchronized (observer) { 3169 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3170 observer.wait(200); // Wait for write-close, give up after 200msec 3171 } 3172 } catch (InterruptedException e) { 3173 Log.wtf(TAG, e); 3174 } 3175 3176 } 3177 } 3178 } 3179 3180 } finally { 3181 observer.stopWatching(); 3182 } 3183 3184 if (nativeProcs != null) { 3185 int[] pids = Process.getPidsForCommands(nativeProcs); 3186 if (pids != null) { 3187 for (int pid : pids) { 3188 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3189 } 3190 } 3191 } 3192 } 3193 3194 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3195 if (true || IS_USER_BUILD) { 3196 return; 3197 } 3198 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3199 if (tracesPath == null || tracesPath.length() == 0) { 3200 return; 3201 } 3202 3203 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3204 StrictMode.allowThreadDiskWrites(); 3205 try { 3206 final File tracesFile = new File(tracesPath); 3207 final File tracesDir = tracesFile.getParentFile(); 3208 final File tracesTmp = new File(tracesDir, "__tmp__"); 3209 try { 3210 if (!tracesDir.exists()) { 3211 tracesFile.mkdirs(); 3212 if (!SELinux.restorecon(tracesDir.getPath())) { 3213 return; 3214 } 3215 } 3216 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3217 3218 if (tracesFile.exists()) { 3219 tracesTmp.delete(); 3220 tracesFile.renameTo(tracesTmp); 3221 } 3222 StringBuilder sb = new StringBuilder(); 3223 Time tobj = new Time(); 3224 tobj.set(System.currentTimeMillis()); 3225 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3226 sb.append(": "); 3227 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3228 sb.append(" since "); 3229 sb.append(msg); 3230 FileOutputStream fos = new FileOutputStream(tracesFile); 3231 fos.write(sb.toString().getBytes()); 3232 if (app == null) { 3233 fos.write("\n*** No application process!".getBytes()); 3234 } 3235 fos.close(); 3236 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3237 } catch (IOException e) { 3238 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3239 return; 3240 } 3241 3242 if (app != null) { 3243 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3244 firstPids.add(app.pid); 3245 dumpStackTraces(tracesPath, firstPids, null, null, null); 3246 } 3247 3248 File lastTracesFile = null; 3249 File curTracesFile = null; 3250 for (int i=9; i>=0; i--) { 3251 String name = String.format("slow%02d.txt", i); 3252 curTracesFile = new File(tracesDir, name); 3253 if (curTracesFile.exists()) { 3254 if (lastTracesFile != null) { 3255 curTracesFile.renameTo(lastTracesFile); 3256 } else { 3257 curTracesFile.delete(); 3258 } 3259 } 3260 lastTracesFile = curTracesFile; 3261 } 3262 tracesFile.renameTo(curTracesFile); 3263 if (tracesTmp.exists()) { 3264 tracesTmp.renameTo(tracesFile); 3265 } 3266 } finally { 3267 StrictMode.setThreadPolicy(oldPolicy); 3268 } 3269 } 3270 3271 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3272 ActivityRecord parent, final String annotation) { 3273 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3274 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3275 3276 if (mController != null) { 3277 try { 3278 // 0 == continue, -1 = kill process immediately 3279 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3280 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3281 } catch (RemoteException e) { 3282 mController = null; 3283 } 3284 } 3285 3286 long anrTime = SystemClock.uptimeMillis(); 3287 if (MONITOR_CPU_USAGE) { 3288 updateCpuStatsNow(); 3289 } 3290 3291 synchronized (this) { 3292 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3293 if (mShuttingDown) { 3294 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3295 return; 3296 } else if (app.notResponding) { 3297 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3298 return; 3299 } else if (app.crashing) { 3300 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3301 return; 3302 } 3303 3304 // In case we come through here for the same app before completing 3305 // this one, mark as anring now so we will bail out. 3306 app.notResponding = true; 3307 3308 // Log the ANR to the event log. 3309 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3310 annotation); 3311 3312 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3313 firstPids.add(app.pid); 3314 3315 int parentPid = app.pid; 3316 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3317 if (parentPid != app.pid) firstPids.add(parentPid); 3318 3319 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3320 3321 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3322 ProcessRecord r = mLruProcesses.get(i); 3323 if (r != null && r.thread != null) { 3324 int pid = r.pid; 3325 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3326 if (r.persistent) { 3327 firstPids.add(pid); 3328 } else { 3329 lastPids.put(pid, Boolean.TRUE); 3330 } 3331 } 3332 } 3333 } 3334 } 3335 3336 // Log the ANR to the main log. 3337 StringBuilder info = new StringBuilder(); 3338 info.setLength(0); 3339 info.append("ANR in ").append(app.processName); 3340 if (activity != null && activity.shortComponentName != null) { 3341 info.append(" (").append(activity.shortComponentName).append(")"); 3342 } 3343 info.append("\n"); 3344 if (annotation != null) { 3345 info.append("Reason: ").append(annotation).append("\n"); 3346 } 3347 if (parent != null && parent != activity) { 3348 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3349 } 3350 3351 final ProcessStats processStats = new ProcessStats(true); 3352 3353 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3354 3355 String cpuInfo = null; 3356 if (MONITOR_CPU_USAGE) { 3357 updateCpuStatsNow(); 3358 synchronized (mProcessStatsThread) { 3359 cpuInfo = mProcessStats.printCurrentState(anrTime); 3360 } 3361 info.append(processStats.printCurrentLoad()); 3362 info.append(cpuInfo); 3363 } 3364 3365 info.append(processStats.printCurrentState(anrTime)); 3366 3367 Slog.e(TAG, info.toString()); 3368 if (tracesFile == null) { 3369 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3370 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3371 } 3372 3373 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3374 cpuInfo, tracesFile, null); 3375 3376 if (mController != null) { 3377 try { 3378 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3379 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3380 if (res != 0) { 3381 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3382 return; 3383 } 3384 } catch (RemoteException e) { 3385 mController = null; 3386 } 3387 } 3388 3389 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3390 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3391 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3392 3393 synchronized (this) { 3394 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3395 Slog.w(TAG, "Killing " + app + ": background ANR"); 3396 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3397 app.processName, app.setAdj, "background ANR"); 3398 Process.killProcessQuiet(app.pid); 3399 return; 3400 } 3401 3402 // Set the app's notResponding state, and look up the errorReportReceiver 3403 makeAppNotRespondingLocked(app, 3404 activity != null ? activity.shortComponentName : null, 3405 annotation != null ? "ANR " + annotation : "ANR", 3406 info.toString()); 3407 3408 // Bring up the infamous App Not Responding dialog 3409 Message msg = Message.obtain(); 3410 HashMap map = new HashMap(); 3411 msg.what = SHOW_NOT_RESPONDING_MSG; 3412 msg.obj = map; 3413 map.put("app", app); 3414 if (activity != null) { 3415 map.put("activity", activity); 3416 } 3417 3418 mHandler.sendMessage(msg); 3419 } 3420 } 3421 3422 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3423 if (!mLaunchWarningShown) { 3424 mLaunchWarningShown = true; 3425 mHandler.post(new Runnable() { 3426 @Override 3427 public void run() { 3428 synchronized (ActivityManagerService.this) { 3429 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3430 d.show(); 3431 mHandler.postDelayed(new Runnable() { 3432 @Override 3433 public void run() { 3434 synchronized (ActivityManagerService.this) { 3435 d.dismiss(); 3436 mLaunchWarningShown = false; 3437 } 3438 } 3439 }, 4000); 3440 } 3441 } 3442 }); 3443 } 3444 } 3445 3446 public boolean clearApplicationUserData(final String packageName, 3447 final IPackageDataObserver observer, int userId) { 3448 enforceNotIsolatedCaller("clearApplicationUserData"); 3449 int uid = Binder.getCallingUid(); 3450 int pid = Binder.getCallingPid(); 3451 userId = handleIncomingUserLocked(pid, uid, 3452 userId, false, true, "clearApplicationUserData", null); 3453 long callingId = Binder.clearCallingIdentity(); 3454 try { 3455 IPackageManager pm = AppGlobals.getPackageManager(); 3456 int pkgUid = -1; 3457 synchronized(this) { 3458 try { 3459 pkgUid = pm.getPackageUid(packageName, userId); 3460 } catch (RemoteException e) { 3461 } 3462 if (pkgUid == -1) { 3463 Slog.w(TAG, "Invalid packageName:" + packageName); 3464 return false; 3465 } 3466 if (uid == pkgUid || checkComponentPermission( 3467 android.Manifest.permission.CLEAR_APP_USER_DATA, 3468 pid, uid, -1, true) 3469 == PackageManager.PERMISSION_GRANTED) { 3470 forceStopPackageLocked(packageName, pkgUid); 3471 } else { 3472 throw new SecurityException(pid+" does not have permission:"+ 3473 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3474 "for process:"+packageName); 3475 } 3476 } 3477 3478 try { 3479 //clear application user data 3480 pm.clearApplicationUserData(packageName, observer, userId); 3481 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3482 Uri.fromParts("package", packageName, null)); 3483 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3484 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3485 null, null, 0, null, null, null, false, false, userId); 3486 } catch (RemoteException e) { 3487 } 3488 } finally { 3489 Binder.restoreCallingIdentity(callingId); 3490 } 3491 return true; 3492 } 3493 3494 public void killBackgroundProcesses(final String packageName, int userId) { 3495 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3496 != PackageManager.PERMISSION_GRANTED && 3497 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3498 != PackageManager.PERMISSION_GRANTED) { 3499 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3500 + Binder.getCallingPid() 3501 + ", uid=" + Binder.getCallingUid() 3502 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3503 Slog.w(TAG, msg); 3504 throw new SecurityException(msg); 3505 } 3506 3507 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3508 userId, true, true, "killBackgroundProcesses", null); 3509 long callingId = Binder.clearCallingIdentity(); 3510 try { 3511 IPackageManager pm = AppGlobals.getPackageManager(); 3512 synchronized(this) { 3513 int appId = -1; 3514 try { 3515 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3516 } catch (RemoteException e) { 3517 } 3518 if (appId == -1) { 3519 Slog.w(TAG, "Invalid packageName: " + packageName); 3520 return; 3521 } 3522 killPackageProcessesLocked(packageName, appId, userId, 3523 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3524 } 3525 } finally { 3526 Binder.restoreCallingIdentity(callingId); 3527 } 3528 } 3529 3530 public void killAllBackgroundProcesses() { 3531 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3532 != PackageManager.PERMISSION_GRANTED) { 3533 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3534 + Binder.getCallingPid() 3535 + ", uid=" + Binder.getCallingUid() 3536 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3537 Slog.w(TAG, msg); 3538 throw new SecurityException(msg); 3539 } 3540 3541 long callingId = Binder.clearCallingIdentity(); 3542 try { 3543 synchronized(this) { 3544 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3545 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3546 final int NA = apps.size(); 3547 for (int ia=0; ia<NA; ia++) { 3548 ProcessRecord app = apps.valueAt(ia); 3549 if (app.persistent) { 3550 // we don't kill persistent processes 3551 continue; 3552 } 3553 if (app.removed) { 3554 procs.add(app); 3555 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3556 app.removed = true; 3557 procs.add(app); 3558 } 3559 } 3560 } 3561 3562 int N = procs.size(); 3563 for (int i=0; i<N; i++) { 3564 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3565 } 3566 } 3567 } finally { 3568 Binder.restoreCallingIdentity(callingId); 3569 } 3570 } 3571 3572 public void forceStopPackage(final String packageName, int userId) { 3573 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3574 != PackageManager.PERMISSION_GRANTED) { 3575 String msg = "Permission Denial: forceStopPackage() from pid=" 3576 + Binder.getCallingPid() 3577 + ", uid=" + Binder.getCallingUid() 3578 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3579 Slog.w(TAG, msg); 3580 throw new SecurityException(msg); 3581 } 3582 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3583 userId, true, true, "forceStopPackage", null); 3584 long callingId = Binder.clearCallingIdentity(); 3585 try { 3586 IPackageManager pm = AppGlobals.getPackageManager(); 3587 synchronized(this) { 3588 int[] users = userId == UserHandle.USER_ALL 3589 ? getUsersLocked() : new int[] { userId }; 3590 for (int user : users) { 3591 int pkgUid = -1; 3592 try { 3593 pkgUid = pm.getPackageUid(packageName, user); 3594 } catch (RemoteException e) { 3595 } 3596 if (pkgUid == -1) { 3597 Slog.w(TAG, "Invalid packageName: " + packageName); 3598 continue; 3599 } 3600 try { 3601 pm.setPackageStoppedState(packageName, true, user); 3602 } catch (RemoteException e) { 3603 } catch (IllegalArgumentException e) { 3604 Slog.w(TAG, "Failed trying to unstop package " 3605 + packageName + ": " + e); 3606 } 3607 if (isUserRunningLocked(user)) { 3608 forceStopPackageLocked(packageName, pkgUid); 3609 } 3610 } 3611 } 3612 } finally { 3613 Binder.restoreCallingIdentity(callingId); 3614 } 3615 } 3616 3617 /* 3618 * The pkg name and app id have to be specified. 3619 */ 3620 public void killApplicationWithAppId(String pkg, int appid) { 3621 if (pkg == null) { 3622 return; 3623 } 3624 // Make sure the uid is valid. 3625 if (appid < 0) { 3626 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3627 return; 3628 } 3629 int callerUid = Binder.getCallingUid(); 3630 // Only the system server can kill an application 3631 if (callerUid == Process.SYSTEM_UID) { 3632 // Post an aysnc message to kill the application 3633 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3634 msg.arg1 = appid; 3635 msg.arg2 = 0; 3636 msg.obj = pkg; 3637 mHandler.sendMessage(msg); 3638 } else { 3639 throw new SecurityException(callerUid + " cannot kill pkg: " + 3640 pkg); 3641 } 3642 } 3643 3644 public void closeSystemDialogs(String reason) { 3645 enforceNotIsolatedCaller("closeSystemDialogs"); 3646 3647 final int pid = Binder.getCallingPid(); 3648 final int uid = Binder.getCallingUid(); 3649 final long origId = Binder.clearCallingIdentity(); 3650 try { 3651 synchronized (this) { 3652 // Only allow this from foreground processes, so that background 3653 // applications can't abuse it to prevent system UI from being shown. 3654 if (uid >= Process.FIRST_APPLICATION_UID) { 3655 ProcessRecord proc; 3656 synchronized (mPidsSelfLocked) { 3657 proc = mPidsSelfLocked.get(pid); 3658 } 3659 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3660 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3661 + " from background process " + proc); 3662 return; 3663 } 3664 } 3665 closeSystemDialogsLocked(reason); 3666 } 3667 } finally { 3668 Binder.restoreCallingIdentity(origId); 3669 } 3670 } 3671 3672 void closeSystemDialogsLocked(String reason) { 3673 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3674 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3675 if (reason != null) { 3676 intent.putExtra("reason", reason); 3677 } 3678 mWindowManager.closeSystemDialogs(reason); 3679 3680 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3681 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3682 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3683 r.stack.finishActivityLocked(r, i, 3684 Activity.RESULT_CANCELED, null, "close-sys", true); 3685 } 3686 } 3687 3688 broadcastIntentLocked(null, null, intent, null, 3689 null, 0, null, null, null, false, false, -1, 3690 Process.SYSTEM_UID, UserHandle.USER_ALL); 3691 } 3692 3693 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3694 throws RemoteException { 3695 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3696 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3697 for (int i=pids.length-1; i>=0; i--) { 3698 infos[i] = new Debug.MemoryInfo(); 3699 Debug.getMemoryInfo(pids[i], infos[i]); 3700 } 3701 return infos; 3702 } 3703 3704 public long[] getProcessPss(int[] pids) throws RemoteException { 3705 enforceNotIsolatedCaller("getProcessPss"); 3706 long[] pss = new long[pids.length]; 3707 for (int i=pids.length-1; i>=0; i--) { 3708 pss[i] = Debug.getPss(pids[i]); 3709 } 3710 return pss; 3711 } 3712 3713 public void killApplicationProcess(String processName, int uid) { 3714 if (processName == null) { 3715 return; 3716 } 3717 3718 int callerUid = Binder.getCallingUid(); 3719 // Only the system server can kill an application 3720 if (callerUid == Process.SYSTEM_UID) { 3721 synchronized (this) { 3722 ProcessRecord app = getProcessRecordLocked(processName, uid); 3723 if (app != null && app.thread != null) { 3724 try { 3725 app.thread.scheduleSuicide(); 3726 } catch (RemoteException e) { 3727 // If the other end already died, then our work here is done. 3728 } 3729 } else { 3730 Slog.w(TAG, "Process/uid not found attempting kill of " 3731 + processName + " / " + uid); 3732 } 3733 } 3734 } else { 3735 throw new SecurityException(callerUid + " cannot kill app process: " + 3736 processName); 3737 } 3738 } 3739 3740 private void forceStopPackageLocked(final String packageName, int uid) { 3741 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3742 false, true, false, UserHandle.getUserId(uid)); 3743 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3744 Uri.fromParts("package", packageName, null)); 3745 if (!mProcessesReady) { 3746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3747 } 3748 intent.putExtra(Intent.EXTRA_UID, uid); 3749 broadcastIntentLocked(null, null, intent, 3750 null, null, 0, null, null, null, 3751 false, false, 3752 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3753 } 3754 3755 private void forceStopUserLocked(int userId) { 3756 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3757 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3758 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3759 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3760 broadcastIntentLocked(null, null, intent, 3761 null, null, 0, null, null, null, 3762 false, false, 3763 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3764 } 3765 3766 private final boolean killPackageProcessesLocked(String packageName, int appId, 3767 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3768 boolean doit, boolean evenPersistent, String reason) { 3769 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3770 3771 // Remove all processes this package may have touched: all with the 3772 // same UID (except for the system or root user), and all whose name 3773 // matches the package name. 3774 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3775 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3776 final int NA = apps.size(); 3777 for (int ia=0; ia<NA; ia++) { 3778 ProcessRecord app = apps.valueAt(ia); 3779 if (app.persistent && !evenPersistent) { 3780 // we don't kill persistent processes 3781 continue; 3782 } 3783 if (app.removed) { 3784 if (doit) { 3785 procs.add(app); 3786 } 3787 continue; 3788 } 3789 3790 // Skip process if it doesn't meet our oom adj requirement. 3791 if (app.setAdj < minOomAdj) { 3792 continue; 3793 } 3794 3795 // If no package is specified, we call all processes under the 3796 // give user id. 3797 if (packageName == null) { 3798 if (app.userId != userId) { 3799 continue; 3800 } 3801 // Package has been specified, we want to hit all processes 3802 // that match it. We need to qualify this by the processes 3803 // that are running under the specified app and user ID. 3804 } else { 3805 if (UserHandle.getAppId(app.uid) != appId) { 3806 continue; 3807 } 3808 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3809 continue; 3810 } 3811 if (!app.pkgList.contains(packageName)) { 3812 continue; 3813 } 3814 } 3815 3816 // Process has passed all conditions, kill it! 3817 if (!doit) { 3818 return true; 3819 } 3820 app.removed = true; 3821 procs.add(app); 3822 } 3823 } 3824 3825 int N = procs.size(); 3826 for (int i=0; i<N; i++) { 3827 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3828 } 3829 return N > 0; 3830 } 3831 3832 private final boolean forceStopPackageLocked(String name, int appId, 3833 boolean callerWillRestart, boolean purgeCache, boolean doit, 3834 boolean evenPersistent, int userId) { 3835 int i; 3836 int N; 3837 3838 if (userId == UserHandle.USER_ALL && name == null) { 3839 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3840 } 3841 3842 if (appId < 0 && name != null) { 3843 try { 3844 appId = UserHandle.getAppId( 3845 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3846 } catch (RemoteException e) { 3847 } 3848 } 3849 3850 if (doit) { 3851 if (name != null) { 3852 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3853 + " user=" + userId); 3854 } else { 3855 Slog.i(TAG, "Force stopping user " + userId); 3856 } 3857 3858 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3859 while (badApps.hasNext()) { 3860 SparseArray<Long> ba = badApps.next(); 3861 for (i=ba.size()-1; i>=0; i--) { 3862 boolean remove = false; 3863 final int entUid = ba.keyAt(i); 3864 if (name != null) { 3865 if (userId == UserHandle.USER_ALL) { 3866 if (UserHandle.getAppId(entUid) == appId) { 3867 remove = true; 3868 } 3869 } else { 3870 if (entUid == UserHandle.getUid(userId, appId)) { 3871 remove = true; 3872 } 3873 } 3874 } else if (UserHandle.getUserId(entUid) == userId) { 3875 remove = true; 3876 } 3877 if (remove) { 3878 ba.removeAt(i); 3879 } 3880 } 3881 if (ba.size() == 0) { 3882 badApps.remove(); 3883 } 3884 } 3885 } 3886 3887 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3888 -100, callerWillRestart, false, doit, evenPersistent, 3889 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3890 3891 TaskRecord lastTask = null; 3892 for (i=0; i<mMainStack.mHistory.size(); i++) { 3893 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3894 final boolean samePackage = r.packageName.equals(name) 3895 || (name == null && r.userId == userId); 3896 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3897 && (samePackage || r.task == lastTask) 3898 && (r.app == null || evenPersistent || !r.app.persistent)) { 3899 if (!doit) { 3900 if (r.finishing) { 3901 // If this activity is just finishing, then it is not 3902 // interesting as far as something to stop. 3903 continue; 3904 } 3905 return true; 3906 } 3907 didSomething = true; 3908 Slog.i(TAG, " Force finishing activity " + r); 3909 if (samePackage) { 3910 if (r.app != null) { 3911 r.app.removed = true; 3912 } 3913 r.app = null; 3914 } 3915 lastTask = r.task; 3916 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3917 null, "force-stop", true)) { 3918 i--; 3919 } 3920 } 3921 } 3922 3923 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3924 if (!doit) { 3925 return true; 3926 } 3927 didSomething = true; 3928 } 3929 3930 if (name == null) { 3931 // Remove all sticky broadcasts from this user. 3932 mStickyBroadcasts.remove(userId); 3933 } 3934 3935 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3936 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3937 userId, providers)) { 3938 if (!doit) { 3939 return true; 3940 } 3941 didSomething = true; 3942 } 3943 N = providers.size(); 3944 for (i=0; i<N; i++) { 3945 removeDyingProviderLocked(null, providers.get(i), true); 3946 } 3947 3948 if (mIntentSenderRecords.size() > 0) { 3949 Iterator<WeakReference<PendingIntentRecord>> it 3950 = mIntentSenderRecords.values().iterator(); 3951 while (it.hasNext()) { 3952 WeakReference<PendingIntentRecord> wpir = it.next(); 3953 if (wpir == null) { 3954 it.remove(); 3955 continue; 3956 } 3957 PendingIntentRecord pir = wpir.get(); 3958 if (pir == null) { 3959 it.remove(); 3960 continue; 3961 } 3962 if (name == null) { 3963 // Stopping user, remove all objects for the user. 3964 if (pir.key.userId != userId) { 3965 // Not the same user, skip it. 3966 continue; 3967 } 3968 } else { 3969 if (UserHandle.getAppId(pir.uid) != appId) { 3970 // Different app id, skip it. 3971 continue; 3972 } 3973 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3974 // Different user, skip it. 3975 continue; 3976 } 3977 if (!pir.key.packageName.equals(name)) { 3978 // Different package, skip it. 3979 continue; 3980 } 3981 } 3982 if (!doit) { 3983 return true; 3984 } 3985 didSomething = true; 3986 it.remove(); 3987 pir.canceled = true; 3988 if (pir.key.activity != null) { 3989 pir.key.activity.pendingResults.remove(pir.ref); 3990 } 3991 } 3992 } 3993 3994 if (doit) { 3995 if (purgeCache && name != null) { 3996 AttributeCache ac = AttributeCache.instance(); 3997 if (ac != null) { 3998 ac.removePackage(name); 3999 } 4000 } 4001 if (mBooted) { 4002 mMainStack.resumeTopActivityLocked(null); 4003 mMainStack.scheduleIdleLocked(); 4004 } 4005 } 4006 4007 return didSomething; 4008 } 4009 4010 private final boolean removeProcessLocked(ProcessRecord app, 4011 boolean callerWillRestart, boolean allowRestart, String reason) { 4012 final String name = app.processName; 4013 final int uid = app.uid; 4014 if (DEBUG_PROCESSES) Slog.d( 4015 TAG, "Force removing proc " + app.toShortString() + " (" + name 4016 + "/" + uid + ")"); 4017 4018 mProcessNames.remove(name, uid); 4019 mIsolatedProcesses.remove(app.uid); 4020 if (mHeavyWeightProcess == app) { 4021 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4022 mHeavyWeightProcess.userId, 0)); 4023 mHeavyWeightProcess = null; 4024 } 4025 boolean needRestart = false; 4026 if (app.pid > 0 && app.pid != MY_PID) { 4027 int pid = app.pid; 4028 synchronized (mPidsSelfLocked) { 4029 mPidsSelfLocked.remove(pid); 4030 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4031 } 4032 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4033 handleAppDiedLocked(app, true, allowRestart); 4034 mLruProcesses.remove(app); 4035 Process.killProcessQuiet(pid); 4036 4037 if (app.persistent && !app.isolated) { 4038 if (!callerWillRestart) { 4039 addAppLocked(app.info, false); 4040 } else { 4041 needRestart = true; 4042 } 4043 } 4044 } else { 4045 mRemovedProcesses.add(app); 4046 } 4047 4048 return needRestart; 4049 } 4050 4051 private final void processStartTimedOutLocked(ProcessRecord app) { 4052 final int pid = app.pid; 4053 boolean gone = false; 4054 synchronized (mPidsSelfLocked) { 4055 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4056 if (knownApp != null && knownApp.thread == null) { 4057 mPidsSelfLocked.remove(pid); 4058 gone = true; 4059 } 4060 } 4061 4062 if (gone) { 4063 Slog.w(TAG, "Process " + app + " failed to attach"); 4064 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4065 app.processName); 4066 mProcessNames.remove(app.processName, app.uid); 4067 mIsolatedProcesses.remove(app.uid); 4068 if (mHeavyWeightProcess == app) { 4069 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4070 mHeavyWeightProcess.userId, 0)); 4071 mHeavyWeightProcess = null; 4072 } 4073 // Take care of any launching providers waiting for this process. 4074 checkAppInLaunchingProvidersLocked(app, true); 4075 // Take care of any services that are waiting for the process. 4076 mServices.processStartTimedOutLocked(app); 4077 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4078 app.processName, app.setAdj, "start timeout"); 4079 Process.killProcessQuiet(pid); 4080 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4081 Slog.w(TAG, "Unattached app died before backup, skipping"); 4082 try { 4083 IBackupManager bm = IBackupManager.Stub.asInterface( 4084 ServiceManager.getService(Context.BACKUP_SERVICE)); 4085 bm.agentDisconnected(app.info.packageName); 4086 } catch (RemoteException e) { 4087 // Can't happen; the backup manager is local 4088 } 4089 } 4090 if (isPendingBroadcastProcessLocked(pid)) { 4091 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4092 skipPendingBroadcastLocked(pid); 4093 } 4094 } else { 4095 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4096 } 4097 } 4098 4099 private final boolean attachApplicationLocked(IApplicationThread thread, 4100 int pid) { 4101 4102 // Find the application record that is being attached... either via 4103 // the pid if we are running in multiple processes, or just pull the 4104 // next app record if we are emulating process with anonymous threads. 4105 ProcessRecord app; 4106 if (pid != MY_PID && pid >= 0) { 4107 synchronized (mPidsSelfLocked) { 4108 app = mPidsSelfLocked.get(pid); 4109 } 4110 } else { 4111 app = null; 4112 } 4113 4114 if (app == null) { 4115 Slog.w(TAG, "No pending application record for pid " + pid 4116 + " (IApplicationThread " + thread + "); dropping process"); 4117 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4118 if (pid > 0 && pid != MY_PID) { 4119 Process.killProcessQuiet(pid); 4120 } else { 4121 try { 4122 thread.scheduleExit(); 4123 } catch (Exception e) { 4124 // Ignore exceptions. 4125 } 4126 } 4127 return false; 4128 } 4129 4130 // If this application record is still attached to a previous 4131 // process, clean it up now. 4132 if (app.thread != null) { 4133 handleAppDiedLocked(app, true, true); 4134 } 4135 4136 // Tell the process all about itself. 4137 4138 if (localLOGV) Slog.v( 4139 TAG, "Binding process pid " + pid + " to record " + app); 4140 4141 String processName = app.processName; 4142 try { 4143 AppDeathRecipient adr = new AppDeathRecipient( 4144 app, pid, thread); 4145 thread.asBinder().linkToDeath(adr, 0); 4146 app.deathRecipient = adr; 4147 } catch (RemoteException e) { 4148 app.resetPackageList(); 4149 startProcessLocked(app, "link fail", processName); 4150 return false; 4151 } 4152 4153 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4154 4155 app.thread = thread; 4156 app.curAdj = app.setAdj = -100; 4157 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4158 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4159 app.forcingToForeground = null; 4160 app.foregroundServices = false; 4161 app.hasShownUi = false; 4162 app.debugging = false; 4163 4164 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4165 4166 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4167 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4168 4169 if (!normalMode) { 4170 Slog.i(TAG, "Launching preboot mode app: " + app); 4171 } 4172 4173 if (localLOGV) Slog.v( 4174 TAG, "New app record " + app 4175 + " thread=" + thread.asBinder() + " pid=" + pid); 4176 try { 4177 int testMode = IApplicationThread.DEBUG_OFF; 4178 if (mDebugApp != null && mDebugApp.equals(processName)) { 4179 testMode = mWaitForDebugger 4180 ? IApplicationThread.DEBUG_WAIT 4181 : IApplicationThread.DEBUG_ON; 4182 app.debugging = true; 4183 if (mDebugTransient) { 4184 mDebugApp = mOrigDebugApp; 4185 mWaitForDebugger = mOrigWaitForDebugger; 4186 } 4187 } 4188 String profileFile = app.instrumentationProfileFile; 4189 ParcelFileDescriptor profileFd = null; 4190 boolean profileAutoStop = false; 4191 if (mProfileApp != null && mProfileApp.equals(processName)) { 4192 mProfileProc = app; 4193 profileFile = mProfileFile; 4194 profileFd = mProfileFd; 4195 profileAutoStop = mAutoStopProfiler; 4196 } 4197 boolean enableOpenGlTrace = false; 4198 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4199 enableOpenGlTrace = true; 4200 mOpenGlTraceApp = null; 4201 } 4202 4203 // If the app is being launched for restore or full backup, set it up specially 4204 boolean isRestrictedBackupMode = false; 4205 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4206 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4207 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4208 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4209 } 4210 4211 ensurePackageDexOpt(app.instrumentationInfo != null 4212 ? app.instrumentationInfo.packageName 4213 : app.info.packageName); 4214 if (app.instrumentationClass != null) { 4215 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4216 } 4217 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4218 + processName + " with config " + mConfiguration); 4219 ApplicationInfo appInfo = app.instrumentationInfo != null 4220 ? app.instrumentationInfo : app.info; 4221 app.compat = compatibilityInfoForPackageLocked(appInfo); 4222 if (profileFd != null) { 4223 profileFd = profileFd.dup(); 4224 } 4225 thread.bindApplication(processName, appInfo, providers, 4226 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4227 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4228 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4229 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4230 mCoreSettingsObserver.getCoreSettingsLocked()); 4231 updateLruProcessLocked(app, false, true); 4232 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4233 } catch (Exception e) { 4234 // todo: Yikes! What should we do? For now we will try to 4235 // start another process, but that could easily get us in 4236 // an infinite loop of restarting processes... 4237 Slog.w(TAG, "Exception thrown during bind!", e); 4238 4239 app.resetPackageList(); 4240 app.unlinkDeathRecipient(); 4241 startProcessLocked(app, "bind fail", processName); 4242 return false; 4243 } 4244 4245 // Remove this record from the list of starting applications. 4246 mPersistentStartingProcesses.remove(app); 4247 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4248 "Attach application locked removing on hold: " + app); 4249 mProcessesOnHold.remove(app); 4250 4251 boolean badApp = false; 4252 boolean didSomething = false; 4253 4254 // See if the top visible activity is waiting to run in this process... 4255 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4256 if (hr != null && normalMode) { 4257 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4258 && processName.equals(hr.processName)) { 4259 try { 4260 if (mHeadless) { 4261 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4262 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4263 didSomething = true; 4264 } 4265 } catch (Exception e) { 4266 Slog.w(TAG, "Exception in new application when starting activity " 4267 + hr.intent.getComponent().flattenToShortString(), e); 4268 badApp = true; 4269 } 4270 } else { 4271 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4272 } 4273 } 4274 4275 // Find any services that should be running in this process... 4276 if (!badApp) { 4277 try { 4278 didSomething |= mServices.attachApplicationLocked(app, processName); 4279 } catch (Exception e) { 4280 badApp = true; 4281 } 4282 } 4283 4284 // Check if a next-broadcast receiver is in this process... 4285 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4286 try { 4287 didSomething = sendPendingBroadcastsLocked(app); 4288 } catch (Exception e) { 4289 // If the app died trying to launch the receiver we declare it 'bad' 4290 badApp = true; 4291 } 4292 } 4293 4294 // Check whether the next backup agent is in this process... 4295 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4296 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4297 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4298 try { 4299 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4300 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4301 mBackupTarget.backupMode); 4302 } catch (Exception e) { 4303 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4304 e.printStackTrace(); 4305 } 4306 } 4307 4308 if (badApp) { 4309 // todo: Also need to kill application to deal with all 4310 // kinds of exceptions. 4311 handleAppDiedLocked(app, false, true); 4312 return false; 4313 } 4314 4315 if (!didSomething) { 4316 updateOomAdjLocked(); 4317 } 4318 4319 return true; 4320 } 4321 4322 public final void attachApplication(IApplicationThread thread) { 4323 synchronized (this) { 4324 int callingPid = Binder.getCallingPid(); 4325 final long origId = Binder.clearCallingIdentity(); 4326 attachApplicationLocked(thread, callingPid); 4327 Binder.restoreCallingIdentity(origId); 4328 } 4329 } 4330 4331 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4332 final long origId = Binder.clearCallingIdentity(); 4333 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4334 if (stopProfiling) { 4335 synchronized (this) { 4336 if (mProfileProc == r.app) { 4337 if (mProfileFd != null) { 4338 try { 4339 mProfileFd.close(); 4340 } catch (IOException e) { 4341 } 4342 clearProfilerLocked(); 4343 } 4344 } 4345 } 4346 } 4347 Binder.restoreCallingIdentity(origId); 4348 } 4349 4350 void enableScreenAfterBoot() { 4351 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4352 SystemClock.uptimeMillis()); 4353 mWindowManager.enableScreenAfterBoot(); 4354 4355 synchronized (this) { 4356 updateEventDispatchingLocked(); 4357 } 4358 } 4359 4360 public void showBootMessage(final CharSequence msg, final boolean always) { 4361 enforceNotIsolatedCaller("showBootMessage"); 4362 mWindowManager.showBootMessage(msg, always); 4363 } 4364 4365 public void dismissKeyguardOnNextActivity() { 4366 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4367 final long token = Binder.clearCallingIdentity(); 4368 try { 4369 synchronized (this) { 4370 if (mLockScreenShown) { 4371 mLockScreenShown = false; 4372 comeOutOfSleepIfNeededLocked(); 4373 } 4374 mMainStack.dismissKeyguardOnNextActivityLocked(); 4375 } 4376 } finally { 4377 Binder.restoreCallingIdentity(token); 4378 } 4379 } 4380 4381 final void finishBooting() { 4382 IntentFilter pkgFilter = new IntentFilter(); 4383 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4384 pkgFilter.addDataScheme("package"); 4385 mContext.registerReceiver(new BroadcastReceiver() { 4386 @Override 4387 public void onReceive(Context context, Intent intent) { 4388 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4389 if (pkgs != null) { 4390 for (String pkg : pkgs) { 4391 synchronized (ActivityManagerService.this) { 4392 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4393 setResultCode(Activity.RESULT_OK); 4394 return; 4395 } 4396 } 4397 } 4398 } 4399 } 4400 }, pkgFilter); 4401 4402 synchronized (this) { 4403 // Ensure that any processes we had put on hold are now started 4404 // up. 4405 final int NP = mProcessesOnHold.size(); 4406 if (NP > 0) { 4407 ArrayList<ProcessRecord> procs = 4408 new ArrayList<ProcessRecord>(mProcessesOnHold); 4409 for (int ip=0; ip<NP; ip++) { 4410 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4411 + procs.get(ip)); 4412 startProcessLocked(procs.get(ip), "on-hold", null); 4413 } 4414 } 4415 4416 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4417 // Start looking for apps that are abusing wake locks. 4418 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4419 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4420 // Tell anyone interested that we are done booting! 4421 SystemProperties.set("sys.boot_completed", "1"); 4422 SystemProperties.set("dev.bootcomplete", "1"); 4423 for (int i=0; i<mStartedUsers.size(); i++) { 4424 UserStartedState uss = mStartedUsers.valueAt(i); 4425 if (uss.mState == UserStartedState.STATE_BOOTING) { 4426 uss.mState = UserStartedState.STATE_RUNNING; 4427 final int userId = mStartedUsers.keyAt(i); 4428 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4429 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4430 broadcastIntentLocked(null, null, intent, 4431 null, null, 0, null, null, 4432 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4433 false, false, MY_PID, Process.SYSTEM_UID, userId); 4434 } 4435 } 4436 } 4437 } 4438 } 4439 4440 final void ensureBootCompleted() { 4441 boolean booting; 4442 boolean enableScreen; 4443 synchronized (this) { 4444 booting = mBooting; 4445 mBooting = false; 4446 enableScreen = !mBooted; 4447 mBooted = true; 4448 } 4449 4450 if (booting) { 4451 finishBooting(); 4452 } 4453 4454 if (enableScreen) { 4455 enableScreenAfterBoot(); 4456 } 4457 } 4458 4459 public final void activityPaused(IBinder token) { 4460 final long origId = Binder.clearCallingIdentity(); 4461 mMainStack.activityPaused(token, false); 4462 Binder.restoreCallingIdentity(origId); 4463 } 4464 4465 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4466 CharSequence description) { 4467 if (localLOGV) Slog.v( 4468 TAG, "Activity stopped: token=" + token); 4469 4470 // Refuse possible leaked file descriptors 4471 if (icicle != null && icicle.hasFileDescriptors()) { 4472 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4473 } 4474 4475 ActivityRecord r = null; 4476 4477 final long origId = Binder.clearCallingIdentity(); 4478 4479 synchronized (this) { 4480 r = mMainStack.isInStackLocked(token); 4481 if (r != null) { 4482 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4483 } 4484 } 4485 4486 if (r != null) { 4487 sendPendingThumbnail(r, null, null, null, false); 4488 } 4489 4490 trimApplications(); 4491 4492 Binder.restoreCallingIdentity(origId); 4493 } 4494 4495 public final void activityDestroyed(IBinder token) { 4496 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4497 mMainStack.activityDestroyed(token); 4498 } 4499 4500 public String getCallingPackage(IBinder token) { 4501 synchronized (this) { 4502 ActivityRecord r = getCallingRecordLocked(token); 4503 return r != null && r.app != null ? r.info.packageName : null; 4504 } 4505 } 4506 4507 public ComponentName getCallingActivity(IBinder token) { 4508 synchronized (this) { 4509 ActivityRecord r = getCallingRecordLocked(token); 4510 return r != null ? r.intent.getComponent() : null; 4511 } 4512 } 4513 4514 private ActivityRecord getCallingRecordLocked(IBinder token) { 4515 ActivityRecord r = mMainStack.isInStackLocked(token); 4516 if (r == null) { 4517 return null; 4518 } 4519 return r.resultTo; 4520 } 4521 4522 public ComponentName getActivityClassForToken(IBinder token) { 4523 synchronized(this) { 4524 ActivityRecord r = mMainStack.isInStackLocked(token); 4525 if (r == null) { 4526 return null; 4527 } 4528 return r.intent.getComponent(); 4529 } 4530 } 4531 4532 public String getPackageForToken(IBinder token) { 4533 synchronized(this) { 4534 ActivityRecord r = mMainStack.isInStackLocked(token); 4535 if (r == null) { 4536 return null; 4537 } 4538 return r.packageName; 4539 } 4540 } 4541 4542 public IIntentSender getIntentSender(int type, 4543 String packageName, IBinder token, String resultWho, 4544 int requestCode, Intent[] intents, String[] resolvedTypes, 4545 int flags, Bundle options, int userId) { 4546 enforceNotIsolatedCaller("getIntentSender"); 4547 // Refuse possible leaked file descriptors 4548 if (intents != null) { 4549 if (intents.length < 1) { 4550 throw new IllegalArgumentException("Intents array length must be >= 1"); 4551 } 4552 for (int i=0; i<intents.length; i++) { 4553 Intent intent = intents[i]; 4554 if (intent != null) { 4555 if (intent.hasFileDescriptors()) { 4556 throw new IllegalArgumentException("File descriptors passed in Intent"); 4557 } 4558 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4559 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4560 throw new IllegalArgumentException( 4561 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4562 } 4563 intents[i] = new Intent(intent); 4564 } 4565 } 4566 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4567 throw new IllegalArgumentException( 4568 "Intent array length does not match resolvedTypes length"); 4569 } 4570 } 4571 if (options != null) { 4572 if (options.hasFileDescriptors()) { 4573 throw new IllegalArgumentException("File descriptors passed in options"); 4574 } 4575 } 4576 4577 synchronized(this) { 4578 int callingUid = Binder.getCallingUid(); 4579 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4580 false, true, "getIntentSender", null); 4581 try { 4582 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4583 int uid = AppGlobals.getPackageManager() 4584 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4585 if (!UserHandle.isSameApp(callingUid, uid)) { 4586 String msg = "Permission Denial: getIntentSender() from pid=" 4587 + Binder.getCallingPid() 4588 + ", uid=" + Binder.getCallingUid() 4589 + ", (need uid=" + uid + ")" 4590 + " is not allowed to send as package " + packageName; 4591 Slog.w(TAG, msg); 4592 throw new SecurityException(msg); 4593 } 4594 } 4595 4596 return getIntentSenderLocked(type, packageName, callingUid, userId, 4597 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4598 4599 } catch (RemoteException e) { 4600 throw new SecurityException(e); 4601 } 4602 } 4603 } 4604 4605 IIntentSender getIntentSenderLocked(int type, String packageName, 4606 int callingUid, int userId, IBinder token, String resultWho, 4607 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4608 Bundle options) { 4609 if (DEBUG_MU) 4610 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4611 ActivityRecord activity = null; 4612 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4613 activity = mMainStack.isInStackLocked(token); 4614 if (activity == null) { 4615 return null; 4616 } 4617 if (activity.finishing) { 4618 return null; 4619 } 4620 } 4621 4622 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4623 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4624 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4625 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4626 |PendingIntent.FLAG_UPDATE_CURRENT); 4627 4628 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4629 type, packageName, activity, resultWho, 4630 requestCode, intents, resolvedTypes, flags, options, userId); 4631 WeakReference<PendingIntentRecord> ref; 4632 ref = mIntentSenderRecords.get(key); 4633 PendingIntentRecord rec = ref != null ? ref.get() : null; 4634 if (rec != null) { 4635 if (!cancelCurrent) { 4636 if (updateCurrent) { 4637 if (rec.key.requestIntent != null) { 4638 rec.key.requestIntent.replaceExtras(intents != null ? 4639 intents[intents.length - 1] : null); 4640 } 4641 if (intents != null) { 4642 intents[intents.length-1] = rec.key.requestIntent; 4643 rec.key.allIntents = intents; 4644 rec.key.allResolvedTypes = resolvedTypes; 4645 } else { 4646 rec.key.allIntents = null; 4647 rec.key.allResolvedTypes = null; 4648 } 4649 } 4650 return rec; 4651 } 4652 rec.canceled = true; 4653 mIntentSenderRecords.remove(key); 4654 } 4655 if (noCreate) { 4656 return rec; 4657 } 4658 rec = new PendingIntentRecord(this, key, callingUid); 4659 mIntentSenderRecords.put(key, rec.ref); 4660 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4661 if (activity.pendingResults == null) { 4662 activity.pendingResults 4663 = new HashSet<WeakReference<PendingIntentRecord>>(); 4664 } 4665 activity.pendingResults.add(rec.ref); 4666 } 4667 return rec; 4668 } 4669 4670 public void cancelIntentSender(IIntentSender sender) { 4671 if (!(sender instanceof PendingIntentRecord)) { 4672 return; 4673 } 4674 synchronized(this) { 4675 PendingIntentRecord rec = (PendingIntentRecord)sender; 4676 try { 4677 int uid = AppGlobals.getPackageManager() 4678 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4679 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4680 String msg = "Permission Denial: cancelIntentSender() from pid=" 4681 + Binder.getCallingPid() 4682 + ", uid=" + Binder.getCallingUid() 4683 + " is not allowed to cancel packges " 4684 + rec.key.packageName; 4685 Slog.w(TAG, msg); 4686 throw new SecurityException(msg); 4687 } 4688 } catch (RemoteException e) { 4689 throw new SecurityException(e); 4690 } 4691 cancelIntentSenderLocked(rec, true); 4692 } 4693 } 4694 4695 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4696 rec.canceled = true; 4697 mIntentSenderRecords.remove(rec.key); 4698 if (cleanActivity && rec.key.activity != null) { 4699 rec.key.activity.pendingResults.remove(rec.ref); 4700 } 4701 } 4702 4703 public String getPackageForIntentSender(IIntentSender pendingResult) { 4704 if (!(pendingResult instanceof PendingIntentRecord)) { 4705 return null; 4706 } 4707 try { 4708 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4709 return res.key.packageName; 4710 } catch (ClassCastException e) { 4711 } 4712 return null; 4713 } 4714 4715 public int getUidForIntentSender(IIntentSender sender) { 4716 if (sender instanceof PendingIntentRecord) { 4717 try { 4718 PendingIntentRecord res = (PendingIntentRecord)sender; 4719 return res.uid; 4720 } catch (ClassCastException e) { 4721 } 4722 } 4723 return -1; 4724 } 4725 4726 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4727 if (!(pendingResult instanceof PendingIntentRecord)) { 4728 return false; 4729 } 4730 try { 4731 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4732 if (res.key.allIntents == null) { 4733 return false; 4734 } 4735 for (int i=0; i<res.key.allIntents.length; i++) { 4736 Intent intent = res.key.allIntents[i]; 4737 if (intent.getPackage() != null && intent.getComponent() != null) { 4738 return false; 4739 } 4740 } 4741 return true; 4742 } catch (ClassCastException e) { 4743 } 4744 return false; 4745 } 4746 4747 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4748 if (!(pendingResult instanceof PendingIntentRecord)) { 4749 return false; 4750 } 4751 try { 4752 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4753 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4754 return true; 4755 } 4756 return false; 4757 } catch (ClassCastException e) { 4758 } 4759 return false; 4760 } 4761 4762 public void setProcessLimit(int max) { 4763 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4764 "setProcessLimit()"); 4765 synchronized (this) { 4766 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4767 mProcessLimitOverride = max; 4768 } 4769 trimApplications(); 4770 } 4771 4772 public int getProcessLimit() { 4773 synchronized (this) { 4774 return mProcessLimitOverride; 4775 } 4776 } 4777 4778 void foregroundTokenDied(ForegroundToken token) { 4779 synchronized (ActivityManagerService.this) { 4780 synchronized (mPidsSelfLocked) { 4781 ForegroundToken cur 4782 = mForegroundProcesses.get(token.pid); 4783 if (cur != token) { 4784 return; 4785 } 4786 mForegroundProcesses.remove(token.pid); 4787 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4788 if (pr == null) { 4789 return; 4790 } 4791 pr.forcingToForeground = null; 4792 pr.foregroundServices = false; 4793 } 4794 updateOomAdjLocked(); 4795 } 4796 } 4797 4798 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4799 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4800 "setProcessForeground()"); 4801 synchronized(this) { 4802 boolean changed = false; 4803 4804 synchronized (mPidsSelfLocked) { 4805 ProcessRecord pr = mPidsSelfLocked.get(pid); 4806 if (pr == null && isForeground) { 4807 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4808 return; 4809 } 4810 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4811 if (oldToken != null) { 4812 oldToken.token.unlinkToDeath(oldToken, 0); 4813 mForegroundProcesses.remove(pid); 4814 if (pr != null) { 4815 pr.forcingToForeground = null; 4816 } 4817 changed = true; 4818 } 4819 if (isForeground && token != null) { 4820 ForegroundToken newToken = new ForegroundToken() { 4821 public void binderDied() { 4822 foregroundTokenDied(this); 4823 } 4824 }; 4825 newToken.pid = pid; 4826 newToken.token = token; 4827 try { 4828 token.linkToDeath(newToken, 0); 4829 mForegroundProcesses.put(pid, newToken); 4830 pr.forcingToForeground = token; 4831 changed = true; 4832 } catch (RemoteException e) { 4833 // If the process died while doing this, we will later 4834 // do the cleanup with the process death link. 4835 } 4836 } 4837 } 4838 4839 if (changed) { 4840 updateOomAdjLocked(); 4841 } 4842 } 4843 } 4844 4845 // ========================================================= 4846 // PERMISSIONS 4847 // ========================================================= 4848 4849 static class PermissionController extends IPermissionController.Stub { 4850 ActivityManagerService mActivityManagerService; 4851 PermissionController(ActivityManagerService activityManagerService) { 4852 mActivityManagerService = activityManagerService; 4853 } 4854 4855 public boolean checkPermission(String permission, int pid, int uid) { 4856 return mActivityManagerService.checkPermission(permission, pid, 4857 uid) == PackageManager.PERMISSION_GRANTED; 4858 } 4859 } 4860 4861 /** 4862 * This can be called with or without the global lock held. 4863 */ 4864 int checkComponentPermission(String permission, int pid, int uid, 4865 int owningUid, boolean exported) { 4866 // We might be performing an operation on behalf of an indirect binder 4867 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4868 // client identity accordingly before proceeding. 4869 Identity tlsIdentity = sCallerIdentity.get(); 4870 if (tlsIdentity != null) { 4871 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4872 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4873 uid = tlsIdentity.uid; 4874 pid = tlsIdentity.pid; 4875 } 4876 4877 if (pid == MY_PID) { 4878 return PackageManager.PERMISSION_GRANTED; 4879 } 4880 4881 return ActivityManager.checkComponentPermission(permission, uid, 4882 owningUid, exported); 4883 } 4884 4885 /** 4886 * As the only public entry point for permissions checking, this method 4887 * can enforce the semantic that requesting a check on a null global 4888 * permission is automatically denied. (Internally a null permission 4889 * string is used when calling {@link #checkComponentPermission} in cases 4890 * when only uid-based security is needed.) 4891 * 4892 * This can be called with or without the global lock held. 4893 */ 4894 public int checkPermission(String permission, int pid, int uid) { 4895 if (permission == null) { 4896 return PackageManager.PERMISSION_DENIED; 4897 } 4898 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4899 } 4900 4901 /** 4902 * Binder IPC calls go through the public entry point. 4903 * This can be called with or without the global lock held. 4904 */ 4905 int checkCallingPermission(String permission) { 4906 return checkPermission(permission, 4907 Binder.getCallingPid(), 4908 UserHandle.getAppId(Binder.getCallingUid())); 4909 } 4910 4911 /** 4912 * This can be called with or without the global lock held. 4913 */ 4914 void enforceCallingPermission(String permission, String func) { 4915 if (checkCallingPermission(permission) 4916 == PackageManager.PERMISSION_GRANTED) { 4917 return; 4918 } 4919 4920 String msg = "Permission Denial: " + func + " from pid=" 4921 + Binder.getCallingPid() 4922 + ", uid=" + Binder.getCallingUid() 4923 + " requires " + permission; 4924 Slog.w(TAG, msg); 4925 throw new SecurityException(msg); 4926 } 4927 4928 /** 4929 * Determine if UID is holding permissions required to access {@link Uri} in 4930 * the given {@link ProviderInfo}. Final permission checking is always done 4931 * in {@link ContentProvider}. 4932 */ 4933 private final boolean checkHoldingPermissionsLocked( 4934 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4935 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4936 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4937 4938 if (pi.applicationInfo.uid == uid) { 4939 return true; 4940 } else if (!pi.exported) { 4941 return false; 4942 } 4943 4944 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4945 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4946 try { 4947 // check if target holds top-level <provider> permissions 4948 if (!readMet && pi.readPermission != null 4949 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4950 readMet = true; 4951 } 4952 if (!writeMet && pi.writePermission != null 4953 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4954 writeMet = true; 4955 } 4956 4957 // track if unprotected read/write is allowed; any denied 4958 // <path-permission> below removes this ability 4959 boolean allowDefaultRead = pi.readPermission == null; 4960 boolean allowDefaultWrite = pi.writePermission == null; 4961 4962 // check if target holds any <path-permission> that match uri 4963 final PathPermission[] pps = pi.pathPermissions; 4964 if (pps != null) { 4965 final String path = uri.getPath(); 4966 int i = pps.length; 4967 while (i > 0 && (!readMet || !writeMet)) { 4968 i--; 4969 PathPermission pp = pps[i]; 4970 if (pp.match(path)) { 4971 if (!readMet) { 4972 final String pprperm = pp.getReadPermission(); 4973 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4974 + pprperm + " for " + pp.getPath() 4975 + ": match=" + pp.match(path) 4976 + " check=" + pm.checkUidPermission(pprperm, uid)); 4977 if (pprperm != null) { 4978 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4979 readMet = true; 4980 } else { 4981 allowDefaultRead = false; 4982 } 4983 } 4984 } 4985 if (!writeMet) { 4986 final String ppwperm = pp.getWritePermission(); 4987 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4988 + ppwperm + " for " + pp.getPath() 4989 + ": match=" + pp.match(path) 4990 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4991 if (ppwperm != null) { 4992 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4993 writeMet = true; 4994 } else { 4995 allowDefaultWrite = false; 4996 } 4997 } 4998 } 4999 } 5000 } 5001 } 5002 5003 // grant unprotected <provider> read/write, if not blocked by 5004 // <path-permission> above 5005 if (allowDefaultRead) readMet = true; 5006 if (allowDefaultWrite) writeMet = true; 5007 5008 } catch (RemoteException e) { 5009 return false; 5010 } 5011 5012 return readMet && writeMet; 5013 } 5014 5015 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5016 int modeFlags) { 5017 // Root gets to do everything. 5018 if (uid == 0) { 5019 return true; 5020 } 5021 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5022 if (perms == null) return false; 5023 UriPermission perm = perms.get(uri); 5024 if (perm == null) return false; 5025 return (modeFlags&perm.modeFlags) == modeFlags; 5026 } 5027 5028 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5029 enforceNotIsolatedCaller("checkUriPermission"); 5030 5031 // Another redirected-binder-call permissions check as in 5032 // {@link checkComponentPermission}. 5033 Identity tlsIdentity = sCallerIdentity.get(); 5034 if (tlsIdentity != null) { 5035 uid = tlsIdentity.uid; 5036 pid = tlsIdentity.pid; 5037 } 5038 5039 // Our own process gets to do everything. 5040 if (pid == MY_PID) { 5041 return PackageManager.PERMISSION_GRANTED; 5042 } 5043 synchronized(this) { 5044 return checkUriPermissionLocked(uri, uid, modeFlags) 5045 ? PackageManager.PERMISSION_GRANTED 5046 : PackageManager.PERMISSION_DENIED; 5047 } 5048 } 5049 5050 /** 5051 * Check if the targetPkg can be granted permission to access uri by 5052 * the callingUid using the given modeFlags. Throws a security exception 5053 * if callingUid is not allowed to do this. Returns the uid of the target 5054 * if the URI permission grant should be performed; returns -1 if it is not 5055 * needed (for example targetPkg already has permission to access the URI). 5056 * If you already know the uid of the target, you can supply it in 5057 * lastTargetUid else set that to -1. 5058 */ 5059 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5060 Uri uri, int modeFlags, int lastTargetUid) { 5061 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5062 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5063 if (modeFlags == 0) { 5064 return -1; 5065 } 5066 5067 if (targetPkg != null) { 5068 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5069 "Checking grant " + targetPkg + " permission to " + uri); 5070 } 5071 5072 final IPackageManager pm = AppGlobals.getPackageManager(); 5073 5074 // If this is not a content: uri, we can't do anything with it. 5075 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5076 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5077 "Can't grant URI permission for non-content URI: " + uri); 5078 return -1; 5079 } 5080 5081 String name = uri.getAuthority(); 5082 ProviderInfo pi = null; 5083 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5084 UserHandle.getUserId(callingUid)); 5085 if (cpr != null) { 5086 pi = cpr.info; 5087 } else { 5088 try { 5089 pi = pm.resolveContentProvider(name, 5090 PackageManager.GET_URI_PERMISSION_PATTERNS, 5091 UserHandle.getUserId(callingUid)); 5092 } catch (RemoteException ex) { 5093 } 5094 } 5095 if (pi == null) { 5096 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5097 return -1; 5098 } 5099 5100 int targetUid = lastTargetUid; 5101 if (targetUid < 0 && targetPkg != null) { 5102 try { 5103 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5104 if (targetUid < 0) { 5105 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5106 "Can't grant URI permission no uid for: " + targetPkg); 5107 return -1; 5108 } 5109 } catch (RemoteException ex) { 5110 return -1; 5111 } 5112 } 5113 5114 if (targetUid >= 0) { 5115 // First... does the target actually need this permission? 5116 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5117 // No need to grant the target this permission. 5118 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5119 "Target " + targetPkg + " already has full permission to " + uri); 5120 return -1; 5121 } 5122 } else { 5123 // First... there is no target package, so can anyone access it? 5124 boolean allowed = pi.exported; 5125 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5126 if (pi.readPermission != null) { 5127 allowed = false; 5128 } 5129 } 5130 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5131 if (pi.writePermission != null) { 5132 allowed = false; 5133 } 5134 } 5135 if (allowed) { 5136 return -1; 5137 } 5138 } 5139 5140 // Second... is the provider allowing granting of URI permissions? 5141 if (!pi.grantUriPermissions) { 5142 throw new SecurityException("Provider " + pi.packageName 5143 + "/" + pi.name 5144 + " does not allow granting of Uri permissions (uri " 5145 + uri + ")"); 5146 } 5147 if (pi.uriPermissionPatterns != null) { 5148 final int N = pi.uriPermissionPatterns.length; 5149 boolean allowed = false; 5150 for (int i=0; i<N; i++) { 5151 if (pi.uriPermissionPatterns[i] != null 5152 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5153 allowed = true; 5154 break; 5155 } 5156 } 5157 if (!allowed) { 5158 throw new SecurityException("Provider " + pi.packageName 5159 + "/" + pi.name 5160 + " does not allow granting of permission to path of Uri " 5161 + uri); 5162 } 5163 } 5164 5165 // Third... does the caller itself have permission to access 5166 // this uri? 5167 if (callingUid != Process.myUid()) { 5168 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5169 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5170 throw new SecurityException("Uid " + callingUid 5171 + " does not have permission to uri " + uri); 5172 } 5173 } 5174 } 5175 5176 return targetUid; 5177 } 5178 5179 public int checkGrantUriPermission(int callingUid, String targetPkg, 5180 Uri uri, int modeFlags) { 5181 enforceNotIsolatedCaller("checkGrantUriPermission"); 5182 synchronized(this) { 5183 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5184 } 5185 } 5186 5187 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5188 Uri uri, int modeFlags, UriPermissionOwner owner) { 5189 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5190 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5191 if (modeFlags == 0) { 5192 return; 5193 } 5194 5195 // So here we are: the caller has the assumed permission 5196 // to the uri, and the target doesn't. Let's now give this to 5197 // the target. 5198 5199 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5200 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5201 5202 HashMap<Uri, UriPermission> targetUris 5203 = mGrantedUriPermissions.get(targetUid); 5204 if (targetUris == null) { 5205 targetUris = new HashMap<Uri, UriPermission>(); 5206 mGrantedUriPermissions.put(targetUid, targetUris); 5207 } 5208 5209 UriPermission perm = targetUris.get(uri); 5210 if (perm == null) { 5211 perm = new UriPermission(targetUid, uri); 5212 targetUris.put(uri, perm); 5213 } 5214 5215 perm.modeFlags |= modeFlags; 5216 if (owner == null) { 5217 perm.globalModeFlags |= modeFlags; 5218 } else { 5219 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5220 perm.readOwners.add(owner); 5221 owner.addReadPermission(perm); 5222 } 5223 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5224 perm.writeOwners.add(owner); 5225 owner.addWritePermission(perm); 5226 } 5227 } 5228 } 5229 5230 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5231 int modeFlags, UriPermissionOwner owner) { 5232 if (targetPkg == null) { 5233 throw new NullPointerException("targetPkg"); 5234 } 5235 5236 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5237 if (targetUid < 0) { 5238 return; 5239 } 5240 5241 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5242 } 5243 5244 static class NeededUriGrants extends ArrayList<Uri> { 5245 final String targetPkg; 5246 final int targetUid; 5247 final int flags; 5248 5249 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5250 targetPkg = _targetPkg; 5251 targetUid = _targetUid; 5252 flags = _flags; 5253 } 5254 } 5255 5256 /** 5257 * Like checkGrantUriPermissionLocked, but takes an Intent. 5258 */ 5259 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5260 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5261 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5262 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5263 + " clip=" + (intent != null ? intent.getClipData() : null) 5264 + " from " + intent + "; flags=0x" 5265 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5266 5267 if (targetPkg == null) { 5268 throw new NullPointerException("targetPkg"); 5269 } 5270 5271 if (intent == null) { 5272 return null; 5273 } 5274 Uri data = intent.getData(); 5275 ClipData clip = intent.getClipData(); 5276 if (data == null && clip == null) { 5277 return null; 5278 } 5279 if (data != null) { 5280 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5281 mode, needed != null ? needed.targetUid : -1); 5282 if (target > 0) { 5283 if (needed == null) { 5284 needed = new NeededUriGrants(targetPkg, target, mode); 5285 } 5286 needed.add(data); 5287 } 5288 } 5289 if (clip != null) { 5290 for (int i=0; i<clip.getItemCount(); i++) { 5291 Uri uri = clip.getItemAt(i).getUri(); 5292 if (uri != null) { 5293 int target = -1; 5294 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5295 mode, needed != null ? needed.targetUid : -1); 5296 if (target > 0) { 5297 if (needed == null) { 5298 needed = new NeededUriGrants(targetPkg, target, mode); 5299 } 5300 needed.add(uri); 5301 } 5302 } else { 5303 Intent clipIntent = clip.getItemAt(i).getIntent(); 5304 if (clipIntent != null) { 5305 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5306 callingUid, targetPkg, clipIntent, mode, needed); 5307 if (newNeeded != null) { 5308 needed = newNeeded; 5309 } 5310 } 5311 } 5312 } 5313 } 5314 5315 return needed; 5316 } 5317 5318 /** 5319 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5320 */ 5321 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5322 UriPermissionOwner owner) { 5323 if (needed != null) { 5324 for (int i=0; i<needed.size(); i++) { 5325 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5326 needed.get(i), needed.flags, owner); 5327 } 5328 } 5329 } 5330 5331 void grantUriPermissionFromIntentLocked(int callingUid, 5332 String targetPkg, Intent intent, UriPermissionOwner owner) { 5333 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5334 intent, intent != null ? intent.getFlags() : 0, null); 5335 if (needed == null) { 5336 return; 5337 } 5338 5339 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5340 } 5341 5342 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5343 Uri uri, int modeFlags) { 5344 enforceNotIsolatedCaller("grantUriPermission"); 5345 synchronized(this) { 5346 final ProcessRecord r = getRecordForAppLocked(caller); 5347 if (r == null) { 5348 throw new SecurityException("Unable to find app for caller " 5349 + caller 5350 + " when granting permission to uri " + uri); 5351 } 5352 if (targetPkg == null) { 5353 throw new IllegalArgumentException("null target"); 5354 } 5355 if (uri == null) { 5356 throw new IllegalArgumentException("null uri"); 5357 } 5358 5359 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5360 null); 5361 } 5362 } 5363 5364 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5365 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5366 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5367 HashMap<Uri, UriPermission> perms 5368 = mGrantedUriPermissions.get(perm.uid); 5369 if (perms != null) { 5370 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5371 "Removing " + perm.uid + " permission to " + perm.uri); 5372 perms.remove(perm.uri); 5373 if (perms.size() == 0) { 5374 mGrantedUriPermissions.remove(perm.uid); 5375 } 5376 } 5377 } 5378 } 5379 5380 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5381 int modeFlags) { 5382 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5383 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5384 if (modeFlags == 0) { 5385 return; 5386 } 5387 5388 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5389 "Revoking all granted permissions to " + uri); 5390 5391 final IPackageManager pm = AppGlobals.getPackageManager(); 5392 5393 final String authority = uri.getAuthority(); 5394 ProviderInfo pi = null; 5395 int userId = UserHandle.getUserId(callingUid); 5396 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5397 if (cpr != null) { 5398 pi = cpr.info; 5399 } else { 5400 try { 5401 pi = pm.resolveContentProvider(authority, 5402 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5403 } catch (RemoteException ex) { 5404 } 5405 } 5406 if (pi == null) { 5407 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5408 return; 5409 } 5410 5411 // Does the caller have this permission on the URI? 5412 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5413 // Right now, if you are not the original owner of the permission, 5414 // you are not allowed to revoke it. 5415 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5416 throw new SecurityException("Uid " + callingUid 5417 + " does not have permission to uri " + uri); 5418 //} 5419 } 5420 5421 // Go through all of the permissions and remove any that match. 5422 final List<String> SEGMENTS = uri.getPathSegments(); 5423 if (SEGMENTS != null) { 5424 final int NS = SEGMENTS.size(); 5425 int N = mGrantedUriPermissions.size(); 5426 for (int i=0; i<N; i++) { 5427 HashMap<Uri, UriPermission> perms 5428 = mGrantedUriPermissions.valueAt(i); 5429 Iterator<UriPermission> it = perms.values().iterator(); 5430 toploop: 5431 while (it.hasNext()) { 5432 UriPermission perm = it.next(); 5433 Uri targetUri = perm.uri; 5434 if (!authority.equals(targetUri.getAuthority())) { 5435 continue; 5436 } 5437 List<String> targetSegments = targetUri.getPathSegments(); 5438 if (targetSegments == null) { 5439 continue; 5440 } 5441 if (targetSegments.size() < NS) { 5442 continue; 5443 } 5444 for (int j=0; j<NS; j++) { 5445 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5446 continue toploop; 5447 } 5448 } 5449 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5450 "Revoking " + perm.uid + " permission to " + perm.uri); 5451 perm.clearModes(modeFlags); 5452 if (perm.modeFlags == 0) { 5453 it.remove(); 5454 } 5455 } 5456 if (perms.size() == 0) { 5457 mGrantedUriPermissions.remove( 5458 mGrantedUriPermissions.keyAt(i)); 5459 N--; 5460 i--; 5461 } 5462 } 5463 } 5464 } 5465 5466 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5467 int modeFlags) { 5468 enforceNotIsolatedCaller("revokeUriPermission"); 5469 synchronized(this) { 5470 final ProcessRecord r = getRecordForAppLocked(caller); 5471 if (r == null) { 5472 throw new SecurityException("Unable to find app for caller " 5473 + caller 5474 + " when revoking permission to uri " + uri); 5475 } 5476 if (uri == null) { 5477 Slog.w(TAG, "revokeUriPermission: null uri"); 5478 return; 5479 } 5480 5481 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5482 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5483 if (modeFlags == 0) { 5484 return; 5485 } 5486 5487 final IPackageManager pm = AppGlobals.getPackageManager(); 5488 5489 final String authority = uri.getAuthority(); 5490 ProviderInfo pi = null; 5491 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5492 if (cpr != null) { 5493 pi = cpr.info; 5494 } else { 5495 try { 5496 pi = pm.resolveContentProvider(authority, 5497 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5498 } catch (RemoteException ex) { 5499 } 5500 } 5501 if (pi == null) { 5502 Slog.w(TAG, "No content provider found for permission revoke: " 5503 + uri.toSafeString()); 5504 return; 5505 } 5506 5507 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5508 } 5509 } 5510 5511 @Override 5512 public IBinder newUriPermissionOwner(String name) { 5513 enforceNotIsolatedCaller("newUriPermissionOwner"); 5514 synchronized(this) { 5515 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5516 return owner.getExternalTokenLocked(); 5517 } 5518 } 5519 5520 @Override 5521 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5522 Uri uri, int modeFlags) { 5523 synchronized(this) { 5524 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5525 if (owner == null) { 5526 throw new IllegalArgumentException("Unknown owner: " + token); 5527 } 5528 if (fromUid != Binder.getCallingUid()) { 5529 if (Binder.getCallingUid() != Process.myUid()) { 5530 // Only system code can grant URI permissions on behalf 5531 // of other users. 5532 throw new SecurityException("nice try"); 5533 } 5534 } 5535 if (targetPkg == null) { 5536 throw new IllegalArgumentException("null target"); 5537 } 5538 if (uri == null) { 5539 throw new IllegalArgumentException("null uri"); 5540 } 5541 5542 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5543 } 5544 } 5545 5546 @Override 5547 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5548 synchronized(this) { 5549 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5550 if (owner == null) { 5551 throw new IllegalArgumentException("Unknown owner: " + token); 5552 } 5553 5554 if (uri == null) { 5555 owner.removeUriPermissionsLocked(mode); 5556 } else { 5557 owner.removeUriPermissionLocked(uri, mode); 5558 } 5559 } 5560 } 5561 5562 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5563 synchronized (this) { 5564 ProcessRecord app = 5565 who != null ? getRecordForAppLocked(who) : null; 5566 if (app == null) return; 5567 5568 Message msg = Message.obtain(); 5569 msg.what = WAIT_FOR_DEBUGGER_MSG; 5570 msg.obj = app; 5571 msg.arg1 = waiting ? 1 : 0; 5572 mHandler.sendMessage(msg); 5573 } 5574 } 5575 5576 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5577 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5578 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5579 outInfo.availMem = Process.getFreeMemory(); 5580 outInfo.totalMem = Process.getTotalMemory(); 5581 outInfo.threshold = homeAppMem; 5582 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5583 outInfo.hiddenAppThreshold = hiddenAppMem; 5584 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5585 ProcessList.SERVICE_ADJ); 5586 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5587 ProcessList.VISIBLE_APP_ADJ); 5588 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5589 ProcessList.FOREGROUND_APP_ADJ); 5590 } 5591 5592 // ========================================================= 5593 // TASK MANAGEMENT 5594 // ========================================================= 5595 5596 public List getTasks(int maxNum, int flags, 5597 IThumbnailReceiver receiver) { 5598 ArrayList list = new ArrayList(); 5599 5600 PendingThumbnailsRecord pending = null; 5601 IApplicationThread topThumbnail = null; 5602 ActivityRecord topRecord = null; 5603 5604 synchronized(this) { 5605 if (localLOGV) Slog.v( 5606 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5607 + ", receiver=" + receiver); 5608 5609 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5610 != PackageManager.PERMISSION_GRANTED) { 5611 if (receiver != null) { 5612 // If the caller wants to wait for pending thumbnails, 5613 // it ain't gonna get them. 5614 try { 5615 receiver.finished(); 5616 } catch (RemoteException ex) { 5617 } 5618 } 5619 String msg = "Permission Denial: getTasks() from pid=" 5620 + Binder.getCallingPid() 5621 + ", uid=" + Binder.getCallingUid() 5622 + " requires " + android.Manifest.permission.GET_TASKS; 5623 Slog.w(TAG, msg); 5624 throw new SecurityException(msg); 5625 } 5626 5627 int pos = mMainStack.mHistory.size()-1; 5628 ActivityRecord next = 5629 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5630 ActivityRecord top = null; 5631 TaskRecord curTask = null; 5632 int numActivities = 0; 5633 int numRunning = 0; 5634 while (pos >= 0 && maxNum > 0) { 5635 final ActivityRecord r = next; 5636 pos--; 5637 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5638 5639 // Initialize state for next task if needed. 5640 if (top == null || 5641 (top.state == ActivityState.INITIALIZING 5642 && top.task == r.task)) { 5643 top = r; 5644 curTask = r.task; 5645 numActivities = numRunning = 0; 5646 } 5647 5648 // Add 'r' into the current task. 5649 numActivities++; 5650 if (r.app != null && r.app.thread != null) { 5651 numRunning++; 5652 } 5653 5654 if (localLOGV) Slog.v( 5655 TAG, r.intent.getComponent().flattenToShortString() 5656 + ": task=" + r.task); 5657 5658 // If the next one is a different task, generate a new 5659 // TaskInfo entry for what we have. 5660 if (next == null || next.task != curTask) { 5661 ActivityManager.RunningTaskInfo ci 5662 = new ActivityManager.RunningTaskInfo(); 5663 ci.id = curTask.taskId; 5664 ci.baseActivity = r.intent.getComponent(); 5665 ci.topActivity = top.intent.getComponent(); 5666 if (top.thumbHolder != null) { 5667 ci.description = top.thumbHolder.lastDescription; 5668 } 5669 ci.numActivities = numActivities; 5670 ci.numRunning = numRunning; 5671 //System.out.println( 5672 // "#" + maxNum + ": " + " descr=" + ci.description); 5673 if (ci.thumbnail == null && receiver != null) { 5674 if (localLOGV) Slog.v( 5675 TAG, "State=" + top.state + "Idle=" + top.idle 5676 + " app=" + top.app 5677 + " thr=" + (top.app != null ? top.app.thread : null)); 5678 if (top.state == ActivityState.RESUMED 5679 || top.state == ActivityState.PAUSING) { 5680 if (top.idle && top.app != null 5681 && top.app.thread != null) { 5682 topRecord = top; 5683 topThumbnail = top.app.thread; 5684 } else { 5685 top.thumbnailNeeded = true; 5686 } 5687 } 5688 if (pending == null) { 5689 pending = new PendingThumbnailsRecord(receiver); 5690 } 5691 pending.pendingRecords.add(top); 5692 } 5693 list.add(ci); 5694 maxNum--; 5695 top = null; 5696 } 5697 } 5698 5699 if (pending != null) { 5700 mPendingThumbnails.add(pending); 5701 } 5702 } 5703 5704 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5705 5706 if (topThumbnail != null) { 5707 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5708 try { 5709 topThumbnail.requestThumbnail(topRecord.appToken); 5710 } catch (Exception e) { 5711 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5712 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5713 } 5714 } 5715 5716 if (pending == null && receiver != null) { 5717 // In this case all thumbnails were available and the client 5718 // is being asked to be told when the remaining ones come in... 5719 // which is unusually, since the top-most currently running 5720 // activity should never have a canned thumbnail! Oh well. 5721 try { 5722 receiver.finished(); 5723 } catch (RemoteException ex) { 5724 } 5725 } 5726 5727 return list; 5728 } 5729 5730 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5731 int flags, int userId) { 5732 final int callingUid = Binder.getCallingUid(); 5733 if (userId != UserHandle.getCallingUserId()) { 5734 // Check if the caller is holding permissions for cross-user requests. 5735 if (checkComponentPermission( 5736 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5737 Binder.getCallingPid(), callingUid, -1, true) 5738 != PackageManager.PERMISSION_GRANTED) { 5739 String msg = "Permission Denial: " 5740 + "Request to get recent tasks for user " + userId 5741 + " but is calling from user " + UserHandle.getUserId(callingUid) 5742 + "; this requires " 5743 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5744 Slog.w(TAG, msg); 5745 throw new SecurityException(msg); 5746 } else { 5747 if (userId == UserHandle.USER_CURRENT) { 5748 userId = mCurrentUserId; 5749 } 5750 } 5751 } 5752 5753 synchronized (this) { 5754 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5755 "getRecentTasks()"); 5756 final boolean detailed = checkCallingPermission( 5757 android.Manifest.permission.GET_DETAILED_TASKS) 5758 == PackageManager.PERMISSION_GRANTED; 5759 5760 IPackageManager pm = AppGlobals.getPackageManager(); 5761 5762 final int N = mRecentTasks.size(); 5763 ArrayList<ActivityManager.RecentTaskInfo> res 5764 = new ArrayList<ActivityManager.RecentTaskInfo>( 5765 maxNum < N ? maxNum : N); 5766 for (int i=0; i<N && maxNum > 0; i++) { 5767 TaskRecord tr = mRecentTasks.get(i); 5768 // Only add calling user's recent tasks 5769 if (tr.userId != userId) continue; 5770 // Return the entry if desired by the caller. We always return 5771 // the first entry, because callers always expect this to be the 5772 // foreground app. We may filter others if the caller has 5773 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5774 // we should exclude the entry. 5775 5776 if (i == 0 5777 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5778 || (tr.intent == null) 5779 || ((tr.intent.getFlags() 5780 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5781 ActivityManager.RecentTaskInfo rti 5782 = new ActivityManager.RecentTaskInfo(); 5783 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5784 rti.persistentId = tr.taskId; 5785 rti.baseIntent = new Intent( 5786 tr.intent != null ? tr.intent : tr.affinityIntent); 5787 if (!detailed) { 5788 rti.baseIntent.replaceExtras((Bundle)null); 5789 } 5790 rti.origActivity = tr.origActivity; 5791 rti.description = tr.lastDescription; 5792 5793 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5794 // Check whether this activity is currently available. 5795 try { 5796 if (rti.origActivity != null) { 5797 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5798 == null) { 5799 continue; 5800 } 5801 } else if (rti.baseIntent != null) { 5802 if (pm.queryIntentActivities(rti.baseIntent, 5803 null, 0, userId) == null) { 5804 continue; 5805 } 5806 } 5807 } catch (RemoteException e) { 5808 // Will never happen. 5809 } 5810 } 5811 5812 res.add(rti); 5813 maxNum--; 5814 } 5815 } 5816 return res; 5817 } 5818 } 5819 5820 private TaskRecord taskForIdLocked(int id) { 5821 final int N = mRecentTasks.size(); 5822 for (int i=0; i<N; i++) { 5823 TaskRecord tr = mRecentTasks.get(i); 5824 if (tr.taskId == id) { 5825 return tr; 5826 } 5827 } 5828 return null; 5829 } 5830 5831 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5832 synchronized (this) { 5833 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5834 "getTaskThumbnails()"); 5835 TaskRecord tr = taskForIdLocked(id); 5836 if (tr != null) { 5837 return mMainStack.getTaskThumbnailsLocked(tr); 5838 } 5839 } 5840 return null; 5841 } 5842 5843 public boolean removeSubTask(int taskId, int subTaskIndex) { 5844 synchronized (this) { 5845 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5846 "removeSubTask()"); 5847 long ident = Binder.clearCallingIdentity(); 5848 try { 5849 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5850 true) != null; 5851 } finally { 5852 Binder.restoreCallingIdentity(ident); 5853 } 5854 } 5855 } 5856 5857 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5858 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5859 Intent baseIntent = new Intent( 5860 tr.intent != null ? tr.intent : tr.affinityIntent); 5861 ComponentName component = baseIntent.getComponent(); 5862 if (component == null) { 5863 Slog.w(TAG, "Now component for base intent of task: " + tr); 5864 return; 5865 } 5866 5867 // Find any running services associated with this app. 5868 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5869 5870 if (killProcesses) { 5871 // Find any running processes associated with this app. 5872 final String pkg = component.getPackageName(); 5873 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5874 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5875 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5876 for (int i=0; i<uids.size(); i++) { 5877 ProcessRecord proc = uids.valueAt(i); 5878 if (proc.userId != tr.userId) { 5879 continue; 5880 } 5881 if (!proc.pkgList.contains(pkg)) { 5882 continue; 5883 } 5884 procs.add(proc); 5885 } 5886 } 5887 5888 // Kill the running processes. 5889 for (int i=0; i<procs.size(); i++) { 5890 ProcessRecord pr = procs.get(i); 5891 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5892 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5893 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5894 pr.processName, pr.setAdj, "remove task"); 5895 pr.killedBackground = true; 5896 Process.killProcessQuiet(pr.pid); 5897 } else { 5898 pr.waitingToKill = "remove task"; 5899 } 5900 } 5901 } 5902 } 5903 5904 public boolean removeTask(int taskId, int flags) { 5905 synchronized (this) { 5906 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5907 "removeTask()"); 5908 long ident = Binder.clearCallingIdentity(); 5909 try { 5910 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5911 false); 5912 if (r != null) { 5913 mRecentTasks.remove(r.task); 5914 cleanUpRemovedTaskLocked(r.task, flags); 5915 return true; 5916 } else { 5917 TaskRecord tr = null; 5918 int i=0; 5919 while (i < mRecentTasks.size()) { 5920 TaskRecord t = mRecentTasks.get(i); 5921 if (t.taskId == taskId) { 5922 tr = t; 5923 break; 5924 } 5925 i++; 5926 } 5927 if (tr != null) { 5928 if (tr.numActivities <= 0) { 5929 // Caller is just removing a recent task that is 5930 // not actively running. That is easy! 5931 mRecentTasks.remove(i); 5932 cleanUpRemovedTaskLocked(tr, flags); 5933 return true; 5934 } else { 5935 Slog.w(TAG, "removeTask: task " + taskId 5936 + " does not have activities to remove, " 5937 + " but numActivities=" + tr.numActivities 5938 + ": " + tr); 5939 } 5940 } 5941 } 5942 } finally { 5943 Binder.restoreCallingIdentity(ident); 5944 } 5945 } 5946 return false; 5947 } 5948 5949 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5950 int j; 5951 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5952 TaskRecord jt = startTask; 5953 5954 // First look backwards 5955 for (j=startIndex-1; j>=0; j--) { 5956 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5957 if (r.task != jt) { 5958 jt = r.task; 5959 if (affinity.equals(jt.affinity)) { 5960 return j; 5961 } 5962 } 5963 } 5964 5965 // Now look forwards 5966 final int N = mMainStack.mHistory.size(); 5967 jt = startTask; 5968 for (j=startIndex+1; j<N; j++) { 5969 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5970 if (r.task != jt) { 5971 if (affinity.equals(jt.affinity)) { 5972 return j; 5973 } 5974 jt = r.task; 5975 } 5976 } 5977 5978 // Might it be at the top? 5979 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5980 return N-1; 5981 } 5982 5983 return -1; 5984 } 5985 5986 /** 5987 * TODO: Add mController hook 5988 */ 5989 public void moveTaskToFront(int task, int flags, Bundle options) { 5990 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5991 "moveTaskToFront()"); 5992 5993 synchronized(this) { 5994 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5995 Binder.getCallingUid(), "Task to front")) { 5996 ActivityOptions.abort(options); 5997 return; 5998 } 5999 final long origId = Binder.clearCallingIdentity(); 6000 try { 6001 TaskRecord tr = taskForIdLocked(task); 6002 if (tr != null) { 6003 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6004 mMainStack.mUserLeaving = true; 6005 } 6006 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6007 // Caller wants the home activity moved with it. To accomplish this, 6008 // we'll just move the home task to the top first. 6009 mMainStack.moveHomeToFrontLocked(); 6010 } 6011 mMainStack.moveTaskToFrontLocked(tr, null, options); 6012 return; 6013 } 6014 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6015 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6016 if (hr.task.taskId == task) { 6017 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6018 mMainStack.mUserLeaving = true; 6019 } 6020 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6021 // Caller wants the home activity moved with it. To accomplish this, 6022 // we'll just move the home task to the top first. 6023 mMainStack.moveHomeToFrontLocked(); 6024 } 6025 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6026 return; 6027 } 6028 } 6029 } finally { 6030 Binder.restoreCallingIdentity(origId); 6031 } 6032 ActivityOptions.abort(options); 6033 } 6034 } 6035 6036 public void moveTaskToBack(int task) { 6037 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6038 "moveTaskToBack()"); 6039 6040 synchronized(this) { 6041 if (mMainStack.mResumedActivity != null 6042 && mMainStack.mResumedActivity.task.taskId == task) { 6043 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6044 Binder.getCallingUid(), "Task to back")) { 6045 return; 6046 } 6047 } 6048 final long origId = Binder.clearCallingIdentity(); 6049 mMainStack.moveTaskToBackLocked(task, null); 6050 Binder.restoreCallingIdentity(origId); 6051 } 6052 } 6053 6054 /** 6055 * Moves an activity, and all of the other activities within the same task, to the bottom 6056 * of the history stack. The activity's order within the task is unchanged. 6057 * 6058 * @param token A reference to the activity we wish to move 6059 * @param nonRoot If false then this only works if the activity is the root 6060 * of a task; if true it will work for any activity in a task. 6061 * @return Returns true if the move completed, false if not. 6062 */ 6063 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6064 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6065 synchronized(this) { 6066 final long origId = Binder.clearCallingIdentity(); 6067 int taskId = getTaskForActivityLocked(token, !nonRoot); 6068 if (taskId >= 0) { 6069 return mMainStack.moveTaskToBackLocked(taskId, null); 6070 } 6071 Binder.restoreCallingIdentity(origId); 6072 } 6073 return false; 6074 } 6075 6076 public void moveTaskBackwards(int task) { 6077 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6078 "moveTaskBackwards()"); 6079 6080 synchronized(this) { 6081 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6082 Binder.getCallingUid(), "Task backwards")) { 6083 return; 6084 } 6085 final long origId = Binder.clearCallingIdentity(); 6086 moveTaskBackwardsLocked(task); 6087 Binder.restoreCallingIdentity(origId); 6088 } 6089 } 6090 6091 private final void moveTaskBackwardsLocked(int task) { 6092 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6093 } 6094 6095 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6096 synchronized(this) { 6097 return getTaskForActivityLocked(token, onlyRoot); 6098 } 6099 } 6100 6101 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6102 final int N = mMainStack.mHistory.size(); 6103 TaskRecord lastTask = null; 6104 for (int i=0; i<N; i++) { 6105 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6106 if (r.appToken == token) { 6107 if (!onlyRoot || lastTask != r.task) { 6108 return r.task.taskId; 6109 } 6110 return -1; 6111 } 6112 lastTask = r.task; 6113 } 6114 6115 return -1; 6116 } 6117 6118 // ========================================================= 6119 // THUMBNAILS 6120 // ========================================================= 6121 6122 public void reportThumbnail(IBinder token, 6123 Bitmap thumbnail, CharSequence description) { 6124 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6125 final long origId = Binder.clearCallingIdentity(); 6126 sendPendingThumbnail(null, token, thumbnail, description, true); 6127 Binder.restoreCallingIdentity(origId); 6128 } 6129 6130 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6131 Bitmap thumbnail, CharSequence description, boolean always) { 6132 TaskRecord task = null; 6133 ArrayList receivers = null; 6134 6135 //System.out.println("Send pending thumbnail: " + r); 6136 6137 synchronized(this) { 6138 if (r == null) { 6139 r = mMainStack.isInStackLocked(token); 6140 if (r == null) { 6141 return; 6142 } 6143 } 6144 if (thumbnail == null && r.thumbHolder != null) { 6145 thumbnail = r.thumbHolder.lastThumbnail; 6146 description = r.thumbHolder.lastDescription; 6147 } 6148 if (thumbnail == null && !always) { 6149 // If there is no thumbnail, and this entry is not actually 6150 // going away, then abort for now and pick up the next 6151 // thumbnail we get. 6152 return; 6153 } 6154 task = r.task; 6155 6156 int N = mPendingThumbnails.size(); 6157 int i=0; 6158 while (i<N) { 6159 PendingThumbnailsRecord pr = 6160 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6161 //System.out.println("Looking in " + pr.pendingRecords); 6162 if (pr.pendingRecords.remove(r)) { 6163 if (receivers == null) { 6164 receivers = new ArrayList(); 6165 } 6166 receivers.add(pr); 6167 if (pr.pendingRecords.size() == 0) { 6168 pr.finished = true; 6169 mPendingThumbnails.remove(i); 6170 N--; 6171 continue; 6172 } 6173 } 6174 i++; 6175 } 6176 } 6177 6178 if (receivers != null) { 6179 final int N = receivers.size(); 6180 for (int i=0; i<N; i++) { 6181 try { 6182 PendingThumbnailsRecord pr = 6183 (PendingThumbnailsRecord)receivers.get(i); 6184 pr.receiver.newThumbnail( 6185 task != null ? task.taskId : -1, thumbnail, description); 6186 if (pr.finished) { 6187 pr.receiver.finished(); 6188 } 6189 } catch (Exception e) { 6190 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6191 } 6192 } 6193 } 6194 } 6195 6196 // ========================================================= 6197 // CONTENT PROVIDERS 6198 // ========================================================= 6199 6200 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6201 List<ProviderInfo> providers = null; 6202 try { 6203 providers = AppGlobals.getPackageManager(). 6204 queryContentProviders(app.processName, app.uid, 6205 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6206 } catch (RemoteException ex) { 6207 } 6208 if (DEBUG_MU) 6209 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6210 int userId = app.userId; 6211 if (providers != null) { 6212 int N = providers.size(); 6213 for (int i=0; i<N; i++) { 6214 ProviderInfo cpi = 6215 (ProviderInfo)providers.get(i); 6216 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6217 cpi.name, cpi.flags); 6218 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6219 // This is a singleton provider, but a user besides the 6220 // default user is asking to initialize a process it runs 6221 // in... well, no, it doesn't actually run in this process, 6222 // it runs in the process of the default user. Get rid of it. 6223 providers.remove(i); 6224 N--; 6225 continue; 6226 } 6227 6228 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6229 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6230 if (cpr == null) { 6231 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6232 mProviderMap.putProviderByClass(comp, cpr); 6233 } 6234 if (DEBUG_MU) 6235 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6236 app.pubProviders.put(cpi.name, cpr); 6237 app.addPackage(cpi.applicationInfo.packageName); 6238 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6239 } 6240 } 6241 return providers; 6242 } 6243 6244 /** 6245 * Check if {@link ProcessRecord} has a possible chance at accessing the 6246 * given {@link ProviderInfo}. Final permission checking is always done 6247 * in {@link ContentProvider}. 6248 */ 6249 private final String checkContentProviderPermissionLocked( 6250 ProviderInfo cpi, ProcessRecord r) { 6251 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6252 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6253 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6254 cpi.applicationInfo.uid, cpi.exported) 6255 == PackageManager.PERMISSION_GRANTED) { 6256 return null; 6257 } 6258 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6259 cpi.applicationInfo.uid, cpi.exported) 6260 == PackageManager.PERMISSION_GRANTED) { 6261 return null; 6262 } 6263 6264 PathPermission[] pps = cpi.pathPermissions; 6265 if (pps != null) { 6266 int i = pps.length; 6267 while (i > 0) { 6268 i--; 6269 PathPermission pp = pps[i]; 6270 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6271 cpi.applicationInfo.uid, cpi.exported) 6272 == PackageManager.PERMISSION_GRANTED) { 6273 return null; 6274 } 6275 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6276 cpi.applicationInfo.uid, cpi.exported) 6277 == PackageManager.PERMISSION_GRANTED) { 6278 return null; 6279 } 6280 } 6281 } 6282 6283 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6284 if (perms != null) { 6285 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6286 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6287 return null; 6288 } 6289 } 6290 } 6291 6292 String msg; 6293 if (!cpi.exported) { 6294 msg = "Permission Denial: opening provider " + cpi.name 6295 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6296 + ", uid=" + callingUid + ") that is not exported from uid " 6297 + cpi.applicationInfo.uid; 6298 } else { 6299 msg = "Permission Denial: opening provider " + cpi.name 6300 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6301 + ", uid=" + callingUid + ") requires " 6302 + cpi.readPermission + " or " + cpi.writePermission; 6303 } 6304 Slog.w(TAG, msg); 6305 return msg; 6306 } 6307 6308 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6309 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6310 if (r != null) { 6311 for (int i=0; i<r.conProviders.size(); i++) { 6312 ContentProviderConnection conn = r.conProviders.get(i); 6313 if (conn.provider == cpr) { 6314 if (DEBUG_PROVIDER) Slog.v(TAG, 6315 "Adding provider requested by " 6316 + r.processName + " from process " 6317 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6318 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6319 if (stable) { 6320 conn.stableCount++; 6321 conn.numStableIncs++; 6322 } else { 6323 conn.unstableCount++; 6324 conn.numUnstableIncs++; 6325 } 6326 return conn; 6327 } 6328 } 6329 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6330 if (stable) { 6331 conn.stableCount = 1; 6332 conn.numStableIncs = 1; 6333 } else { 6334 conn.unstableCount = 1; 6335 conn.numUnstableIncs = 1; 6336 } 6337 cpr.connections.add(conn); 6338 r.conProviders.add(conn); 6339 return conn; 6340 } 6341 cpr.addExternalProcessHandleLocked(externalProcessToken); 6342 return null; 6343 } 6344 6345 boolean decProviderCountLocked(ContentProviderConnection conn, 6346 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6347 if (conn != null) { 6348 cpr = conn.provider; 6349 if (DEBUG_PROVIDER) Slog.v(TAG, 6350 "Removing provider requested by " 6351 + conn.client.processName + " from process " 6352 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6353 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6354 if (stable) { 6355 conn.stableCount--; 6356 } else { 6357 conn.unstableCount--; 6358 } 6359 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6360 cpr.connections.remove(conn); 6361 conn.client.conProviders.remove(conn); 6362 return true; 6363 } 6364 return false; 6365 } 6366 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6367 return false; 6368 } 6369 6370 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6371 String name, IBinder token, boolean stable, int userId) { 6372 ContentProviderRecord cpr; 6373 ContentProviderConnection conn = null; 6374 ProviderInfo cpi = null; 6375 6376 synchronized(this) { 6377 ProcessRecord r = null; 6378 if (caller != null) { 6379 r = getRecordForAppLocked(caller); 6380 if (r == null) { 6381 throw new SecurityException( 6382 "Unable to find app for caller " + caller 6383 + " (pid=" + Binder.getCallingPid() 6384 + ") when getting content provider " + name); 6385 } 6386 if (r.userId != userId) { 6387 throw new SecurityException("Calling requested user " + userId 6388 + " but app is user " + r.userId); 6389 } 6390 } 6391 6392 // First check if this content provider has been published... 6393 cpr = mProviderMap.getProviderByName(name, userId); 6394 boolean providerRunning = cpr != null; 6395 if (providerRunning) { 6396 cpi = cpr.info; 6397 String msg; 6398 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6399 throw new SecurityException(msg); 6400 } 6401 6402 if (r != null && cpr.canRunHere(r)) { 6403 // This provider has been published or is in the process 6404 // of being published... but it is also allowed to run 6405 // in the caller's process, so don't make a connection 6406 // and just let the caller instantiate its own instance. 6407 ContentProviderHolder holder = cpr.newHolder(null); 6408 // don't give caller the provider object, it needs 6409 // to make its own. 6410 holder.provider = null; 6411 return holder; 6412 } 6413 6414 final long origId = Binder.clearCallingIdentity(); 6415 6416 // In this case the provider instance already exists, so we can 6417 // return it right away. 6418 conn = incProviderCountLocked(r, cpr, token, stable); 6419 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6420 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6421 // If this is a perceptible app accessing the provider, 6422 // make sure to count it as being accessed and thus 6423 // back up on the LRU list. This is good because 6424 // content providers are often expensive to start. 6425 updateLruProcessLocked(cpr.proc, false, true); 6426 } 6427 } 6428 6429 if (cpr.proc != null) { 6430 if (false) { 6431 if (cpr.name.flattenToShortString().equals( 6432 "com.android.providers.calendar/.CalendarProvider2")) { 6433 Slog.v(TAG, "****************** KILLING " 6434 + cpr.name.flattenToShortString()); 6435 Process.killProcess(cpr.proc.pid); 6436 } 6437 } 6438 boolean success = updateOomAdjLocked(cpr.proc); 6439 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6440 // NOTE: there is still a race here where a signal could be 6441 // pending on the process even though we managed to update its 6442 // adj level. Not sure what to do about this, but at least 6443 // the race is now smaller. 6444 if (!success) { 6445 // Uh oh... it looks like the provider's process 6446 // has been killed on us. We need to wait for a new 6447 // process to be started, and make sure its death 6448 // doesn't kill our process. 6449 Slog.i(TAG, 6450 "Existing provider " + cpr.name.flattenToShortString() 6451 + " is crashing; detaching " + r); 6452 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6453 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6454 if (!lastRef) { 6455 // This wasn't the last ref our process had on 6456 // the provider... we have now been killed, bail. 6457 return null; 6458 } 6459 providerRunning = false; 6460 conn = null; 6461 } 6462 } 6463 6464 Binder.restoreCallingIdentity(origId); 6465 } 6466 6467 boolean singleton; 6468 if (!providerRunning) { 6469 try { 6470 cpi = AppGlobals.getPackageManager(). 6471 resolveContentProvider(name, 6472 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6473 } catch (RemoteException ex) { 6474 } 6475 if (cpi == null) { 6476 return null; 6477 } 6478 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6479 cpi.name, cpi.flags); 6480 if (singleton) { 6481 userId = 0; 6482 } 6483 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6484 6485 String msg; 6486 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6487 throw new SecurityException(msg); 6488 } 6489 6490 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6491 && !cpi.processName.equals("system")) { 6492 // If this content provider does not run in the system 6493 // process, and the system is not yet ready to run other 6494 // processes, then fail fast instead of hanging. 6495 throw new IllegalArgumentException( 6496 "Attempt to launch content provider before system ready"); 6497 } 6498 6499 // Make sure that the user who owns this provider is started. If not, 6500 // we don't want to allow it to run. 6501 if (mStartedUsers.get(userId) == null) { 6502 Slog.w(TAG, "Unable to launch app " 6503 + cpi.applicationInfo.packageName + "/" 6504 + cpi.applicationInfo.uid + " for provider " 6505 + name + ": user " + userId + " is stopped"); 6506 return null; 6507 } 6508 6509 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6510 cpr = mProviderMap.getProviderByClass(comp, userId); 6511 final boolean firstClass = cpr == null; 6512 if (firstClass) { 6513 try { 6514 ApplicationInfo ai = 6515 AppGlobals.getPackageManager(). 6516 getApplicationInfo( 6517 cpi.applicationInfo.packageName, 6518 STOCK_PM_FLAGS, userId); 6519 if (ai == null) { 6520 Slog.w(TAG, "No package info for content provider " 6521 + cpi.name); 6522 return null; 6523 } 6524 ai = getAppInfoForUser(ai, userId); 6525 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6526 } catch (RemoteException ex) { 6527 // pm is in same process, this will never happen. 6528 } 6529 } 6530 6531 if (r != null && cpr.canRunHere(r)) { 6532 // If this is a multiprocess provider, then just return its 6533 // info and allow the caller to instantiate it. Only do 6534 // this if the provider is the same user as the caller's 6535 // process, or can run as root (so can be in any process). 6536 return cpr.newHolder(null); 6537 } 6538 6539 if (DEBUG_PROVIDER) { 6540 RuntimeException e = new RuntimeException("here"); 6541 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6542 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6543 } 6544 6545 // This is single process, and our app is now connecting to it. 6546 // See if we are already in the process of launching this 6547 // provider. 6548 final int N = mLaunchingProviders.size(); 6549 int i; 6550 for (i=0; i<N; i++) { 6551 if (mLaunchingProviders.get(i) == cpr) { 6552 break; 6553 } 6554 } 6555 6556 // If the provider is not already being launched, then get it 6557 // started. 6558 if (i >= N) { 6559 final long origId = Binder.clearCallingIdentity(); 6560 6561 try { 6562 // Content provider is now in use, its package can't be stopped. 6563 try { 6564 AppGlobals.getPackageManager().setPackageStoppedState( 6565 cpr.appInfo.packageName, false, userId); 6566 } catch (RemoteException e) { 6567 } catch (IllegalArgumentException e) { 6568 Slog.w(TAG, "Failed trying to unstop package " 6569 + cpr.appInfo.packageName + ": " + e); 6570 } 6571 6572 ProcessRecord proc = startProcessLocked(cpi.processName, 6573 cpr.appInfo, false, 0, "content provider", 6574 new ComponentName(cpi.applicationInfo.packageName, 6575 cpi.name), false, false); 6576 if (proc == null) { 6577 Slog.w(TAG, "Unable to launch app " 6578 + cpi.applicationInfo.packageName + "/" 6579 + cpi.applicationInfo.uid + " for provider " 6580 + name + ": process is bad"); 6581 return null; 6582 } 6583 cpr.launchingApp = proc; 6584 mLaunchingProviders.add(cpr); 6585 } finally { 6586 Binder.restoreCallingIdentity(origId); 6587 } 6588 } 6589 6590 // Make sure the provider is published (the same provider class 6591 // may be published under multiple names). 6592 if (firstClass) { 6593 mProviderMap.putProviderByClass(comp, cpr); 6594 } 6595 6596 mProviderMap.putProviderByName(name, cpr); 6597 conn = incProviderCountLocked(r, cpr, token, stable); 6598 if (conn != null) { 6599 conn.waiting = true; 6600 } 6601 } 6602 } 6603 6604 // Wait for the provider to be published... 6605 synchronized (cpr) { 6606 while (cpr.provider == null) { 6607 if (cpr.launchingApp == null) { 6608 Slog.w(TAG, "Unable to launch app " 6609 + cpi.applicationInfo.packageName + "/" 6610 + cpi.applicationInfo.uid + " for provider " 6611 + name + ": launching app became null"); 6612 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6613 cpi.applicationInfo.packageName, 6614 cpi.applicationInfo.uid, name); 6615 return null; 6616 } 6617 try { 6618 if (DEBUG_MU) { 6619 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6620 + cpr.launchingApp); 6621 } 6622 if (conn != null) { 6623 conn.waiting = true; 6624 } 6625 cpr.wait(); 6626 } catch (InterruptedException ex) { 6627 } finally { 6628 if (conn != null) { 6629 conn.waiting = false; 6630 } 6631 } 6632 } 6633 } 6634 return cpr != null ? cpr.newHolder(conn) : null; 6635 } 6636 6637 public final ContentProviderHolder getContentProvider( 6638 IApplicationThread caller, String name, boolean stable) { 6639 enforceNotIsolatedCaller("getContentProvider"); 6640 if (caller == null) { 6641 String msg = "null IApplicationThread when getting content provider " 6642 + name; 6643 Slog.w(TAG, msg); 6644 throw new SecurityException(msg); 6645 } 6646 6647 return getContentProviderImpl(caller, name, null, stable, 6648 UserHandle.getCallingUserId()); 6649 } 6650 6651 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6652 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6653 "Do not have permission in call getContentProviderExternal()"); 6654 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6655 } 6656 6657 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6658 IBinder token, int userId) { 6659 return getContentProviderImpl(null, name, token, true, userId); 6660 } 6661 6662 /** 6663 * Drop a content provider from a ProcessRecord's bookkeeping 6664 * @param cpr 6665 */ 6666 public void removeContentProvider(IBinder connection, boolean stable) { 6667 enforceNotIsolatedCaller("removeContentProvider"); 6668 synchronized (this) { 6669 ContentProviderConnection conn; 6670 try { 6671 conn = (ContentProviderConnection)connection; 6672 } catch (ClassCastException e) { 6673 String msg ="removeContentProvider: " + connection 6674 + " not a ContentProviderConnection"; 6675 Slog.w(TAG, msg); 6676 throw new IllegalArgumentException(msg); 6677 } 6678 if (conn == null) { 6679 throw new NullPointerException("connection is null"); 6680 } 6681 if (decProviderCountLocked(conn, null, null, stable)) { 6682 updateOomAdjLocked(); 6683 } 6684 } 6685 } 6686 6687 public void removeContentProviderExternal(String name, IBinder token) { 6688 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6689 "Do not have permission in call removeContentProviderExternal()"); 6690 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6691 } 6692 6693 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6694 synchronized (this) { 6695 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6696 if(cpr == null) { 6697 //remove from mProvidersByClass 6698 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6699 return; 6700 } 6701 6702 //update content provider record entry info 6703 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6704 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6705 if (localCpr.hasExternalProcessHandles()) { 6706 if (localCpr.removeExternalProcessHandleLocked(token)) { 6707 updateOomAdjLocked(); 6708 } else { 6709 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6710 + " with no external reference for token: " 6711 + token + "."); 6712 } 6713 } else { 6714 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6715 + " with no external references."); 6716 } 6717 } 6718 } 6719 6720 public final void publishContentProviders(IApplicationThread caller, 6721 List<ContentProviderHolder> providers) { 6722 if (providers == null) { 6723 return; 6724 } 6725 6726 enforceNotIsolatedCaller("publishContentProviders"); 6727 synchronized (this) { 6728 final ProcessRecord r = getRecordForAppLocked(caller); 6729 if (DEBUG_MU) 6730 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6731 if (r == null) { 6732 throw new SecurityException( 6733 "Unable to find app for caller " + caller 6734 + " (pid=" + Binder.getCallingPid() 6735 + ") when publishing content providers"); 6736 } 6737 6738 final long origId = Binder.clearCallingIdentity(); 6739 6740 final int N = providers.size(); 6741 for (int i=0; i<N; i++) { 6742 ContentProviderHolder src = providers.get(i); 6743 if (src == null || src.info == null || src.provider == null) { 6744 continue; 6745 } 6746 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6747 if (DEBUG_MU) 6748 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6749 if (dst != null) { 6750 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6751 mProviderMap.putProviderByClass(comp, dst); 6752 String names[] = dst.info.authority.split(";"); 6753 for (int j = 0; j < names.length; j++) { 6754 mProviderMap.putProviderByName(names[j], dst); 6755 } 6756 6757 int NL = mLaunchingProviders.size(); 6758 int j; 6759 for (j=0; j<NL; j++) { 6760 if (mLaunchingProviders.get(j) == dst) { 6761 mLaunchingProviders.remove(j); 6762 j--; 6763 NL--; 6764 } 6765 } 6766 synchronized (dst) { 6767 dst.provider = src.provider; 6768 dst.proc = r; 6769 dst.notifyAll(); 6770 } 6771 updateOomAdjLocked(r); 6772 } 6773 } 6774 6775 Binder.restoreCallingIdentity(origId); 6776 } 6777 } 6778 6779 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6780 ContentProviderConnection conn; 6781 try { 6782 conn = (ContentProviderConnection)connection; 6783 } catch (ClassCastException e) { 6784 String msg ="refContentProvider: " + connection 6785 + " not a ContentProviderConnection"; 6786 Slog.w(TAG, msg); 6787 throw new IllegalArgumentException(msg); 6788 } 6789 if (conn == null) { 6790 throw new NullPointerException("connection is null"); 6791 } 6792 6793 synchronized (this) { 6794 if (stable > 0) { 6795 conn.numStableIncs += stable; 6796 } 6797 stable = conn.stableCount + stable; 6798 if (stable < 0) { 6799 throw new IllegalStateException("stableCount < 0: " + stable); 6800 } 6801 6802 if (unstable > 0) { 6803 conn.numUnstableIncs += unstable; 6804 } 6805 unstable = conn.unstableCount + unstable; 6806 if (unstable < 0) { 6807 throw new IllegalStateException("unstableCount < 0: " + unstable); 6808 } 6809 6810 if ((stable+unstable) <= 0) { 6811 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6812 + stable + " unstable=" + unstable); 6813 } 6814 conn.stableCount = stable; 6815 conn.unstableCount = unstable; 6816 return !conn.dead; 6817 } 6818 } 6819 6820 public void unstableProviderDied(IBinder connection) { 6821 ContentProviderConnection conn; 6822 try { 6823 conn = (ContentProviderConnection)connection; 6824 } catch (ClassCastException e) { 6825 String msg ="refContentProvider: " + connection 6826 + " not a ContentProviderConnection"; 6827 Slog.w(TAG, msg); 6828 throw new IllegalArgumentException(msg); 6829 } 6830 if (conn == null) { 6831 throw new NullPointerException("connection is null"); 6832 } 6833 6834 // Safely retrieve the content provider associated with the connection. 6835 IContentProvider provider; 6836 synchronized (this) { 6837 provider = conn.provider.provider; 6838 } 6839 6840 if (provider == null) { 6841 // Um, yeah, we're way ahead of you. 6842 return; 6843 } 6844 6845 // Make sure the caller is being honest with us. 6846 if (provider.asBinder().pingBinder()) { 6847 // Er, no, still looks good to us. 6848 synchronized (this) { 6849 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6850 + " says " + conn + " died, but we don't agree"); 6851 return; 6852 } 6853 } 6854 6855 // Well look at that! It's dead! 6856 synchronized (this) { 6857 if (conn.provider.provider != provider) { 6858 // But something changed... good enough. 6859 return; 6860 } 6861 6862 ProcessRecord proc = conn.provider.proc; 6863 if (proc == null || proc.thread == null) { 6864 // Seems like the process is already cleaned up. 6865 return; 6866 } 6867 6868 // As far as we're concerned, this is just like receiving a 6869 // death notification... just a bit prematurely. 6870 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6871 + ") early provider death"); 6872 final long ident = Binder.clearCallingIdentity(); 6873 try { 6874 appDiedLocked(proc, proc.pid, proc.thread); 6875 } finally { 6876 Binder.restoreCallingIdentity(ident); 6877 } 6878 } 6879 } 6880 6881 public static final void installSystemProviders() { 6882 List<ProviderInfo> providers; 6883 synchronized (mSelf) { 6884 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6885 providers = mSelf.generateApplicationProvidersLocked(app); 6886 if (providers != null) { 6887 for (int i=providers.size()-1; i>=0; i--) { 6888 ProviderInfo pi = (ProviderInfo)providers.get(i); 6889 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6890 Slog.w(TAG, "Not installing system proc provider " + pi.name 6891 + ": not system .apk"); 6892 providers.remove(i); 6893 } 6894 } 6895 } 6896 } 6897 if (providers != null) { 6898 mSystemThread.installSystemProviders(providers); 6899 } 6900 6901 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6902 6903 mSelf.mUsageStatsService.monitorPackages(); 6904 } 6905 6906 /** 6907 * Allows app to retrieve the MIME type of a URI without having permission 6908 * to access its content provider. 6909 * 6910 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6911 * 6912 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6913 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6914 */ 6915 public String getProviderMimeType(Uri uri, int userId) { 6916 enforceNotIsolatedCaller("getProviderMimeType"); 6917 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6918 userId, false, true, "getProviderMimeType", null); 6919 final String name = uri.getAuthority(); 6920 final long ident = Binder.clearCallingIdentity(); 6921 ContentProviderHolder holder = null; 6922 6923 try { 6924 holder = getContentProviderExternalUnchecked(name, null, userId); 6925 if (holder != null) { 6926 return holder.provider.getType(uri); 6927 } 6928 } catch (RemoteException e) { 6929 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6930 return null; 6931 } finally { 6932 if (holder != null) { 6933 removeContentProviderExternalUnchecked(name, null, userId); 6934 } 6935 Binder.restoreCallingIdentity(ident); 6936 } 6937 6938 return null; 6939 } 6940 6941 // ========================================================= 6942 // GLOBAL MANAGEMENT 6943 // ========================================================= 6944 6945 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6946 ApplicationInfo info, String customProcess, boolean isolated) { 6947 String proc = customProcess != null ? customProcess : info.processName; 6948 BatteryStatsImpl.Uid.Proc ps = null; 6949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6950 int uid = info.uid; 6951 if (isolated) { 6952 int userId = UserHandle.getUserId(uid); 6953 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6954 uid = 0; 6955 while (true) { 6956 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6957 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6958 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6959 } 6960 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6961 mNextIsolatedProcessUid++; 6962 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6963 // No process for this uid, use it. 6964 break; 6965 } 6966 stepsLeft--; 6967 if (stepsLeft <= 0) { 6968 return null; 6969 } 6970 } 6971 } 6972 synchronized (stats) { 6973 ps = stats.getProcessStatsLocked(info.uid, proc); 6974 } 6975 return new ProcessRecord(ps, thread, info, proc, uid); 6976 } 6977 6978 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6979 ProcessRecord app; 6980 if (!isolated) { 6981 app = getProcessRecordLocked(info.processName, info.uid); 6982 } else { 6983 app = null; 6984 } 6985 6986 if (app == null) { 6987 app = newProcessRecordLocked(null, info, null, isolated); 6988 mProcessNames.put(info.processName, app.uid, app); 6989 if (isolated) { 6990 mIsolatedProcesses.put(app.uid, app); 6991 } 6992 updateLruProcessLocked(app, true, true); 6993 } 6994 6995 // This package really, really can not be stopped. 6996 try { 6997 AppGlobals.getPackageManager().setPackageStoppedState( 6998 info.packageName, false, UserHandle.getUserId(app.uid)); 6999 } catch (RemoteException e) { 7000 } catch (IllegalArgumentException e) { 7001 Slog.w(TAG, "Failed trying to unstop package " 7002 + info.packageName + ": " + e); 7003 } 7004 7005 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7006 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7007 app.persistent = true; 7008 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7009 } 7010 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7011 mPersistentStartingProcesses.add(app); 7012 startProcessLocked(app, "added application", app.processName); 7013 } 7014 7015 return app; 7016 } 7017 7018 public void unhandledBack() { 7019 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7020 "unhandledBack()"); 7021 7022 synchronized(this) { 7023 int count = mMainStack.mHistory.size(); 7024 if (DEBUG_SWITCH) Slog.d( 7025 TAG, "Performing unhandledBack(): stack size = " + count); 7026 if (count > 1) { 7027 final long origId = Binder.clearCallingIdentity(); 7028 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7029 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7030 Binder.restoreCallingIdentity(origId); 7031 } 7032 } 7033 } 7034 7035 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7036 enforceNotIsolatedCaller("openContentUri"); 7037 final int userId = UserHandle.getCallingUserId(); 7038 String name = uri.getAuthority(); 7039 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7040 ParcelFileDescriptor pfd = null; 7041 if (cph != null) { 7042 // We record the binder invoker's uid in thread-local storage before 7043 // going to the content provider to open the file. Later, in the code 7044 // that handles all permissions checks, we look for this uid and use 7045 // that rather than the Activity Manager's own uid. The effect is that 7046 // we do the check against the caller's permissions even though it looks 7047 // to the content provider like the Activity Manager itself is making 7048 // the request. 7049 sCallerIdentity.set(new Identity( 7050 Binder.getCallingPid(), Binder.getCallingUid())); 7051 try { 7052 pfd = cph.provider.openFile(uri, "r"); 7053 } catch (FileNotFoundException e) { 7054 // do nothing; pfd will be returned null 7055 } finally { 7056 // Ensure that whatever happens, we clean up the identity state 7057 sCallerIdentity.remove(); 7058 } 7059 7060 // We've got the fd now, so we're done with the provider. 7061 removeContentProviderExternalUnchecked(name, null, userId); 7062 } else { 7063 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7064 } 7065 return pfd; 7066 } 7067 7068 // Actually is sleeping or shutting down or whatever else in the future 7069 // is an inactive state. 7070 public boolean isSleeping() { 7071 return mSleeping || mShuttingDown; 7072 } 7073 7074 public void goingToSleep() { 7075 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7076 != PackageManager.PERMISSION_GRANTED) { 7077 throw new SecurityException("Requires permission " 7078 + android.Manifest.permission.DEVICE_POWER); 7079 } 7080 7081 synchronized(this) { 7082 mWentToSleep = true; 7083 updateEventDispatchingLocked(); 7084 7085 if (!mSleeping) { 7086 mSleeping = true; 7087 mMainStack.stopIfSleepingLocked(); 7088 7089 // Initialize the wake times of all processes. 7090 checkExcessivePowerUsageLocked(false); 7091 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7092 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7093 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7094 } 7095 } 7096 } 7097 7098 public boolean shutdown(int timeout) { 7099 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7100 != PackageManager.PERMISSION_GRANTED) { 7101 throw new SecurityException("Requires permission " 7102 + android.Manifest.permission.SHUTDOWN); 7103 } 7104 7105 boolean timedout = false; 7106 7107 synchronized(this) { 7108 mShuttingDown = true; 7109 updateEventDispatchingLocked(); 7110 7111 if (mMainStack.mResumedActivity != null) { 7112 mMainStack.stopIfSleepingLocked(); 7113 final long endTime = System.currentTimeMillis() + timeout; 7114 while (mMainStack.mResumedActivity != null 7115 || mMainStack.mPausingActivity != null) { 7116 long delay = endTime - System.currentTimeMillis(); 7117 if (delay <= 0) { 7118 Slog.w(TAG, "Activity manager shutdown timed out"); 7119 timedout = true; 7120 break; 7121 } 7122 try { 7123 this.wait(); 7124 } catch (InterruptedException e) { 7125 } 7126 } 7127 } 7128 } 7129 7130 mUsageStatsService.shutdown(); 7131 mBatteryStatsService.shutdown(); 7132 7133 return timedout; 7134 } 7135 7136 public final void activitySlept(IBinder token) { 7137 if (localLOGV) Slog.v( 7138 TAG, "Activity slept: token=" + token); 7139 7140 ActivityRecord r = null; 7141 7142 final long origId = Binder.clearCallingIdentity(); 7143 7144 synchronized (this) { 7145 r = mMainStack.isInStackLocked(token); 7146 if (r != null) { 7147 mMainStack.activitySleptLocked(r); 7148 } 7149 } 7150 7151 Binder.restoreCallingIdentity(origId); 7152 } 7153 7154 private void comeOutOfSleepIfNeededLocked() { 7155 if (!mWentToSleep && !mLockScreenShown) { 7156 if (mSleeping) { 7157 mSleeping = false; 7158 mMainStack.awakeFromSleepingLocked(); 7159 mMainStack.resumeTopActivityLocked(null); 7160 } 7161 } 7162 } 7163 7164 public void wakingUp() { 7165 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7166 != PackageManager.PERMISSION_GRANTED) { 7167 throw new SecurityException("Requires permission " 7168 + android.Manifest.permission.DEVICE_POWER); 7169 } 7170 7171 synchronized(this) { 7172 mWentToSleep = false; 7173 updateEventDispatchingLocked(); 7174 comeOutOfSleepIfNeededLocked(); 7175 } 7176 } 7177 7178 private void updateEventDispatchingLocked() { 7179 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7180 } 7181 7182 public void setLockScreenShown(boolean shown) { 7183 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7184 != PackageManager.PERMISSION_GRANTED) { 7185 throw new SecurityException("Requires permission " 7186 + android.Manifest.permission.DEVICE_POWER); 7187 } 7188 7189 synchronized(this) { 7190 mLockScreenShown = shown; 7191 comeOutOfSleepIfNeededLocked(); 7192 } 7193 } 7194 7195 public void stopAppSwitches() { 7196 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7197 != PackageManager.PERMISSION_GRANTED) { 7198 throw new SecurityException("Requires permission " 7199 + android.Manifest.permission.STOP_APP_SWITCHES); 7200 } 7201 7202 synchronized(this) { 7203 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7204 + APP_SWITCH_DELAY_TIME; 7205 mDidAppSwitch = false; 7206 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7207 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7208 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7209 } 7210 } 7211 7212 public void resumeAppSwitches() { 7213 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7214 != PackageManager.PERMISSION_GRANTED) { 7215 throw new SecurityException("Requires permission " 7216 + android.Manifest.permission.STOP_APP_SWITCHES); 7217 } 7218 7219 synchronized(this) { 7220 // Note that we don't execute any pending app switches... we will 7221 // let those wait until either the timeout, or the next start 7222 // activity request. 7223 mAppSwitchesAllowedTime = 0; 7224 } 7225 } 7226 7227 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7228 String name) { 7229 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7230 return true; 7231 } 7232 7233 final int perm = checkComponentPermission( 7234 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7235 callingUid, -1, true); 7236 if (perm == PackageManager.PERMISSION_GRANTED) { 7237 return true; 7238 } 7239 7240 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7241 return false; 7242 } 7243 7244 public void setDebugApp(String packageName, boolean waitForDebugger, 7245 boolean persistent) { 7246 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7247 "setDebugApp()"); 7248 7249 // Note that this is not really thread safe if there are multiple 7250 // callers into it at the same time, but that's not a situation we 7251 // care about. 7252 if (persistent) { 7253 final ContentResolver resolver = mContext.getContentResolver(); 7254 Settings.System.putString( 7255 resolver, Settings.System.DEBUG_APP, 7256 packageName); 7257 Settings.System.putInt( 7258 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7259 waitForDebugger ? 1 : 0); 7260 } 7261 7262 synchronized (this) { 7263 if (!persistent) { 7264 mOrigDebugApp = mDebugApp; 7265 mOrigWaitForDebugger = mWaitForDebugger; 7266 } 7267 mDebugApp = packageName; 7268 mWaitForDebugger = waitForDebugger; 7269 mDebugTransient = !persistent; 7270 if (packageName != null) { 7271 final long origId = Binder.clearCallingIdentity(); 7272 forceStopPackageLocked(packageName, -1, false, false, true, true, 7273 UserHandle.USER_ALL); 7274 Binder.restoreCallingIdentity(origId); 7275 } 7276 } 7277 } 7278 7279 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7280 synchronized (this) { 7281 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7282 if (!isDebuggable) { 7283 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7284 throw new SecurityException("Process not debuggable: " + app.packageName); 7285 } 7286 } 7287 7288 mOpenGlTraceApp = processName; 7289 } 7290 } 7291 7292 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7293 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7294 synchronized (this) { 7295 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7296 if (!isDebuggable) { 7297 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7298 throw new SecurityException("Process not debuggable: " + app.packageName); 7299 } 7300 } 7301 mProfileApp = processName; 7302 mProfileFile = profileFile; 7303 if (mProfileFd != null) { 7304 try { 7305 mProfileFd.close(); 7306 } catch (IOException e) { 7307 } 7308 mProfileFd = null; 7309 } 7310 mProfileFd = profileFd; 7311 mProfileType = 0; 7312 mAutoStopProfiler = autoStopProfiler; 7313 } 7314 } 7315 7316 public void setAlwaysFinish(boolean enabled) { 7317 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7318 "setAlwaysFinish()"); 7319 7320 Settings.System.putInt( 7321 mContext.getContentResolver(), 7322 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7323 7324 synchronized (this) { 7325 mAlwaysFinishActivities = enabled; 7326 } 7327 } 7328 7329 public void setActivityController(IActivityController controller) { 7330 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7331 "setActivityController()"); 7332 synchronized (this) { 7333 mController = controller; 7334 } 7335 } 7336 7337 public boolean isUserAMonkey() { 7338 // For now the fact that there is a controller implies 7339 // we have a monkey. 7340 synchronized (this) { 7341 return mController != null; 7342 } 7343 } 7344 7345 public void registerProcessObserver(IProcessObserver observer) { 7346 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7347 "registerProcessObserver()"); 7348 synchronized (this) { 7349 mProcessObservers.register(observer); 7350 } 7351 } 7352 7353 public void unregisterProcessObserver(IProcessObserver observer) { 7354 synchronized (this) { 7355 mProcessObservers.unregister(observer); 7356 } 7357 } 7358 7359 public void setImmersive(IBinder token, boolean immersive) { 7360 synchronized(this) { 7361 ActivityRecord r = mMainStack.isInStackLocked(token); 7362 if (r == null) { 7363 throw new IllegalArgumentException(); 7364 } 7365 r.immersive = immersive; 7366 } 7367 } 7368 7369 public boolean isImmersive(IBinder token) { 7370 synchronized (this) { 7371 ActivityRecord r = mMainStack.isInStackLocked(token); 7372 if (r == null) { 7373 throw new IllegalArgumentException(); 7374 } 7375 return r.immersive; 7376 } 7377 } 7378 7379 public boolean isTopActivityImmersive() { 7380 enforceNotIsolatedCaller("startActivity"); 7381 synchronized (this) { 7382 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7383 return (r != null) ? r.immersive : false; 7384 } 7385 } 7386 7387 public final void enterSafeMode() { 7388 synchronized(this) { 7389 // It only makes sense to do this before the system is ready 7390 // and started launching other packages. 7391 if (!mSystemReady) { 7392 try { 7393 AppGlobals.getPackageManager().enterSafeMode(); 7394 } catch (RemoteException e) { 7395 } 7396 } 7397 } 7398 } 7399 7400 public final void showSafeModeOverlay() { 7401 View v = LayoutInflater.from(mContext).inflate( 7402 com.android.internal.R.layout.safe_mode, null); 7403 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7404 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7405 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7406 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7407 lp.gravity = Gravity.BOTTOM | Gravity.START; 7408 lp.format = v.getBackground().getOpacity(); 7409 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7410 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7411 ((WindowManager)mContext.getSystemService( 7412 Context.WINDOW_SERVICE)).addView(v, lp); 7413 } 7414 7415 public void noteWakeupAlarm(IIntentSender sender) { 7416 if (!(sender instanceof PendingIntentRecord)) { 7417 return; 7418 } 7419 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7420 synchronized (stats) { 7421 if (mBatteryStatsService.isOnBattery()) { 7422 mBatteryStatsService.enforceCallingPermission(); 7423 PendingIntentRecord rec = (PendingIntentRecord)sender; 7424 int MY_UID = Binder.getCallingUid(); 7425 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7426 BatteryStatsImpl.Uid.Pkg pkg = 7427 stats.getPackageStatsLocked(uid, rec.key.packageName); 7428 pkg.incWakeupsLocked(); 7429 } 7430 } 7431 } 7432 7433 public boolean killPids(int[] pids, String pReason, boolean secure) { 7434 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7435 throw new SecurityException("killPids only available to the system"); 7436 } 7437 String reason = (pReason == null) ? "Unknown" : pReason; 7438 // XXX Note: don't acquire main activity lock here, because the window 7439 // manager calls in with its locks held. 7440 7441 boolean killed = false; 7442 synchronized (mPidsSelfLocked) { 7443 int[] types = new int[pids.length]; 7444 int worstType = 0; 7445 for (int i=0; i<pids.length; i++) { 7446 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7447 if (proc != null) { 7448 int type = proc.setAdj; 7449 types[i] = type; 7450 if (type > worstType) { 7451 worstType = type; 7452 } 7453 } 7454 } 7455 7456 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7457 // then constrain it so we will kill all hidden procs. 7458 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7459 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7460 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7461 } 7462 7463 // If this is not a secure call, don't let it kill processes that 7464 // are important. 7465 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7466 worstType = ProcessList.SERVICE_ADJ; 7467 } 7468 7469 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7470 for (int i=0; i<pids.length; i++) { 7471 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7472 if (proc == null) { 7473 continue; 7474 } 7475 int adj = proc.setAdj; 7476 if (adj >= worstType && !proc.killedBackground) { 7477 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7478 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7479 proc.processName, adj, reason); 7480 killed = true; 7481 proc.killedBackground = true; 7482 Process.killProcessQuiet(pids[i]); 7483 } 7484 } 7485 } 7486 return killed; 7487 } 7488 7489 @Override 7490 public boolean killProcessesBelowForeground(String reason) { 7491 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7492 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7493 } 7494 7495 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7496 } 7497 7498 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7499 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7500 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7501 } 7502 7503 boolean killed = false; 7504 synchronized (mPidsSelfLocked) { 7505 final int size = mPidsSelfLocked.size(); 7506 for (int i = 0; i < size; i++) { 7507 final int pid = mPidsSelfLocked.keyAt(i); 7508 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7509 if (proc == null) continue; 7510 7511 final int adj = proc.setAdj; 7512 if (adj > belowAdj && !proc.killedBackground) { 7513 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7514 EventLog.writeEvent( 7515 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7516 killed = true; 7517 proc.killedBackground = true; 7518 Process.killProcessQuiet(pid); 7519 } 7520 } 7521 } 7522 return killed; 7523 } 7524 7525 public final void startRunning(String pkg, String cls, String action, 7526 String data) { 7527 synchronized(this) { 7528 if (mStartRunning) { 7529 return; 7530 } 7531 mStartRunning = true; 7532 mTopComponent = pkg != null && cls != null 7533 ? new ComponentName(pkg, cls) : null; 7534 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7535 mTopData = data; 7536 if (!mSystemReady) { 7537 return; 7538 } 7539 } 7540 7541 systemReady(null); 7542 } 7543 7544 private void retrieveSettings() { 7545 final ContentResolver resolver = mContext.getContentResolver(); 7546 String debugApp = Settings.System.getString( 7547 resolver, Settings.System.DEBUG_APP); 7548 boolean waitForDebugger = Settings.System.getInt( 7549 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7550 boolean alwaysFinishActivities = Settings.System.getInt( 7551 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7552 7553 Configuration configuration = new Configuration(); 7554 Settings.System.getConfiguration(resolver, configuration); 7555 7556 synchronized (this) { 7557 mDebugApp = mOrigDebugApp = debugApp; 7558 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7559 mAlwaysFinishActivities = alwaysFinishActivities; 7560 // This happens before any activities are started, so we can 7561 // change mConfiguration in-place. 7562 updateConfigurationLocked(configuration, null, false, true); 7563 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7564 } 7565 } 7566 7567 public boolean testIsSystemReady() { 7568 // no need to synchronize(this) just to read & return the value 7569 return mSystemReady; 7570 } 7571 7572 private static File getCalledPreBootReceiversFile() { 7573 File dataDir = Environment.getDataDirectory(); 7574 File systemDir = new File(dataDir, "system"); 7575 File fname = new File(systemDir, "called_pre_boots.dat"); 7576 return fname; 7577 } 7578 7579 static final int LAST_DONE_VERSION = 10000; 7580 7581 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7582 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7583 File file = getCalledPreBootReceiversFile(); 7584 FileInputStream fis = null; 7585 try { 7586 fis = new FileInputStream(file); 7587 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7588 int fvers = dis.readInt(); 7589 if (fvers == LAST_DONE_VERSION) { 7590 String vers = dis.readUTF(); 7591 String codename = dis.readUTF(); 7592 String build = dis.readUTF(); 7593 if (android.os.Build.VERSION.RELEASE.equals(vers) 7594 && android.os.Build.VERSION.CODENAME.equals(codename) 7595 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7596 int num = dis.readInt(); 7597 while (num > 0) { 7598 num--; 7599 String pkg = dis.readUTF(); 7600 String cls = dis.readUTF(); 7601 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7602 } 7603 } 7604 } 7605 } catch (FileNotFoundException e) { 7606 } catch (IOException e) { 7607 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7608 } finally { 7609 if (fis != null) { 7610 try { 7611 fis.close(); 7612 } catch (IOException e) { 7613 } 7614 } 7615 } 7616 return lastDoneReceivers; 7617 } 7618 7619 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7620 File file = getCalledPreBootReceiversFile(); 7621 FileOutputStream fos = null; 7622 DataOutputStream dos = null; 7623 try { 7624 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7625 fos = new FileOutputStream(file); 7626 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7627 dos.writeInt(LAST_DONE_VERSION); 7628 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7629 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7630 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7631 dos.writeInt(list.size()); 7632 for (int i=0; i<list.size(); i++) { 7633 dos.writeUTF(list.get(i).getPackageName()); 7634 dos.writeUTF(list.get(i).getClassName()); 7635 } 7636 } catch (IOException e) { 7637 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7638 file.delete(); 7639 } finally { 7640 FileUtils.sync(fos); 7641 if (dos != null) { 7642 try { 7643 dos.close(); 7644 } catch (IOException e) { 7645 // TODO Auto-generated catch block 7646 e.printStackTrace(); 7647 } 7648 } 7649 } 7650 } 7651 7652 public void systemReady(final Runnable goingCallback) { 7653 synchronized(this) { 7654 if (mSystemReady) { 7655 if (goingCallback != null) goingCallback.run(); 7656 return; 7657 } 7658 7659 // Check to see if there are any update receivers to run. 7660 if (!mDidUpdate) { 7661 if (mWaitingUpdate) { 7662 return; 7663 } 7664 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7665 List<ResolveInfo> ris = null; 7666 try { 7667 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7668 intent, null, 0, 0); 7669 } catch (RemoteException e) { 7670 } 7671 if (ris != null) { 7672 for (int i=ris.size()-1; i>=0; i--) { 7673 if ((ris.get(i).activityInfo.applicationInfo.flags 7674 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7675 ris.remove(i); 7676 } 7677 } 7678 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7679 7680 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7681 7682 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7683 for (int i=0; i<ris.size(); i++) { 7684 ActivityInfo ai = ris.get(i).activityInfo; 7685 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7686 if (lastDoneReceivers.contains(comp)) { 7687 ris.remove(i); 7688 i--; 7689 } 7690 } 7691 7692 final int[] users = getUsersLocked(); 7693 for (int i=0; i<ris.size(); i++) { 7694 ActivityInfo ai = ris.get(i).activityInfo; 7695 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7696 doneReceivers.add(comp); 7697 intent.setComponent(comp); 7698 for (int j=0; j<users.length; j++) { 7699 IIntentReceiver finisher = null; 7700 if (i == ris.size()-1 && j == users.length-1) { 7701 finisher = new IIntentReceiver.Stub() { 7702 public void performReceive(Intent intent, int resultCode, 7703 String data, Bundle extras, boolean ordered, 7704 boolean sticky, int sendingUser) { 7705 // The raw IIntentReceiver interface is called 7706 // with the AM lock held, so redispatch to 7707 // execute our code without the lock. 7708 mHandler.post(new Runnable() { 7709 public void run() { 7710 synchronized (ActivityManagerService.this) { 7711 mDidUpdate = true; 7712 } 7713 writeLastDonePreBootReceivers(doneReceivers); 7714 showBootMessage(mContext.getText( 7715 R.string.android_upgrading_complete), 7716 false); 7717 systemReady(goingCallback); 7718 } 7719 }); 7720 } 7721 }; 7722 } 7723 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7724 + " for user " + users[j]); 7725 broadcastIntentLocked(null, null, intent, null, finisher, 7726 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7727 users[j]); 7728 if (finisher != null) { 7729 mWaitingUpdate = true; 7730 } 7731 } 7732 } 7733 } 7734 if (mWaitingUpdate) { 7735 return; 7736 } 7737 mDidUpdate = true; 7738 } 7739 7740 mSystemReady = true; 7741 if (!mStartRunning) { 7742 return; 7743 } 7744 } 7745 7746 ArrayList<ProcessRecord> procsToKill = null; 7747 synchronized(mPidsSelfLocked) { 7748 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7749 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7750 if (!isAllowedWhileBooting(proc.info)){ 7751 if (procsToKill == null) { 7752 procsToKill = new ArrayList<ProcessRecord>(); 7753 } 7754 procsToKill.add(proc); 7755 } 7756 } 7757 } 7758 7759 synchronized(this) { 7760 if (procsToKill != null) { 7761 for (int i=procsToKill.size()-1; i>=0; i--) { 7762 ProcessRecord proc = procsToKill.get(i); 7763 Slog.i(TAG, "Removing system update proc: " + proc); 7764 removeProcessLocked(proc, true, false, "system update done"); 7765 } 7766 } 7767 7768 // Now that we have cleaned up any update processes, we 7769 // are ready to start launching real processes and know that 7770 // we won't trample on them any more. 7771 mProcessesReady = true; 7772 } 7773 7774 Slog.i(TAG, "System now ready"); 7775 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7776 SystemClock.uptimeMillis()); 7777 7778 synchronized(this) { 7779 // Make sure we have no pre-ready processes sitting around. 7780 7781 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7782 ResolveInfo ri = mContext.getPackageManager() 7783 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7784 STOCK_PM_FLAGS); 7785 CharSequence errorMsg = null; 7786 if (ri != null) { 7787 ActivityInfo ai = ri.activityInfo; 7788 ApplicationInfo app = ai.applicationInfo; 7789 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7790 mTopAction = Intent.ACTION_FACTORY_TEST; 7791 mTopData = null; 7792 mTopComponent = new ComponentName(app.packageName, 7793 ai.name); 7794 } else { 7795 errorMsg = mContext.getResources().getText( 7796 com.android.internal.R.string.factorytest_not_system); 7797 } 7798 } else { 7799 errorMsg = mContext.getResources().getText( 7800 com.android.internal.R.string.factorytest_no_action); 7801 } 7802 if (errorMsg != null) { 7803 mTopAction = null; 7804 mTopData = null; 7805 mTopComponent = null; 7806 Message msg = Message.obtain(); 7807 msg.what = SHOW_FACTORY_ERROR_MSG; 7808 msg.getData().putCharSequence("msg", errorMsg); 7809 mHandler.sendMessage(msg); 7810 } 7811 } 7812 } 7813 7814 retrieveSettings(); 7815 7816 if (goingCallback != null) goingCallback.run(); 7817 7818 synchronized (this) { 7819 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7820 try { 7821 List apps = AppGlobals.getPackageManager(). 7822 getPersistentApplications(STOCK_PM_FLAGS); 7823 if (apps != null) { 7824 int N = apps.size(); 7825 int i; 7826 for (i=0; i<N; i++) { 7827 ApplicationInfo info 7828 = (ApplicationInfo)apps.get(i); 7829 if (info != null && 7830 !info.packageName.equals("android")) { 7831 addAppLocked(info, false); 7832 } 7833 } 7834 } 7835 } catch (RemoteException ex) { 7836 // pm is in same process, this will never happen. 7837 } 7838 } 7839 7840 // Start up initial activity. 7841 mBooting = true; 7842 7843 try { 7844 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7845 Message msg = Message.obtain(); 7846 msg.what = SHOW_UID_ERROR_MSG; 7847 mHandler.sendMessage(msg); 7848 } 7849 } catch (RemoteException e) { 7850 } 7851 7852 long ident = Binder.clearCallingIdentity(); 7853 try { 7854 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7855 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7856 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7857 broadcastIntentLocked(null, null, intent, 7858 null, null, 0, null, null, null, 7859 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7860 } finally { 7861 Binder.restoreCallingIdentity(ident); 7862 } 7863 mMainStack.resumeTopActivityLocked(null); 7864 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7865 } 7866 } 7867 7868 private boolean makeAppCrashingLocked(ProcessRecord app, 7869 String shortMsg, String longMsg, String stackTrace) { 7870 app.crashing = true; 7871 app.crashingReport = generateProcessError(app, 7872 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7873 startAppProblemLocked(app); 7874 app.stopFreezingAllLocked(); 7875 return handleAppCrashLocked(app); 7876 } 7877 7878 private void makeAppNotRespondingLocked(ProcessRecord app, 7879 String activity, String shortMsg, String longMsg) { 7880 app.notResponding = true; 7881 app.notRespondingReport = generateProcessError(app, 7882 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7883 activity, shortMsg, longMsg, null); 7884 startAppProblemLocked(app); 7885 app.stopFreezingAllLocked(); 7886 } 7887 7888 /** 7889 * Generate a process error record, suitable for attachment to a ProcessRecord. 7890 * 7891 * @param app The ProcessRecord in which the error occurred. 7892 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7893 * ActivityManager.AppErrorStateInfo 7894 * @param activity The activity associated with the crash, if known. 7895 * @param shortMsg Short message describing the crash. 7896 * @param longMsg Long message describing the crash. 7897 * @param stackTrace Full crash stack trace, may be null. 7898 * 7899 * @return Returns a fully-formed AppErrorStateInfo record. 7900 */ 7901 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7902 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7903 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7904 7905 report.condition = condition; 7906 report.processName = app.processName; 7907 report.pid = app.pid; 7908 report.uid = app.info.uid; 7909 report.tag = activity; 7910 report.shortMsg = shortMsg; 7911 report.longMsg = longMsg; 7912 report.stackTrace = stackTrace; 7913 7914 return report; 7915 } 7916 7917 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7918 synchronized (this) { 7919 app.crashing = false; 7920 app.crashingReport = null; 7921 app.notResponding = false; 7922 app.notRespondingReport = null; 7923 if (app.anrDialog == fromDialog) { 7924 app.anrDialog = null; 7925 } 7926 if (app.waitDialog == fromDialog) { 7927 app.waitDialog = null; 7928 } 7929 if (app.pid > 0 && app.pid != MY_PID) { 7930 handleAppCrashLocked(app); 7931 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7932 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7933 app.processName, app.setAdj, "user's request after error"); 7934 Process.killProcessQuiet(app.pid); 7935 } 7936 } 7937 } 7938 7939 private boolean handleAppCrashLocked(ProcessRecord app) { 7940 if (mHeadless) { 7941 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7942 return false; 7943 } 7944 long now = SystemClock.uptimeMillis(); 7945 7946 Long crashTime; 7947 if (!app.isolated) { 7948 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7949 } else { 7950 crashTime = null; 7951 } 7952 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7953 // This process loses! 7954 Slog.w(TAG, "Process " + app.info.processName 7955 + " has crashed too many times: killing!"); 7956 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7957 app.info.processName, app.uid); 7958 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7959 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7960 if (r.app == app) { 7961 Slog.w(TAG, " Force finishing activity " 7962 + r.intent.getComponent().flattenToShortString()); 7963 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7964 null, "crashed", false); 7965 } 7966 } 7967 if (!app.persistent) { 7968 // We don't want to start this process again until the user 7969 // explicitly does so... but for persistent process, we really 7970 // need to keep it running. If a persistent process is actually 7971 // repeatedly crashing, then badness for everyone. 7972 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7973 app.info.processName); 7974 if (!app.isolated) { 7975 // XXX We don't have a way to mark isolated processes 7976 // as bad, since they don't have a peristent identity. 7977 mBadProcesses.put(app.info.processName, app.uid, now); 7978 mProcessCrashTimes.remove(app.info.processName, app.uid); 7979 } 7980 app.bad = true; 7981 app.removed = true; 7982 // Don't let services in this process be restarted and potentially 7983 // annoy the user repeatedly. Unless it is persistent, since those 7984 // processes run critical code. 7985 removeProcessLocked(app, false, false, "crash"); 7986 mMainStack.resumeTopActivityLocked(null); 7987 return false; 7988 } 7989 mMainStack.resumeTopActivityLocked(null); 7990 } else { 7991 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7992 if (r != null && r.app == app) { 7993 // If the top running activity is from this crashing 7994 // process, then terminate it to avoid getting in a loop. 7995 Slog.w(TAG, " Force finishing activity " 7996 + r.intent.getComponent().flattenToShortString()); 7997 int index = mMainStack.indexOfActivityLocked(r); 7998 r.stack.finishActivityLocked(r, index, 7999 Activity.RESULT_CANCELED, null, "crashed", false); 8000 // Also terminate any activities below it that aren't yet 8001 // stopped, to avoid a situation where one will get 8002 // re-start our crashing activity once it gets resumed again. 8003 index--; 8004 if (index >= 0) { 8005 r = (ActivityRecord)mMainStack.mHistory.get(index); 8006 if (r.state == ActivityState.RESUMED 8007 || r.state == ActivityState.PAUSING 8008 || r.state == ActivityState.PAUSED) { 8009 if (!r.isHomeActivity || mHomeProcess != r.app) { 8010 Slog.w(TAG, " Force finishing activity " 8011 + r.intent.getComponent().flattenToShortString()); 8012 r.stack.finishActivityLocked(r, index, 8013 Activity.RESULT_CANCELED, null, "crashed", false); 8014 } 8015 } 8016 } 8017 } 8018 } 8019 8020 // Bump up the crash count of any services currently running in the proc. 8021 if (app.services.size() != 0) { 8022 // Any services running in the application need to be placed 8023 // back in the pending list. 8024 Iterator<ServiceRecord> it = app.services.iterator(); 8025 while (it.hasNext()) { 8026 ServiceRecord sr = it.next(); 8027 sr.crashCount++; 8028 } 8029 } 8030 8031 // If the crashing process is what we consider to be the "home process" and it has been 8032 // replaced by a third-party app, clear the package preferred activities from packages 8033 // with a home activity running in the process to prevent a repeatedly crashing app 8034 // from blocking the user to manually clear the list. 8035 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8036 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8037 Iterator it = mHomeProcess.activities.iterator(); 8038 while (it.hasNext()) { 8039 ActivityRecord r = (ActivityRecord)it.next(); 8040 if (r.isHomeActivity) { 8041 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8042 try { 8043 ActivityThread.getPackageManager() 8044 .clearPackagePreferredActivities(r.packageName); 8045 } catch (RemoteException c) { 8046 // pm is in same process, this will never happen. 8047 } 8048 } 8049 } 8050 } 8051 8052 if (!app.isolated) { 8053 // XXX Can't keep track of crash times for isolated processes, 8054 // because they don't have a perisistent identity. 8055 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8056 } 8057 8058 return true; 8059 } 8060 8061 void startAppProblemLocked(ProcessRecord app) { 8062 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8063 mContext, app.info.packageName, app.info.flags); 8064 skipCurrentReceiverLocked(app); 8065 } 8066 8067 void skipCurrentReceiverLocked(ProcessRecord app) { 8068 for (BroadcastQueue queue : mBroadcastQueues) { 8069 queue.skipCurrentReceiverLocked(app); 8070 } 8071 } 8072 8073 /** 8074 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8075 * The application process will exit immediately after this call returns. 8076 * @param app object of the crashing app, null for the system server 8077 * @param crashInfo describing the exception 8078 */ 8079 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8080 ProcessRecord r = findAppProcess(app, "Crash"); 8081 final String processName = app == null ? "system_server" 8082 : (r == null ? "unknown" : r.processName); 8083 8084 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8085 processName, 8086 r == null ? -1 : r.info.flags, 8087 crashInfo.exceptionClassName, 8088 crashInfo.exceptionMessage, 8089 crashInfo.throwFileName, 8090 crashInfo.throwLineNumber); 8091 8092 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8093 8094 crashApplication(r, crashInfo); 8095 } 8096 8097 public void handleApplicationStrictModeViolation( 8098 IBinder app, 8099 int violationMask, 8100 StrictMode.ViolationInfo info) { 8101 ProcessRecord r = findAppProcess(app, "StrictMode"); 8102 if (r == null) { 8103 return; 8104 } 8105 8106 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8107 Integer stackFingerprint = info.hashCode(); 8108 boolean logIt = true; 8109 synchronized (mAlreadyLoggedViolatedStacks) { 8110 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8111 logIt = false; 8112 // TODO: sub-sample into EventLog for these, with 8113 // the info.durationMillis? Then we'd get 8114 // the relative pain numbers, without logging all 8115 // the stack traces repeatedly. We'd want to do 8116 // likewise in the client code, which also does 8117 // dup suppression, before the Binder call. 8118 } else { 8119 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8120 mAlreadyLoggedViolatedStacks.clear(); 8121 } 8122 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8123 } 8124 } 8125 if (logIt) { 8126 logStrictModeViolationToDropBox(r, info); 8127 } 8128 } 8129 8130 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8131 AppErrorResult result = new AppErrorResult(); 8132 synchronized (this) { 8133 final long origId = Binder.clearCallingIdentity(); 8134 8135 Message msg = Message.obtain(); 8136 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8137 HashMap<String, Object> data = new HashMap<String, Object>(); 8138 data.put("result", result); 8139 data.put("app", r); 8140 data.put("violationMask", violationMask); 8141 data.put("info", info); 8142 msg.obj = data; 8143 mHandler.sendMessage(msg); 8144 8145 Binder.restoreCallingIdentity(origId); 8146 } 8147 int res = result.get(); 8148 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8149 } 8150 } 8151 8152 // Depending on the policy in effect, there could be a bunch of 8153 // these in quick succession so we try to batch these together to 8154 // minimize disk writes, number of dropbox entries, and maximize 8155 // compression, by having more fewer, larger records. 8156 private void logStrictModeViolationToDropBox( 8157 ProcessRecord process, 8158 StrictMode.ViolationInfo info) { 8159 if (info == null) { 8160 return; 8161 } 8162 final boolean isSystemApp = process == null || 8163 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8164 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8165 final String processName = process == null ? "unknown" : process.processName; 8166 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8167 final DropBoxManager dbox = (DropBoxManager) 8168 mContext.getSystemService(Context.DROPBOX_SERVICE); 8169 8170 // Exit early if the dropbox isn't configured to accept this report type. 8171 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8172 8173 boolean bufferWasEmpty; 8174 boolean needsFlush; 8175 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8176 synchronized (sb) { 8177 bufferWasEmpty = sb.length() == 0; 8178 appendDropBoxProcessHeaders(process, processName, sb); 8179 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8180 sb.append("System-App: ").append(isSystemApp).append("\n"); 8181 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8182 if (info.violationNumThisLoop != 0) { 8183 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8184 } 8185 if (info.numAnimationsRunning != 0) { 8186 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8187 } 8188 if (info.broadcastIntentAction != null) { 8189 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8190 } 8191 if (info.durationMillis != -1) { 8192 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8193 } 8194 if (info.numInstances != -1) { 8195 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8196 } 8197 if (info.tags != null) { 8198 for (String tag : info.tags) { 8199 sb.append("Span-Tag: ").append(tag).append("\n"); 8200 } 8201 } 8202 sb.append("\n"); 8203 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8204 sb.append(info.crashInfo.stackTrace); 8205 } 8206 sb.append("\n"); 8207 8208 // Only buffer up to ~64k. Various logging bits truncate 8209 // things at 128k. 8210 needsFlush = (sb.length() > 64 * 1024); 8211 } 8212 8213 // Flush immediately if the buffer's grown too large, or this 8214 // is a non-system app. Non-system apps are isolated with a 8215 // different tag & policy and not batched. 8216 // 8217 // Batching is useful during internal testing with 8218 // StrictMode settings turned up high. Without batching, 8219 // thousands of separate files could be created on boot. 8220 if (!isSystemApp || needsFlush) { 8221 new Thread("Error dump: " + dropboxTag) { 8222 @Override 8223 public void run() { 8224 String report; 8225 synchronized (sb) { 8226 report = sb.toString(); 8227 sb.delete(0, sb.length()); 8228 sb.trimToSize(); 8229 } 8230 if (report.length() != 0) { 8231 dbox.addText(dropboxTag, report); 8232 } 8233 } 8234 }.start(); 8235 return; 8236 } 8237 8238 // System app batching: 8239 if (!bufferWasEmpty) { 8240 // An existing dropbox-writing thread is outstanding, so 8241 // we don't need to start it up. The existing thread will 8242 // catch the buffer appends we just did. 8243 return; 8244 } 8245 8246 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8247 // (After this point, we shouldn't access AMS internal data structures.) 8248 new Thread("Error dump: " + dropboxTag) { 8249 @Override 8250 public void run() { 8251 // 5 second sleep to let stacks arrive and be batched together 8252 try { 8253 Thread.sleep(5000); // 5 seconds 8254 } catch (InterruptedException e) {} 8255 8256 String errorReport; 8257 synchronized (mStrictModeBuffer) { 8258 errorReport = mStrictModeBuffer.toString(); 8259 if (errorReport.length() == 0) { 8260 return; 8261 } 8262 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8263 mStrictModeBuffer.trimToSize(); 8264 } 8265 dbox.addText(dropboxTag, errorReport); 8266 } 8267 }.start(); 8268 } 8269 8270 /** 8271 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8272 * @param app object of the crashing app, null for the system server 8273 * @param tag reported by the caller 8274 * @param crashInfo describing the context of the error 8275 * @return true if the process should exit immediately (WTF is fatal) 8276 */ 8277 public boolean handleApplicationWtf(IBinder app, String tag, 8278 ApplicationErrorReport.CrashInfo crashInfo) { 8279 ProcessRecord r = findAppProcess(app, "WTF"); 8280 final String processName = app == null ? "system_server" 8281 : (r == null ? "unknown" : r.processName); 8282 8283 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8284 processName, 8285 r == null ? -1 : r.info.flags, 8286 tag, crashInfo.exceptionMessage); 8287 8288 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8289 8290 if (r != null && r.pid != Process.myPid() && 8291 Settings.Secure.getInt(mContext.getContentResolver(), 8292 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8293 crashApplication(r, crashInfo); 8294 return true; 8295 } else { 8296 return false; 8297 } 8298 } 8299 8300 /** 8301 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8302 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8303 */ 8304 private ProcessRecord findAppProcess(IBinder app, String reason) { 8305 if (app == null) { 8306 return null; 8307 } 8308 8309 synchronized (this) { 8310 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8311 final int NA = apps.size(); 8312 for (int ia=0; ia<NA; ia++) { 8313 ProcessRecord p = apps.valueAt(ia); 8314 if (p.thread != null && p.thread.asBinder() == app) { 8315 return p; 8316 } 8317 } 8318 } 8319 8320 Slog.w(TAG, "Can't find mystery application for " + reason 8321 + " from pid=" + Binder.getCallingPid() 8322 + " uid=" + Binder.getCallingUid() + ": " + app); 8323 return null; 8324 } 8325 } 8326 8327 /** 8328 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8329 * to append various headers to the dropbox log text. 8330 */ 8331 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8332 StringBuilder sb) { 8333 // Watchdog thread ends up invoking this function (with 8334 // a null ProcessRecord) to add the stack file to dropbox. 8335 // Do not acquire a lock on this (am) in such cases, as it 8336 // could cause a potential deadlock, if and when watchdog 8337 // is invoked due to unavailability of lock on am and it 8338 // would prevent watchdog from killing system_server. 8339 if (process == null) { 8340 sb.append("Process: ").append(processName).append("\n"); 8341 return; 8342 } 8343 // Note: ProcessRecord 'process' is guarded by the service 8344 // instance. (notably process.pkgList, which could otherwise change 8345 // concurrently during execution of this method) 8346 synchronized (this) { 8347 sb.append("Process: ").append(processName).append("\n"); 8348 int flags = process.info.flags; 8349 IPackageManager pm = AppGlobals.getPackageManager(); 8350 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8351 for (String pkg : process.pkgList) { 8352 sb.append("Package: ").append(pkg); 8353 try { 8354 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8355 if (pi != null) { 8356 sb.append(" v").append(pi.versionCode); 8357 if (pi.versionName != null) { 8358 sb.append(" (").append(pi.versionName).append(")"); 8359 } 8360 } 8361 } catch (RemoteException e) { 8362 Slog.e(TAG, "Error getting package info: " + pkg, e); 8363 } 8364 sb.append("\n"); 8365 } 8366 } 8367 } 8368 8369 private static String processClass(ProcessRecord process) { 8370 if (process == null || process.pid == MY_PID) { 8371 return "system_server"; 8372 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8373 return "system_app"; 8374 } else { 8375 return "data_app"; 8376 } 8377 } 8378 8379 /** 8380 * Write a description of an error (crash, WTF, ANR) to the drop box. 8381 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8382 * @param process which caused the error, null means the system server 8383 * @param activity which triggered the error, null if unknown 8384 * @param parent activity related to the error, null if unknown 8385 * @param subject line related to the error, null if absent 8386 * @param report in long form describing the error, null if absent 8387 * @param logFile to include in the report, null if none 8388 * @param crashInfo giving an application stack trace, null if absent 8389 */ 8390 public void addErrorToDropBox(String eventType, 8391 ProcessRecord process, String processName, ActivityRecord activity, 8392 ActivityRecord parent, String subject, 8393 final String report, final File logFile, 8394 final ApplicationErrorReport.CrashInfo crashInfo) { 8395 // NOTE -- this must never acquire the ActivityManagerService lock, 8396 // otherwise the watchdog may be prevented from resetting the system. 8397 8398 final String dropboxTag = processClass(process) + "_" + eventType; 8399 final DropBoxManager dbox = (DropBoxManager) 8400 mContext.getSystemService(Context.DROPBOX_SERVICE); 8401 8402 // Exit early if the dropbox isn't configured to accept this report type. 8403 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8404 8405 final StringBuilder sb = new StringBuilder(1024); 8406 appendDropBoxProcessHeaders(process, processName, sb); 8407 if (activity != null) { 8408 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8409 } 8410 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8411 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8412 } 8413 if (parent != null && parent != activity) { 8414 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8415 } 8416 if (subject != null) { 8417 sb.append("Subject: ").append(subject).append("\n"); 8418 } 8419 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8420 if (Debug.isDebuggerConnected()) { 8421 sb.append("Debugger: Connected\n"); 8422 } 8423 sb.append("\n"); 8424 8425 // Do the rest in a worker thread to avoid blocking the caller on I/O 8426 // (After this point, we shouldn't access AMS internal data structures.) 8427 Thread worker = new Thread("Error dump: " + dropboxTag) { 8428 @Override 8429 public void run() { 8430 if (report != null) { 8431 sb.append(report); 8432 } 8433 if (logFile != null) { 8434 try { 8435 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8436 } catch (IOException e) { 8437 Slog.e(TAG, "Error reading " + logFile, e); 8438 } 8439 } 8440 if (crashInfo != null && crashInfo.stackTrace != null) { 8441 sb.append(crashInfo.stackTrace); 8442 } 8443 8444 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8445 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8446 if (lines > 0) { 8447 sb.append("\n"); 8448 8449 // Merge several logcat streams, and take the last N lines 8450 InputStreamReader input = null; 8451 try { 8452 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8453 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8454 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8455 8456 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8457 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8458 input = new InputStreamReader(logcat.getInputStream()); 8459 8460 int num; 8461 char[] buf = new char[8192]; 8462 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8463 } catch (IOException e) { 8464 Slog.e(TAG, "Error running logcat", e); 8465 } finally { 8466 if (input != null) try { input.close(); } catch (IOException e) {} 8467 } 8468 } 8469 8470 dbox.addText(dropboxTag, sb.toString()); 8471 } 8472 }; 8473 8474 if (process == null) { 8475 // If process is null, we are being called from some internal code 8476 // and may be about to die -- run this synchronously. 8477 worker.run(); 8478 } else { 8479 worker.start(); 8480 } 8481 } 8482 8483 /** 8484 * Bring up the "unexpected error" dialog box for a crashing app. 8485 * Deal with edge cases (intercepts from instrumented applications, 8486 * ActivityController, error intent receivers, that sort of thing). 8487 * @param r the application crashing 8488 * @param crashInfo describing the failure 8489 */ 8490 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8491 long timeMillis = System.currentTimeMillis(); 8492 String shortMsg = crashInfo.exceptionClassName; 8493 String longMsg = crashInfo.exceptionMessage; 8494 String stackTrace = crashInfo.stackTrace; 8495 if (shortMsg != null && longMsg != null) { 8496 longMsg = shortMsg + ": " + longMsg; 8497 } else if (shortMsg != null) { 8498 longMsg = shortMsg; 8499 } 8500 8501 AppErrorResult result = new AppErrorResult(); 8502 synchronized (this) { 8503 if (mController != null) { 8504 try { 8505 String name = r != null ? r.processName : null; 8506 int pid = r != null ? r.pid : Binder.getCallingPid(); 8507 if (!mController.appCrashed(name, pid, 8508 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8509 Slog.w(TAG, "Force-killing crashed app " + name 8510 + " at watcher's request"); 8511 Process.killProcess(pid); 8512 return; 8513 } 8514 } catch (RemoteException e) { 8515 mController = null; 8516 } 8517 } 8518 8519 final long origId = Binder.clearCallingIdentity(); 8520 8521 // If this process is running instrumentation, finish it. 8522 if (r != null && r.instrumentationClass != null) { 8523 Slog.w(TAG, "Error in app " + r.processName 8524 + " running instrumentation " + r.instrumentationClass + ":"); 8525 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8526 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8527 Bundle info = new Bundle(); 8528 info.putString("shortMsg", shortMsg); 8529 info.putString("longMsg", longMsg); 8530 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8531 Binder.restoreCallingIdentity(origId); 8532 return; 8533 } 8534 8535 // If we can't identify the process or it's already exceeded its crash quota, 8536 // quit right away without showing a crash dialog. 8537 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8538 Binder.restoreCallingIdentity(origId); 8539 return; 8540 } 8541 8542 Message msg = Message.obtain(); 8543 msg.what = SHOW_ERROR_MSG; 8544 HashMap data = new HashMap(); 8545 data.put("result", result); 8546 data.put("app", r); 8547 msg.obj = data; 8548 mHandler.sendMessage(msg); 8549 8550 Binder.restoreCallingIdentity(origId); 8551 } 8552 8553 int res = result.get(); 8554 8555 Intent appErrorIntent = null; 8556 synchronized (this) { 8557 if (r != null && !r.isolated) { 8558 // XXX Can't keep track of crash time for isolated processes, 8559 // since they don't have a persistent identity. 8560 mProcessCrashTimes.put(r.info.processName, r.uid, 8561 SystemClock.uptimeMillis()); 8562 } 8563 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8564 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8565 } 8566 } 8567 8568 if (appErrorIntent != null) { 8569 try { 8570 mContext.startActivity(appErrorIntent); 8571 } catch (ActivityNotFoundException e) { 8572 Slog.w(TAG, "bug report receiver dissappeared", e); 8573 } 8574 } 8575 } 8576 8577 Intent createAppErrorIntentLocked(ProcessRecord r, 8578 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8579 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8580 if (report == null) { 8581 return null; 8582 } 8583 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8584 result.setComponent(r.errorReportReceiver); 8585 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8586 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8587 return result; 8588 } 8589 8590 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8591 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8592 if (r.errorReportReceiver == null) { 8593 return null; 8594 } 8595 8596 if (!r.crashing && !r.notResponding) { 8597 return null; 8598 } 8599 8600 ApplicationErrorReport report = new ApplicationErrorReport(); 8601 report.packageName = r.info.packageName; 8602 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8603 report.processName = r.processName; 8604 report.time = timeMillis; 8605 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8606 8607 if (r.crashing) { 8608 report.type = ApplicationErrorReport.TYPE_CRASH; 8609 report.crashInfo = crashInfo; 8610 } else if (r.notResponding) { 8611 report.type = ApplicationErrorReport.TYPE_ANR; 8612 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8613 8614 report.anrInfo.activity = r.notRespondingReport.tag; 8615 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8616 report.anrInfo.info = r.notRespondingReport.longMsg; 8617 } 8618 8619 return report; 8620 } 8621 8622 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8623 enforceNotIsolatedCaller("getProcessesInErrorState"); 8624 // assume our apps are happy - lazy create the list 8625 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8626 8627 final boolean allUsers = ActivityManager.checkUidPermission( 8628 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8629 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8630 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8631 8632 synchronized (this) { 8633 8634 // iterate across all processes 8635 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8636 ProcessRecord app = mLruProcesses.get(i); 8637 if (!allUsers && app.userId != userId) { 8638 continue; 8639 } 8640 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8641 // This one's in trouble, so we'll generate a report for it 8642 // crashes are higher priority (in case there's a crash *and* an anr) 8643 ActivityManager.ProcessErrorStateInfo report = null; 8644 if (app.crashing) { 8645 report = app.crashingReport; 8646 } else if (app.notResponding) { 8647 report = app.notRespondingReport; 8648 } 8649 8650 if (report != null) { 8651 if (errList == null) { 8652 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8653 } 8654 errList.add(report); 8655 } else { 8656 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8657 " crashing = " + app.crashing + 8658 " notResponding = " + app.notResponding); 8659 } 8660 } 8661 } 8662 } 8663 8664 return errList; 8665 } 8666 8667 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8668 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8669 if (currApp != null) { 8670 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8671 } 8672 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8673 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8674 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8675 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8676 if (currApp != null) { 8677 currApp.lru = 0; 8678 } 8679 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8680 } else if (adj >= ProcessList.SERVICE_ADJ) { 8681 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8682 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8683 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8684 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8685 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8686 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8687 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8688 } else { 8689 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8690 } 8691 } 8692 8693 private void fillInProcMemInfo(ProcessRecord app, 8694 ActivityManager.RunningAppProcessInfo outInfo) { 8695 outInfo.pid = app.pid; 8696 outInfo.uid = app.info.uid; 8697 if (mHeavyWeightProcess == app) { 8698 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8699 } 8700 if (app.persistent) { 8701 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8702 } 8703 if (app.hasActivities) { 8704 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8705 } 8706 outInfo.lastTrimLevel = app.trimMemoryLevel; 8707 int adj = app.curAdj; 8708 outInfo.importance = oomAdjToImportance(adj, outInfo); 8709 outInfo.importanceReasonCode = app.adjTypeCode; 8710 } 8711 8712 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8713 enforceNotIsolatedCaller("getRunningAppProcesses"); 8714 // Lazy instantiation of list 8715 List<ActivityManager.RunningAppProcessInfo> runList = null; 8716 final boolean allUsers = ActivityManager.checkUidPermission( 8717 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8718 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8719 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8720 synchronized (this) { 8721 // Iterate across all processes 8722 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8723 ProcessRecord app = mLruProcesses.get(i); 8724 if (!allUsers && app.userId != userId) { 8725 continue; 8726 } 8727 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8728 // Generate process state info for running application 8729 ActivityManager.RunningAppProcessInfo currApp = 8730 new ActivityManager.RunningAppProcessInfo(app.processName, 8731 app.pid, app.getPackageList()); 8732 fillInProcMemInfo(app, currApp); 8733 if (app.adjSource instanceof ProcessRecord) { 8734 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8735 currApp.importanceReasonImportance = oomAdjToImportance( 8736 app.adjSourceOom, null); 8737 } else if (app.adjSource instanceof ActivityRecord) { 8738 ActivityRecord r = (ActivityRecord)app.adjSource; 8739 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8740 } 8741 if (app.adjTarget instanceof ComponentName) { 8742 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8743 } 8744 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8745 // + " lru=" + currApp.lru); 8746 if (runList == null) { 8747 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8748 } 8749 runList.add(currApp); 8750 } 8751 } 8752 } 8753 return runList; 8754 } 8755 8756 public List<ApplicationInfo> getRunningExternalApplications() { 8757 enforceNotIsolatedCaller("getRunningExternalApplications"); 8758 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8759 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8760 if (runningApps != null && runningApps.size() > 0) { 8761 Set<String> extList = new HashSet<String>(); 8762 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8763 if (app.pkgList != null) { 8764 for (String pkg : app.pkgList) { 8765 extList.add(pkg); 8766 } 8767 } 8768 } 8769 IPackageManager pm = AppGlobals.getPackageManager(); 8770 for (String pkg : extList) { 8771 try { 8772 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8773 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8774 retList.add(info); 8775 } 8776 } catch (RemoteException e) { 8777 } 8778 } 8779 } 8780 return retList; 8781 } 8782 8783 @Override 8784 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8785 enforceNotIsolatedCaller("getMyMemoryState"); 8786 synchronized (this) { 8787 ProcessRecord proc; 8788 synchronized (mPidsSelfLocked) { 8789 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8790 } 8791 fillInProcMemInfo(proc, outInfo); 8792 } 8793 } 8794 8795 @Override 8796 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8797 if (checkCallingPermission(android.Manifest.permission.DUMP) 8798 != PackageManager.PERMISSION_GRANTED) { 8799 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8800 + Binder.getCallingPid() 8801 + ", uid=" + Binder.getCallingUid() 8802 + " without permission " 8803 + android.Manifest.permission.DUMP); 8804 return; 8805 } 8806 8807 boolean dumpAll = false; 8808 boolean dumpClient = false; 8809 String dumpPackage = null; 8810 8811 int opti = 0; 8812 while (opti < args.length) { 8813 String opt = args[opti]; 8814 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8815 break; 8816 } 8817 opti++; 8818 if ("-a".equals(opt)) { 8819 dumpAll = true; 8820 } else if ("-c".equals(opt)) { 8821 dumpClient = true; 8822 } else if ("-h".equals(opt)) { 8823 pw.println("Activity manager dump options:"); 8824 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8825 pw.println(" cmd may be one of:"); 8826 pw.println(" a[ctivities]: activity stack state"); 8827 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8828 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8829 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8830 pw.println(" o[om]: out of memory management"); 8831 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8832 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8833 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8834 pw.println(" service [COMP_SPEC]: service client-side state"); 8835 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8836 pw.println(" all: dump all activities"); 8837 pw.println(" top: dump the top activity"); 8838 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8839 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8840 pw.println(" a partial substring in a component name, a"); 8841 pw.println(" hex object identifier."); 8842 pw.println(" -a: include all available server state."); 8843 pw.println(" -c: include client state."); 8844 return; 8845 } else { 8846 pw.println("Unknown argument: " + opt + "; use -h for help"); 8847 } 8848 } 8849 8850 long origId = Binder.clearCallingIdentity(); 8851 boolean more = false; 8852 // Is the caller requesting to dump a particular piece of data? 8853 if (opti < args.length) { 8854 String cmd = args[opti]; 8855 opti++; 8856 if ("activities".equals(cmd) || "a".equals(cmd)) { 8857 synchronized (this) { 8858 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8859 } 8860 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8861 String[] newArgs; 8862 String name; 8863 if (opti >= args.length) { 8864 name = null; 8865 newArgs = EMPTY_STRING_ARRAY; 8866 } else { 8867 name = args[opti]; 8868 opti++; 8869 newArgs = new String[args.length - opti]; 8870 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8871 args.length - opti); 8872 } 8873 synchronized (this) { 8874 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8875 } 8876 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8877 String[] newArgs; 8878 String name; 8879 if (opti >= args.length) { 8880 name = null; 8881 newArgs = EMPTY_STRING_ARRAY; 8882 } else { 8883 name = args[opti]; 8884 opti++; 8885 newArgs = new String[args.length - opti]; 8886 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8887 args.length - opti); 8888 } 8889 synchronized (this) { 8890 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8891 } 8892 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8893 String[] newArgs; 8894 String name; 8895 if (opti >= args.length) { 8896 name = null; 8897 newArgs = EMPTY_STRING_ARRAY; 8898 } else { 8899 name = args[opti]; 8900 opti++; 8901 newArgs = new String[args.length - opti]; 8902 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8903 args.length - opti); 8904 } 8905 synchronized (this) { 8906 dumpProcessesLocked(fd, pw, args, opti, true, name); 8907 } 8908 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8909 synchronized (this) { 8910 dumpOomLocked(fd, pw, args, opti, true); 8911 } 8912 } else if ("provider".equals(cmd)) { 8913 String[] newArgs; 8914 String name; 8915 if (opti >= args.length) { 8916 name = null; 8917 newArgs = EMPTY_STRING_ARRAY; 8918 } else { 8919 name = args[opti]; 8920 opti++; 8921 newArgs = new String[args.length - opti]; 8922 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8923 } 8924 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8925 pw.println("No providers match: " + name); 8926 pw.println("Use -h for help."); 8927 } 8928 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8929 synchronized (this) { 8930 dumpProvidersLocked(fd, pw, args, opti, true, null); 8931 } 8932 } else if ("service".equals(cmd)) { 8933 String[] newArgs; 8934 String name; 8935 if (opti >= args.length) { 8936 name = null; 8937 newArgs = EMPTY_STRING_ARRAY; 8938 } else { 8939 name = args[opti]; 8940 opti++; 8941 newArgs = new String[args.length - opti]; 8942 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8943 args.length - opti); 8944 } 8945 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8946 pw.println("No services match: " + name); 8947 pw.println("Use -h for help."); 8948 } 8949 } else if ("package".equals(cmd)) { 8950 String[] newArgs; 8951 if (opti >= args.length) { 8952 pw.println("package: no package name specified"); 8953 pw.println("Use -h for help."); 8954 } else { 8955 dumpPackage = args[opti]; 8956 opti++; 8957 newArgs = new String[args.length - opti]; 8958 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8959 args.length - opti); 8960 args = newArgs; 8961 opti = 0; 8962 more = true; 8963 } 8964 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8965 synchronized (this) { 8966 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8967 } 8968 } else { 8969 // Dumping a single activity? 8970 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8971 pw.println("Bad activity command, or no activities match: " + cmd); 8972 pw.println("Use -h for help."); 8973 } 8974 } 8975 if (!more) { 8976 Binder.restoreCallingIdentity(origId); 8977 return; 8978 } 8979 } 8980 8981 // No piece of data specified, dump everything. 8982 synchronized (this) { 8983 boolean needSep; 8984 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8985 if (needSep) { 8986 pw.println(" "); 8987 } 8988 if (dumpAll) { 8989 pw.println("-------------------------------------------------------------------------------"); 8990 } 8991 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8992 if (needSep) { 8993 pw.println(" "); 8994 } 8995 if (dumpAll) { 8996 pw.println("-------------------------------------------------------------------------------"); 8997 } 8998 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8999 if (needSep) { 9000 pw.println(" "); 9001 } 9002 if (dumpAll) { 9003 pw.println("-------------------------------------------------------------------------------"); 9004 } 9005 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9006 if (needSep) { 9007 pw.println(" "); 9008 } 9009 if (dumpAll) { 9010 pw.println("-------------------------------------------------------------------------------"); 9011 } 9012 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9013 if (needSep) { 9014 pw.println(" "); 9015 } 9016 if (dumpAll) { 9017 pw.println("-------------------------------------------------------------------------------"); 9018 } 9019 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9020 } 9021 Binder.restoreCallingIdentity(origId); 9022 } 9023 9024 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9025 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9026 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9027 pw.println(" Main stack:"); 9028 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9029 dumpPackage); 9030 pw.println(" "); 9031 pw.println(" Running activities (most recent first):"); 9032 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9033 dumpPackage); 9034 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9035 pw.println(" "); 9036 pw.println(" Activities waiting for another to become visible:"); 9037 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9038 !dumpAll, false, dumpPackage); 9039 } 9040 if (mMainStack.mStoppingActivities.size() > 0) { 9041 pw.println(" "); 9042 pw.println(" Activities waiting to stop:"); 9043 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9044 !dumpAll, false, dumpPackage); 9045 } 9046 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9047 pw.println(" "); 9048 pw.println(" Activities waiting to sleep:"); 9049 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9050 !dumpAll, false, dumpPackage); 9051 } 9052 if (mMainStack.mFinishingActivities.size() > 0) { 9053 pw.println(" "); 9054 pw.println(" Activities waiting to finish:"); 9055 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9056 !dumpAll, false, dumpPackage); 9057 } 9058 9059 pw.println(" "); 9060 if (mMainStack.mPausingActivity != null) { 9061 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9062 } 9063 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9064 pw.println(" mFocusedActivity: " + mFocusedActivity); 9065 if (dumpAll) { 9066 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9067 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9068 pw.println(" mDismissKeyguardOnNextActivity: " 9069 + mMainStack.mDismissKeyguardOnNextActivity); 9070 } 9071 9072 if (mRecentTasks.size() > 0) { 9073 pw.println(); 9074 pw.println(" Recent tasks:"); 9075 9076 final int N = mRecentTasks.size(); 9077 for (int i=0; i<N; i++) { 9078 TaskRecord tr = mRecentTasks.get(i); 9079 if (dumpPackage != null) { 9080 if (tr.realActivity == null || 9081 !dumpPackage.equals(tr.realActivity)) { 9082 continue; 9083 } 9084 } 9085 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9086 pw.println(tr); 9087 if (dumpAll) { 9088 mRecentTasks.get(i).dump(pw, " "); 9089 } 9090 } 9091 } 9092 9093 if (dumpAll) { 9094 pw.println(" "); 9095 pw.println(" mCurTask: " + mCurTask); 9096 } 9097 9098 return true; 9099 } 9100 9101 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9102 int opti, boolean dumpAll, String dumpPackage) { 9103 boolean needSep = false; 9104 int numPers = 0; 9105 9106 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9107 9108 if (dumpAll) { 9109 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9110 final int NA = procs.size(); 9111 for (int ia=0; ia<NA; ia++) { 9112 ProcessRecord r = procs.valueAt(ia); 9113 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9114 continue; 9115 } 9116 if (!needSep) { 9117 pw.println(" All known processes:"); 9118 needSep = true; 9119 } 9120 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9121 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9122 pw.print(" "); pw.println(r); 9123 r.dump(pw, " "); 9124 if (r.persistent) { 9125 numPers++; 9126 } 9127 } 9128 } 9129 } 9130 9131 if (mIsolatedProcesses.size() > 0) { 9132 if (needSep) pw.println(" "); 9133 needSep = true; 9134 pw.println(" Isolated process list (sorted by uid):"); 9135 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9136 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9137 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9138 continue; 9139 } 9140 pw.println(String.format("%sIsolated #%2d: %s", 9141 " ", i, r.toString())); 9142 } 9143 } 9144 9145 if (mLruProcesses.size() > 0) { 9146 if (needSep) pw.println(" "); 9147 needSep = true; 9148 pw.println(" Process LRU list (sorted by oom_adj):"); 9149 dumpProcessOomList(pw, this, mLruProcesses, " ", 9150 "Proc", "PERS", false, dumpPackage); 9151 needSep = true; 9152 } 9153 9154 if (dumpAll) { 9155 synchronized (mPidsSelfLocked) { 9156 boolean printed = false; 9157 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9158 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9159 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9160 continue; 9161 } 9162 if (!printed) { 9163 if (needSep) pw.println(" "); 9164 needSep = true; 9165 pw.println(" PID mappings:"); 9166 printed = true; 9167 } 9168 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9169 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9170 } 9171 } 9172 } 9173 9174 if (mForegroundProcesses.size() > 0) { 9175 synchronized (mPidsSelfLocked) { 9176 boolean printed = false; 9177 for (int i=0; i<mForegroundProcesses.size(); i++) { 9178 ProcessRecord r = mPidsSelfLocked.get( 9179 mForegroundProcesses.valueAt(i).pid); 9180 if (dumpPackage != null && (r == null 9181 || !dumpPackage.equals(r.info.packageName))) { 9182 continue; 9183 } 9184 if (!printed) { 9185 if (needSep) pw.println(" "); 9186 needSep = true; 9187 pw.println(" Foreground Processes:"); 9188 printed = true; 9189 } 9190 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9191 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9192 } 9193 } 9194 } 9195 9196 if (mPersistentStartingProcesses.size() > 0) { 9197 if (needSep) pw.println(" "); 9198 needSep = true; 9199 pw.println(" Persisent processes that are starting:"); 9200 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9201 "Starting Norm", "Restarting PERS", dumpPackage); 9202 } 9203 9204 if (mRemovedProcesses.size() > 0) { 9205 if (needSep) pw.println(" "); 9206 needSep = true; 9207 pw.println(" Processes that are being removed:"); 9208 dumpProcessList(pw, this, mRemovedProcesses, " ", 9209 "Removed Norm", "Removed PERS", dumpPackage); 9210 } 9211 9212 if (mProcessesOnHold.size() > 0) { 9213 if (needSep) pw.println(" "); 9214 needSep = true; 9215 pw.println(" Processes that are on old until the system is ready:"); 9216 dumpProcessList(pw, this, mProcessesOnHold, " ", 9217 "OnHold Norm", "OnHold PERS", dumpPackage); 9218 } 9219 9220 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9221 9222 if (mProcessCrashTimes.getMap().size() > 0) { 9223 boolean printed = false; 9224 long now = SystemClock.uptimeMillis(); 9225 for (Map.Entry<String, SparseArray<Long>> procs 9226 : mProcessCrashTimes.getMap().entrySet()) { 9227 String pname = procs.getKey(); 9228 SparseArray<Long> uids = procs.getValue(); 9229 final int N = uids.size(); 9230 for (int i=0; i<N; i++) { 9231 int puid = uids.keyAt(i); 9232 ProcessRecord r = mProcessNames.get(pname, puid); 9233 if (dumpPackage != null && (r == null 9234 || !dumpPackage.equals(r.info.packageName))) { 9235 continue; 9236 } 9237 if (!printed) { 9238 if (needSep) pw.println(" "); 9239 needSep = true; 9240 pw.println(" Time since processes crashed:"); 9241 printed = true; 9242 } 9243 pw.print(" Process "); pw.print(pname); 9244 pw.print(" uid "); pw.print(puid); 9245 pw.print(": last crashed "); 9246 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9247 pw.println(" ago"); 9248 } 9249 } 9250 } 9251 9252 if (mBadProcesses.getMap().size() > 0) { 9253 boolean printed = false; 9254 for (Map.Entry<String, SparseArray<Long>> procs 9255 : mBadProcesses.getMap().entrySet()) { 9256 String pname = procs.getKey(); 9257 SparseArray<Long> uids = procs.getValue(); 9258 final int N = uids.size(); 9259 for (int i=0; i<N; i++) { 9260 int puid = uids.keyAt(i); 9261 ProcessRecord r = mProcessNames.get(pname, puid); 9262 if (dumpPackage != null && (r == null 9263 || !dumpPackage.equals(r.info.packageName))) { 9264 continue; 9265 } 9266 if (!printed) { 9267 if (needSep) pw.println(" "); 9268 needSep = true; 9269 pw.println(" Bad processes:"); 9270 } 9271 pw.print(" Bad process "); pw.print(pname); 9272 pw.print(" uid "); pw.print(puid); 9273 pw.print(": crashed at time "); 9274 pw.println(uids.valueAt(i)); 9275 } 9276 } 9277 } 9278 9279 pw.println(); 9280 pw.println(" mStartedUsers:"); 9281 for (int i=0; i<mStartedUsers.size(); i++) { 9282 UserStartedState uss = mStartedUsers.valueAt(i); 9283 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9284 pw.print(": "); uss.dump("", pw); 9285 } 9286 pw.print(" mUserLru: ["); 9287 for (int i=0; i<mUserLru.size(); i++) { 9288 if (i > 0) pw.print(", "); 9289 pw.print(mUserLru.get(i)); 9290 } 9291 pw.println("]"); 9292 pw.println(" mHomeProcess: " + mHomeProcess); 9293 pw.println(" mPreviousProcess: " + mPreviousProcess); 9294 if (dumpAll) { 9295 StringBuilder sb = new StringBuilder(128); 9296 sb.append(" mPreviousProcessVisibleTime: "); 9297 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9298 pw.println(sb); 9299 } 9300 if (mHeavyWeightProcess != null) { 9301 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9302 } 9303 pw.println(" mConfiguration: " + mConfiguration); 9304 if (dumpAll) { 9305 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9306 if (mCompatModePackages.getPackages().size() > 0) { 9307 boolean printed = false; 9308 for (Map.Entry<String, Integer> entry 9309 : mCompatModePackages.getPackages().entrySet()) { 9310 String pkg = entry.getKey(); 9311 int mode = entry.getValue(); 9312 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9313 continue; 9314 } 9315 if (!printed) { 9316 pw.println(" mScreenCompatPackages:"); 9317 printed = true; 9318 } 9319 pw.print(" "); pw.print(pkg); pw.print(": "); 9320 pw.print(mode); pw.println(); 9321 } 9322 } 9323 } 9324 if (mSleeping || mWentToSleep || mLockScreenShown) { 9325 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9326 + " mLockScreenShown " + mLockScreenShown); 9327 } 9328 if (mShuttingDown) { 9329 pw.println(" mShuttingDown=" + mShuttingDown); 9330 } 9331 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9332 || mOrigWaitForDebugger) { 9333 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9334 + " mDebugTransient=" + mDebugTransient 9335 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9336 } 9337 if (mOpenGlTraceApp != null) { 9338 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9339 } 9340 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9341 || mProfileFd != null) { 9342 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9343 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9344 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9345 + mAutoStopProfiler); 9346 } 9347 if (mAlwaysFinishActivities || mController != null) { 9348 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9349 + " mController=" + mController); 9350 } 9351 if (dumpAll) { 9352 pw.println(" Total persistent processes: " + numPers); 9353 pw.println(" mStartRunning=" + mStartRunning 9354 + " mProcessesReady=" + mProcessesReady 9355 + " mSystemReady=" + mSystemReady); 9356 pw.println(" mBooting=" + mBooting 9357 + " mBooted=" + mBooted 9358 + " mFactoryTest=" + mFactoryTest); 9359 pw.print(" mLastPowerCheckRealtime="); 9360 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9361 pw.println(""); 9362 pw.print(" mLastPowerCheckUptime="); 9363 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9364 pw.println(""); 9365 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9366 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9367 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9368 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9369 + " mNumHiddenProcs=" + mNumHiddenProcs 9370 + " mNumServiceProcs=" + mNumServiceProcs 9371 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9372 } 9373 9374 return true; 9375 } 9376 9377 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9378 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9379 if (mProcessesToGc.size() > 0) { 9380 boolean printed = false; 9381 long now = SystemClock.uptimeMillis(); 9382 for (int i=0; i<mProcessesToGc.size(); i++) { 9383 ProcessRecord proc = mProcessesToGc.get(i); 9384 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9385 continue; 9386 } 9387 if (!printed) { 9388 if (needSep) pw.println(" "); 9389 needSep = true; 9390 pw.println(" Processes that are waiting to GC:"); 9391 printed = true; 9392 } 9393 pw.print(" Process "); pw.println(proc); 9394 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9395 pw.print(", last gced="); 9396 pw.print(now-proc.lastRequestedGc); 9397 pw.print(" ms ago, last lowMem="); 9398 pw.print(now-proc.lastLowMemory); 9399 pw.println(" ms ago"); 9400 9401 } 9402 } 9403 return needSep; 9404 } 9405 9406 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9407 int opti, boolean dumpAll) { 9408 boolean needSep = false; 9409 9410 if (mLruProcesses.size() > 0) { 9411 if (needSep) pw.println(" "); 9412 needSep = true; 9413 pw.println(" OOM levels:"); 9414 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9415 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9416 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9417 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9418 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9419 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9420 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9421 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9422 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9423 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9424 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9425 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9426 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9427 9428 if (needSep) pw.println(" "); 9429 needSep = true; 9430 pw.println(" Process OOM control:"); 9431 dumpProcessOomList(pw, this, mLruProcesses, " ", 9432 "Proc", "PERS", true, null); 9433 needSep = true; 9434 } 9435 9436 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9437 9438 pw.println(); 9439 pw.println(" mHomeProcess: " + mHomeProcess); 9440 pw.println(" mPreviousProcess: " + mPreviousProcess); 9441 if (mHeavyWeightProcess != null) { 9442 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9443 } 9444 9445 return true; 9446 } 9447 9448 /** 9449 * There are three ways to call this: 9450 * - no provider specified: dump all the providers 9451 * - a flattened component name that matched an existing provider was specified as the 9452 * first arg: dump that one provider 9453 * - the first arg isn't the flattened component name of an existing provider: 9454 * dump all providers whose component contains the first arg as a substring 9455 */ 9456 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9457 int opti, boolean dumpAll) { 9458 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9459 } 9460 9461 static class ItemMatcher { 9462 ArrayList<ComponentName> components; 9463 ArrayList<String> strings; 9464 ArrayList<Integer> objects; 9465 boolean all; 9466 9467 ItemMatcher() { 9468 all = true; 9469 } 9470 9471 void build(String name) { 9472 ComponentName componentName = ComponentName.unflattenFromString(name); 9473 if (componentName != null) { 9474 if (components == null) { 9475 components = new ArrayList<ComponentName>(); 9476 } 9477 components.add(componentName); 9478 all = false; 9479 } else { 9480 int objectId = 0; 9481 // Not a '/' separated full component name; maybe an object ID? 9482 try { 9483 objectId = Integer.parseInt(name, 16); 9484 if (objects == null) { 9485 objects = new ArrayList<Integer>(); 9486 } 9487 objects.add(objectId); 9488 all = false; 9489 } catch (RuntimeException e) { 9490 // Not an integer; just do string match. 9491 if (strings == null) { 9492 strings = new ArrayList<String>(); 9493 } 9494 strings.add(name); 9495 all = false; 9496 } 9497 } 9498 } 9499 9500 int build(String[] args, int opti) { 9501 for (; opti<args.length; opti++) { 9502 String name = args[opti]; 9503 if ("--".equals(name)) { 9504 return opti+1; 9505 } 9506 build(name); 9507 } 9508 return opti; 9509 } 9510 9511 boolean match(Object object, ComponentName comp) { 9512 if (all) { 9513 return true; 9514 } 9515 if (components != null) { 9516 for (int i=0; i<components.size(); i++) { 9517 if (components.get(i).equals(comp)) { 9518 return true; 9519 } 9520 } 9521 } 9522 if (objects != null) { 9523 for (int i=0; i<objects.size(); i++) { 9524 if (System.identityHashCode(object) == objects.get(i)) { 9525 return true; 9526 } 9527 } 9528 } 9529 if (strings != null) { 9530 String flat = comp.flattenToString(); 9531 for (int i=0; i<strings.size(); i++) { 9532 if (flat.contains(strings.get(i))) { 9533 return true; 9534 } 9535 } 9536 } 9537 return false; 9538 } 9539 } 9540 9541 /** 9542 * There are three things that cmd can be: 9543 * - a flattened component name that matches an existing activity 9544 * - the cmd arg isn't the flattened component name of an existing activity: 9545 * dump all activity whose component contains the cmd as a substring 9546 * - A hex number of the ActivityRecord object instance. 9547 */ 9548 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9549 int opti, boolean dumpAll) { 9550 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9551 9552 if ("all".equals(name)) { 9553 synchronized (this) { 9554 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9555 activities.add(r1); 9556 } 9557 } 9558 } else if ("top".equals(name)) { 9559 synchronized (this) { 9560 final int N = mMainStack.mHistory.size(); 9561 if (N > 0) { 9562 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9563 } 9564 } 9565 } else { 9566 ItemMatcher matcher = new ItemMatcher(); 9567 matcher.build(name); 9568 9569 synchronized (this) { 9570 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9571 if (matcher.match(r1, r1.intent.getComponent())) { 9572 activities.add(r1); 9573 } 9574 } 9575 } 9576 } 9577 9578 if (activities.size() <= 0) { 9579 return false; 9580 } 9581 9582 String[] newArgs = new String[args.length - opti]; 9583 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9584 9585 TaskRecord lastTask = null; 9586 boolean needSep = false; 9587 for (int i=activities.size()-1; i>=0; i--) { 9588 ActivityRecord r = (ActivityRecord)activities.get(i); 9589 if (needSep) { 9590 pw.println(); 9591 } 9592 needSep = true; 9593 synchronized (this) { 9594 if (lastTask != r.task) { 9595 lastTask = r.task; 9596 pw.print("TASK "); pw.print(lastTask.affinity); 9597 pw.print(" id="); pw.println(lastTask.taskId); 9598 if (dumpAll) { 9599 lastTask.dump(pw, " "); 9600 } 9601 } 9602 } 9603 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9604 } 9605 return true; 9606 } 9607 9608 /** 9609 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9610 * there is a thread associated with the activity. 9611 */ 9612 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9613 final ActivityRecord r, String[] args, boolean dumpAll) { 9614 String innerPrefix = prefix + " "; 9615 synchronized (this) { 9616 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9617 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9618 pw.print(" pid="); 9619 if (r.app != null) pw.println(r.app.pid); 9620 else pw.println("(not running)"); 9621 if (dumpAll) { 9622 r.dump(pw, innerPrefix); 9623 } 9624 } 9625 if (r.app != null && r.app.thread != null) { 9626 // flush anything that is already in the PrintWriter since the thread is going 9627 // to write to the file descriptor directly 9628 pw.flush(); 9629 try { 9630 TransferPipe tp = new TransferPipe(); 9631 try { 9632 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9633 r.appToken, innerPrefix, args); 9634 tp.go(fd); 9635 } finally { 9636 tp.kill(); 9637 } 9638 } catch (IOException e) { 9639 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9640 } catch (RemoteException e) { 9641 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9642 } 9643 } 9644 } 9645 9646 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9647 int opti, boolean dumpAll, String dumpPackage) { 9648 boolean needSep = false; 9649 boolean onlyHistory = false; 9650 9651 if ("history".equals(dumpPackage)) { 9652 onlyHistory = true; 9653 dumpPackage = null; 9654 } 9655 9656 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9657 if (!onlyHistory && dumpAll) { 9658 if (mRegisteredReceivers.size() > 0) { 9659 boolean printed = false; 9660 Iterator it = mRegisteredReceivers.values().iterator(); 9661 while (it.hasNext()) { 9662 ReceiverList r = (ReceiverList)it.next(); 9663 if (dumpPackage != null && (r.app == null || 9664 !dumpPackage.equals(r.app.info.packageName))) { 9665 continue; 9666 } 9667 if (!printed) { 9668 pw.println(" Registered Receivers:"); 9669 needSep = true; 9670 printed = true; 9671 } 9672 pw.print(" * "); pw.println(r); 9673 r.dump(pw, " "); 9674 } 9675 } 9676 9677 if (mReceiverResolver.dump(pw, needSep ? 9678 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9679 " ", dumpPackage, false)) { 9680 needSep = true; 9681 } 9682 } 9683 9684 for (BroadcastQueue q : mBroadcastQueues) { 9685 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9686 } 9687 9688 needSep = true; 9689 9690 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9691 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9692 if (needSep) { 9693 pw.println(); 9694 } 9695 needSep = true; 9696 pw.print(" Sticky broadcasts for user "); 9697 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9698 StringBuilder sb = new StringBuilder(128); 9699 for (Map.Entry<String, ArrayList<Intent>> ent 9700 : mStickyBroadcasts.valueAt(user).entrySet()) { 9701 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9702 if (dumpAll) { 9703 pw.println(":"); 9704 ArrayList<Intent> intents = ent.getValue(); 9705 final int N = intents.size(); 9706 for (int i=0; i<N; i++) { 9707 sb.setLength(0); 9708 sb.append(" Intent: "); 9709 intents.get(i).toShortString(sb, false, true, false, false); 9710 pw.println(sb.toString()); 9711 Bundle bundle = intents.get(i).getExtras(); 9712 if (bundle != null) { 9713 pw.print(" "); 9714 pw.println(bundle.toString()); 9715 } 9716 } 9717 } else { 9718 pw.println(""); 9719 } 9720 } 9721 } 9722 } 9723 9724 if (!onlyHistory && dumpAll) { 9725 pw.println(); 9726 for (BroadcastQueue queue : mBroadcastQueues) { 9727 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9728 + queue.mBroadcastsScheduled); 9729 } 9730 pw.println(" mHandler:"); 9731 mHandler.dump(new PrintWriterPrinter(pw), " "); 9732 needSep = true; 9733 } 9734 9735 return needSep; 9736 } 9737 9738 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9739 int opti, boolean dumpAll, String dumpPackage) { 9740 boolean needSep = true; 9741 9742 ItemMatcher matcher = new ItemMatcher(); 9743 matcher.build(args, opti); 9744 9745 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9746 9747 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9748 9749 if (mLaunchingProviders.size() > 0) { 9750 boolean printed = false; 9751 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9752 ContentProviderRecord r = mLaunchingProviders.get(i); 9753 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9754 continue; 9755 } 9756 if (!printed) { 9757 if (needSep) pw.println(" "); 9758 needSep = true; 9759 pw.println(" Launching content providers:"); 9760 printed = true; 9761 } 9762 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9763 pw.println(r); 9764 } 9765 } 9766 9767 if (mGrantedUriPermissions.size() > 0) { 9768 if (needSep) pw.println(); 9769 needSep = true; 9770 pw.println("Granted Uri Permissions:"); 9771 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9772 int uid = mGrantedUriPermissions.keyAt(i); 9773 HashMap<Uri, UriPermission> perms 9774 = mGrantedUriPermissions.valueAt(i); 9775 pw.print(" * UID "); pw.print(uid); 9776 pw.println(" holds:"); 9777 for (UriPermission perm : perms.values()) { 9778 pw.print(" "); pw.println(perm); 9779 if (dumpAll) { 9780 perm.dump(pw, " "); 9781 } 9782 } 9783 } 9784 needSep = true; 9785 } 9786 9787 return needSep; 9788 } 9789 9790 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9791 int opti, boolean dumpAll, String dumpPackage) { 9792 boolean needSep = false; 9793 9794 if (mIntentSenderRecords.size() > 0) { 9795 boolean printed = false; 9796 Iterator<WeakReference<PendingIntentRecord>> it 9797 = mIntentSenderRecords.values().iterator(); 9798 while (it.hasNext()) { 9799 WeakReference<PendingIntentRecord> ref = it.next(); 9800 PendingIntentRecord rec = ref != null ? ref.get(): null; 9801 if (dumpPackage != null && (rec == null 9802 || !dumpPackage.equals(rec.key.packageName))) { 9803 continue; 9804 } 9805 if (!printed) { 9806 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9807 printed = true; 9808 } 9809 needSep = true; 9810 if (rec != null) { 9811 pw.print(" * "); pw.println(rec); 9812 if (dumpAll) { 9813 rec.dump(pw, " "); 9814 } 9815 } else { 9816 pw.print(" * "); pw.println(ref); 9817 } 9818 } 9819 } 9820 9821 return needSep; 9822 } 9823 9824 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9825 String prefix, String label, boolean complete, boolean brief, boolean client, 9826 String dumpPackage) { 9827 TaskRecord lastTask = null; 9828 boolean needNL = false; 9829 final String innerPrefix = prefix + " "; 9830 final String[] args = new String[0]; 9831 for (int i=list.size()-1; i>=0; i--) { 9832 final ActivityRecord r = (ActivityRecord)list.get(i); 9833 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9834 continue; 9835 } 9836 final boolean full = !brief && (complete || !r.isInHistory()); 9837 if (needNL) { 9838 pw.println(" "); 9839 needNL = false; 9840 } 9841 if (lastTask != r.task) { 9842 lastTask = r.task; 9843 pw.print(prefix); 9844 pw.print(full ? "* " : " "); 9845 pw.println(lastTask); 9846 if (full) { 9847 lastTask.dump(pw, prefix + " "); 9848 } else if (complete) { 9849 // Complete + brief == give a summary. Isn't that obvious?!? 9850 if (lastTask.intent != null) { 9851 pw.print(prefix); pw.print(" "); 9852 pw.println(lastTask.intent.toInsecureStringWithClip()); 9853 } 9854 } 9855 } 9856 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9857 pw.print(" #"); pw.print(i); pw.print(": "); 9858 pw.println(r); 9859 if (full) { 9860 r.dump(pw, innerPrefix); 9861 } else if (complete) { 9862 // Complete + brief == give a summary. Isn't that obvious?!? 9863 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9864 if (r.app != null) { 9865 pw.print(innerPrefix); pw.println(r.app); 9866 } 9867 } 9868 if (client && r.app != null && r.app.thread != null) { 9869 // flush anything that is already in the PrintWriter since the thread is going 9870 // to write to the file descriptor directly 9871 pw.flush(); 9872 try { 9873 TransferPipe tp = new TransferPipe(); 9874 try { 9875 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9876 r.appToken, innerPrefix, args); 9877 // Short timeout, since blocking here can 9878 // deadlock with the application. 9879 tp.go(fd, 2000); 9880 } finally { 9881 tp.kill(); 9882 } 9883 } catch (IOException e) { 9884 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9885 } catch (RemoteException e) { 9886 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9887 } 9888 needNL = true; 9889 } 9890 } 9891 } 9892 9893 private static String buildOomTag(String prefix, String space, int val, int base) { 9894 if (val == base) { 9895 if (space == null) return prefix; 9896 return prefix + " "; 9897 } 9898 return prefix + "+" + Integer.toString(val-base); 9899 } 9900 9901 private static final int dumpProcessList(PrintWriter pw, 9902 ActivityManagerService service, List list, 9903 String prefix, String normalLabel, String persistentLabel, 9904 String dumpPackage) { 9905 int numPers = 0; 9906 final int N = list.size()-1; 9907 for (int i=N; i>=0; i--) { 9908 ProcessRecord r = (ProcessRecord)list.get(i); 9909 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9910 continue; 9911 } 9912 pw.println(String.format("%s%s #%2d: %s", 9913 prefix, (r.persistent ? persistentLabel : normalLabel), 9914 i, r.toString())); 9915 if (r.persistent) { 9916 numPers++; 9917 } 9918 } 9919 return numPers; 9920 } 9921 9922 private static final boolean dumpProcessOomList(PrintWriter pw, 9923 ActivityManagerService service, List<ProcessRecord> origList, 9924 String prefix, String normalLabel, String persistentLabel, 9925 boolean inclDetails, String dumpPackage) { 9926 9927 ArrayList<Pair<ProcessRecord, Integer>> list 9928 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9929 for (int i=0; i<origList.size(); i++) { 9930 ProcessRecord r = origList.get(i); 9931 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9932 continue; 9933 } 9934 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9935 } 9936 9937 if (list.size() <= 0) { 9938 return false; 9939 } 9940 9941 Comparator<Pair<ProcessRecord, Integer>> comparator 9942 = new Comparator<Pair<ProcessRecord, Integer>>() { 9943 @Override 9944 public int compare(Pair<ProcessRecord, Integer> object1, 9945 Pair<ProcessRecord, Integer> object2) { 9946 if (object1.first.setAdj != object2.first.setAdj) { 9947 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9948 } 9949 if (object1.second.intValue() != object2.second.intValue()) { 9950 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9951 } 9952 return 0; 9953 } 9954 }; 9955 9956 Collections.sort(list, comparator); 9957 9958 final long curRealtime = SystemClock.elapsedRealtime(); 9959 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9960 final long curUptime = SystemClock.uptimeMillis(); 9961 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9962 9963 for (int i=list.size()-1; i>=0; i--) { 9964 ProcessRecord r = list.get(i).first; 9965 String oomAdj; 9966 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9967 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9968 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9969 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9970 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9971 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9972 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9973 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9974 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9975 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9976 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9977 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9978 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9979 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9980 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9981 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9982 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9983 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9984 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9985 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9986 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9987 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9988 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9989 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9990 } else { 9991 oomAdj = Integer.toString(r.setAdj); 9992 } 9993 String schedGroup; 9994 switch (r.setSchedGroup) { 9995 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9996 schedGroup = "B"; 9997 break; 9998 case Process.THREAD_GROUP_DEFAULT: 9999 schedGroup = "F"; 10000 break; 10001 default: 10002 schedGroup = Integer.toString(r.setSchedGroup); 10003 break; 10004 } 10005 String foreground; 10006 if (r.foregroundActivities) { 10007 foreground = "A"; 10008 } else if (r.foregroundServices) { 10009 foreground = "S"; 10010 } else { 10011 foreground = " "; 10012 } 10013 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10014 prefix, (r.persistent ? persistentLabel : normalLabel), 10015 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10016 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10017 if (r.adjSource != null || r.adjTarget != null) { 10018 pw.print(prefix); 10019 pw.print(" "); 10020 if (r.adjTarget instanceof ComponentName) { 10021 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10022 } else if (r.adjTarget != null) { 10023 pw.print(r.adjTarget.toString()); 10024 } else { 10025 pw.print("{null}"); 10026 } 10027 pw.print("<="); 10028 if (r.adjSource instanceof ProcessRecord) { 10029 pw.print("Proc{"); 10030 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10031 pw.println("}"); 10032 } else if (r.adjSource != null) { 10033 pw.println(r.adjSource.toString()); 10034 } else { 10035 pw.println("{null}"); 10036 } 10037 } 10038 if (inclDetails) { 10039 pw.print(prefix); 10040 pw.print(" "); 10041 pw.print("oom: max="); pw.print(r.maxAdj); 10042 pw.print(" hidden="); pw.print(r.hiddenAdj); 10043 pw.print(" empty="); pw.print(r.emptyAdj); 10044 pw.print(" curRaw="); pw.print(r.curRawAdj); 10045 pw.print(" setRaw="); pw.print(r.setRawAdj); 10046 pw.print(" cur="); pw.print(r.curAdj); 10047 pw.print(" set="); pw.println(r.setAdj); 10048 pw.print(prefix); 10049 pw.print(" "); 10050 pw.print("keeping="); pw.print(r.keeping); 10051 pw.print(" hidden="); pw.print(r.hidden); 10052 pw.print(" empty="); pw.print(r.empty); 10053 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10054 10055 if (!r.keeping) { 10056 if (r.lastWakeTime != 0) { 10057 long wtime; 10058 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10059 synchronized (stats) { 10060 wtime = stats.getProcessWakeTime(r.info.uid, 10061 r.pid, curRealtime); 10062 } 10063 long timeUsed = wtime - r.lastWakeTime; 10064 pw.print(prefix); 10065 pw.print(" "); 10066 pw.print("keep awake over "); 10067 TimeUtils.formatDuration(realtimeSince, pw); 10068 pw.print(" used "); 10069 TimeUtils.formatDuration(timeUsed, pw); 10070 pw.print(" ("); 10071 pw.print((timeUsed*100)/realtimeSince); 10072 pw.println("%)"); 10073 } 10074 if (r.lastCpuTime != 0) { 10075 long timeUsed = r.curCpuTime - r.lastCpuTime; 10076 pw.print(prefix); 10077 pw.print(" "); 10078 pw.print("run cpu over "); 10079 TimeUtils.formatDuration(uptimeSince, pw); 10080 pw.print(" used "); 10081 TimeUtils.formatDuration(timeUsed, pw); 10082 pw.print(" ("); 10083 pw.print((timeUsed*100)/uptimeSince); 10084 pw.println("%)"); 10085 } 10086 } 10087 } 10088 } 10089 return true; 10090 } 10091 10092 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10093 ArrayList<ProcessRecord> procs; 10094 synchronized (this) { 10095 if (args != null && args.length > start 10096 && args[start].charAt(0) != '-') { 10097 procs = new ArrayList<ProcessRecord>(); 10098 int pid = -1; 10099 try { 10100 pid = Integer.parseInt(args[start]); 10101 } catch (NumberFormatException e) { 10102 10103 } 10104 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10105 ProcessRecord proc = mLruProcesses.get(i); 10106 if (proc.pid == pid) { 10107 procs.add(proc); 10108 } else if (proc.processName.equals(args[start])) { 10109 procs.add(proc); 10110 } 10111 } 10112 if (procs.size() <= 0) { 10113 pw.println("No process found for: " + args[start]); 10114 return null; 10115 } 10116 } else { 10117 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10118 } 10119 } 10120 return procs; 10121 } 10122 10123 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10124 PrintWriter pw, String[] args) { 10125 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10126 if (procs == null) { 10127 return; 10128 } 10129 10130 long uptime = SystemClock.uptimeMillis(); 10131 long realtime = SystemClock.elapsedRealtime(); 10132 pw.println("Applications Graphics Acceleration Info:"); 10133 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10134 10135 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10136 ProcessRecord r = procs.get(i); 10137 if (r.thread != null) { 10138 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10139 pw.flush(); 10140 try { 10141 TransferPipe tp = new TransferPipe(); 10142 try { 10143 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10144 tp.go(fd); 10145 } finally { 10146 tp.kill(); 10147 } 10148 } catch (IOException e) { 10149 pw.println("Failure while dumping the app: " + r); 10150 pw.flush(); 10151 } catch (RemoteException e) { 10152 pw.println("Got a RemoteException while dumping the app " + r); 10153 pw.flush(); 10154 } 10155 } 10156 } 10157 } 10158 10159 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10160 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10161 if (procs == null) { 10162 return; 10163 } 10164 10165 pw.println("Applications Database Info:"); 10166 10167 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10168 ProcessRecord r = procs.get(i); 10169 if (r.thread != null) { 10170 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10171 pw.flush(); 10172 try { 10173 TransferPipe tp = new TransferPipe(); 10174 try { 10175 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10176 tp.go(fd); 10177 } finally { 10178 tp.kill(); 10179 } 10180 } catch (IOException e) { 10181 pw.println("Failure while dumping the app: " + r); 10182 pw.flush(); 10183 } catch (RemoteException e) { 10184 pw.println("Got a RemoteException while dumping the app " + r); 10185 pw.flush(); 10186 } 10187 } 10188 } 10189 } 10190 10191 final static class MemItem { 10192 final String label; 10193 final String shortLabel; 10194 final long pss; 10195 final int id; 10196 ArrayList<MemItem> subitems; 10197 10198 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10199 label = _label; 10200 shortLabel = _shortLabel; 10201 pss = _pss; 10202 id = _id; 10203 } 10204 } 10205 10206 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10207 boolean sort) { 10208 if (sort) { 10209 Collections.sort(items, new Comparator<MemItem>() { 10210 @Override 10211 public int compare(MemItem lhs, MemItem rhs) { 10212 if (lhs.pss < rhs.pss) { 10213 return 1; 10214 } else if (lhs.pss > rhs.pss) { 10215 return -1; 10216 } 10217 return 0; 10218 } 10219 }); 10220 } 10221 10222 for (int i=0; i<items.size(); i++) { 10223 MemItem mi = items.get(i); 10224 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10225 if (mi.subitems != null) { 10226 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10227 } 10228 } 10229 } 10230 10231 // These are in KB. 10232 static final long[] DUMP_MEM_BUCKETS = new long[] { 10233 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10234 120*1024, 160*1024, 200*1024, 10235 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10236 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10237 }; 10238 10239 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10240 boolean stackLike) { 10241 int start = label.lastIndexOf('.'); 10242 if (start >= 0) start++; 10243 else start = 0; 10244 int end = label.length(); 10245 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10246 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10247 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10248 out.append(bucket); 10249 out.append(stackLike ? "MB." : "MB "); 10250 out.append(label, start, end); 10251 return; 10252 } 10253 } 10254 out.append(memKB/1024); 10255 out.append(stackLike ? "MB." : "MB "); 10256 out.append(label, start, end); 10257 } 10258 10259 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10260 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10261 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10262 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10263 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10264 }; 10265 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10266 "System", "Persistent", "Foreground", 10267 "Visible", "Perceptible", "Heavy Weight", 10268 "Backup", "A Services", "Home", "Previous", 10269 "B Services", "Background" 10270 }; 10271 10272 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10273 PrintWriter pw, String prefix, String[] args, boolean brief, 10274 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10275 boolean dumpAll = false; 10276 boolean oomOnly = false; 10277 10278 int opti = 0; 10279 while (opti < args.length) { 10280 String opt = args[opti]; 10281 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10282 break; 10283 } 10284 opti++; 10285 if ("-a".equals(opt)) { 10286 dumpAll = true; 10287 } else if ("--oom".equals(opt)) { 10288 oomOnly = true; 10289 } else if ("-h".equals(opt)) { 10290 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10291 pw.println(" -a: include all available information for each process."); 10292 pw.println(" --oom: only show processes organized by oom adj."); 10293 pw.println("If [process] is specified it can be the name or "); 10294 pw.println("pid of a specific process to dump."); 10295 return; 10296 } else { 10297 pw.println("Unknown argument: " + opt + "; use -h for help"); 10298 } 10299 } 10300 10301 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10302 if (procs == null) { 10303 return; 10304 } 10305 10306 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10307 long uptime = SystemClock.uptimeMillis(); 10308 long realtime = SystemClock.elapsedRealtime(); 10309 10310 if (procs.size() == 1 || isCheckinRequest) { 10311 dumpAll = true; 10312 } 10313 10314 if (isCheckinRequest) { 10315 // short checkin version 10316 pw.println(uptime + "," + realtime); 10317 pw.flush(); 10318 } else { 10319 pw.println("Applications Memory Usage (kB):"); 10320 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10321 } 10322 10323 String[] innerArgs = new String[args.length-opti]; 10324 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10325 10326 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10327 long nativePss=0, dalvikPss=0, otherPss=0; 10328 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10329 10330 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10331 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10332 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10333 10334 long totalPss = 0; 10335 10336 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10337 ProcessRecord r = procs.get(i); 10338 if (r.thread != null) { 10339 if (!isCheckinRequest && dumpAll) { 10340 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10341 pw.flush(); 10342 } 10343 Debug.MemoryInfo mi = null; 10344 if (dumpAll) { 10345 try { 10346 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10347 } catch (RemoteException e) { 10348 if (!isCheckinRequest) { 10349 pw.println("Got RemoteException!"); 10350 pw.flush(); 10351 } 10352 } 10353 } else { 10354 mi = new Debug.MemoryInfo(); 10355 Debug.getMemoryInfo(r.pid, mi); 10356 } 10357 10358 if (!isCheckinRequest && mi != null) { 10359 long myTotalPss = mi.getTotalPss(); 10360 totalPss += myTotalPss; 10361 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10362 r.processName, myTotalPss, 0); 10363 procMems.add(pssItem); 10364 10365 nativePss += mi.nativePss; 10366 dalvikPss += mi.dalvikPss; 10367 otherPss += mi.otherPss; 10368 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10369 long mem = mi.getOtherPss(j); 10370 miscPss[j] += mem; 10371 otherPss -= mem; 10372 } 10373 10374 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10375 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10376 || oomIndex == (oomPss.length-1)) { 10377 oomPss[oomIndex] += myTotalPss; 10378 if (oomProcs[oomIndex] == null) { 10379 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10380 } 10381 oomProcs[oomIndex].add(pssItem); 10382 break; 10383 } 10384 } 10385 } 10386 } 10387 } 10388 10389 if (!isCheckinRequest && procs.size() > 1) { 10390 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10391 10392 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10393 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10394 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10395 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10396 String label = Debug.MemoryInfo.getOtherLabel(j); 10397 catMems.add(new MemItem(label, label, miscPss[j], j)); 10398 } 10399 10400 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10401 for (int j=0; j<oomPss.length; j++) { 10402 if (oomPss[j] != 0) { 10403 String label = DUMP_MEM_OOM_LABEL[j]; 10404 MemItem item = new MemItem(label, label, oomPss[j], 10405 DUMP_MEM_OOM_ADJ[j]); 10406 item.subitems = oomProcs[j]; 10407 oomMems.add(item); 10408 } 10409 } 10410 10411 if (outTag != null || outStack != null) { 10412 if (outTag != null) { 10413 appendMemBucket(outTag, totalPss, "total", false); 10414 } 10415 if (outStack != null) { 10416 appendMemBucket(outStack, totalPss, "total", true); 10417 } 10418 boolean firstLine = true; 10419 for (int i=0; i<oomMems.size(); i++) { 10420 MemItem miCat = oomMems.get(i); 10421 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10422 continue; 10423 } 10424 if (miCat.id < ProcessList.SERVICE_ADJ 10425 || miCat.id == ProcessList.HOME_APP_ADJ 10426 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10427 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10428 outTag.append(" / "); 10429 } 10430 if (outStack != null) { 10431 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10432 if (firstLine) { 10433 outStack.append(":"); 10434 firstLine = false; 10435 } 10436 outStack.append("\n\t at "); 10437 } else { 10438 outStack.append("$"); 10439 } 10440 } 10441 for (int j=0; j<miCat.subitems.size(); j++) { 10442 MemItem mi = miCat.subitems.get(j); 10443 if (j > 0) { 10444 if (outTag != null) { 10445 outTag.append(" "); 10446 } 10447 if (outStack != null) { 10448 outStack.append("$"); 10449 } 10450 } 10451 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10452 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10453 } 10454 if (outStack != null) { 10455 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10456 } 10457 } 10458 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10459 outStack.append("("); 10460 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10461 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10462 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10463 outStack.append(":"); 10464 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10465 } 10466 } 10467 outStack.append(")"); 10468 } 10469 } 10470 } 10471 } 10472 10473 if (!brief && !oomOnly) { 10474 pw.println(); 10475 pw.println("Total PSS by process:"); 10476 dumpMemItems(pw, " ", procMems, true); 10477 pw.println(); 10478 } 10479 pw.println("Total PSS by OOM adjustment:"); 10480 dumpMemItems(pw, " ", oomMems, false); 10481 if (!oomOnly) { 10482 PrintWriter out = categoryPw != null ? categoryPw : pw; 10483 out.println(); 10484 out.println("Total PSS by category:"); 10485 dumpMemItems(out, " ", catMems, true); 10486 } 10487 pw.println(); 10488 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10489 final int[] SINGLE_LONG_FORMAT = new int[] { 10490 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10491 }; 10492 long[] longOut = new long[1]; 10493 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10494 SINGLE_LONG_FORMAT, null, longOut, null); 10495 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10496 longOut[0] = 0; 10497 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10498 SINGLE_LONG_FORMAT, null, longOut, null); 10499 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10500 longOut[0] = 0; 10501 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10502 SINGLE_LONG_FORMAT, null, longOut, null); 10503 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10504 longOut[0] = 0; 10505 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10506 SINGLE_LONG_FORMAT, null, longOut, null); 10507 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10508 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10509 pw.print(shared); pw.println(" kB"); 10510 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10511 pw.print(voltile); pw.println(" kB volatile"); 10512 } 10513 } 10514 10515 /** 10516 * Searches array of arguments for the specified string 10517 * @param args array of argument strings 10518 * @param value value to search for 10519 * @return true if the value is contained in the array 10520 */ 10521 private static boolean scanArgs(String[] args, String value) { 10522 if (args != null) { 10523 for (String arg : args) { 10524 if (value.equals(arg)) { 10525 return true; 10526 } 10527 } 10528 } 10529 return false; 10530 } 10531 10532 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10533 ContentProviderRecord cpr, boolean always) { 10534 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10535 10536 if (!inLaunching || always) { 10537 synchronized (cpr) { 10538 cpr.launchingApp = null; 10539 cpr.notifyAll(); 10540 } 10541 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10542 String names[] = cpr.info.authority.split(";"); 10543 for (int j = 0; j < names.length; j++) { 10544 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10545 } 10546 } 10547 10548 for (int i=0; i<cpr.connections.size(); i++) { 10549 ContentProviderConnection conn = cpr.connections.get(i); 10550 if (conn.waiting) { 10551 // If this connection is waiting for the provider, then we don't 10552 // need to mess with its process unless we are always removing 10553 // or for some reason the provider is not currently launching. 10554 if (inLaunching && !always) { 10555 continue; 10556 } 10557 } 10558 ProcessRecord capp = conn.client; 10559 conn.dead = true; 10560 if (conn.stableCount > 0) { 10561 if (!capp.persistent && capp.thread != null 10562 && capp.pid != 0 10563 && capp.pid != MY_PID) { 10564 Slog.i(TAG, "Kill " + capp.processName 10565 + " (pid " + capp.pid + "): provider " + cpr.info.name 10566 + " in dying process " + (proc != null ? proc.processName : "??")); 10567 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10568 capp.processName, capp.setAdj, "dying provider " 10569 + cpr.name.toShortString()); 10570 Process.killProcessQuiet(capp.pid); 10571 } 10572 } else if (capp.thread != null && conn.provider.provider != null) { 10573 try { 10574 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10575 } catch (RemoteException e) { 10576 } 10577 // In the protocol here, we don't expect the client to correctly 10578 // clean up this connection, we'll just remove it. 10579 cpr.connections.remove(i); 10580 conn.client.conProviders.remove(conn); 10581 } 10582 } 10583 10584 if (inLaunching && always) { 10585 mLaunchingProviders.remove(cpr); 10586 } 10587 return inLaunching; 10588 } 10589 10590 /** 10591 * Main code for cleaning up a process when it has gone away. This is 10592 * called both as a result of the process dying, or directly when stopping 10593 * a process when running in single process mode. 10594 */ 10595 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10596 boolean restarting, boolean allowRestart, int index) { 10597 if (index >= 0) { 10598 mLruProcesses.remove(index); 10599 } 10600 10601 mProcessesToGc.remove(app); 10602 10603 // Dismiss any open dialogs. 10604 if (app.crashDialog != null) { 10605 app.crashDialog.dismiss(); 10606 app.crashDialog = null; 10607 } 10608 if (app.anrDialog != null) { 10609 app.anrDialog.dismiss(); 10610 app.anrDialog = null; 10611 } 10612 if (app.waitDialog != null) { 10613 app.waitDialog.dismiss(); 10614 app.waitDialog = null; 10615 } 10616 10617 app.crashing = false; 10618 app.notResponding = false; 10619 10620 app.resetPackageList(); 10621 app.unlinkDeathRecipient(); 10622 app.thread = null; 10623 app.forcingToForeground = null; 10624 app.foregroundServices = false; 10625 app.foregroundActivities = false; 10626 app.hasShownUi = false; 10627 app.hasAboveClient = false; 10628 10629 mServices.killServicesLocked(app, allowRestart); 10630 10631 boolean restart = false; 10632 10633 // Remove published content providers. 10634 if (!app.pubProviders.isEmpty()) { 10635 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10636 while (it.hasNext()) { 10637 ContentProviderRecord cpr = it.next(); 10638 10639 final boolean always = app.bad || !allowRestart; 10640 if (removeDyingProviderLocked(app, cpr, always) || always) { 10641 // We left the provider in the launching list, need to 10642 // restart it. 10643 restart = true; 10644 } 10645 10646 cpr.provider = null; 10647 cpr.proc = null; 10648 } 10649 app.pubProviders.clear(); 10650 } 10651 10652 // Take care of any launching providers waiting for this process. 10653 if (checkAppInLaunchingProvidersLocked(app, false)) { 10654 restart = true; 10655 } 10656 10657 // Unregister from connected content providers. 10658 if (!app.conProviders.isEmpty()) { 10659 for (int i=0; i<app.conProviders.size(); i++) { 10660 ContentProviderConnection conn = app.conProviders.get(i); 10661 conn.provider.connections.remove(conn); 10662 } 10663 app.conProviders.clear(); 10664 } 10665 10666 // At this point there may be remaining entries in mLaunchingProviders 10667 // where we were the only one waiting, so they are no longer of use. 10668 // Look for these and clean up if found. 10669 // XXX Commented out for now. Trying to figure out a way to reproduce 10670 // the actual situation to identify what is actually going on. 10671 if (false) { 10672 for (int i=0; i<mLaunchingProviders.size(); i++) { 10673 ContentProviderRecord cpr = (ContentProviderRecord) 10674 mLaunchingProviders.get(i); 10675 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10676 synchronized (cpr) { 10677 cpr.launchingApp = null; 10678 cpr.notifyAll(); 10679 } 10680 } 10681 } 10682 } 10683 10684 skipCurrentReceiverLocked(app); 10685 10686 // Unregister any receivers. 10687 if (app.receivers.size() > 0) { 10688 Iterator<ReceiverList> it = app.receivers.iterator(); 10689 while (it.hasNext()) { 10690 removeReceiverLocked(it.next()); 10691 } 10692 app.receivers.clear(); 10693 } 10694 10695 // If the app is undergoing backup, tell the backup manager about it 10696 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10697 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10698 try { 10699 IBackupManager bm = IBackupManager.Stub.asInterface( 10700 ServiceManager.getService(Context.BACKUP_SERVICE)); 10701 bm.agentDisconnected(app.info.packageName); 10702 } catch (RemoteException e) { 10703 // can't happen; backup manager is local 10704 } 10705 } 10706 10707 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10708 ProcessChangeItem item = mPendingProcessChanges.get(i); 10709 if (item.pid == app.pid) { 10710 mPendingProcessChanges.remove(i); 10711 mAvailProcessChanges.add(item); 10712 } 10713 } 10714 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10715 10716 // If the caller is restarting this app, then leave it in its 10717 // current lists and let the caller take care of it. 10718 if (restarting) { 10719 return; 10720 } 10721 10722 if (!app.persistent || app.isolated) { 10723 if (DEBUG_PROCESSES) Slog.v(TAG, 10724 "Removing non-persistent process during cleanup: " + app); 10725 mProcessNames.remove(app.processName, app.uid); 10726 mIsolatedProcesses.remove(app.uid); 10727 if (mHeavyWeightProcess == app) { 10728 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10729 mHeavyWeightProcess.userId, 0)); 10730 mHeavyWeightProcess = null; 10731 } 10732 } else if (!app.removed) { 10733 // This app is persistent, so we need to keep its record around. 10734 // If it is not already on the pending app list, add it there 10735 // and start a new process for it. 10736 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10737 mPersistentStartingProcesses.add(app); 10738 restart = true; 10739 } 10740 } 10741 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10742 "Clean-up removing on hold: " + app); 10743 mProcessesOnHold.remove(app); 10744 10745 if (app == mHomeProcess) { 10746 mHomeProcess = null; 10747 } 10748 if (app == mPreviousProcess) { 10749 mPreviousProcess = null; 10750 } 10751 10752 if (restart && !app.isolated) { 10753 // We have components that still need to be running in the 10754 // process, so re-launch it. 10755 mProcessNames.put(app.processName, app.uid, app); 10756 startProcessLocked(app, "restart", app.processName); 10757 } else if (app.pid > 0 && app.pid != MY_PID) { 10758 // Goodbye! 10759 synchronized (mPidsSelfLocked) { 10760 mPidsSelfLocked.remove(app.pid); 10761 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10762 } 10763 app.setPid(0); 10764 } 10765 } 10766 10767 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10768 // Look through the content providers we are waiting to have launched, 10769 // and if any run in this process then either schedule a restart of 10770 // the process or kill the client waiting for it if this process has 10771 // gone bad. 10772 int NL = mLaunchingProviders.size(); 10773 boolean restart = false; 10774 for (int i=0; i<NL; i++) { 10775 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10776 if (cpr.launchingApp == app) { 10777 if (!alwaysBad && !app.bad) { 10778 restart = true; 10779 } else { 10780 removeDyingProviderLocked(app, cpr, true); 10781 // cpr should have been removed from mLaunchingProviders 10782 NL = mLaunchingProviders.size(); 10783 i--; 10784 } 10785 } 10786 } 10787 return restart; 10788 } 10789 10790 // ========================================================= 10791 // SERVICES 10792 // ========================================================= 10793 10794 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10795 int flags) { 10796 enforceNotIsolatedCaller("getServices"); 10797 synchronized (this) { 10798 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10799 } 10800 } 10801 10802 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10803 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10804 synchronized (this) { 10805 return mServices.getRunningServiceControlPanelLocked(name); 10806 } 10807 } 10808 10809 public ComponentName startService(IApplicationThread caller, Intent service, 10810 String resolvedType, int userId) { 10811 enforceNotIsolatedCaller("startService"); 10812 // Refuse possible leaked file descriptors 10813 if (service != null && service.hasFileDescriptors() == true) { 10814 throw new IllegalArgumentException("File descriptors passed in Intent"); 10815 } 10816 10817 if (DEBUG_SERVICE) 10818 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10819 synchronized(this) { 10820 final int callingPid = Binder.getCallingPid(); 10821 final int callingUid = Binder.getCallingUid(); 10822 checkValidCaller(callingUid, userId); 10823 final long origId = Binder.clearCallingIdentity(); 10824 ComponentName res = mServices.startServiceLocked(caller, service, 10825 resolvedType, callingPid, callingUid, userId); 10826 Binder.restoreCallingIdentity(origId); 10827 return res; 10828 } 10829 } 10830 10831 ComponentName startServiceInPackage(int uid, 10832 Intent service, String resolvedType, int userId) { 10833 synchronized(this) { 10834 if (DEBUG_SERVICE) 10835 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10836 final long origId = Binder.clearCallingIdentity(); 10837 ComponentName res = mServices.startServiceLocked(null, service, 10838 resolvedType, -1, uid, userId); 10839 Binder.restoreCallingIdentity(origId); 10840 return res; 10841 } 10842 } 10843 10844 public int stopService(IApplicationThread caller, Intent service, 10845 String resolvedType, int userId) { 10846 enforceNotIsolatedCaller("stopService"); 10847 // Refuse possible leaked file descriptors 10848 if (service != null && service.hasFileDescriptors() == true) { 10849 throw new IllegalArgumentException("File descriptors passed in Intent"); 10850 } 10851 10852 checkValidCaller(Binder.getCallingUid(), userId); 10853 10854 synchronized(this) { 10855 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10856 } 10857 } 10858 10859 public IBinder peekService(Intent service, String resolvedType) { 10860 enforceNotIsolatedCaller("peekService"); 10861 // Refuse possible leaked file descriptors 10862 if (service != null && service.hasFileDescriptors() == true) { 10863 throw new IllegalArgumentException("File descriptors passed in Intent"); 10864 } 10865 synchronized(this) { 10866 return mServices.peekServiceLocked(service, resolvedType); 10867 } 10868 } 10869 10870 public boolean stopServiceToken(ComponentName className, IBinder token, 10871 int startId) { 10872 synchronized(this) { 10873 return mServices.stopServiceTokenLocked(className, token, startId); 10874 } 10875 } 10876 10877 public void setServiceForeground(ComponentName className, IBinder token, 10878 int id, Notification notification, boolean removeNotification) { 10879 synchronized(this) { 10880 mServices.setServiceForegroundLocked(className, token, id, notification, 10881 removeNotification); 10882 } 10883 } 10884 10885 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10886 boolean requireFull, String name, String callerPackage) { 10887 synchronized(this) { 10888 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10889 requireFull, name, callerPackage); 10890 } 10891 } 10892 10893 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10894 boolean requireFull, String name, String callerPackage) { 10895 final int callingUserId = UserHandle.getUserId(callingUid); 10896 if (callingUserId != userId) { 10897 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10898 if ((requireFull || checkComponentPermission( 10899 android.Manifest.permission.INTERACT_ACROSS_USERS, 10900 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10901 && checkComponentPermission( 10902 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10903 callingPid, callingUid, -1, true) 10904 != PackageManager.PERMISSION_GRANTED) { 10905 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10906 // In this case, they would like to just execute as their 10907 // owner user instead of failing. 10908 userId = callingUserId; 10909 } else { 10910 StringBuilder builder = new StringBuilder(128); 10911 builder.append("Permission Denial: "); 10912 builder.append(name); 10913 if (callerPackage != null) { 10914 builder.append(" from "); 10915 builder.append(callerPackage); 10916 } 10917 builder.append(" asks to run as user "); 10918 builder.append(userId); 10919 builder.append(" but is calling from user "); 10920 builder.append(UserHandle.getUserId(callingUid)); 10921 builder.append("; this requires "); 10922 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10923 if (!requireFull) { 10924 builder.append(" or "); 10925 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10926 } 10927 String msg = builder.toString(); 10928 Slog.w(TAG, msg); 10929 throw new SecurityException(msg); 10930 } 10931 } 10932 } 10933 if (userId == UserHandle.USER_CURRENT 10934 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10935 userId = mCurrentUserId; 10936 } 10937 if (!allowAll && userId < 0) { 10938 throw new IllegalArgumentException( 10939 "Call does not support special user #" + userId); 10940 } 10941 } 10942 return userId; 10943 } 10944 10945 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10946 String className, int flags) { 10947 boolean result = false; 10948 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10949 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10950 if (ActivityManager.checkUidPermission( 10951 android.Manifest.permission.INTERACT_ACROSS_USERS, 10952 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10953 ComponentName comp = new ComponentName(aInfo.packageName, className); 10954 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10955 + " requests FLAG_SINGLE_USER, but app does not hold " 10956 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10957 Slog.w(TAG, msg); 10958 throw new SecurityException(msg); 10959 } 10960 result = true; 10961 } 10962 } else if (componentProcessName == aInfo.packageName) { 10963 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10964 } else if ("system".equals(componentProcessName)) { 10965 result = true; 10966 } 10967 if (DEBUG_MU) { 10968 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10969 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10970 } 10971 return result; 10972 } 10973 10974 public int bindService(IApplicationThread caller, IBinder token, 10975 Intent service, String resolvedType, 10976 IServiceConnection connection, int flags, int userId) { 10977 enforceNotIsolatedCaller("bindService"); 10978 // Refuse possible leaked file descriptors 10979 if (service != null && service.hasFileDescriptors() == true) { 10980 throw new IllegalArgumentException("File descriptors passed in Intent"); 10981 } 10982 10983 synchronized(this) { 10984 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10985 connection, flags, userId); 10986 } 10987 } 10988 10989 public boolean unbindService(IServiceConnection connection) { 10990 synchronized (this) { 10991 return mServices.unbindServiceLocked(connection); 10992 } 10993 } 10994 10995 public void publishService(IBinder token, Intent intent, IBinder service) { 10996 // Refuse possible leaked file descriptors 10997 if (intent != null && intent.hasFileDescriptors() == true) { 10998 throw new IllegalArgumentException("File descriptors passed in Intent"); 10999 } 11000 11001 synchronized(this) { 11002 if (!(token instanceof ServiceRecord)) { 11003 throw new IllegalArgumentException("Invalid service token"); 11004 } 11005 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11006 } 11007 } 11008 11009 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11010 // Refuse possible leaked file descriptors 11011 if (intent != null && intent.hasFileDescriptors() == true) { 11012 throw new IllegalArgumentException("File descriptors passed in Intent"); 11013 } 11014 11015 synchronized(this) { 11016 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11017 } 11018 } 11019 11020 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11021 synchronized(this) { 11022 if (!(token instanceof ServiceRecord)) { 11023 throw new IllegalArgumentException("Invalid service token"); 11024 } 11025 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11026 } 11027 } 11028 11029 // ========================================================= 11030 // BACKUP AND RESTORE 11031 // ========================================================= 11032 11033 // Cause the target app to be launched if necessary and its backup agent 11034 // instantiated. The backup agent will invoke backupAgentCreated() on the 11035 // activity manager to announce its creation. 11036 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11037 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11038 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11039 11040 synchronized(this) { 11041 // !!! TODO: currently no check here that we're already bound 11042 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11043 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11044 synchronized (stats) { 11045 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11046 } 11047 11048 // Backup agent is now in use, its package can't be stopped. 11049 try { 11050 AppGlobals.getPackageManager().setPackageStoppedState( 11051 app.packageName, false, UserHandle.getUserId(app.uid)); 11052 } catch (RemoteException e) { 11053 } catch (IllegalArgumentException e) { 11054 Slog.w(TAG, "Failed trying to unstop package " 11055 + app.packageName + ": " + e); 11056 } 11057 11058 BackupRecord r = new BackupRecord(ss, app, backupMode); 11059 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11060 ? new ComponentName(app.packageName, app.backupAgentName) 11061 : new ComponentName("android", "FullBackupAgent"); 11062 // startProcessLocked() returns existing proc's record if it's already running 11063 ProcessRecord proc = startProcessLocked(app.processName, app, 11064 false, 0, "backup", hostingName, false, false); 11065 if (proc == null) { 11066 Slog.e(TAG, "Unable to start backup agent process " + r); 11067 return false; 11068 } 11069 11070 r.app = proc; 11071 mBackupTarget = r; 11072 mBackupAppName = app.packageName; 11073 11074 // Try not to kill the process during backup 11075 updateOomAdjLocked(proc); 11076 11077 // If the process is already attached, schedule the creation of the backup agent now. 11078 // If it is not yet live, this will be done when it attaches to the framework. 11079 if (proc.thread != null) { 11080 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11081 try { 11082 proc.thread.scheduleCreateBackupAgent(app, 11083 compatibilityInfoForPackageLocked(app), backupMode); 11084 } catch (RemoteException e) { 11085 // Will time out on the backup manager side 11086 } 11087 } else { 11088 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11089 } 11090 // Invariants: at this point, the target app process exists and the application 11091 // is either already running or in the process of coming up. mBackupTarget and 11092 // mBackupAppName describe the app, so that when it binds back to the AM we 11093 // know that it's scheduled for a backup-agent operation. 11094 } 11095 11096 return true; 11097 } 11098 11099 // A backup agent has just come up 11100 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11101 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11102 + " = " + agent); 11103 11104 synchronized(this) { 11105 if (!agentPackageName.equals(mBackupAppName)) { 11106 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11107 return; 11108 } 11109 } 11110 11111 long oldIdent = Binder.clearCallingIdentity(); 11112 try { 11113 IBackupManager bm = IBackupManager.Stub.asInterface( 11114 ServiceManager.getService(Context.BACKUP_SERVICE)); 11115 bm.agentConnected(agentPackageName, agent); 11116 } catch (RemoteException e) { 11117 // can't happen; the backup manager service is local 11118 } catch (Exception e) { 11119 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11120 e.printStackTrace(); 11121 } finally { 11122 Binder.restoreCallingIdentity(oldIdent); 11123 } 11124 } 11125 11126 // done with this agent 11127 public void unbindBackupAgent(ApplicationInfo appInfo) { 11128 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11129 if (appInfo == null) { 11130 Slog.w(TAG, "unbind backup agent for null app"); 11131 return; 11132 } 11133 11134 synchronized(this) { 11135 if (mBackupAppName == null) { 11136 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11137 return; 11138 } 11139 11140 if (!mBackupAppName.equals(appInfo.packageName)) { 11141 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11142 return; 11143 } 11144 11145 ProcessRecord proc = mBackupTarget.app; 11146 mBackupTarget = null; 11147 mBackupAppName = null; 11148 11149 // Not backing this app up any more; reset its OOM adjustment 11150 updateOomAdjLocked(proc); 11151 11152 // If the app crashed during backup, 'thread' will be null here 11153 if (proc.thread != null) { 11154 try { 11155 proc.thread.scheduleDestroyBackupAgent(appInfo, 11156 compatibilityInfoForPackageLocked(appInfo)); 11157 } catch (Exception e) { 11158 Slog.e(TAG, "Exception when unbinding backup agent:"); 11159 e.printStackTrace(); 11160 } 11161 } 11162 } 11163 } 11164 // ========================================================= 11165 // BROADCASTS 11166 // ========================================================= 11167 11168 private final List getStickiesLocked(String action, IntentFilter filter, 11169 List cur, int userId) { 11170 final ContentResolver resolver = mContext.getContentResolver(); 11171 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11172 if (stickies == null) { 11173 return cur; 11174 } 11175 final ArrayList<Intent> list = stickies.get(action); 11176 if (list == null) { 11177 return cur; 11178 } 11179 int N = list.size(); 11180 for (int i=0; i<N; i++) { 11181 Intent intent = list.get(i); 11182 if (filter.match(resolver, intent, true, TAG) >= 0) { 11183 if (cur == null) { 11184 cur = new ArrayList<Intent>(); 11185 } 11186 cur.add(intent); 11187 } 11188 } 11189 return cur; 11190 } 11191 11192 boolean isPendingBroadcastProcessLocked(int pid) { 11193 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11194 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11195 } 11196 11197 void skipPendingBroadcastLocked(int pid) { 11198 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11199 for (BroadcastQueue queue : mBroadcastQueues) { 11200 queue.skipPendingBroadcastLocked(pid); 11201 } 11202 } 11203 11204 // The app just attached; send any pending broadcasts that it should receive 11205 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11206 boolean didSomething = false; 11207 for (BroadcastQueue queue : mBroadcastQueues) { 11208 didSomething |= queue.sendPendingBroadcastsLocked(app); 11209 } 11210 return didSomething; 11211 } 11212 11213 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11214 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11215 enforceNotIsolatedCaller("registerReceiver"); 11216 int callingUid; 11217 int callingPid; 11218 synchronized(this) { 11219 ProcessRecord callerApp = null; 11220 if (caller != null) { 11221 callerApp = getRecordForAppLocked(caller); 11222 if (callerApp == null) { 11223 throw new SecurityException( 11224 "Unable to find app for caller " + caller 11225 + " (pid=" + Binder.getCallingPid() 11226 + ") when registering receiver " + receiver); 11227 } 11228 if (callerApp.info.uid != Process.SYSTEM_UID && 11229 !callerApp.pkgList.contains(callerPackage)) { 11230 throw new SecurityException("Given caller package " + callerPackage 11231 + " is not running in process " + callerApp); 11232 } 11233 callingUid = callerApp.info.uid; 11234 callingPid = callerApp.pid; 11235 } else { 11236 callerPackage = null; 11237 callingUid = Binder.getCallingUid(); 11238 callingPid = Binder.getCallingPid(); 11239 } 11240 11241 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11242 true, true, "registerReceiver", callerPackage); 11243 11244 List allSticky = null; 11245 11246 // Look for any matching sticky broadcasts... 11247 Iterator actions = filter.actionsIterator(); 11248 if (actions != null) { 11249 while (actions.hasNext()) { 11250 String action = (String)actions.next(); 11251 allSticky = getStickiesLocked(action, filter, allSticky, 11252 UserHandle.USER_ALL); 11253 allSticky = getStickiesLocked(action, filter, allSticky, 11254 UserHandle.getUserId(callingUid)); 11255 } 11256 } else { 11257 allSticky = getStickiesLocked(null, filter, allSticky, 11258 UserHandle.USER_ALL); 11259 allSticky = getStickiesLocked(null, filter, allSticky, 11260 UserHandle.getUserId(callingUid)); 11261 } 11262 11263 // The first sticky in the list is returned directly back to 11264 // the client. 11265 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11266 11267 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11268 + ": " + sticky); 11269 11270 if (receiver == null) { 11271 return sticky; 11272 } 11273 11274 ReceiverList rl 11275 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11276 if (rl == null) { 11277 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11278 userId, receiver); 11279 if (rl.app != null) { 11280 rl.app.receivers.add(rl); 11281 } else { 11282 try { 11283 receiver.asBinder().linkToDeath(rl, 0); 11284 } catch (RemoteException e) { 11285 return sticky; 11286 } 11287 rl.linkedToDeath = true; 11288 } 11289 mRegisteredReceivers.put(receiver.asBinder(), rl); 11290 } else if (rl.uid != callingUid) { 11291 throw new IllegalArgumentException( 11292 "Receiver requested to register for uid " + callingUid 11293 + " was previously registered for uid " + rl.uid); 11294 } else if (rl.pid != callingPid) { 11295 throw new IllegalArgumentException( 11296 "Receiver requested to register for pid " + callingPid 11297 + " was previously registered for pid " + rl.pid); 11298 } else if (rl.userId != userId) { 11299 throw new IllegalArgumentException( 11300 "Receiver requested to register for user " + userId 11301 + " was previously registered for user " + rl.userId); 11302 } 11303 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11304 permission, callingUid, userId); 11305 rl.add(bf); 11306 if (!bf.debugCheck()) { 11307 Slog.w(TAG, "==> For Dynamic broadast"); 11308 } 11309 mReceiverResolver.addFilter(bf); 11310 11311 // Enqueue broadcasts for all existing stickies that match 11312 // this filter. 11313 if (allSticky != null) { 11314 ArrayList receivers = new ArrayList(); 11315 receivers.add(bf); 11316 11317 int N = allSticky.size(); 11318 for (int i=0; i<N; i++) { 11319 Intent intent = (Intent)allSticky.get(i); 11320 BroadcastQueue queue = broadcastQueueForIntent(intent); 11321 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11322 null, -1, -1, null, receivers, null, 0, null, null, 11323 false, true, true, -1); 11324 queue.enqueueParallelBroadcastLocked(r); 11325 queue.scheduleBroadcastsLocked(); 11326 } 11327 } 11328 11329 return sticky; 11330 } 11331 } 11332 11333 public void unregisterReceiver(IIntentReceiver receiver) { 11334 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11335 11336 final long origId = Binder.clearCallingIdentity(); 11337 try { 11338 boolean doTrim = false; 11339 11340 synchronized(this) { 11341 ReceiverList rl 11342 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11343 if (rl != null) { 11344 if (rl.curBroadcast != null) { 11345 BroadcastRecord r = rl.curBroadcast; 11346 final boolean doNext = finishReceiverLocked( 11347 receiver.asBinder(), r.resultCode, r.resultData, 11348 r.resultExtras, r.resultAbort, true); 11349 if (doNext) { 11350 doTrim = true; 11351 r.queue.processNextBroadcast(false); 11352 } 11353 } 11354 11355 if (rl.app != null) { 11356 rl.app.receivers.remove(rl); 11357 } 11358 removeReceiverLocked(rl); 11359 if (rl.linkedToDeath) { 11360 rl.linkedToDeath = false; 11361 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11362 } 11363 } 11364 } 11365 11366 // If we actually concluded any broadcasts, we might now be able 11367 // to trim the recipients' apps from our working set 11368 if (doTrim) { 11369 trimApplications(); 11370 return; 11371 } 11372 11373 } finally { 11374 Binder.restoreCallingIdentity(origId); 11375 } 11376 } 11377 11378 void removeReceiverLocked(ReceiverList rl) { 11379 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11380 int N = rl.size(); 11381 for (int i=0; i<N; i++) { 11382 mReceiverResolver.removeFilter(rl.get(i)); 11383 } 11384 } 11385 11386 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11387 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11388 ProcessRecord r = mLruProcesses.get(i); 11389 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11390 try { 11391 r.thread.dispatchPackageBroadcast(cmd, packages); 11392 } catch (RemoteException ex) { 11393 } 11394 } 11395 } 11396 } 11397 11398 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11399 int[] users) { 11400 List<ResolveInfo> receivers = null; 11401 try { 11402 HashSet<ComponentName> singleUserReceivers = null; 11403 boolean scannedFirstReceivers = false; 11404 for (int user : users) { 11405 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11406 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11407 if (newReceivers != null && newReceivers.size() == 0) { 11408 newReceivers = null; 11409 } 11410 if (receivers == null) { 11411 receivers = newReceivers; 11412 } else if (newReceivers != null) { 11413 // We need to concatenate the additional receivers 11414 // found with what we have do far. This would be easy, 11415 // but we also need to de-dup any receivers that are 11416 // singleUser. 11417 if (!scannedFirstReceivers) { 11418 // Collect any single user receivers we had already retrieved. 11419 scannedFirstReceivers = true; 11420 for (int i=0; i<receivers.size(); i++) { 11421 ResolveInfo ri = receivers.get(i); 11422 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11423 ComponentName cn = new ComponentName( 11424 ri.activityInfo.packageName, ri.activityInfo.name); 11425 if (singleUserReceivers == null) { 11426 singleUserReceivers = new HashSet<ComponentName>(); 11427 } 11428 singleUserReceivers.add(cn); 11429 } 11430 } 11431 } 11432 // Add the new results to the existing results, tracking 11433 // and de-dupping single user receivers. 11434 for (int i=0; i<newReceivers.size(); i++) { 11435 ResolveInfo ri = newReceivers.get(i); 11436 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11437 ComponentName cn = new ComponentName( 11438 ri.activityInfo.packageName, ri.activityInfo.name); 11439 if (singleUserReceivers == null) { 11440 singleUserReceivers = new HashSet<ComponentName>(); 11441 } 11442 if (!singleUserReceivers.contains(cn)) { 11443 singleUserReceivers.add(cn); 11444 receivers.add(ri); 11445 } 11446 } else { 11447 receivers.add(ri); 11448 } 11449 } 11450 } 11451 } 11452 } catch (RemoteException ex) { 11453 // pm is in same process, this will never happen. 11454 } 11455 return receivers; 11456 } 11457 11458 private final int broadcastIntentLocked(ProcessRecord callerApp, 11459 String callerPackage, Intent intent, String resolvedType, 11460 IIntentReceiver resultTo, int resultCode, String resultData, 11461 Bundle map, String requiredPermission, 11462 boolean ordered, boolean sticky, int callingPid, int callingUid, 11463 int userId) { 11464 intent = new Intent(intent); 11465 11466 // By default broadcasts do not go to stopped apps. 11467 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11468 11469 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11470 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11471 + " ordered=" + ordered + " userid=" + userId); 11472 if ((resultTo != null) && !ordered) { 11473 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11474 } 11475 11476 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11477 true, false, "broadcast", callerPackage); 11478 11479 // Make sure that the user who is receiving this broadcast is started 11480 // If not, we will just skip it. 11481 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11482 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11483 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11484 Slog.w(TAG, "Skipping broadcast of " + intent 11485 + ": user " + userId + " is stopped"); 11486 return ActivityManager.BROADCAST_SUCCESS; 11487 } 11488 } 11489 11490 /* 11491 * Prevent non-system code (defined here to be non-persistent 11492 * processes) from sending protected broadcasts. 11493 */ 11494 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11495 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11496 callingUid == 0) { 11497 // Always okay. 11498 } else if (callerApp == null || !callerApp.persistent) { 11499 try { 11500 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11501 intent.getAction())) { 11502 String msg = "Permission Denial: not allowed to send broadcast " 11503 + intent.getAction() + " from pid=" 11504 + callingPid + ", uid=" + callingUid; 11505 Slog.w(TAG, msg); 11506 throw new SecurityException(msg); 11507 } 11508 } catch (RemoteException e) { 11509 Slog.w(TAG, "Remote exception", e); 11510 return ActivityManager.BROADCAST_SUCCESS; 11511 } 11512 } 11513 11514 // Handle special intents: if this broadcast is from the package 11515 // manager about a package being removed, we need to remove all of 11516 // its activities from the history stack. 11517 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11518 intent.getAction()); 11519 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11520 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11521 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11522 || uidRemoved) { 11523 if (checkComponentPermission( 11524 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11525 callingPid, callingUid, -1, true) 11526 == PackageManager.PERMISSION_GRANTED) { 11527 if (uidRemoved) { 11528 final Bundle intentExtras = intent.getExtras(); 11529 final int uid = intentExtras != null 11530 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11531 if (uid >= 0) { 11532 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11533 synchronized (bs) { 11534 bs.removeUidStatsLocked(uid); 11535 } 11536 } 11537 } else { 11538 // If resources are unavailable just force stop all 11539 // those packages and flush the attribute cache as well. 11540 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11541 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11542 if (list != null && (list.length > 0)) { 11543 for (String pkg : list) { 11544 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11545 } 11546 sendPackageBroadcastLocked( 11547 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11548 } 11549 } else { 11550 Uri data = intent.getData(); 11551 String ssp; 11552 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11553 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11554 forceStopPackageLocked(ssp, 11555 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11556 false, userId); 11557 } 11558 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11559 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11560 new String[] {ssp}, userId); 11561 } 11562 } 11563 } 11564 } 11565 } else { 11566 String msg = "Permission Denial: " + intent.getAction() 11567 + " broadcast from " + callerPackage + " (pid=" + callingPid 11568 + ", uid=" + callingUid + ")" 11569 + " requires " 11570 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11571 Slog.w(TAG, msg); 11572 throw new SecurityException(msg); 11573 } 11574 11575 // Special case for adding a package: by default turn on compatibility 11576 // mode. 11577 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11578 Uri data = intent.getData(); 11579 String ssp; 11580 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11581 mCompatModePackages.handlePackageAddedLocked(ssp, 11582 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11583 } 11584 } 11585 11586 /* 11587 * If this is the time zone changed action, queue up a message that will reset the timezone 11588 * of all currently running processes. This message will get queued up before the broadcast 11589 * happens. 11590 */ 11591 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11592 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11593 } 11594 11595 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11596 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11597 } 11598 11599 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11600 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11601 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11602 } 11603 11604 // Add to the sticky list if requested. 11605 if (sticky) { 11606 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11607 callingPid, callingUid) 11608 != PackageManager.PERMISSION_GRANTED) { 11609 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11610 + callingPid + ", uid=" + callingUid 11611 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11612 Slog.w(TAG, msg); 11613 throw new SecurityException(msg); 11614 } 11615 if (requiredPermission != null) { 11616 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11617 + " and enforce permission " + requiredPermission); 11618 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11619 } 11620 if (intent.getComponent() != null) { 11621 throw new SecurityException( 11622 "Sticky broadcasts can't target a specific component"); 11623 } 11624 // We use userId directly here, since the "all" target is maintained 11625 // as a separate set of sticky broadcasts. 11626 if (userId != UserHandle.USER_ALL) { 11627 // But first, if this is not a broadcast to all users, then 11628 // make sure it doesn't conflict with an existing broadcast to 11629 // all users. 11630 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11631 UserHandle.USER_ALL); 11632 if (stickies != null) { 11633 ArrayList<Intent> list = stickies.get(intent.getAction()); 11634 if (list != null) { 11635 int N = list.size(); 11636 int i; 11637 for (i=0; i<N; i++) { 11638 if (intent.filterEquals(list.get(i))) { 11639 throw new IllegalArgumentException( 11640 "Sticky broadcast " + intent + " for user " 11641 + userId + " conflicts with existing global broadcast"); 11642 } 11643 } 11644 } 11645 } 11646 } 11647 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11648 if (stickies == null) { 11649 stickies = new HashMap<String, ArrayList<Intent>>(); 11650 mStickyBroadcasts.put(userId, stickies); 11651 } 11652 ArrayList<Intent> list = stickies.get(intent.getAction()); 11653 if (list == null) { 11654 list = new ArrayList<Intent>(); 11655 stickies.put(intent.getAction(), list); 11656 } 11657 int N = list.size(); 11658 int i; 11659 for (i=0; i<N; i++) { 11660 if (intent.filterEquals(list.get(i))) { 11661 // This sticky already exists, replace it. 11662 list.set(i, new Intent(intent)); 11663 break; 11664 } 11665 } 11666 if (i >= N) { 11667 list.add(new Intent(intent)); 11668 } 11669 } 11670 11671 int[] users; 11672 if (userId == UserHandle.USER_ALL) { 11673 // Caller wants broadcast to go to all started users. 11674 users = new int[mStartedUsers.size()]; 11675 for (int i=0; i<mStartedUsers.size(); i++) { 11676 users[i] = mStartedUsers.keyAt(i); 11677 } 11678 } else { 11679 // Caller wants broadcast to go to one specific user. 11680 users = new int[] {userId}; 11681 } 11682 11683 // Figure out who all will receive this broadcast. 11684 List receivers = null; 11685 List<BroadcastFilter> registeredReceivers = null; 11686 // Need to resolve the intent to interested receivers... 11687 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11688 == 0) { 11689 receivers = collectReceiverComponents(intent, resolvedType, users); 11690 } 11691 if (intent.getComponent() == null) { 11692 registeredReceivers = mReceiverResolver.queryIntent(intent, 11693 resolvedType, false, userId); 11694 } 11695 11696 final boolean replacePending = 11697 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11698 11699 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11700 + " replacePending=" + replacePending); 11701 11702 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11703 if (!ordered && NR > 0) { 11704 // If we are not serializing this broadcast, then send the 11705 // registered receivers separately so they don't wait for the 11706 // components to be launched. 11707 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11708 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11709 callerPackage, callingPid, callingUid, requiredPermission, 11710 registeredReceivers, resultTo, resultCode, resultData, map, 11711 ordered, sticky, false, userId); 11712 if (DEBUG_BROADCAST) Slog.v( 11713 TAG, "Enqueueing parallel broadcast " + r); 11714 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11715 if (!replaced) { 11716 queue.enqueueParallelBroadcastLocked(r); 11717 queue.scheduleBroadcastsLocked(); 11718 } 11719 registeredReceivers = null; 11720 NR = 0; 11721 } 11722 11723 // Merge into one list. 11724 int ir = 0; 11725 if (receivers != null) { 11726 // A special case for PACKAGE_ADDED: do not allow the package 11727 // being added to see this broadcast. This prevents them from 11728 // using this as a back door to get run as soon as they are 11729 // installed. Maybe in the future we want to have a special install 11730 // broadcast or such for apps, but we'd like to deliberately make 11731 // this decision. 11732 String skipPackages[] = null; 11733 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11734 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11735 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11736 Uri data = intent.getData(); 11737 if (data != null) { 11738 String pkgName = data.getSchemeSpecificPart(); 11739 if (pkgName != null) { 11740 skipPackages = new String[] { pkgName }; 11741 } 11742 } 11743 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11744 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11745 } 11746 if (skipPackages != null && (skipPackages.length > 0)) { 11747 for (String skipPackage : skipPackages) { 11748 if (skipPackage != null) { 11749 int NT = receivers.size(); 11750 for (int it=0; it<NT; it++) { 11751 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11752 if (curt.activityInfo.packageName.equals(skipPackage)) { 11753 receivers.remove(it); 11754 it--; 11755 NT--; 11756 } 11757 } 11758 } 11759 } 11760 } 11761 11762 int NT = receivers != null ? receivers.size() : 0; 11763 int it = 0; 11764 ResolveInfo curt = null; 11765 BroadcastFilter curr = null; 11766 while (it < NT && ir < NR) { 11767 if (curt == null) { 11768 curt = (ResolveInfo)receivers.get(it); 11769 } 11770 if (curr == null) { 11771 curr = registeredReceivers.get(ir); 11772 } 11773 if (curr.getPriority() >= curt.priority) { 11774 // Insert this broadcast record into the final list. 11775 receivers.add(it, curr); 11776 ir++; 11777 curr = null; 11778 it++; 11779 NT++; 11780 } else { 11781 // Skip to the next ResolveInfo in the final list. 11782 it++; 11783 curt = null; 11784 } 11785 } 11786 } 11787 while (ir < NR) { 11788 if (receivers == null) { 11789 receivers = new ArrayList(); 11790 } 11791 receivers.add(registeredReceivers.get(ir)); 11792 ir++; 11793 } 11794 11795 if ((receivers != null && receivers.size() > 0) 11796 || resultTo != null) { 11797 BroadcastQueue queue = broadcastQueueForIntent(intent); 11798 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11799 callerPackage, callingPid, callingUid, requiredPermission, 11800 receivers, resultTo, resultCode, resultData, map, ordered, 11801 sticky, false, userId); 11802 if (DEBUG_BROADCAST) Slog.v( 11803 TAG, "Enqueueing ordered broadcast " + r 11804 + ": prev had " + queue.mOrderedBroadcasts.size()); 11805 if (DEBUG_BROADCAST) { 11806 int seq = r.intent.getIntExtra("seq", -1); 11807 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11808 } 11809 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11810 if (!replaced) { 11811 queue.enqueueOrderedBroadcastLocked(r); 11812 queue.scheduleBroadcastsLocked(); 11813 } 11814 } 11815 11816 return ActivityManager.BROADCAST_SUCCESS; 11817 } 11818 11819 final Intent verifyBroadcastLocked(Intent intent) { 11820 // Refuse possible leaked file descriptors 11821 if (intent != null && intent.hasFileDescriptors() == true) { 11822 throw new IllegalArgumentException("File descriptors passed in Intent"); 11823 } 11824 11825 int flags = intent.getFlags(); 11826 11827 if (!mProcessesReady) { 11828 // if the caller really truly claims to know what they're doing, go 11829 // ahead and allow the broadcast without launching any receivers 11830 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11831 intent = new Intent(intent); 11832 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11833 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11834 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11835 + " before boot completion"); 11836 throw new IllegalStateException("Cannot broadcast before boot completed"); 11837 } 11838 } 11839 11840 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11841 throw new IllegalArgumentException( 11842 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11843 } 11844 11845 return intent; 11846 } 11847 11848 public final int broadcastIntent(IApplicationThread caller, 11849 Intent intent, String resolvedType, IIntentReceiver resultTo, 11850 int resultCode, String resultData, Bundle map, 11851 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11852 enforceNotIsolatedCaller("broadcastIntent"); 11853 synchronized(this) { 11854 intent = verifyBroadcastLocked(intent); 11855 11856 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11857 final int callingPid = Binder.getCallingPid(); 11858 final int callingUid = Binder.getCallingUid(); 11859 final long origId = Binder.clearCallingIdentity(); 11860 int res = broadcastIntentLocked(callerApp, 11861 callerApp != null ? callerApp.info.packageName : null, 11862 intent, resolvedType, resultTo, 11863 resultCode, resultData, map, requiredPermission, serialized, sticky, 11864 callingPid, callingUid, userId); 11865 Binder.restoreCallingIdentity(origId); 11866 return res; 11867 } 11868 } 11869 11870 int broadcastIntentInPackage(String packageName, int uid, 11871 Intent intent, String resolvedType, IIntentReceiver resultTo, 11872 int resultCode, String resultData, Bundle map, 11873 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11874 synchronized(this) { 11875 intent = verifyBroadcastLocked(intent); 11876 11877 final long origId = Binder.clearCallingIdentity(); 11878 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11879 resultTo, resultCode, resultData, map, requiredPermission, 11880 serialized, sticky, -1, uid, userId); 11881 Binder.restoreCallingIdentity(origId); 11882 return res; 11883 } 11884 } 11885 11886 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11887 // Refuse possible leaked file descriptors 11888 if (intent != null && intent.hasFileDescriptors() == true) { 11889 throw new IllegalArgumentException("File descriptors passed in Intent"); 11890 } 11891 11892 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11893 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11894 11895 synchronized(this) { 11896 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11897 != PackageManager.PERMISSION_GRANTED) { 11898 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11899 + Binder.getCallingPid() 11900 + ", uid=" + Binder.getCallingUid() 11901 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11902 Slog.w(TAG, msg); 11903 throw new SecurityException(msg); 11904 } 11905 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11906 if (stickies != null) { 11907 ArrayList<Intent> list = stickies.get(intent.getAction()); 11908 if (list != null) { 11909 int N = list.size(); 11910 int i; 11911 for (i=0; i<N; i++) { 11912 if (intent.filterEquals(list.get(i))) { 11913 list.remove(i); 11914 break; 11915 } 11916 } 11917 if (list.size() <= 0) { 11918 stickies.remove(intent.getAction()); 11919 } 11920 } 11921 if (stickies.size() <= 0) { 11922 mStickyBroadcasts.remove(userId); 11923 } 11924 } 11925 } 11926 } 11927 11928 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11929 String resultData, Bundle resultExtras, boolean resultAbort, 11930 boolean explicit) { 11931 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11932 if (r == null) { 11933 Slog.w(TAG, "finishReceiver called but not found on queue"); 11934 return false; 11935 } 11936 11937 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11938 explicit); 11939 } 11940 11941 public void finishReceiver(IBinder who, int resultCode, String resultData, 11942 Bundle resultExtras, boolean resultAbort) { 11943 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11944 11945 // Refuse possible leaked file descriptors 11946 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11947 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11948 } 11949 11950 final long origId = Binder.clearCallingIdentity(); 11951 try { 11952 boolean doNext = false; 11953 BroadcastRecord r = null; 11954 11955 synchronized(this) { 11956 r = broadcastRecordForReceiverLocked(who); 11957 if (r != null) { 11958 doNext = r.queue.finishReceiverLocked(r, resultCode, 11959 resultData, resultExtras, resultAbort, true); 11960 } 11961 } 11962 11963 if (doNext) { 11964 r.queue.processNextBroadcast(false); 11965 } 11966 trimApplications(); 11967 } finally { 11968 Binder.restoreCallingIdentity(origId); 11969 } 11970 } 11971 11972 // ========================================================= 11973 // INSTRUMENTATION 11974 // ========================================================= 11975 11976 public boolean startInstrumentation(ComponentName className, 11977 String profileFile, int flags, Bundle arguments, 11978 IInstrumentationWatcher watcher, int userId) { 11979 enforceNotIsolatedCaller("startInstrumentation"); 11980 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 11981 userId, false, true, "startInstrumentation", null); 11982 // Refuse possible leaked file descriptors 11983 if (arguments != null && arguments.hasFileDescriptors()) { 11984 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11985 } 11986 11987 synchronized(this) { 11988 InstrumentationInfo ii = null; 11989 ApplicationInfo ai = null; 11990 try { 11991 ii = mContext.getPackageManager().getInstrumentationInfo( 11992 className, STOCK_PM_FLAGS); 11993 ai = AppGlobals.getPackageManager().getApplicationInfo( 11994 ii.targetPackage, STOCK_PM_FLAGS, userId); 11995 } catch (PackageManager.NameNotFoundException e) { 11996 } catch (RemoteException e) { 11997 } 11998 if (ii == null) { 11999 reportStartInstrumentationFailure(watcher, className, 12000 "Unable to find instrumentation info for: " + className); 12001 return false; 12002 } 12003 if (ai == null) { 12004 reportStartInstrumentationFailure(watcher, className, 12005 "Unable to find instrumentation target package: " + ii.targetPackage); 12006 return false; 12007 } 12008 12009 int match = mContext.getPackageManager().checkSignatures( 12010 ii.targetPackage, ii.packageName); 12011 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12012 String msg = "Permission Denial: starting instrumentation " 12013 + className + " from pid=" 12014 + Binder.getCallingPid() 12015 + ", uid=" + Binder.getCallingPid() 12016 + " not allowed because package " + ii.packageName 12017 + " does not have a signature matching the target " 12018 + ii.targetPackage; 12019 reportStartInstrumentationFailure(watcher, className, msg); 12020 throw new SecurityException(msg); 12021 } 12022 12023 final long origId = Binder.clearCallingIdentity(); 12024 // Instrumentation can kill and relaunch even persistent processes 12025 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12026 ProcessRecord app = addAppLocked(ai, false); 12027 app.instrumentationClass = className; 12028 app.instrumentationInfo = ai; 12029 app.instrumentationProfileFile = profileFile; 12030 app.instrumentationArguments = arguments; 12031 app.instrumentationWatcher = watcher; 12032 app.instrumentationResultClass = className; 12033 Binder.restoreCallingIdentity(origId); 12034 } 12035 12036 return true; 12037 } 12038 12039 /** 12040 * Report errors that occur while attempting to start Instrumentation. Always writes the 12041 * error to the logs, but if somebody is watching, send the report there too. This enables 12042 * the "am" command to report errors with more information. 12043 * 12044 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12045 * @param cn The component name of the instrumentation. 12046 * @param report The error report. 12047 */ 12048 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12049 ComponentName cn, String report) { 12050 Slog.w(TAG, report); 12051 try { 12052 if (watcher != null) { 12053 Bundle results = new Bundle(); 12054 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12055 results.putString("Error", report); 12056 watcher.instrumentationStatus(cn, -1, results); 12057 } 12058 } catch (RemoteException e) { 12059 Slog.w(TAG, e); 12060 } 12061 } 12062 12063 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12064 if (app.instrumentationWatcher != null) { 12065 try { 12066 // NOTE: IInstrumentationWatcher *must* be oneway here 12067 app.instrumentationWatcher.instrumentationFinished( 12068 app.instrumentationClass, 12069 resultCode, 12070 results); 12071 } catch (RemoteException e) { 12072 } 12073 } 12074 app.instrumentationWatcher = null; 12075 app.instrumentationClass = null; 12076 app.instrumentationInfo = null; 12077 app.instrumentationProfileFile = null; 12078 app.instrumentationArguments = null; 12079 12080 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12081 } 12082 12083 public void finishInstrumentation(IApplicationThread target, 12084 int resultCode, Bundle results) { 12085 int userId = UserHandle.getCallingUserId(); 12086 // Refuse possible leaked file descriptors 12087 if (results != null && results.hasFileDescriptors()) { 12088 throw new IllegalArgumentException("File descriptors passed in Intent"); 12089 } 12090 12091 synchronized(this) { 12092 ProcessRecord app = getRecordForAppLocked(target); 12093 if (app == null) { 12094 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12095 return; 12096 } 12097 final long origId = Binder.clearCallingIdentity(); 12098 finishInstrumentationLocked(app, resultCode, results); 12099 Binder.restoreCallingIdentity(origId); 12100 } 12101 } 12102 12103 // ========================================================= 12104 // CONFIGURATION 12105 // ========================================================= 12106 12107 public ConfigurationInfo getDeviceConfigurationInfo() { 12108 ConfigurationInfo config = new ConfigurationInfo(); 12109 synchronized (this) { 12110 config.reqTouchScreen = mConfiguration.touchscreen; 12111 config.reqKeyboardType = mConfiguration.keyboard; 12112 config.reqNavigation = mConfiguration.navigation; 12113 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12114 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12115 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12116 } 12117 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12118 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12119 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12120 } 12121 config.reqGlEsVersion = GL_ES_VERSION; 12122 } 12123 return config; 12124 } 12125 12126 public Configuration getConfiguration() { 12127 Configuration ci; 12128 synchronized(this) { 12129 ci = new Configuration(mConfiguration); 12130 } 12131 return ci; 12132 } 12133 12134 public void updatePersistentConfiguration(Configuration values) { 12135 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12136 "updateConfiguration()"); 12137 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12138 "updateConfiguration()"); 12139 if (values == null) { 12140 throw new NullPointerException("Configuration must not be null"); 12141 } 12142 12143 synchronized(this) { 12144 final long origId = Binder.clearCallingIdentity(); 12145 updateConfigurationLocked(values, null, true, false); 12146 Binder.restoreCallingIdentity(origId); 12147 } 12148 } 12149 12150 public void updateConfiguration(Configuration values) { 12151 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12152 "updateConfiguration()"); 12153 12154 synchronized(this) { 12155 if (values == null && mWindowManager != null) { 12156 // sentinel: fetch the current configuration from the window manager 12157 values = mWindowManager.computeNewConfiguration(); 12158 } 12159 12160 if (mWindowManager != null) { 12161 mProcessList.applyDisplaySize(mWindowManager); 12162 } 12163 12164 final long origId = Binder.clearCallingIdentity(); 12165 if (values != null) { 12166 Settings.System.clearConfiguration(values); 12167 } 12168 updateConfigurationLocked(values, null, false, false); 12169 Binder.restoreCallingIdentity(origId); 12170 } 12171 } 12172 12173 /** 12174 * Do either or both things: (1) change the current configuration, and (2) 12175 * make sure the given activity is running with the (now) current 12176 * configuration. Returns true if the activity has been left running, or 12177 * false if <var>starting</var> is being destroyed to match the new 12178 * configuration. 12179 * @param persistent TODO 12180 */ 12181 boolean updateConfigurationLocked(Configuration values, 12182 ActivityRecord starting, boolean persistent, boolean initLocale) { 12183 // do nothing if we are headless 12184 if (mHeadless) return true; 12185 12186 int changes = 0; 12187 12188 boolean kept = true; 12189 12190 if (values != null) { 12191 Configuration newConfig = new Configuration(mConfiguration); 12192 changes = newConfig.updateFrom(values); 12193 if (changes != 0) { 12194 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12195 Slog.i(TAG, "Updating configuration to: " + values); 12196 } 12197 12198 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12199 12200 if (values.locale != null && !initLocale) { 12201 saveLocaleLocked(values.locale, 12202 !values.locale.equals(mConfiguration.locale), 12203 values.userSetLocale); 12204 } 12205 12206 mConfigurationSeq++; 12207 if (mConfigurationSeq <= 0) { 12208 mConfigurationSeq = 1; 12209 } 12210 newConfig.seq = mConfigurationSeq; 12211 mConfiguration = newConfig; 12212 Slog.i(TAG, "Config changed: " + newConfig); 12213 12214 final Configuration configCopy = new Configuration(mConfiguration); 12215 12216 // TODO: If our config changes, should we auto dismiss any currently 12217 // showing dialogs? 12218 mShowDialogs = shouldShowDialogs(newConfig); 12219 12220 AttributeCache ac = AttributeCache.instance(); 12221 if (ac != null) { 12222 ac.updateConfiguration(configCopy); 12223 } 12224 12225 // Make sure all resources in our process are updated 12226 // right now, so that anyone who is going to retrieve 12227 // resource values after we return will be sure to get 12228 // the new ones. This is especially important during 12229 // boot, where the first config change needs to guarantee 12230 // all resources have that config before following boot 12231 // code is executed. 12232 mSystemThread.applyConfigurationToResources(configCopy); 12233 12234 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12235 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12236 msg.obj = new Configuration(configCopy); 12237 mHandler.sendMessage(msg); 12238 } 12239 12240 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12241 ProcessRecord app = mLruProcesses.get(i); 12242 try { 12243 if (app.thread != null) { 12244 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12245 + app.processName + " new config " + mConfiguration); 12246 app.thread.scheduleConfigurationChanged(configCopy); 12247 } 12248 } catch (Exception e) { 12249 } 12250 } 12251 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12253 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12254 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12255 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12256 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12257 broadcastIntentLocked(null, null, 12258 new Intent(Intent.ACTION_LOCALE_CHANGED), 12259 null, null, 0, null, null, 12260 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12261 } 12262 } 12263 } 12264 12265 if (changes != 0 && starting == null) { 12266 // If the configuration changed, and the caller is not already 12267 // in the process of starting an activity, then find the top 12268 // activity to check if its configuration needs to change. 12269 starting = mMainStack.topRunningActivityLocked(null); 12270 } 12271 12272 if (starting != null) { 12273 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12274 // And we need to make sure at this point that all other activities 12275 // are made visible with the correct configuration. 12276 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12277 } 12278 12279 if (values != null && mWindowManager != null) { 12280 mWindowManager.setNewConfiguration(mConfiguration); 12281 } 12282 12283 return kept; 12284 } 12285 12286 /** 12287 * Decide based on the configuration whether we should shouw the ANR, 12288 * crash, etc dialogs. The idea is that if there is no affordnace to 12289 * press the on-screen buttons, we shouldn't show the dialog. 12290 * 12291 * A thought: SystemUI might also want to get told about this, the Power 12292 * dialog / global actions also might want different behaviors. 12293 */ 12294 private static final boolean shouldShowDialogs(Configuration config) { 12295 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12296 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12297 } 12298 12299 /** 12300 * Save the locale. You must be inside a synchronized (this) block. 12301 */ 12302 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12303 if(isDiff) { 12304 SystemProperties.set("user.language", l.getLanguage()); 12305 SystemProperties.set("user.region", l.getCountry()); 12306 } 12307 12308 if(isPersist) { 12309 SystemProperties.set("persist.sys.language", l.getLanguage()); 12310 SystemProperties.set("persist.sys.country", l.getCountry()); 12311 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12312 } 12313 } 12314 12315 @Override 12316 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12317 ActivityRecord srec = ActivityRecord.forToken(token); 12318 return srec != null && srec.task.affinity != null && 12319 srec.task.affinity.equals(destAffinity); 12320 } 12321 12322 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12323 Intent resultData) { 12324 ComponentName dest = destIntent.getComponent(); 12325 12326 synchronized (this) { 12327 ActivityRecord srec = ActivityRecord.forToken(token); 12328 if (srec == null) { 12329 return false; 12330 } 12331 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12332 final int start = history.indexOf(srec); 12333 if (start < 0) { 12334 // Current activity is not in history stack; do nothing. 12335 return false; 12336 } 12337 int finishTo = start - 1; 12338 ActivityRecord parent = null; 12339 boolean foundParentInTask = false; 12340 if (dest != null) { 12341 TaskRecord tr = srec.task; 12342 for (int i = start - 1; i >= 0; i--) { 12343 ActivityRecord r = history.get(i); 12344 if (tr != r.task) { 12345 // Couldn't find parent in the same task; stop at the one above this. 12346 // (Root of current task; in-app "home" behavior) 12347 // Always at least finish the current activity. 12348 finishTo = Math.min(start - 1, i + 1); 12349 parent = history.get(finishTo); 12350 break; 12351 } else if (r.info.packageName.equals(dest.getPackageName()) && 12352 r.info.name.equals(dest.getClassName())) { 12353 finishTo = i; 12354 parent = r; 12355 foundParentInTask = true; 12356 break; 12357 } 12358 } 12359 } 12360 12361 if (mController != null) { 12362 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12363 if (next != null) { 12364 // ask watcher if this is allowed 12365 boolean resumeOK = true; 12366 try { 12367 resumeOK = mController.activityResuming(next.packageName); 12368 } catch (RemoteException e) { 12369 mController = null; 12370 } 12371 12372 if (!resumeOK) { 12373 return false; 12374 } 12375 } 12376 } 12377 final long origId = Binder.clearCallingIdentity(); 12378 for (int i = start; i > finishTo; i--) { 12379 ActivityRecord r = history.get(i); 12380 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12381 "navigate-up", true); 12382 // Only return the supplied result for the first activity finished 12383 resultCode = Activity.RESULT_CANCELED; 12384 resultData = null; 12385 } 12386 12387 if (parent != null && foundParentInTask) { 12388 final int parentLaunchMode = parent.info.launchMode; 12389 final int destIntentFlags = destIntent.getFlags(); 12390 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12391 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12392 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12393 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12394 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12395 } else { 12396 try { 12397 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12398 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12399 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12400 null, aInfo, parent.appToken, null, 12401 0, -1, parent.launchedFromUid, 0, null, true, null); 12402 foundParentInTask = res == ActivityManager.START_SUCCESS; 12403 } catch (RemoteException e) { 12404 foundParentInTask = false; 12405 } 12406 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12407 resultData, "navigate-up", true); 12408 } 12409 } 12410 Binder.restoreCallingIdentity(origId); 12411 return foundParentInTask; 12412 } 12413 } 12414 12415 public int getLaunchedFromUid(IBinder activityToken) { 12416 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12417 if (srec == null) { 12418 return -1; 12419 } 12420 return srec.launchedFromUid; 12421 } 12422 12423 // ========================================================= 12424 // LIFETIME MANAGEMENT 12425 // ========================================================= 12426 12427 // Returns which broadcast queue the app is the current [or imminent] receiver 12428 // on, or 'null' if the app is not an active broadcast recipient. 12429 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12430 BroadcastRecord r = app.curReceiver; 12431 if (r != null) { 12432 return r.queue; 12433 } 12434 12435 // It's not the current receiver, but it might be starting up to become one 12436 synchronized (this) { 12437 for (BroadcastQueue queue : mBroadcastQueues) { 12438 r = queue.mPendingBroadcast; 12439 if (r != null && r.curApp == app) { 12440 // found it; report which queue it's in 12441 return queue; 12442 } 12443 } 12444 } 12445 12446 return null; 12447 } 12448 12449 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12450 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12451 if (mAdjSeq == app.adjSeq) { 12452 // This adjustment has already been computed. If we are calling 12453 // from the top, we may have already computed our adjustment with 12454 // an earlier hidden adjustment that isn't really for us... if 12455 // so, use the new hidden adjustment. 12456 if (!recursed && app.hidden) { 12457 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12458 app.hasActivities ? hiddenAdj : emptyAdj; 12459 } 12460 return app.curRawAdj; 12461 } 12462 12463 if (app.thread == null) { 12464 app.adjSeq = mAdjSeq; 12465 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12466 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12467 } 12468 12469 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12470 app.adjSource = null; 12471 app.adjTarget = null; 12472 app.empty = false; 12473 app.hidden = false; 12474 12475 final int activitiesSize = app.activities.size(); 12476 12477 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12478 // The max adjustment doesn't allow this app to be anything 12479 // below foreground, so it is not worth doing work for it. 12480 app.adjType = "fixed"; 12481 app.adjSeq = mAdjSeq; 12482 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12483 app.hasActivities = false; 12484 app.foregroundActivities = false; 12485 app.keeping = true; 12486 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12487 // System process can do UI, and when they do we want to have 12488 // them trim their memory after the user leaves the UI. To 12489 // facilitate this, here we need to determine whether or not it 12490 // is currently showing UI. 12491 app.systemNoUi = true; 12492 if (app == TOP_APP) { 12493 app.systemNoUi = false; 12494 app.hasActivities = true; 12495 } else if (activitiesSize > 0) { 12496 for (int j = 0; j < activitiesSize; j++) { 12497 final ActivityRecord r = app.activities.get(j); 12498 if (r.visible) { 12499 app.systemNoUi = false; 12500 } 12501 if (r.app == app) { 12502 app.hasActivities = true; 12503 } 12504 } 12505 } 12506 return (app.curAdj=app.maxAdj); 12507 } 12508 12509 app.keeping = false; 12510 app.systemNoUi = false; 12511 app.hasActivities = false; 12512 12513 // Determine the importance of the process, starting with most 12514 // important to least, and assign an appropriate OOM adjustment. 12515 int adj; 12516 int schedGroup; 12517 boolean foregroundActivities = false; 12518 boolean interesting = false; 12519 BroadcastQueue queue; 12520 if (app == TOP_APP) { 12521 // The last app on the list is the foreground app. 12522 adj = ProcessList.FOREGROUND_APP_ADJ; 12523 schedGroup = Process.THREAD_GROUP_DEFAULT; 12524 app.adjType = "top-activity"; 12525 foregroundActivities = true; 12526 interesting = true; 12527 app.hasActivities = true; 12528 } else if (app.instrumentationClass != null) { 12529 // Don't want to kill running instrumentation. 12530 adj = ProcessList.FOREGROUND_APP_ADJ; 12531 schedGroup = Process.THREAD_GROUP_DEFAULT; 12532 app.adjType = "instrumentation"; 12533 interesting = true; 12534 } else if ((queue = isReceivingBroadcast(app)) != null) { 12535 // An app that is currently receiving a broadcast also 12536 // counts as being in the foreground for OOM killer purposes. 12537 // It's placed in a sched group based on the nature of the 12538 // broadcast as reflected by which queue it's active in. 12539 adj = ProcessList.FOREGROUND_APP_ADJ; 12540 schedGroup = (queue == mFgBroadcastQueue) 12541 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12542 app.adjType = "broadcast"; 12543 } else if (app.executingServices.size() > 0) { 12544 // An app that is currently executing a service callback also 12545 // counts as being in the foreground. 12546 adj = ProcessList.FOREGROUND_APP_ADJ; 12547 schedGroup = Process.THREAD_GROUP_DEFAULT; 12548 app.adjType = "exec-service"; 12549 } else { 12550 // Assume process is hidden (has activities); we will correct 12551 // later if this is not the case. 12552 adj = hiddenAdj; 12553 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12554 app.hidden = true; 12555 app.adjType = "bg-activities"; 12556 } 12557 12558 boolean hasStoppingActivities = false; 12559 12560 // Examine all activities if not already foreground. 12561 if (!foregroundActivities && activitiesSize > 0) { 12562 for (int j = 0; j < activitiesSize; j++) { 12563 final ActivityRecord r = app.activities.get(j); 12564 if (r.visible) { 12565 // App has a visible activity; only upgrade adjustment. 12566 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12567 adj = ProcessList.VISIBLE_APP_ADJ; 12568 app.adjType = "visible"; 12569 } 12570 schedGroup = Process.THREAD_GROUP_DEFAULT; 12571 app.hidden = false; 12572 app.hasActivities = true; 12573 foregroundActivities = true; 12574 break; 12575 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12576 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12577 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12578 app.adjType = "pausing"; 12579 } 12580 app.hidden = false; 12581 foregroundActivities = true; 12582 } else if (r.state == ActivityState.STOPPING) { 12583 // We will apply the actual adjustment later, because 12584 // we want to allow this process to immediately go through 12585 // any memory trimming that is in effect. 12586 app.hidden = false; 12587 foregroundActivities = true; 12588 hasStoppingActivities = true; 12589 } 12590 if (r.app == app) { 12591 app.hasActivities = true; 12592 } 12593 } 12594 } 12595 12596 if (adj == hiddenAdj && !app.hasActivities) { 12597 // Whoops, this process is completely empty as far as we know 12598 // at this point. 12599 adj = emptyAdj; 12600 app.empty = true; 12601 app.adjType = "bg-empty"; 12602 } 12603 12604 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12605 if (app.foregroundServices) { 12606 // The user is aware of this app, so make it visible. 12607 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12608 app.hidden = false; 12609 app.adjType = "foreground-service"; 12610 schedGroup = Process.THREAD_GROUP_DEFAULT; 12611 } else if (app.forcingToForeground != null) { 12612 // The user is aware of this app, so make it visible. 12613 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12614 app.hidden = false; 12615 app.adjType = "force-foreground"; 12616 app.adjSource = app.forcingToForeground; 12617 schedGroup = Process.THREAD_GROUP_DEFAULT; 12618 } 12619 } 12620 12621 if (app.foregroundServices) { 12622 interesting = true; 12623 } 12624 12625 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12626 // We don't want to kill the current heavy-weight process. 12627 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12628 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12629 app.hidden = false; 12630 app.adjType = "heavy"; 12631 } 12632 12633 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12634 // This process is hosting what we currently consider to be the 12635 // home app, so we don't want to let it go into the background. 12636 adj = ProcessList.HOME_APP_ADJ; 12637 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12638 app.hidden = false; 12639 app.adjType = "home"; 12640 } 12641 12642 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12643 && app.activities.size() > 0) { 12644 // This was the previous process that showed UI to the user. 12645 // We want to try to keep it around more aggressively, to give 12646 // a good experience around switching between two apps. 12647 adj = ProcessList.PREVIOUS_APP_ADJ; 12648 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12649 app.hidden = false; 12650 app.adjType = "previous"; 12651 } 12652 12653 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12654 + " reason=" + app.adjType); 12655 12656 // By default, we use the computed adjustment. It may be changed if 12657 // there are applications dependent on our services or providers, but 12658 // this gives us a baseline and makes sure we don't get into an 12659 // infinite recursion. 12660 app.adjSeq = mAdjSeq; 12661 app.curRawAdj = app.nonStoppingAdj = adj; 12662 12663 if (mBackupTarget != null && app == mBackupTarget.app) { 12664 // If possible we want to avoid killing apps while they're being backed up 12665 if (adj > ProcessList.BACKUP_APP_ADJ) { 12666 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12667 adj = ProcessList.BACKUP_APP_ADJ; 12668 app.adjType = "backup"; 12669 app.hidden = false; 12670 } 12671 } 12672 12673 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12674 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12675 final long now = SystemClock.uptimeMillis(); 12676 // This process is more important if the top activity is 12677 // bound to the service. 12678 Iterator<ServiceRecord> jt = app.services.iterator(); 12679 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12680 ServiceRecord s = jt.next(); 12681 if (s.startRequested) { 12682 if (app.hasShownUi && app != mHomeProcess) { 12683 // If this process has shown some UI, let it immediately 12684 // go to the LRU list because it may be pretty heavy with 12685 // UI stuff. We'll tag it with a label just to help 12686 // debug and understand what is going on. 12687 if (adj > ProcessList.SERVICE_ADJ) { 12688 app.adjType = "started-bg-ui-services"; 12689 } 12690 } else { 12691 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12692 // This service has seen some activity within 12693 // recent memory, so we will keep its process ahead 12694 // of the background processes. 12695 if (adj > ProcessList.SERVICE_ADJ) { 12696 adj = ProcessList.SERVICE_ADJ; 12697 app.adjType = "started-services"; 12698 app.hidden = false; 12699 } 12700 } 12701 // If we have let the service slide into the background 12702 // state, still have some text describing what it is doing 12703 // even though the service no longer has an impact. 12704 if (adj > ProcessList.SERVICE_ADJ) { 12705 app.adjType = "started-bg-services"; 12706 } 12707 } 12708 // Don't kill this process because it is doing work; it 12709 // has said it is doing work. 12710 app.keeping = true; 12711 } 12712 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12713 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12714 Iterator<ArrayList<ConnectionRecord>> kt 12715 = s.connections.values().iterator(); 12716 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12717 ArrayList<ConnectionRecord> clist = kt.next(); 12718 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12719 // XXX should compute this based on the max of 12720 // all connected clients. 12721 ConnectionRecord cr = clist.get(i); 12722 if (cr.binding.client == app) { 12723 // Binding to ourself is not interesting. 12724 continue; 12725 } 12726 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12727 ProcessRecord client = cr.binding.client; 12728 int clientAdj = adj; 12729 int myHiddenAdj = hiddenAdj; 12730 if (myHiddenAdj > client.hiddenAdj) { 12731 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12732 myHiddenAdj = client.hiddenAdj; 12733 } else { 12734 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12735 } 12736 } 12737 int myEmptyAdj = emptyAdj; 12738 if (myEmptyAdj > client.emptyAdj) { 12739 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12740 myEmptyAdj = client.emptyAdj; 12741 } else { 12742 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12743 } 12744 } 12745 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12746 myEmptyAdj, TOP_APP, true, doingAll); 12747 String adjType = null; 12748 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12749 // Not doing bind OOM management, so treat 12750 // this guy more like a started service. 12751 if (app.hasShownUi && app != mHomeProcess) { 12752 // If this process has shown some UI, let it immediately 12753 // go to the LRU list because it may be pretty heavy with 12754 // UI stuff. We'll tag it with a label just to help 12755 // debug and understand what is going on. 12756 if (adj > clientAdj) { 12757 adjType = "bound-bg-ui-services"; 12758 } 12759 app.hidden = false; 12760 clientAdj = adj; 12761 } else { 12762 if (now >= (s.lastActivity 12763 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12764 // This service has not seen activity within 12765 // recent memory, so allow it to drop to the 12766 // LRU list if there is no other reason to keep 12767 // it around. We'll also tag it with a label just 12768 // to help debug and undertand what is going on. 12769 if (adj > clientAdj) { 12770 adjType = "bound-bg-services"; 12771 } 12772 clientAdj = adj; 12773 } 12774 } 12775 } 12776 if (adj > clientAdj) { 12777 // If this process has recently shown UI, and 12778 // the process that is binding to it is less 12779 // important than being visible, then we don't 12780 // care about the binding as much as we care 12781 // about letting this process get into the LRU 12782 // list to be killed and restarted if needed for 12783 // memory. 12784 if (app.hasShownUi && app != mHomeProcess 12785 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12786 adjType = "bound-bg-ui-services"; 12787 } else { 12788 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12789 |Context.BIND_IMPORTANT)) != 0) { 12790 adj = clientAdj; 12791 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12792 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12793 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12794 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12795 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12796 adj = clientAdj; 12797 } else { 12798 app.pendingUiClean = true; 12799 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12800 adj = ProcessList.VISIBLE_APP_ADJ; 12801 } 12802 } 12803 if (!client.hidden) { 12804 app.hidden = false; 12805 } 12806 if (client.keeping) { 12807 app.keeping = true; 12808 } 12809 adjType = "service"; 12810 } 12811 } 12812 if (adjType != null) { 12813 app.adjType = adjType; 12814 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12815 .REASON_SERVICE_IN_USE; 12816 app.adjSource = cr.binding.client; 12817 app.adjSourceOom = clientAdj; 12818 app.adjTarget = s.name; 12819 } 12820 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12821 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12822 schedGroup = Process.THREAD_GROUP_DEFAULT; 12823 } 12824 } 12825 } 12826 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12827 ActivityRecord a = cr.activity; 12828 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12829 (a.visible || a.state == ActivityState.RESUMED 12830 || a.state == ActivityState.PAUSING)) { 12831 adj = ProcessList.FOREGROUND_APP_ADJ; 12832 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12833 schedGroup = Process.THREAD_GROUP_DEFAULT; 12834 } 12835 app.hidden = false; 12836 app.adjType = "service"; 12837 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12838 .REASON_SERVICE_IN_USE; 12839 app.adjSource = a; 12840 app.adjSourceOom = adj; 12841 app.adjTarget = s.name; 12842 } 12843 } 12844 } 12845 } 12846 } 12847 } 12848 12849 // Finally, if this process has active services running in it, we 12850 // would like to avoid killing it unless it would prevent the current 12851 // application from running. By default we put the process in 12852 // with the rest of the background processes; as we scan through 12853 // its services we may bump it up from there. 12854 if (adj > hiddenAdj) { 12855 adj = hiddenAdj; 12856 app.hidden = false; 12857 app.adjType = "bg-services"; 12858 } 12859 } 12860 12861 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12862 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12863 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12864 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12865 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12866 ContentProviderRecord cpr = jt.next(); 12867 for (int i = cpr.connections.size()-1; 12868 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12869 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12870 i--) { 12871 ContentProviderConnection conn = cpr.connections.get(i); 12872 ProcessRecord client = conn.client; 12873 if (client == app) { 12874 // Being our own client is not interesting. 12875 continue; 12876 } 12877 int myHiddenAdj = hiddenAdj; 12878 if (myHiddenAdj > client.hiddenAdj) { 12879 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12880 myHiddenAdj = client.hiddenAdj; 12881 } else { 12882 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12883 } 12884 } 12885 int myEmptyAdj = emptyAdj; 12886 if (myEmptyAdj > client.emptyAdj) { 12887 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12888 myEmptyAdj = client.emptyAdj; 12889 } else { 12890 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12891 } 12892 } 12893 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12894 myEmptyAdj, TOP_APP, true, doingAll); 12895 if (adj > clientAdj) { 12896 if (app.hasShownUi && app != mHomeProcess 12897 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12898 app.adjType = "bg-ui-provider"; 12899 } else { 12900 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12901 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12902 app.adjType = "provider"; 12903 } 12904 if (!client.hidden) { 12905 app.hidden = false; 12906 } 12907 if (client.keeping) { 12908 app.keeping = true; 12909 } 12910 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12911 .REASON_PROVIDER_IN_USE; 12912 app.adjSource = client; 12913 app.adjSourceOom = clientAdj; 12914 app.adjTarget = cpr.name; 12915 } 12916 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12917 schedGroup = Process.THREAD_GROUP_DEFAULT; 12918 } 12919 } 12920 // If the provider has external (non-framework) process 12921 // dependencies, ensure that its adjustment is at least 12922 // FOREGROUND_APP_ADJ. 12923 if (cpr.hasExternalProcessHandles()) { 12924 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12925 adj = ProcessList.FOREGROUND_APP_ADJ; 12926 schedGroup = Process.THREAD_GROUP_DEFAULT; 12927 app.hidden = false; 12928 app.keeping = true; 12929 app.adjType = "provider"; 12930 app.adjTarget = cpr.name; 12931 } 12932 } 12933 } 12934 } 12935 12936 if (adj == ProcessList.SERVICE_ADJ) { 12937 if (doingAll) { 12938 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12939 mNewNumServiceProcs++; 12940 } 12941 if (app.serviceb) { 12942 adj = ProcessList.SERVICE_B_ADJ; 12943 } 12944 } else { 12945 app.serviceb = false; 12946 } 12947 12948 app.nonStoppingAdj = adj; 12949 12950 if (hasStoppingActivities) { 12951 // Only upgrade adjustment. 12952 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12953 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12954 app.adjType = "stopping"; 12955 } 12956 } 12957 12958 app.curRawAdj = adj; 12959 12960 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12961 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12962 if (adj > app.maxAdj) { 12963 adj = app.maxAdj; 12964 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12965 schedGroup = Process.THREAD_GROUP_DEFAULT; 12966 } 12967 } 12968 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12969 app.keeping = true; 12970 } 12971 12972 if (app.hasAboveClient) { 12973 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12974 // then we need to drop its adjustment to be lower than the service's 12975 // in order to honor the request. We want to drop it by one adjustment 12976 // level... but there is special meaning applied to various levels so 12977 // we will skip some of them. 12978 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12979 // System process will not get dropped, ever 12980 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12981 adj = ProcessList.VISIBLE_APP_ADJ; 12982 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12983 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12984 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12985 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12986 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12987 adj++; 12988 } 12989 } 12990 12991 int importance = app.memImportance; 12992 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 12993 app.curAdj = adj; 12994 app.curSchedGroup = schedGroup; 12995 if (!interesting) { 12996 // For this reporting, if there is not something explicitly 12997 // interesting in this process then we will push it to the 12998 // background importance. 12999 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13000 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13001 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13002 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13003 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13004 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13005 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13006 } else if (adj >= ProcessList.SERVICE_ADJ) { 13007 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13008 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13009 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13010 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13011 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13012 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13013 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13014 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13015 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13016 } else { 13017 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13018 } 13019 } 13020 13021 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13022 if (foregroundActivities != app.foregroundActivities) { 13023 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13024 } 13025 if (changes != 0) { 13026 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13027 app.memImportance = importance; 13028 app.foregroundActivities = foregroundActivities; 13029 int i = mPendingProcessChanges.size()-1; 13030 ProcessChangeItem item = null; 13031 while (i >= 0) { 13032 item = mPendingProcessChanges.get(i); 13033 if (item.pid == app.pid) { 13034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13035 break; 13036 } 13037 i--; 13038 } 13039 if (i < 0) { 13040 // No existing item in pending changes; need a new one. 13041 final int NA = mAvailProcessChanges.size(); 13042 if (NA > 0) { 13043 item = mAvailProcessChanges.remove(NA-1); 13044 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13045 } else { 13046 item = new ProcessChangeItem(); 13047 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13048 } 13049 item.changes = 0; 13050 item.pid = app.pid; 13051 item.uid = app.info.uid; 13052 if (mPendingProcessChanges.size() == 0) { 13053 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13054 "*** Enqueueing dispatch processes changed!"); 13055 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13056 } 13057 mPendingProcessChanges.add(item); 13058 } 13059 item.changes |= changes; 13060 item.importance = importance; 13061 item.foregroundActivities = foregroundActivities; 13062 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13063 + Integer.toHexString(System.identityHashCode(item)) 13064 + " " + app.toShortString() + ": changes=" + item.changes 13065 + " importance=" + item.importance 13066 + " foreground=" + item.foregroundActivities 13067 + " type=" + app.adjType + " source=" + app.adjSource 13068 + " target=" + app.adjTarget); 13069 } 13070 13071 return app.curRawAdj; 13072 } 13073 13074 /** 13075 * Ask a given process to GC right now. 13076 */ 13077 final void performAppGcLocked(ProcessRecord app) { 13078 try { 13079 app.lastRequestedGc = SystemClock.uptimeMillis(); 13080 if (app.thread != null) { 13081 if (app.reportLowMemory) { 13082 app.reportLowMemory = false; 13083 app.thread.scheduleLowMemory(); 13084 } else { 13085 app.thread.processInBackground(); 13086 } 13087 } 13088 } catch (Exception e) { 13089 // whatever. 13090 } 13091 } 13092 13093 /** 13094 * Returns true if things are idle enough to perform GCs. 13095 */ 13096 private final boolean canGcNowLocked() { 13097 boolean processingBroadcasts = false; 13098 for (BroadcastQueue q : mBroadcastQueues) { 13099 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13100 processingBroadcasts = true; 13101 } 13102 } 13103 return !processingBroadcasts 13104 && (mSleeping || (mMainStack.mResumedActivity != null && 13105 mMainStack.mResumedActivity.idle)); 13106 } 13107 13108 /** 13109 * Perform GCs on all processes that are waiting for it, but only 13110 * if things are idle. 13111 */ 13112 final void performAppGcsLocked() { 13113 final int N = mProcessesToGc.size(); 13114 if (N <= 0) { 13115 return; 13116 } 13117 if (canGcNowLocked()) { 13118 while (mProcessesToGc.size() > 0) { 13119 ProcessRecord proc = mProcessesToGc.remove(0); 13120 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13121 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13122 <= SystemClock.uptimeMillis()) { 13123 // To avoid spamming the system, we will GC processes one 13124 // at a time, waiting a few seconds between each. 13125 performAppGcLocked(proc); 13126 scheduleAppGcsLocked(); 13127 return; 13128 } else { 13129 // It hasn't been long enough since we last GCed this 13130 // process... put it in the list to wait for its time. 13131 addProcessToGcListLocked(proc); 13132 break; 13133 } 13134 } 13135 } 13136 13137 scheduleAppGcsLocked(); 13138 } 13139 } 13140 13141 /** 13142 * If all looks good, perform GCs on all processes waiting for them. 13143 */ 13144 final void performAppGcsIfAppropriateLocked() { 13145 if (canGcNowLocked()) { 13146 performAppGcsLocked(); 13147 return; 13148 } 13149 // Still not idle, wait some more. 13150 scheduleAppGcsLocked(); 13151 } 13152 13153 /** 13154 * Schedule the execution of all pending app GCs. 13155 */ 13156 final void scheduleAppGcsLocked() { 13157 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13158 13159 if (mProcessesToGc.size() > 0) { 13160 // Schedule a GC for the time to the next process. 13161 ProcessRecord proc = mProcessesToGc.get(0); 13162 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13163 13164 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13165 long now = SystemClock.uptimeMillis(); 13166 if (when < (now+GC_TIMEOUT)) { 13167 when = now + GC_TIMEOUT; 13168 } 13169 mHandler.sendMessageAtTime(msg, when); 13170 } 13171 } 13172 13173 /** 13174 * Add a process to the array of processes waiting to be GCed. Keeps the 13175 * list in sorted order by the last GC time. The process can't already be 13176 * on the list. 13177 */ 13178 final void addProcessToGcListLocked(ProcessRecord proc) { 13179 boolean added = false; 13180 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13181 if (mProcessesToGc.get(i).lastRequestedGc < 13182 proc.lastRequestedGc) { 13183 added = true; 13184 mProcessesToGc.add(i+1, proc); 13185 break; 13186 } 13187 } 13188 if (!added) { 13189 mProcessesToGc.add(0, proc); 13190 } 13191 } 13192 13193 /** 13194 * Set up to ask a process to GC itself. This will either do it 13195 * immediately, or put it on the list of processes to gc the next 13196 * time things are idle. 13197 */ 13198 final void scheduleAppGcLocked(ProcessRecord app) { 13199 long now = SystemClock.uptimeMillis(); 13200 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13201 return; 13202 } 13203 if (!mProcessesToGc.contains(app)) { 13204 addProcessToGcListLocked(app); 13205 scheduleAppGcsLocked(); 13206 } 13207 } 13208 13209 final void checkExcessivePowerUsageLocked(boolean doKills) { 13210 updateCpuStatsNow(); 13211 13212 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13213 boolean doWakeKills = doKills; 13214 boolean doCpuKills = doKills; 13215 if (mLastPowerCheckRealtime == 0) { 13216 doWakeKills = false; 13217 } 13218 if (mLastPowerCheckUptime == 0) { 13219 doCpuKills = false; 13220 } 13221 if (stats.isScreenOn()) { 13222 doWakeKills = false; 13223 } 13224 final long curRealtime = SystemClock.elapsedRealtime(); 13225 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13226 final long curUptime = SystemClock.uptimeMillis(); 13227 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13228 mLastPowerCheckRealtime = curRealtime; 13229 mLastPowerCheckUptime = curUptime; 13230 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13231 doWakeKills = false; 13232 } 13233 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13234 doCpuKills = false; 13235 } 13236 int i = mLruProcesses.size(); 13237 while (i > 0) { 13238 i--; 13239 ProcessRecord app = mLruProcesses.get(i); 13240 if (!app.keeping) { 13241 long wtime; 13242 synchronized (stats) { 13243 wtime = stats.getProcessWakeTime(app.info.uid, 13244 app.pid, curRealtime); 13245 } 13246 long wtimeUsed = wtime - app.lastWakeTime; 13247 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13248 if (DEBUG_POWER) { 13249 StringBuilder sb = new StringBuilder(128); 13250 sb.append("Wake for "); 13251 app.toShortString(sb); 13252 sb.append(": over "); 13253 TimeUtils.formatDuration(realtimeSince, sb); 13254 sb.append(" used "); 13255 TimeUtils.formatDuration(wtimeUsed, sb); 13256 sb.append(" ("); 13257 sb.append((wtimeUsed*100)/realtimeSince); 13258 sb.append("%)"); 13259 Slog.i(TAG, sb.toString()); 13260 sb.setLength(0); 13261 sb.append("CPU for "); 13262 app.toShortString(sb); 13263 sb.append(": over "); 13264 TimeUtils.formatDuration(uptimeSince, sb); 13265 sb.append(" used "); 13266 TimeUtils.formatDuration(cputimeUsed, sb); 13267 sb.append(" ("); 13268 sb.append((cputimeUsed*100)/uptimeSince); 13269 sb.append("%)"); 13270 Slog.i(TAG, sb.toString()); 13271 } 13272 // If a process has held a wake lock for more 13273 // than 50% of the time during this period, 13274 // that sounds bad. Kill! 13275 if (doWakeKills && realtimeSince > 0 13276 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13277 synchronized (stats) { 13278 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13279 realtimeSince, wtimeUsed); 13280 } 13281 Slog.w(TAG, "Excessive wake lock in " + app.processName 13282 + " (pid " + app.pid + "): held " + wtimeUsed 13283 + " during " + realtimeSince); 13284 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13285 app.processName, app.setAdj, "excessive wake lock"); 13286 Process.killProcessQuiet(app.pid); 13287 } else if (doCpuKills && uptimeSince > 0 13288 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13289 synchronized (stats) { 13290 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13291 uptimeSince, cputimeUsed); 13292 } 13293 Slog.w(TAG, "Excessive CPU in " + app.processName 13294 + " (pid " + app.pid + "): used " + cputimeUsed 13295 + " during " + uptimeSince); 13296 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13297 app.processName, app.setAdj, "excessive cpu"); 13298 Process.killProcessQuiet(app.pid); 13299 } else { 13300 app.lastWakeTime = wtime; 13301 app.lastCpuTime = app.curCpuTime; 13302 } 13303 } 13304 } 13305 } 13306 13307 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13308 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13309 app.hiddenAdj = hiddenAdj; 13310 app.emptyAdj = emptyAdj; 13311 13312 if (app.thread == null) { 13313 return false; 13314 } 13315 13316 final boolean wasKeeping = app.keeping; 13317 13318 boolean success = true; 13319 13320 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13321 13322 if (app.curRawAdj != app.setRawAdj) { 13323 if (wasKeeping && !app.keeping) { 13324 // This app is no longer something we want to keep. Note 13325 // its current wake lock time to later know to kill it if 13326 // it is not behaving well. 13327 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13328 synchronized (stats) { 13329 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13330 app.pid, SystemClock.elapsedRealtime()); 13331 } 13332 app.lastCpuTime = app.curCpuTime; 13333 } 13334 13335 app.setRawAdj = app.curRawAdj; 13336 } 13337 13338 if (app.curAdj != app.setAdj) { 13339 if (Process.setOomAdj(app.pid, app.curAdj)) { 13340 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13341 TAG, "Set " + app.pid + " " + app.processName + 13342 " adj " + app.curAdj + ": " + app.adjType); 13343 app.setAdj = app.curAdj; 13344 } else { 13345 success = false; 13346 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13347 } 13348 } 13349 if (app.setSchedGroup != app.curSchedGroup) { 13350 app.setSchedGroup = app.curSchedGroup; 13351 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13352 "Setting process group of " + app.processName 13353 + " to " + app.curSchedGroup); 13354 if (app.waitingToKill != null && 13355 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13356 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13357 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13358 app.processName, app.setAdj, app.waitingToKill); 13359 app.killedBackground = true; 13360 Process.killProcessQuiet(app.pid); 13361 success = false; 13362 } else { 13363 if (true) { 13364 long oldId = Binder.clearCallingIdentity(); 13365 try { 13366 Process.setProcessGroup(app.pid, app.curSchedGroup); 13367 } catch (Exception e) { 13368 Slog.w(TAG, "Failed setting process group of " + app.pid 13369 + " to " + app.curSchedGroup); 13370 e.printStackTrace(); 13371 } finally { 13372 Binder.restoreCallingIdentity(oldId); 13373 } 13374 } else { 13375 if (app.thread != null) { 13376 try { 13377 app.thread.setSchedulingGroup(app.curSchedGroup); 13378 } catch (RemoteException e) { 13379 } 13380 } 13381 } 13382 } 13383 } 13384 return success; 13385 } 13386 13387 private final ActivityRecord resumedAppLocked() { 13388 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13389 if (resumedActivity == null || resumedActivity.app == null) { 13390 resumedActivity = mMainStack.mPausingActivity; 13391 if (resumedActivity == null || resumedActivity.app == null) { 13392 resumedActivity = mMainStack.topRunningActivityLocked(null); 13393 } 13394 } 13395 return resumedActivity; 13396 } 13397 13398 final boolean updateOomAdjLocked(ProcessRecord app) { 13399 final ActivityRecord TOP_ACT = resumedAppLocked(); 13400 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13401 int curAdj = app.curAdj; 13402 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13403 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13404 13405 mAdjSeq++; 13406 13407 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13408 TOP_APP, false); 13409 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13410 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13411 if (nowHidden != wasHidden) { 13412 // Changed to/from hidden state, so apps after it in the LRU 13413 // list may also be changed. 13414 updateOomAdjLocked(); 13415 } 13416 return success; 13417 } 13418 13419 final void updateOomAdjLocked() { 13420 final ActivityRecord TOP_ACT = resumedAppLocked(); 13421 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13422 13423 if (false) { 13424 RuntimeException e = new RuntimeException(); 13425 e.fillInStackTrace(); 13426 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13427 } 13428 13429 mAdjSeq++; 13430 mNewNumServiceProcs = 0; 13431 13432 // Let's determine how many processes we have running vs. 13433 // how many slots we have for background processes; we may want 13434 // to put multiple processes in a slot of there are enough of 13435 // them. 13436 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13437 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13438 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13439 if (emptyFactor < 1) emptyFactor = 1; 13440 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13441 if (hiddenFactor < 1) hiddenFactor = 1; 13442 int stepHidden = 0; 13443 int stepEmpty = 0; 13444 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13445 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13446 int numHidden = 0; 13447 int numEmpty = 0; 13448 int numTrimming = 0; 13449 13450 mNumNonHiddenProcs = 0; 13451 mNumHiddenProcs = 0; 13452 13453 // First update the OOM adjustment for each of the 13454 // application processes based on their current state. 13455 int i = mLruProcesses.size(); 13456 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13457 int nextHiddenAdj = curHiddenAdj+1; 13458 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13459 int nextEmptyAdj = curEmptyAdj+2; 13460 while (i > 0) { 13461 i--; 13462 ProcessRecord app = mLruProcesses.get(i); 13463 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13464 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13465 if (!app.killedBackground) { 13466 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13467 // This process was assigned as a hidden process... step the 13468 // hidden level. 13469 mNumHiddenProcs++; 13470 if (curHiddenAdj != nextHiddenAdj) { 13471 stepHidden++; 13472 if (stepHidden >= hiddenFactor) { 13473 stepHidden = 0; 13474 curHiddenAdj = nextHiddenAdj; 13475 nextHiddenAdj += 2; 13476 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13477 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13478 } 13479 } 13480 } 13481 numHidden++; 13482 if (numHidden > hiddenProcessLimit) { 13483 Slog.i(TAG, "No longer want " + app.processName 13484 + " (pid " + app.pid + "): hidden #" + numHidden); 13485 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13486 app.processName, app.setAdj, "too many background"); 13487 app.killedBackground = true; 13488 Process.killProcessQuiet(app.pid); 13489 } 13490 } else { 13491 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13492 // This process was assigned as an empty process... step the 13493 // empty level. 13494 if (curEmptyAdj != nextEmptyAdj) { 13495 stepEmpty++; 13496 if (stepEmpty >= emptyFactor) { 13497 stepEmpty = 0; 13498 curEmptyAdj = nextEmptyAdj; 13499 nextEmptyAdj += 2; 13500 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13501 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13502 } 13503 } 13504 } 13505 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13506 mNumNonHiddenProcs++; 13507 } 13508 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13509 numEmpty++; 13510 if (numEmpty > emptyProcessLimit) { 13511 Slog.i(TAG, "No longer want " + app.processName 13512 + " (pid " + app.pid + "): empty #" + numEmpty); 13513 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13514 app.processName, app.setAdj, "too many background"); 13515 app.killedBackground = true; 13516 Process.killProcessQuiet(app.pid); 13517 } 13518 } 13519 } 13520 if (app.isolated && app.services.size() <= 0) { 13521 // If this is an isolated process, and there are no 13522 // services running in it, then the process is no longer 13523 // needed. We agressively kill these because we can by 13524 // definition not re-use the same process again, and it is 13525 // good to avoid having whatever code was running in them 13526 // left sitting around after no longer needed. 13527 Slog.i(TAG, "Isolated process " + app.processName 13528 + " (pid " + app.pid + ") no longer needed"); 13529 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13530 app.processName, app.setAdj, "isolated not needed"); 13531 app.killedBackground = true; 13532 Process.killProcessQuiet(app.pid); 13533 } 13534 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13535 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13536 && !app.killedBackground) { 13537 numTrimming++; 13538 } 13539 } 13540 } 13541 13542 mNumServiceProcs = mNewNumServiceProcs; 13543 13544 // Now determine the memory trimming level of background processes. 13545 // Unfortunately we need to start at the back of the list to do this 13546 // properly. We only do this if the number of background apps we 13547 // are managing to keep around is less than half the maximum we desire; 13548 // if we are keeping a good number around, we'll let them use whatever 13549 // memory they want. 13550 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13551 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13552 final int numHiddenAndEmpty = numHidden + numEmpty; 13553 final int N = mLruProcesses.size(); 13554 int factor = numTrimming/3; 13555 int minFactor = 2; 13556 if (mHomeProcess != null) minFactor++; 13557 if (mPreviousProcess != null) minFactor++; 13558 if (factor < minFactor) factor = minFactor; 13559 int step = 0; 13560 int fgTrimLevel; 13561 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13562 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13563 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13564 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13565 } else { 13566 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13567 } 13568 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13569 for (i=0; i<N; i++) { 13570 ProcessRecord app = mLruProcesses.get(i); 13571 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13572 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13573 && !app.killedBackground) { 13574 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13575 try { 13576 app.thread.scheduleTrimMemory(curLevel); 13577 } catch (RemoteException e) { 13578 } 13579 if (false) { 13580 // For now we won't do this; our memory trimming seems 13581 // to be good enough at this point that destroying 13582 // activities causes more harm than good. 13583 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13584 && app != mHomeProcess && app != mPreviousProcess) { 13585 // Need to do this on its own message because the stack may not 13586 // be in a consistent state at this point. 13587 // For these apps we will also finish their activities 13588 // to help them free memory. 13589 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13590 } 13591 } 13592 } 13593 app.trimMemoryLevel = curLevel; 13594 step++; 13595 if (step >= factor) { 13596 step = 0; 13597 switch (curLevel) { 13598 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13599 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13600 break; 13601 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13602 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13603 break; 13604 } 13605 } 13606 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13607 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13608 && app.thread != null) { 13609 try { 13610 app.thread.scheduleTrimMemory( 13611 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13612 } catch (RemoteException e) { 13613 } 13614 } 13615 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13616 } else { 13617 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13618 && app.pendingUiClean) { 13619 // If this application is now in the background and it 13620 // had done UI, then give it the special trim level to 13621 // have it free UI resources. 13622 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13623 if (app.trimMemoryLevel < level && app.thread != null) { 13624 try { 13625 app.thread.scheduleTrimMemory(level); 13626 } catch (RemoteException e) { 13627 } 13628 } 13629 app.pendingUiClean = false; 13630 } 13631 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13632 try { 13633 app.thread.scheduleTrimMemory(fgTrimLevel); 13634 } catch (RemoteException e) { 13635 } 13636 } 13637 app.trimMemoryLevel = fgTrimLevel; 13638 } 13639 } 13640 } else { 13641 final int N = mLruProcesses.size(); 13642 for (i=0; i<N; i++) { 13643 ProcessRecord app = mLruProcesses.get(i); 13644 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13645 && app.pendingUiClean) { 13646 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13647 && app.thread != null) { 13648 try { 13649 app.thread.scheduleTrimMemory( 13650 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13651 } catch (RemoteException e) { 13652 } 13653 } 13654 app.pendingUiClean = false; 13655 } 13656 app.trimMemoryLevel = 0; 13657 } 13658 } 13659 13660 if (mAlwaysFinishActivities) { 13661 // Need to do this on its own message because the stack may not 13662 // be in a consistent state at this point. 13663 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13664 } 13665 } 13666 13667 final void trimApplications() { 13668 synchronized (this) { 13669 int i; 13670 13671 // First remove any unused application processes whose package 13672 // has been removed. 13673 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13674 final ProcessRecord app = mRemovedProcesses.get(i); 13675 if (app.activities.size() == 0 13676 && app.curReceiver == null && app.services.size() == 0) { 13677 Slog.i( 13678 TAG, "Exiting empty application process " 13679 + app.processName + " (" 13680 + (app.thread != null ? app.thread.asBinder() : null) 13681 + ")\n"); 13682 if (app.pid > 0 && app.pid != MY_PID) { 13683 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13684 app.processName, app.setAdj, "empty"); 13685 Process.killProcessQuiet(app.pid); 13686 } else { 13687 try { 13688 app.thread.scheduleExit(); 13689 } catch (Exception e) { 13690 // Ignore exceptions. 13691 } 13692 } 13693 cleanUpApplicationRecordLocked(app, false, true, -1); 13694 mRemovedProcesses.remove(i); 13695 13696 if (app.persistent) { 13697 if (app.persistent) { 13698 addAppLocked(app.info, false); 13699 } 13700 } 13701 } 13702 } 13703 13704 // Now update the oom adj for all processes. 13705 updateOomAdjLocked(); 13706 } 13707 } 13708 13709 /** This method sends the specified signal to each of the persistent apps */ 13710 public void signalPersistentProcesses(int sig) throws RemoteException { 13711 if (sig != Process.SIGNAL_USR1) { 13712 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13713 } 13714 13715 synchronized (this) { 13716 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13717 != PackageManager.PERMISSION_GRANTED) { 13718 throw new SecurityException("Requires permission " 13719 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13720 } 13721 13722 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13723 ProcessRecord r = mLruProcesses.get(i); 13724 if (r.thread != null && r.persistent) { 13725 Process.sendSignal(r.pid, sig); 13726 } 13727 } 13728 } 13729 } 13730 13731 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13732 if (proc == null || proc == mProfileProc) { 13733 proc = mProfileProc; 13734 path = mProfileFile; 13735 profileType = mProfileType; 13736 clearProfilerLocked(); 13737 } 13738 if (proc == null) { 13739 return; 13740 } 13741 try { 13742 proc.thread.profilerControl(false, path, null, profileType); 13743 } catch (RemoteException e) { 13744 throw new IllegalStateException("Process disappeared"); 13745 } 13746 } 13747 13748 private void clearProfilerLocked() { 13749 if (mProfileFd != null) { 13750 try { 13751 mProfileFd.close(); 13752 } catch (IOException e) { 13753 } 13754 } 13755 mProfileApp = null; 13756 mProfileProc = null; 13757 mProfileFile = null; 13758 mProfileType = 0; 13759 mAutoStopProfiler = false; 13760 } 13761 13762 public boolean profileControl(String process, int userId, boolean start, 13763 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13764 13765 try { 13766 synchronized (this) { 13767 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13768 // its own permission. 13769 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13770 != PackageManager.PERMISSION_GRANTED) { 13771 throw new SecurityException("Requires permission " 13772 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13773 } 13774 13775 if (start && fd == null) { 13776 throw new IllegalArgumentException("null fd"); 13777 } 13778 13779 ProcessRecord proc = null; 13780 if (process != null) { 13781 proc = findProcessLocked(process, userId, "profileControl"); 13782 } 13783 13784 if (start && (proc == null || proc.thread == null)) { 13785 throw new IllegalArgumentException("Unknown process: " + process); 13786 } 13787 13788 if (start) { 13789 stopProfilerLocked(null, null, 0); 13790 setProfileApp(proc.info, proc.processName, path, fd, false); 13791 mProfileProc = proc; 13792 mProfileType = profileType; 13793 try { 13794 fd = fd.dup(); 13795 } catch (IOException e) { 13796 fd = null; 13797 } 13798 proc.thread.profilerControl(start, path, fd, profileType); 13799 fd = null; 13800 mProfileFd = null; 13801 } else { 13802 stopProfilerLocked(proc, path, profileType); 13803 if (fd != null) { 13804 try { 13805 fd.close(); 13806 } catch (IOException e) { 13807 } 13808 } 13809 } 13810 13811 return true; 13812 } 13813 } catch (RemoteException e) { 13814 throw new IllegalStateException("Process disappeared"); 13815 } finally { 13816 if (fd != null) { 13817 try { 13818 fd.close(); 13819 } catch (IOException e) { 13820 } 13821 } 13822 } 13823 } 13824 13825 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13826 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 13827 userId, true, true, callName, null); 13828 ProcessRecord proc = null; 13829 try { 13830 int pid = Integer.parseInt(process); 13831 synchronized (mPidsSelfLocked) { 13832 proc = mPidsSelfLocked.get(pid); 13833 } 13834 } catch (NumberFormatException e) { 13835 } 13836 13837 if (proc == null) { 13838 HashMap<String, SparseArray<ProcessRecord>> all 13839 = mProcessNames.getMap(); 13840 SparseArray<ProcessRecord> procs = all.get(process); 13841 if (procs != null && procs.size() > 0) { 13842 proc = procs.valueAt(0); 13843 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13844 for (int i=1; i<procs.size(); i++) { 13845 ProcessRecord thisProc = procs.valueAt(i); 13846 if (thisProc.userId == userId) { 13847 proc = thisProc; 13848 break; 13849 } 13850 } 13851 } 13852 } 13853 } 13854 13855 return proc; 13856 } 13857 13858 public boolean dumpHeap(String process, int userId, boolean managed, 13859 String path, ParcelFileDescriptor fd) throws RemoteException { 13860 13861 try { 13862 synchronized (this) { 13863 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13864 // its own permission (same as profileControl). 13865 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13866 != PackageManager.PERMISSION_GRANTED) { 13867 throw new SecurityException("Requires permission " 13868 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13869 } 13870 13871 if (fd == null) { 13872 throw new IllegalArgumentException("null fd"); 13873 } 13874 13875 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13876 if (proc == null || proc.thread == null) { 13877 throw new IllegalArgumentException("Unknown process: " + process); 13878 } 13879 13880 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13881 if (!isDebuggable) { 13882 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13883 throw new SecurityException("Process not debuggable: " + proc); 13884 } 13885 } 13886 13887 proc.thread.dumpHeap(managed, path, fd); 13888 fd = null; 13889 return true; 13890 } 13891 } catch (RemoteException e) { 13892 throw new IllegalStateException("Process disappeared"); 13893 } finally { 13894 if (fd != null) { 13895 try { 13896 fd.close(); 13897 } catch (IOException e) { 13898 } 13899 } 13900 } 13901 } 13902 13903 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13904 public void monitor() { 13905 synchronized (this) { } 13906 } 13907 13908 void onCoreSettingsChange(Bundle settings) { 13909 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13910 ProcessRecord processRecord = mLruProcesses.get(i); 13911 try { 13912 if (processRecord.thread != null) { 13913 processRecord.thread.setCoreSettings(settings); 13914 } 13915 } catch (RemoteException re) { 13916 /* ignore */ 13917 } 13918 } 13919 } 13920 13921 // Multi-user methods 13922 13923 @Override 13924 public boolean switchUser(int userId) { 13925 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13926 != PackageManager.PERMISSION_GRANTED) { 13927 String msg = "Permission Denial: switchUser() from pid=" 13928 + Binder.getCallingPid() 13929 + ", uid=" + Binder.getCallingUid() 13930 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13931 Slog.w(TAG, msg); 13932 throw new SecurityException(msg); 13933 } 13934 13935 final long ident = Binder.clearCallingIdentity(); 13936 try { 13937 synchronized (this) { 13938 final int oldUserId = mCurrentUserId; 13939 if (oldUserId == userId) { 13940 return true; 13941 } 13942 13943 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 13944 if (userInfo == null) { 13945 Slog.w(TAG, "No user info for user #" + userId); 13946 return false; 13947 } 13948 13949 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 13950 R.anim.screen_user_enter); 13951 13952 // If the user we are switching to is not currently started, then 13953 // we need to start it now. 13954 if (mStartedUsers.get(userId) == null) { 13955 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13956 } 13957 13958 mCurrentUserId = userId; 13959 final Integer userIdInt = Integer.valueOf(userId); 13960 mUserLru.remove(userIdInt); 13961 mUserLru.add(userIdInt); 13962 13963 final UserStartedState uss = mStartedUsers.get(userId); 13964 13965 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 13966 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 13967 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 13968 oldUserId, userId, uss)); 13969 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 13970 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 13971 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 13972 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13973 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13974 broadcastIntentLocked(null, null, intent, 13975 null, null, 0, null, null, null, 13976 false, false, MY_PID, Process.SYSTEM_UID, userId); 13977 13978 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 13979 if (userId != 0) { 13980 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 13981 broadcastIntentLocked(null, null, intent, null, 13982 new IIntentReceiver.Stub() { 13983 public void performReceive(Intent intent, int resultCode, 13984 String data, Bundle extras, boolean ordered, 13985 boolean sticky, int sendingUser) { 13986 synchronized (ActivityManagerService.this) { 13987 getUserManagerLocked().makeInitialized(userInfo.id); 13988 } 13989 } 13990 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 13991 userId); 13992 } else { 13993 getUserManagerLocked().makeInitialized(userInfo.id); 13994 } 13995 } 13996 13997 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 13998 if (!haveActivities) { 13999 startHomeActivityLocked(userId); 14000 } 14001 14002 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14003 } 14004 } finally { 14005 Binder.restoreCallingIdentity(ident); 14006 } 14007 14008 return true; 14009 } 14010 14011 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14012 long ident = Binder.clearCallingIdentity(); 14013 try { 14014 Intent intent; 14015 if (oldUserId >= 0) { 14016 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14017 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14018 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14019 broadcastIntentLocked(null, null, intent, 14020 null, null, 0, null, null, null, 14021 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14022 } 14023 if (newUserId >= 0) { 14024 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14025 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14026 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14027 broadcastIntentLocked(null, null, intent, 14028 null, null, 0, null, null, null, 14029 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14030 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14031 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14032 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14033 broadcastIntentLocked(null, null, intent, 14034 null, null, 0, null, null, 14035 android.Manifest.permission.MANAGE_USERS, 14036 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14037 } 14038 } finally { 14039 Binder.restoreCallingIdentity(ident); 14040 } 14041 } 14042 14043 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14044 final int newUserId) { 14045 final int N = mUserSwitchObservers.beginBroadcast(); 14046 if (N > 0) { 14047 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14048 int mCount = 0; 14049 @Override 14050 public void sendResult(Bundle data) throws RemoteException { 14051 synchronized (ActivityManagerService.this) { 14052 if (mCurUserSwitchCallback == this) { 14053 mCount++; 14054 if (mCount == N) { 14055 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14056 } 14057 } 14058 } 14059 } 14060 }; 14061 synchronized (this) { 14062 mCurUserSwitchCallback = callback; 14063 } 14064 for (int i=0; i<N; i++) { 14065 try { 14066 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14067 newUserId, callback); 14068 } catch (RemoteException e) { 14069 } 14070 } 14071 } else { 14072 synchronized (this) { 14073 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14074 } 14075 } 14076 mUserSwitchObservers.finishBroadcast(); 14077 } 14078 14079 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14080 synchronized (this) { 14081 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14082 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14083 } 14084 } 14085 14086 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14087 mCurUserSwitchCallback = null; 14088 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14089 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14090 oldUserId, newUserId, uss)); 14091 } 14092 14093 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14094 final int N = mUserSwitchObservers.beginBroadcast(); 14095 for (int i=0; i<N; i++) { 14096 try { 14097 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14098 } catch (RemoteException e) { 14099 } 14100 } 14101 mUserSwitchObservers.finishBroadcast(); 14102 synchronized (this) { 14103 mWindowManager.stopFreezingScreen(); 14104 } 14105 } 14106 14107 void finishUserSwitch(UserStartedState uss) { 14108 synchronized (this) { 14109 if (uss.mState == UserStartedState.STATE_BOOTING 14110 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14111 uss.mState = UserStartedState.STATE_RUNNING; 14112 final int userId = uss.mHandle.getIdentifier(); 14113 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14114 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14115 broadcastIntentLocked(null, null, intent, 14116 null, null, 0, null, null, 14117 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14118 false, false, MY_PID, Process.SYSTEM_UID, userId); 14119 } 14120 } 14121 } 14122 14123 @Override 14124 public int stopUser(final int userId, final IStopUserCallback callback) { 14125 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14126 != PackageManager.PERMISSION_GRANTED) { 14127 String msg = "Permission Denial: switchUser() from pid=" 14128 + Binder.getCallingPid() 14129 + ", uid=" + Binder.getCallingUid() 14130 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14131 Slog.w(TAG, msg); 14132 throw new SecurityException(msg); 14133 } 14134 if (userId <= 0) { 14135 throw new IllegalArgumentException("Can't stop primary user " + userId); 14136 } 14137 synchronized (this) { 14138 if (mCurrentUserId == userId) { 14139 return ActivityManager.USER_OP_IS_CURRENT; 14140 } 14141 14142 final UserStartedState uss = mStartedUsers.get(userId); 14143 if (uss == null) { 14144 // User is not started, nothing to do... but we do need to 14145 // callback if requested. 14146 if (callback != null) { 14147 mHandler.post(new Runnable() { 14148 @Override 14149 public void run() { 14150 try { 14151 callback.userStopped(userId); 14152 } catch (RemoteException e) { 14153 } 14154 } 14155 }); 14156 } 14157 return ActivityManager.USER_OP_SUCCESS; 14158 } 14159 14160 if (callback != null) { 14161 uss.mStopCallbacks.add(callback); 14162 } 14163 14164 if (uss.mState != UserStartedState.STATE_STOPPING) { 14165 uss.mState = UserStartedState.STATE_STOPPING; 14166 14167 long ident = Binder.clearCallingIdentity(); 14168 try { 14169 // Inform of user switch 14170 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14171 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14172 @Override 14173 public void performReceive(Intent intent, int resultCode, String data, 14174 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14175 finishUserStop(uss); 14176 } 14177 }; 14178 broadcastIntentLocked(null, null, intent, 14179 null, resultReceiver, 0, null, null, null, 14180 true, false, MY_PID, Process.SYSTEM_UID, userId); 14181 } finally { 14182 Binder.restoreCallingIdentity(ident); 14183 } 14184 } 14185 } 14186 14187 return ActivityManager.USER_OP_SUCCESS; 14188 } 14189 14190 void finishUserStop(UserStartedState uss) { 14191 final int userId = uss.mHandle.getIdentifier(); 14192 boolean stopped; 14193 ArrayList<IStopUserCallback> callbacks; 14194 synchronized (this) { 14195 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14196 if (uss.mState != UserStartedState.STATE_STOPPING 14197 || mStartedUsers.get(userId) != uss) { 14198 stopped = false; 14199 } else { 14200 stopped = true; 14201 // User can no longer run. 14202 mStartedUsers.remove(userId); 14203 14204 // Clean up all state and processes associated with the user. 14205 // Kill all the processes for the user. 14206 forceStopUserLocked(userId); 14207 } 14208 } 14209 14210 for (int i=0; i<callbacks.size(); i++) { 14211 try { 14212 if (stopped) callbacks.get(i).userStopped(userId); 14213 else callbacks.get(i).userStopAborted(userId); 14214 } catch (RemoteException e) { 14215 } 14216 } 14217 } 14218 14219 @Override 14220 public UserInfo getCurrentUser() { 14221 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14222 != PackageManager.PERMISSION_GRANTED) { 14223 String msg = "Permission Denial: getCurrentUser() from pid=" 14224 + Binder.getCallingPid() 14225 + ", uid=" + Binder.getCallingUid() 14226 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14227 Slog.w(TAG, msg); 14228 throw new SecurityException(msg); 14229 } 14230 synchronized (this) { 14231 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14232 } 14233 } 14234 14235 @Override 14236 public boolean isUserRunning(int userId) { 14237 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14238 != PackageManager.PERMISSION_GRANTED) { 14239 String msg = "Permission Denial: isUserRunning() from pid=" 14240 + Binder.getCallingPid() 14241 + ", uid=" + Binder.getCallingUid() 14242 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14243 Slog.w(TAG, msg); 14244 throw new SecurityException(msg); 14245 } 14246 synchronized (this) { 14247 return isUserRunningLocked(userId); 14248 } 14249 } 14250 14251 boolean isUserRunningLocked(int userId) { 14252 UserStartedState state = mStartedUsers.get(userId); 14253 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14254 } 14255 14256 @Override 14257 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14258 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14259 != PackageManager.PERMISSION_GRANTED) { 14260 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14261 + Binder.getCallingPid() 14262 + ", uid=" + Binder.getCallingUid() 14263 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14264 Slog.w(TAG, msg); 14265 throw new SecurityException(msg); 14266 } 14267 14268 mUserSwitchObservers.register(observer); 14269 } 14270 14271 @Override 14272 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14273 mUserSwitchObservers.unregister(observer); 14274 } 14275 14276 private boolean userExists(int userId) { 14277 if (userId == 0) { 14278 return true; 14279 } 14280 UserManagerService ums = getUserManagerLocked(); 14281 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14282 } 14283 14284 int[] getUsersLocked() { 14285 UserManagerService ums = getUserManagerLocked(); 14286 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14287 } 14288 14289 UserManagerService getUserManagerLocked() { 14290 if (mUserManager == null) { 14291 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14292 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14293 } 14294 return mUserManager; 14295 } 14296 14297 private void checkValidCaller(int uid, int userId) { 14298 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14299 14300 throw new SecurityException("Caller uid=" + uid 14301 + " is not privileged to communicate with user=" + userId); 14302 } 14303 14304 private int applyUserId(int uid, int userId) { 14305 return UserHandle.getUid(userId, uid); 14306 } 14307 14308 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14309 if (info == null) return null; 14310 ApplicationInfo newInfo = new ApplicationInfo(info); 14311 newInfo.uid = applyUserId(info.uid, userId); 14312 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14313 + info.packageName; 14314 return newInfo; 14315 } 14316 14317 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14318 if (aInfo == null 14319 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14320 return aInfo; 14321 } 14322 14323 ActivityInfo info = new ActivityInfo(aInfo); 14324 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14325 return info; 14326 } 14327} 14328