ActivityManagerService.java revision f1b674197577e815040cd75ef86d611965d603ad
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 // Maximum number of users we allow to be running at a time. 257 static final int MAX_RUNNING_USERS = 3; 258 259 static final int MY_PID = Process.myPid(); 260 261 static final String[] EMPTY_STRING_ARRAY = new String[0]; 262 263 public ActivityStack mMainStack; 264 265 private final boolean mHeadless; 266 267 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 268 // default actuion automatically. Important for devices without direct input 269 // devices. 270 private boolean mShowDialogs = true; 271 272 /** 273 * Description of a request to start a new activity, which has been held 274 * due to app switches being disabled. 275 */ 276 static class PendingActivityLaunch { 277 ActivityRecord r; 278 ActivityRecord sourceRecord; 279 int startFlags; 280 } 281 282 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 283 = new ArrayList<PendingActivityLaunch>(); 284 285 286 BroadcastQueue mFgBroadcastQueue; 287 BroadcastQueue mBgBroadcastQueue; 288 // Convenient for easy iteration over the queues. Foreground is first 289 // so that dispatch of foreground broadcasts gets precedence. 290 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 291 292 BroadcastQueue broadcastQueueForIntent(Intent intent) { 293 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 294 if (DEBUG_BACKGROUND_BROADCAST) { 295 Slog.i(TAG, "Broadcast intent " + intent + " on " 296 + (isFg ? "foreground" : "background") 297 + " queue"); 298 } 299 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 300 } 301 302 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 303 for (BroadcastQueue queue : mBroadcastQueues) { 304 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 305 if (r != null) { 306 return r; 307 } 308 } 309 return null; 310 } 311 312 /** 313 * Activity we have told the window manager to have key focus. 314 */ 315 ActivityRecord mFocusedActivity = null; 316 /** 317 * List of intents that were used to start the most recent tasks. 318 */ 319 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 320 321 /** 322 * Process management. 323 */ 324 final ProcessList mProcessList = new ProcessList(); 325 326 /** 327 * All of the applications we currently have running organized by name. 328 * The keys are strings of the application package name (as 329 * returned by the package manager), and the keys are ApplicationRecord 330 * objects. 331 */ 332 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 333 334 /** 335 * The currently running isolated processes. 336 */ 337 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 338 339 /** 340 * Counter for assigning isolated process uids, to avoid frequently reusing the 341 * same ones. 342 */ 343 int mNextIsolatedProcessUid = 0; 344 345 /** 346 * The currently running heavy-weight process, if any. 347 */ 348 ProcessRecord mHeavyWeightProcess = null; 349 350 /** 351 * The last time that various processes have crashed. 352 */ 353 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 354 355 /** 356 * Set of applications that we consider to be bad, and will reject 357 * incoming broadcasts from (which the user has no control over). 358 * Processes are added to this set when they have crashed twice within 359 * a minimum amount of time; they are removed from it when they are 360 * later restarted (hopefully due to some user action). The value is the 361 * time it was added to the list. 362 */ 363 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 364 365 /** 366 * All of the processes we currently have running organized by pid. 367 * The keys are the pid running the application. 368 * 369 * <p>NOTE: This object is protected by its own lock, NOT the global 370 * activity manager lock! 371 */ 372 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 373 374 /** 375 * All of the processes that have been forced to be foreground. The key 376 * is the pid of the caller who requested it (we hold a death 377 * link on it). 378 */ 379 abstract class ForegroundToken implements IBinder.DeathRecipient { 380 int pid; 381 IBinder token; 382 } 383 final SparseArray<ForegroundToken> mForegroundProcesses 384 = new SparseArray<ForegroundToken>(); 385 386 /** 387 * List of records for processes that someone had tried to start before the 388 * system was ready. We don't start them at that point, but ensure they 389 * are started by the time booting is complete. 390 */ 391 final ArrayList<ProcessRecord> mProcessesOnHold 392 = new ArrayList<ProcessRecord>(); 393 394 /** 395 * List of persistent applications that are in the process 396 * of being started. 397 */ 398 final ArrayList<ProcessRecord> mPersistentStartingProcesses 399 = new ArrayList<ProcessRecord>(); 400 401 /** 402 * Processes that are being forcibly torn down. 403 */ 404 final ArrayList<ProcessRecord> mRemovedProcesses 405 = new ArrayList<ProcessRecord>(); 406 407 /** 408 * List of running applications, sorted by recent usage. 409 * The first entry in the list is the least recently used. 410 * It contains ApplicationRecord objects. This list does NOT include 411 * any persistent application records (since we never want to exit them). 412 */ 413 final ArrayList<ProcessRecord> mLruProcesses 414 = new ArrayList<ProcessRecord>(); 415 416 /** 417 * List of processes that should gc as soon as things are idle. 418 */ 419 final ArrayList<ProcessRecord> mProcessesToGc 420 = new ArrayList<ProcessRecord>(); 421 422 /** 423 * This is the process holding what we currently consider to be 424 * the "home" activity. 425 */ 426 ProcessRecord mHomeProcess; 427 428 /** 429 * This is the process holding the activity the user last visited that 430 * is in a different process from the one they are currently in. 431 */ 432 ProcessRecord mPreviousProcess; 433 434 /** 435 * The time at which the previous process was last visible. 436 */ 437 long mPreviousProcessVisibleTime; 438 439 /** 440 * Which uses have been started, so are allowed to run code. 441 */ 442 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 443 444 /** 445 * LRU list of history of current users. Most recently current is at the end. 446 */ 447 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 448 449 /** 450 * Registered observers of the user switching mechanics. 451 */ 452 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 453 = new RemoteCallbackList<IUserSwitchObserver>(); 454 455 /** 456 * Currently active user switch. 457 */ 458 Object mCurUserSwitchCallback; 459 460 /** 461 * Packages that the user has asked to have run in screen size 462 * compatibility mode instead of filling the screen. 463 */ 464 final CompatModePackages mCompatModePackages; 465 466 /** 467 * Set of PendingResultRecord objects that are currently active. 468 */ 469 final HashSet mPendingResultRecords = new HashSet(); 470 471 /** 472 * Set of IntentSenderRecord objects that are currently active. 473 */ 474 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 475 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 476 477 /** 478 * Fingerprints (hashCode()) of stack traces that we've 479 * already logged DropBox entries for. Guarded by itself. If 480 * something (rogue user app) forces this over 481 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 482 */ 483 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 484 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 485 486 /** 487 * Strict Mode background batched logging state. 488 * 489 * The string buffer is guarded by itself, and its lock is also 490 * used to determine if another batched write is already 491 * in-flight. 492 */ 493 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 494 495 /** 496 * Keeps track of all IIntentReceivers that have been registered for 497 * broadcasts. Hash keys are the receiver IBinder, hash value is 498 * a ReceiverList. 499 */ 500 final HashMap mRegisteredReceivers = new HashMap(); 501 502 /** 503 * Resolver for broadcast intents to registered receivers. 504 * Holds BroadcastFilter (subclass of IntentFilter). 505 */ 506 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 507 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 508 @Override 509 protected boolean allowFilterResult( 510 BroadcastFilter filter, List<BroadcastFilter> dest) { 511 IBinder target = filter.receiverList.receiver.asBinder(); 512 for (int i=dest.size()-1; i>=0; i--) { 513 if (dest.get(i).receiverList.receiver.asBinder() == target) { 514 return false; 515 } 516 } 517 return true; 518 } 519 520 @Override 521 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 522 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 523 || userId == filter.owningUserId) { 524 return super.newResult(filter, match, userId); 525 } 526 return null; 527 } 528 529 @Override 530 protected BroadcastFilter[] newArray(int size) { 531 return new BroadcastFilter[size]; 532 } 533 534 @Override 535 protected String packageForFilter(BroadcastFilter filter) { 536 return filter.packageName; 537 } 538 }; 539 540 /** 541 * State of all active sticky broadcasts per user. Keys are the action of the 542 * sticky Intent, values are an ArrayList of all broadcasted intents with 543 * that action (which should usually be one). The SparseArray is keyed 544 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 545 * for stickies that are sent to all users. 546 */ 547 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts = 548 new SparseArray<HashMap<String, ArrayList<Intent>>>(); 549 550 final ActiveServices mServices; 551 552 /** 553 * Backup/restore process management 554 */ 555 String mBackupAppName = null; 556 BackupRecord mBackupTarget = null; 557 558 /** 559 * List of PendingThumbnailsRecord objects of clients who are still 560 * waiting to receive all of the thumbnails for a task. 561 */ 562 final ArrayList mPendingThumbnails = new ArrayList(); 563 564 /** 565 * List of HistoryRecord objects that have been finished and must 566 * still report back to a pending thumbnail receiver. 567 */ 568 final ArrayList mCancelledThumbnails = new ArrayList(); 569 570 final ProviderMap mProviderMap; 571 572 /** 573 * List of content providers who have clients waiting for them. The 574 * application is currently being launched and the provider will be 575 * removed from this list once it is published. 576 */ 577 final ArrayList<ContentProviderRecord> mLaunchingProviders 578 = new ArrayList<ContentProviderRecord>(); 579 580 /** 581 * Global set of specific Uri permissions that have been granted. 582 */ 583 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 584 = new SparseArray<HashMap<Uri, UriPermission>>(); 585 586 CoreSettingsObserver mCoreSettingsObserver; 587 588 /** 589 * Thread-local storage used to carry caller permissions over through 590 * indirect content-provider access. 591 * @see #ActivityManagerService.openContentUri() 592 */ 593 private class Identity { 594 public int pid; 595 public int uid; 596 597 Identity(int _pid, int _uid) { 598 pid = _pid; 599 uid = _uid; 600 } 601 } 602 603 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 604 605 /** 606 * All information we have collected about the runtime performance of 607 * any user id that can impact battery performance. 608 */ 609 final BatteryStatsService mBatteryStatsService; 610 611 /** 612 * information about component usage 613 */ 614 final UsageStatsService mUsageStatsService; 615 616 /** 617 * Current configuration information. HistoryRecord objects are given 618 * a reference to this object to indicate which configuration they are 619 * currently running in, so this object must be kept immutable. 620 */ 621 Configuration mConfiguration = new Configuration(); 622 623 /** 624 * Current sequencing integer of the configuration, for skipping old 625 * configurations. 626 */ 627 int mConfigurationSeq = 0; 628 629 /** 630 * Hardware-reported OpenGLES version. 631 */ 632 final int GL_ES_VERSION; 633 634 /** 635 * List of initialization arguments to pass to all processes when binding applications to them. 636 * For example, references to the commonly used services. 637 */ 638 HashMap<String, IBinder> mAppBindArgs; 639 640 /** 641 * Temporary to avoid allocations. Protected by main lock. 642 */ 643 final StringBuilder mStringBuilder = new StringBuilder(256); 644 645 /** 646 * Used to control how we initialize the service. 647 */ 648 boolean mStartRunning = false; 649 ComponentName mTopComponent; 650 String mTopAction; 651 String mTopData; 652 boolean mProcessesReady = false; 653 boolean mSystemReady = false; 654 boolean mBooting = false; 655 boolean mWaitingUpdate = false; 656 boolean mDidUpdate = false; 657 boolean mOnBattery = false; 658 boolean mLaunchWarningShown = false; 659 660 Context mContext; 661 662 int mFactoryTest; 663 664 boolean mCheckedForSetup; 665 666 /** 667 * The time at which we will allow normal application switches again, 668 * after a call to {@link #stopAppSwitches()}. 669 */ 670 long mAppSwitchesAllowedTime; 671 672 /** 673 * This is set to true after the first switch after mAppSwitchesAllowedTime 674 * is set; any switches after that will clear the time. 675 */ 676 boolean mDidAppSwitch; 677 678 /** 679 * Last time (in realtime) at which we checked for power usage. 680 */ 681 long mLastPowerCheckRealtime; 682 683 /** 684 * Last time (in uptime) at which we checked for power usage. 685 */ 686 long mLastPowerCheckUptime; 687 688 /** 689 * Set while we are wanting to sleep, to prevent any 690 * activities from being started/resumed. 691 */ 692 boolean mSleeping = false; 693 694 /** 695 * State of external calls telling us if the device is asleep. 696 */ 697 boolean mWentToSleep = false; 698 699 /** 700 * State of external call telling us if the lock screen is shown. 701 */ 702 boolean mLockScreenShown = false; 703 704 /** 705 * Set if we are shutting down the system, similar to sleeping. 706 */ 707 boolean mShuttingDown = false; 708 709 /** 710 * Task identifier that activities are currently being started 711 * in. Incremented each time a new task is created. 712 * todo: Replace this with a TokenSpace class that generates non-repeating 713 * integers that won't wrap. 714 */ 715 int mCurTask = 1; 716 717 /** 718 * Current sequence id for oom_adj computation traversal. 719 */ 720 int mAdjSeq = 0; 721 722 /** 723 * Current sequence id for process LRU updating. 724 */ 725 int mLruSeq = 0; 726 727 /** 728 * Keep track of the non-hidden/empty process we last found, to help 729 * determine how to distribute hidden/empty processes next time. 730 */ 731 int mNumNonHiddenProcs = 0; 732 733 /** 734 * Keep track of the number of hidden procs, to balance oom adj 735 * distribution between those and empty procs. 736 */ 737 int mNumHiddenProcs = 0; 738 739 /** 740 * Keep track of the number of service processes we last found, to 741 * determine on the next iteration which should be B services. 742 */ 743 int mNumServiceProcs = 0; 744 int mNewNumServiceProcs = 0; 745 746 /** 747 * System monitoring: number of processes that died since the last 748 * N procs were started. 749 */ 750 int[] mProcDeaths = new int[20]; 751 752 /** 753 * This is set if we had to do a delayed dexopt of an app before launching 754 * it, to increasing the ANR timeouts in that case. 755 */ 756 boolean mDidDexOpt; 757 758 String mDebugApp = null; 759 boolean mWaitForDebugger = false; 760 boolean mDebugTransient = false; 761 String mOrigDebugApp = null; 762 boolean mOrigWaitForDebugger = false; 763 boolean mAlwaysFinishActivities = false; 764 IActivityController mController = null; 765 String mProfileApp = null; 766 ProcessRecord mProfileProc = null; 767 String mProfileFile; 768 ParcelFileDescriptor mProfileFd; 769 int mProfileType = 0; 770 boolean mAutoStopProfiler = false; 771 String mOpenGlTraceApp = null; 772 773 static class ProcessChangeItem { 774 static final int CHANGE_ACTIVITIES = 1<<0; 775 static final int CHANGE_IMPORTANCE= 1<<1; 776 int changes; 777 int uid; 778 int pid; 779 int importance; 780 boolean foregroundActivities; 781 } 782 783 final RemoteCallbackList<IProcessObserver> mProcessObservers 784 = new RemoteCallbackList<IProcessObserver>(); 785 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 786 787 final ArrayList<ProcessChangeItem> mPendingProcessChanges 788 = new ArrayList<ProcessChangeItem>(); 789 final ArrayList<ProcessChangeItem> mAvailProcessChanges 790 = new ArrayList<ProcessChangeItem>(); 791 792 /** 793 * Callback of last caller to {@link #requestPss}. 794 */ 795 Runnable mRequestPssCallback; 796 797 /** 798 * Remaining processes for which we are waiting results from the last 799 * call to {@link #requestPss}. 800 */ 801 final ArrayList<ProcessRecord> mRequestPssList 802 = new ArrayList<ProcessRecord>(); 803 804 /** 805 * Runtime statistics collection thread. This object's lock is used to 806 * protect all related state. 807 */ 808 final Thread mProcessStatsThread; 809 810 /** 811 * Used to collect process stats when showing not responding dialog. 812 * Protected by mProcessStatsThread. 813 */ 814 final ProcessStats mProcessStats = new ProcessStats( 815 MONITOR_THREAD_CPU_USAGE); 816 final AtomicLong mLastCpuTime = new AtomicLong(0); 817 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 818 819 long mLastWriteTime = 0; 820 821 /** 822 * Set to true after the system has finished booting. 823 */ 824 boolean mBooted = false; 825 826 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 827 int mProcessLimitOverride = -1; 828 829 WindowManagerService mWindowManager; 830 831 static ActivityManagerService mSelf; 832 static ActivityThread mSystemThread; 833 834 private int mCurrentUserId; 835 private UserManagerService mUserManager; 836 837 private final class AppDeathRecipient implements IBinder.DeathRecipient { 838 final ProcessRecord mApp; 839 final int mPid; 840 final IApplicationThread mAppThread; 841 842 AppDeathRecipient(ProcessRecord app, int pid, 843 IApplicationThread thread) { 844 if (localLOGV) Slog.v( 845 TAG, "New death recipient " + this 846 + " for thread " + thread.asBinder()); 847 mApp = app; 848 mPid = pid; 849 mAppThread = thread; 850 } 851 852 public void binderDied() { 853 if (localLOGV) Slog.v( 854 TAG, "Death received in " + this 855 + " for thread " + mAppThread.asBinder()); 856 synchronized(ActivityManagerService.this) { 857 appDiedLocked(mApp, mPid, mAppThread); 858 } 859 } 860 } 861 862 static final int SHOW_ERROR_MSG = 1; 863 static final int SHOW_NOT_RESPONDING_MSG = 2; 864 static final int SHOW_FACTORY_ERROR_MSG = 3; 865 static final int UPDATE_CONFIGURATION_MSG = 4; 866 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 867 static final int WAIT_FOR_DEBUGGER_MSG = 6; 868 static final int SERVICE_TIMEOUT_MSG = 12; 869 static final int UPDATE_TIME_ZONE = 13; 870 static final int SHOW_UID_ERROR_MSG = 14; 871 static final int IM_FEELING_LUCKY_MSG = 15; 872 static final int PROC_START_TIMEOUT_MSG = 20; 873 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 874 static final int KILL_APPLICATION_MSG = 22; 875 static final int FINALIZE_PENDING_INTENT_MSG = 23; 876 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 877 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 878 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 879 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 880 static final int CLEAR_DNS_CACHE = 28; 881 static final int UPDATE_HTTP_PROXY = 29; 882 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 883 static final int DISPATCH_PROCESSES_CHANGED = 31; 884 static final int DISPATCH_PROCESS_DIED = 32; 885 static final int REPORT_MEM_USAGE = 33; 886 static final int REPORT_USER_SWITCH_MSG = 34; 887 static final int CONTINUE_USER_SWITCH_MSG = 35; 888 static final int USER_SWITCH_TIMEOUT_MSG = 36; 889 890 static final int FIRST_ACTIVITY_STACK_MSG = 100; 891 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 892 static final int FIRST_COMPAT_MODE_MSG = 300; 893 894 AlertDialog mUidAlert; 895 CompatModeDialog mCompatModeDialog; 896 long mLastMemUsageReportTime = 0; 897 898 final Handler mHandler = new Handler() { 899 //public Handler() { 900 // if (localLOGV) Slog.v(TAG, "Handler started!"); 901 //} 902 903 public void handleMessage(Message msg) { 904 switch (msg.what) { 905 case SHOW_ERROR_MSG: { 906 HashMap data = (HashMap) msg.obj; 907 synchronized (ActivityManagerService.this) { 908 ProcessRecord proc = (ProcessRecord)data.get("app"); 909 if (proc != null && proc.crashDialog != null) { 910 Slog.e(TAG, "App already has crash dialog: " + proc); 911 return; 912 } 913 AppErrorResult res = (AppErrorResult) data.get("result"); 914 if (mShowDialogs && !mSleeping && !mShuttingDown) { 915 Dialog d = new AppErrorDialog(mContext, res, proc); 916 d.show(); 917 proc.crashDialog = d; 918 } else { 919 // The device is asleep, so just pretend that the user 920 // saw a crash dialog and hit "force quit". 921 res.set(0); 922 } 923 } 924 925 ensureBootCompleted(); 926 } break; 927 case SHOW_NOT_RESPONDING_MSG: { 928 synchronized (ActivityManagerService.this) { 929 HashMap data = (HashMap) msg.obj; 930 ProcessRecord proc = (ProcessRecord)data.get("app"); 931 if (proc != null && proc.anrDialog != null) { 932 Slog.e(TAG, "App already has anr dialog: " + proc); 933 return; 934 } 935 936 Intent intent = new Intent("android.intent.action.ANR"); 937 if (!mProcessesReady) { 938 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 939 | Intent.FLAG_RECEIVER_FOREGROUND); 940 } 941 broadcastIntentLocked(null, null, intent, 942 null, null, 0, null, null, null, 943 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 944 945 if (mShowDialogs) { 946 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 947 mContext, proc, (ActivityRecord)data.get("activity")); 948 d.show(); 949 proc.anrDialog = d; 950 } else { 951 // Just kill the app if there is no dialog to be shown. 952 killAppAtUsersRequest(proc, null); 953 } 954 } 955 956 ensureBootCompleted(); 957 } break; 958 case SHOW_STRICT_MODE_VIOLATION_MSG: { 959 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 960 synchronized (ActivityManagerService.this) { 961 ProcessRecord proc = (ProcessRecord) data.get("app"); 962 if (proc == null) { 963 Slog.e(TAG, "App not found when showing strict mode dialog."); 964 break; 965 } 966 if (proc.crashDialog != null) { 967 Slog.e(TAG, "App already has strict mode dialog: " + proc); 968 return; 969 } 970 AppErrorResult res = (AppErrorResult) data.get("result"); 971 if (mShowDialogs && !mSleeping && !mShuttingDown) { 972 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 973 d.show(); 974 proc.crashDialog = d; 975 } else { 976 // The device is asleep, so just pretend that the user 977 // saw a crash dialog and hit "force quit". 978 res.set(0); 979 } 980 } 981 ensureBootCompleted(); 982 } break; 983 case SHOW_FACTORY_ERROR_MSG: { 984 Dialog d = new FactoryErrorDialog( 985 mContext, msg.getData().getCharSequence("msg")); 986 d.show(); 987 ensureBootCompleted(); 988 } break; 989 case UPDATE_CONFIGURATION_MSG: { 990 final ContentResolver resolver = mContext.getContentResolver(); 991 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 992 } break; 993 case GC_BACKGROUND_PROCESSES_MSG: { 994 synchronized (ActivityManagerService.this) { 995 performAppGcsIfAppropriateLocked(); 996 } 997 } break; 998 case WAIT_FOR_DEBUGGER_MSG: { 999 synchronized (ActivityManagerService.this) { 1000 ProcessRecord app = (ProcessRecord)msg.obj; 1001 if (msg.arg1 != 0) { 1002 if (!app.waitedForDebugger) { 1003 Dialog d = new AppWaitingForDebuggerDialog( 1004 ActivityManagerService.this, 1005 mContext, app); 1006 app.waitDialog = d; 1007 app.waitedForDebugger = true; 1008 d.show(); 1009 } 1010 } else { 1011 if (app.waitDialog != null) { 1012 app.waitDialog.dismiss(); 1013 app.waitDialog = null; 1014 } 1015 } 1016 } 1017 } break; 1018 case SERVICE_TIMEOUT_MSG: { 1019 if (mDidDexOpt) { 1020 mDidDexOpt = false; 1021 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1022 nmsg.obj = msg.obj; 1023 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1024 return; 1025 } 1026 mServices.serviceTimeout((ProcessRecord)msg.obj); 1027 } break; 1028 case UPDATE_TIME_ZONE: { 1029 synchronized (ActivityManagerService.this) { 1030 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1031 ProcessRecord r = mLruProcesses.get(i); 1032 if (r.thread != null) { 1033 try { 1034 r.thread.updateTimeZone(); 1035 } catch (RemoteException ex) { 1036 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1037 } 1038 } 1039 } 1040 } 1041 } break; 1042 case CLEAR_DNS_CACHE: { 1043 synchronized (ActivityManagerService.this) { 1044 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1045 ProcessRecord r = mLruProcesses.get(i); 1046 if (r.thread != null) { 1047 try { 1048 r.thread.clearDnsCache(); 1049 } catch (RemoteException ex) { 1050 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1051 } 1052 } 1053 } 1054 } 1055 } break; 1056 case UPDATE_HTTP_PROXY: { 1057 ProxyProperties proxy = (ProxyProperties)msg.obj; 1058 String host = ""; 1059 String port = ""; 1060 String exclList = ""; 1061 if (proxy != null) { 1062 host = proxy.getHost(); 1063 port = Integer.toString(proxy.getPort()); 1064 exclList = proxy.getExclusionList(); 1065 } 1066 synchronized (ActivityManagerService.this) { 1067 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1068 ProcessRecord r = mLruProcesses.get(i); 1069 if (r.thread != null) { 1070 try { 1071 r.thread.setHttpProxy(host, port, exclList); 1072 } catch (RemoteException ex) { 1073 Slog.w(TAG, "Failed to update http proxy for: " + 1074 r.info.processName); 1075 } 1076 } 1077 } 1078 } 1079 } break; 1080 case SHOW_UID_ERROR_MSG: { 1081 String title = "System UIDs Inconsistent"; 1082 String text = "UIDs on the system are inconsistent, you need to wipe your" 1083 + " data partition or your device will be unstable."; 1084 Log.e(TAG, title + ": " + text); 1085 if (mShowDialogs) { 1086 // XXX This is a temporary dialog, no need to localize. 1087 AlertDialog d = new BaseErrorDialog(mContext); 1088 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1089 d.setCancelable(false); 1090 d.setTitle(title); 1091 d.setMessage(text); 1092 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1093 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1094 mUidAlert = d; 1095 d.show(); 1096 } 1097 } break; 1098 case IM_FEELING_LUCKY_MSG: { 1099 if (mUidAlert != null) { 1100 mUidAlert.dismiss(); 1101 mUidAlert = null; 1102 } 1103 } break; 1104 case PROC_START_TIMEOUT_MSG: { 1105 if (mDidDexOpt) { 1106 mDidDexOpt = false; 1107 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1108 nmsg.obj = msg.obj; 1109 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1110 return; 1111 } 1112 ProcessRecord app = (ProcessRecord)msg.obj; 1113 synchronized (ActivityManagerService.this) { 1114 processStartTimedOutLocked(app); 1115 } 1116 } break; 1117 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1118 synchronized (ActivityManagerService.this) { 1119 doPendingActivityLaunchesLocked(true); 1120 } 1121 } break; 1122 case KILL_APPLICATION_MSG: { 1123 synchronized (ActivityManagerService.this) { 1124 int appid = msg.arg1; 1125 boolean restart = (msg.arg2 == 1); 1126 String pkg = (String) msg.obj; 1127 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1128 UserHandle.USER_ALL); 1129 } 1130 } break; 1131 case FINALIZE_PENDING_INTENT_MSG: { 1132 ((PendingIntentRecord)msg.obj).completeFinalize(); 1133 } break; 1134 case POST_HEAVY_NOTIFICATION_MSG: { 1135 INotificationManager inm = NotificationManager.getService(); 1136 if (inm == null) { 1137 return; 1138 } 1139 1140 ActivityRecord root = (ActivityRecord)msg.obj; 1141 ProcessRecord process = root.app; 1142 if (process == null) { 1143 return; 1144 } 1145 1146 try { 1147 Context context = mContext.createPackageContext(process.info.packageName, 0); 1148 String text = mContext.getString(R.string.heavy_weight_notification, 1149 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1150 Notification notification = new Notification(); 1151 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1152 notification.when = 0; 1153 notification.flags = Notification.FLAG_ONGOING_EVENT; 1154 notification.tickerText = text; 1155 notification.defaults = 0; // please be quiet 1156 notification.sound = null; 1157 notification.vibrate = null; 1158 notification.setLatestEventInfo(context, text, 1159 mContext.getText(R.string.heavy_weight_notification_detail), 1160 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1161 PendingIntent.FLAG_CANCEL_CURRENT, null, 1162 new UserHandle(root.userId))); 1163 1164 try { 1165 int[] outId = new int[1]; 1166 inm.enqueueNotificationWithTag("android", null, 1167 R.string.heavy_weight_notification, 1168 notification, outId, root.userId); 1169 } catch (RuntimeException e) { 1170 Slog.w(ActivityManagerService.TAG, 1171 "Error showing notification for heavy-weight app", e); 1172 } catch (RemoteException e) { 1173 } 1174 } catch (NameNotFoundException e) { 1175 Slog.w(TAG, "Unable to create context for heavy notification", e); 1176 } 1177 } break; 1178 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1179 INotificationManager inm = NotificationManager.getService(); 1180 if (inm == null) { 1181 return; 1182 } 1183 try { 1184 inm.cancelNotificationWithTag("android", null, 1185 R.string.heavy_weight_notification, msg.arg1); 1186 } catch (RuntimeException e) { 1187 Slog.w(ActivityManagerService.TAG, 1188 "Error canceling notification for service", e); 1189 } catch (RemoteException e) { 1190 } 1191 } break; 1192 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1193 synchronized (ActivityManagerService.this) { 1194 checkExcessivePowerUsageLocked(true); 1195 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1196 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1197 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1198 } 1199 } break; 1200 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1201 synchronized (ActivityManagerService.this) { 1202 ActivityRecord ar = (ActivityRecord)msg.obj; 1203 if (mCompatModeDialog != null) { 1204 if (mCompatModeDialog.mAppInfo.packageName.equals( 1205 ar.info.applicationInfo.packageName)) { 1206 return; 1207 } 1208 mCompatModeDialog.dismiss(); 1209 mCompatModeDialog = null; 1210 } 1211 if (ar != null && false) { 1212 if (mCompatModePackages.getPackageAskCompatModeLocked( 1213 ar.packageName)) { 1214 int mode = mCompatModePackages.computeCompatModeLocked( 1215 ar.info.applicationInfo); 1216 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1217 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1218 mCompatModeDialog = new CompatModeDialog( 1219 ActivityManagerService.this, mContext, 1220 ar.info.applicationInfo); 1221 mCompatModeDialog.show(); 1222 } 1223 } 1224 } 1225 } 1226 break; 1227 } 1228 case DISPATCH_PROCESSES_CHANGED: { 1229 dispatchProcessesChanged(); 1230 break; 1231 } 1232 case DISPATCH_PROCESS_DIED: { 1233 final int pid = msg.arg1; 1234 final int uid = msg.arg2; 1235 dispatchProcessDied(pid, uid); 1236 break; 1237 } 1238 case REPORT_MEM_USAGE: { 1239 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1240 if (!isDebuggable) { 1241 return; 1242 } 1243 synchronized (ActivityManagerService.this) { 1244 long now = SystemClock.uptimeMillis(); 1245 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1246 // Don't report more than every 5 minutes to somewhat 1247 // avoid spamming. 1248 return; 1249 } 1250 mLastMemUsageReportTime = now; 1251 } 1252 Thread thread = new Thread() { 1253 @Override public void run() { 1254 StringBuilder dropBuilder = new StringBuilder(1024); 1255 StringBuilder logBuilder = new StringBuilder(1024); 1256 StringWriter oomSw = new StringWriter(); 1257 PrintWriter oomPw = new PrintWriter(oomSw); 1258 StringWriter catSw = new StringWriter(); 1259 PrintWriter catPw = new PrintWriter(catSw); 1260 String[] emptyArgs = new String[] { }; 1261 StringBuilder tag = new StringBuilder(128); 1262 StringBuilder stack = new StringBuilder(128); 1263 tag.append("Low on memory -- "); 1264 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1265 tag, stack); 1266 dropBuilder.append(stack); 1267 dropBuilder.append('\n'); 1268 dropBuilder.append('\n'); 1269 String oomString = oomSw.toString(); 1270 dropBuilder.append(oomString); 1271 dropBuilder.append('\n'); 1272 logBuilder.append(oomString); 1273 try { 1274 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1275 "procrank", }); 1276 final InputStreamReader converter = new InputStreamReader( 1277 proc.getInputStream()); 1278 BufferedReader in = new BufferedReader(converter); 1279 String line; 1280 while (true) { 1281 line = in.readLine(); 1282 if (line == null) { 1283 break; 1284 } 1285 if (line.length() > 0) { 1286 logBuilder.append(line); 1287 logBuilder.append('\n'); 1288 } 1289 dropBuilder.append(line); 1290 dropBuilder.append('\n'); 1291 } 1292 converter.close(); 1293 } catch (IOException e) { 1294 } 1295 synchronized (ActivityManagerService.this) { 1296 catPw.println(); 1297 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1298 catPw.println(); 1299 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1300 false, false, null); 1301 catPw.println(); 1302 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1303 } 1304 dropBuilder.append(catSw.toString()); 1305 addErrorToDropBox("lowmem", null, "system_server", null, 1306 null, tag.toString(), dropBuilder.toString(), null, null); 1307 Slog.i(TAG, logBuilder.toString()); 1308 synchronized (ActivityManagerService.this) { 1309 long now = SystemClock.uptimeMillis(); 1310 if (mLastMemUsageReportTime < now) { 1311 mLastMemUsageReportTime = now; 1312 } 1313 } 1314 } 1315 }; 1316 thread.start(); 1317 break; 1318 } 1319 case REPORT_USER_SWITCH_MSG: { 1320 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1321 break; 1322 } 1323 case CONTINUE_USER_SWITCH_MSG: { 1324 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1325 break; 1326 } 1327 case USER_SWITCH_TIMEOUT_MSG: { 1328 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1329 break; 1330 } 1331 } 1332 } 1333 }; 1334 1335 public static void setSystemProcess() { 1336 try { 1337 ActivityManagerService m = mSelf; 1338 1339 ServiceManager.addService("activity", m, true); 1340 ServiceManager.addService("meminfo", new MemBinder(m)); 1341 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1342 ServiceManager.addService("dbinfo", new DbBinder(m)); 1343 if (MONITOR_CPU_USAGE) { 1344 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1345 } 1346 ServiceManager.addService("permission", new PermissionController(m)); 1347 1348 ApplicationInfo info = 1349 mSelf.mContext.getPackageManager().getApplicationInfo( 1350 "android", STOCK_PM_FLAGS); 1351 mSystemThread.installSystemApplicationInfo(info); 1352 1353 synchronized (mSelf) { 1354 ProcessRecord app = mSelf.newProcessRecordLocked( 1355 mSystemThread.getApplicationThread(), info, 1356 info.processName, false); 1357 app.persistent = true; 1358 app.pid = MY_PID; 1359 app.maxAdj = ProcessList.SYSTEM_ADJ; 1360 mSelf.mProcessNames.put(app.processName, app.uid, app); 1361 synchronized (mSelf.mPidsSelfLocked) { 1362 mSelf.mPidsSelfLocked.put(app.pid, app); 1363 } 1364 mSelf.updateLruProcessLocked(app, true, true); 1365 } 1366 } catch (PackageManager.NameNotFoundException e) { 1367 throw new RuntimeException( 1368 "Unable to find android system package", e); 1369 } 1370 } 1371 1372 public void setWindowManager(WindowManagerService wm) { 1373 mWindowManager = wm; 1374 } 1375 1376 public static final Context main(int factoryTest) { 1377 AThread thr = new AThread(); 1378 thr.start(); 1379 1380 synchronized (thr) { 1381 while (thr.mService == null) { 1382 try { 1383 thr.wait(); 1384 } catch (InterruptedException e) { 1385 } 1386 } 1387 } 1388 1389 ActivityManagerService m = thr.mService; 1390 mSelf = m; 1391 ActivityThread at = ActivityThread.systemMain(); 1392 mSystemThread = at; 1393 Context context = at.getSystemContext(); 1394 context.setTheme(android.R.style.Theme_Holo); 1395 m.mContext = context; 1396 m.mFactoryTest = factoryTest; 1397 m.mMainStack = new ActivityStack(m, context, true); 1398 1399 m.mBatteryStatsService.publish(context); 1400 m.mUsageStatsService.publish(context); 1401 1402 synchronized (thr) { 1403 thr.mReady = true; 1404 thr.notifyAll(); 1405 } 1406 1407 m.startRunning(null, null, null, null); 1408 1409 return context; 1410 } 1411 1412 public static ActivityManagerService self() { 1413 return mSelf; 1414 } 1415 1416 static class AThread extends Thread { 1417 ActivityManagerService mService; 1418 boolean mReady = false; 1419 1420 public AThread() { 1421 super("ActivityManager"); 1422 } 1423 1424 public void run() { 1425 Looper.prepare(); 1426 1427 android.os.Process.setThreadPriority( 1428 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1429 android.os.Process.setCanSelfBackground(false); 1430 1431 ActivityManagerService m = new ActivityManagerService(); 1432 1433 synchronized (this) { 1434 mService = m; 1435 notifyAll(); 1436 } 1437 1438 synchronized (this) { 1439 while (!mReady) { 1440 try { 1441 wait(); 1442 } catch (InterruptedException e) { 1443 } 1444 } 1445 } 1446 1447 // For debug builds, log event loop stalls to dropbox for analysis. 1448 if (StrictMode.conditionallyEnableDebugLogging()) { 1449 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1450 } 1451 1452 Looper.loop(); 1453 } 1454 } 1455 1456 static class MemBinder extends Binder { 1457 ActivityManagerService mActivityManagerService; 1458 MemBinder(ActivityManagerService activityManagerService) { 1459 mActivityManagerService = activityManagerService; 1460 } 1461 1462 @Override 1463 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1464 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1465 != PackageManager.PERMISSION_GRANTED) { 1466 pw.println("Permission Denial: can't dump meminfo from from pid=" 1467 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1468 + " without permission " + android.Manifest.permission.DUMP); 1469 return; 1470 } 1471 1472 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1473 false, null, null, null); 1474 } 1475 } 1476 1477 static class GraphicsBinder extends Binder { 1478 ActivityManagerService mActivityManagerService; 1479 GraphicsBinder(ActivityManagerService activityManagerService) { 1480 mActivityManagerService = activityManagerService; 1481 } 1482 1483 @Override 1484 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1485 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1486 != PackageManager.PERMISSION_GRANTED) { 1487 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1488 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1489 + " without permission " + android.Manifest.permission.DUMP); 1490 return; 1491 } 1492 1493 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1494 } 1495 } 1496 1497 static class DbBinder extends Binder { 1498 ActivityManagerService mActivityManagerService; 1499 DbBinder(ActivityManagerService activityManagerService) { 1500 mActivityManagerService = activityManagerService; 1501 } 1502 1503 @Override 1504 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1505 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1506 != PackageManager.PERMISSION_GRANTED) { 1507 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1508 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1509 + " without permission " + android.Manifest.permission.DUMP); 1510 return; 1511 } 1512 1513 mActivityManagerService.dumpDbInfo(fd, pw, args); 1514 } 1515 } 1516 1517 static class CpuBinder extends Binder { 1518 ActivityManagerService mActivityManagerService; 1519 CpuBinder(ActivityManagerService activityManagerService) { 1520 mActivityManagerService = activityManagerService; 1521 } 1522 1523 @Override 1524 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1525 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1526 != PackageManager.PERMISSION_GRANTED) { 1527 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1528 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1529 + " without permission " + android.Manifest.permission.DUMP); 1530 return; 1531 } 1532 1533 synchronized (mActivityManagerService.mProcessStatsThread) { 1534 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1535 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1536 SystemClock.uptimeMillis())); 1537 } 1538 } 1539 } 1540 1541 private ActivityManagerService() { 1542 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1543 1544 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1545 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1546 mBroadcastQueues[0] = mFgBroadcastQueue; 1547 mBroadcastQueues[1] = mBgBroadcastQueue; 1548 1549 mServices = new ActiveServices(this); 1550 mProviderMap = new ProviderMap(this); 1551 1552 File dataDir = Environment.getDataDirectory(); 1553 File systemDir = new File(dataDir, "system"); 1554 systemDir.mkdirs(); 1555 mBatteryStatsService = new BatteryStatsService(new File( 1556 systemDir, "batterystats.bin").toString()); 1557 mBatteryStatsService.getActiveStatistics().readLocked(); 1558 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1559 mOnBattery = DEBUG_POWER ? true 1560 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1561 mBatteryStatsService.getActiveStatistics().setCallback(this); 1562 1563 mUsageStatsService = new UsageStatsService(new File( 1564 systemDir, "usagestats").toString()); 1565 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1566 1567 // User 0 is the first and only user that runs at boot. 1568 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1569 mUserLru.add(Integer.valueOf(0)); 1570 1571 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1572 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1573 1574 mConfiguration.setToDefaults(); 1575 mConfiguration.setLocale(Locale.getDefault()); 1576 1577 mConfigurationSeq = mConfiguration.seq = 1; 1578 mProcessStats.init(); 1579 1580 mCompatModePackages = new CompatModePackages(this, systemDir); 1581 1582 // Add ourself to the Watchdog monitors. 1583 Watchdog.getInstance().addMonitor(this); 1584 1585 mProcessStatsThread = new Thread("ProcessStats") { 1586 public void run() { 1587 while (true) { 1588 try { 1589 try { 1590 synchronized(this) { 1591 final long now = SystemClock.uptimeMillis(); 1592 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1593 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1594 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1595 // + ", write delay=" + nextWriteDelay); 1596 if (nextWriteDelay < nextCpuDelay) { 1597 nextCpuDelay = nextWriteDelay; 1598 } 1599 if (nextCpuDelay > 0) { 1600 mProcessStatsMutexFree.set(true); 1601 this.wait(nextCpuDelay); 1602 } 1603 } 1604 } catch (InterruptedException e) { 1605 } 1606 updateCpuStatsNow(); 1607 } catch (Exception e) { 1608 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1609 } 1610 } 1611 } 1612 }; 1613 mProcessStatsThread.start(); 1614 } 1615 1616 @Override 1617 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1618 throws RemoteException { 1619 if (code == SYSPROPS_TRANSACTION) { 1620 // We need to tell all apps about the system property change. 1621 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1622 synchronized(this) { 1623 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1624 final int NA = apps.size(); 1625 for (int ia=0; ia<NA; ia++) { 1626 ProcessRecord app = apps.valueAt(ia); 1627 if (app.thread != null) { 1628 procs.add(app.thread.asBinder()); 1629 } 1630 } 1631 } 1632 } 1633 1634 int N = procs.size(); 1635 for (int i=0; i<N; i++) { 1636 Parcel data2 = Parcel.obtain(); 1637 try { 1638 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1639 } catch (RemoteException e) { 1640 } 1641 data2.recycle(); 1642 } 1643 } 1644 try { 1645 return super.onTransact(code, data, reply, flags); 1646 } catch (RuntimeException e) { 1647 // The activity manager only throws security exceptions, so let's 1648 // log all others. 1649 if (!(e instanceof SecurityException)) { 1650 Slog.e(TAG, "Activity Manager Crash", e); 1651 } 1652 throw e; 1653 } 1654 } 1655 1656 void updateCpuStats() { 1657 final long now = SystemClock.uptimeMillis(); 1658 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1659 return; 1660 } 1661 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1662 synchronized (mProcessStatsThread) { 1663 mProcessStatsThread.notify(); 1664 } 1665 } 1666 } 1667 1668 void updateCpuStatsNow() { 1669 synchronized (mProcessStatsThread) { 1670 mProcessStatsMutexFree.set(false); 1671 final long now = SystemClock.uptimeMillis(); 1672 boolean haveNewCpuStats = false; 1673 1674 if (MONITOR_CPU_USAGE && 1675 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1676 mLastCpuTime.set(now); 1677 haveNewCpuStats = true; 1678 mProcessStats.update(); 1679 //Slog.i(TAG, mProcessStats.printCurrentState()); 1680 //Slog.i(TAG, "Total CPU usage: " 1681 // + mProcessStats.getTotalCpuPercent() + "%"); 1682 1683 // Slog the cpu usage if the property is set. 1684 if ("true".equals(SystemProperties.get("events.cpu"))) { 1685 int user = mProcessStats.getLastUserTime(); 1686 int system = mProcessStats.getLastSystemTime(); 1687 int iowait = mProcessStats.getLastIoWaitTime(); 1688 int irq = mProcessStats.getLastIrqTime(); 1689 int softIrq = mProcessStats.getLastSoftIrqTime(); 1690 int idle = mProcessStats.getLastIdleTime(); 1691 1692 int total = user + system + iowait + irq + softIrq + idle; 1693 if (total == 0) total = 1; 1694 1695 EventLog.writeEvent(EventLogTags.CPU, 1696 ((user+system+iowait+irq+softIrq) * 100) / total, 1697 (user * 100) / total, 1698 (system * 100) / total, 1699 (iowait * 100) / total, 1700 (irq * 100) / total, 1701 (softIrq * 100) / total); 1702 } 1703 } 1704 1705 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1706 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1707 synchronized(bstats) { 1708 synchronized(mPidsSelfLocked) { 1709 if (haveNewCpuStats) { 1710 if (mOnBattery) { 1711 int perc = bstats.startAddingCpuLocked(); 1712 int totalUTime = 0; 1713 int totalSTime = 0; 1714 final int N = mProcessStats.countStats(); 1715 for (int i=0; i<N; i++) { 1716 ProcessStats.Stats st = mProcessStats.getStats(i); 1717 if (!st.working) { 1718 continue; 1719 } 1720 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1721 int otherUTime = (st.rel_utime*perc)/100; 1722 int otherSTime = (st.rel_stime*perc)/100; 1723 totalUTime += otherUTime; 1724 totalSTime += otherSTime; 1725 if (pr != null) { 1726 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1727 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1728 st.rel_stime-otherSTime); 1729 ps.addSpeedStepTimes(cpuSpeedTimes); 1730 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1731 } else { 1732 BatteryStatsImpl.Uid.Proc ps = 1733 bstats.getProcessStatsLocked(st.name, st.pid); 1734 if (ps != null) { 1735 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1736 st.rel_stime-otherSTime); 1737 ps.addSpeedStepTimes(cpuSpeedTimes); 1738 } 1739 } 1740 } 1741 bstats.finishAddingCpuLocked(perc, totalUTime, 1742 totalSTime, cpuSpeedTimes); 1743 } 1744 } 1745 } 1746 1747 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1748 mLastWriteTime = now; 1749 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1750 } 1751 } 1752 } 1753 } 1754 1755 @Override 1756 public void batteryNeedsCpuUpdate() { 1757 updateCpuStatsNow(); 1758 } 1759 1760 @Override 1761 public void batteryPowerChanged(boolean onBattery) { 1762 // When plugging in, update the CPU stats first before changing 1763 // the plug state. 1764 updateCpuStatsNow(); 1765 synchronized (this) { 1766 synchronized(mPidsSelfLocked) { 1767 mOnBattery = DEBUG_POWER ? true : onBattery; 1768 } 1769 } 1770 } 1771 1772 /** 1773 * Initialize the application bind args. These are passed to each 1774 * process when the bindApplication() IPC is sent to the process. They're 1775 * lazily setup to make sure the services are running when they're asked for. 1776 */ 1777 private HashMap<String, IBinder> getCommonServicesLocked() { 1778 if (mAppBindArgs == null) { 1779 mAppBindArgs = new HashMap<String, IBinder>(); 1780 1781 // Setup the application init args 1782 mAppBindArgs.put("package", ServiceManager.getService("package")); 1783 mAppBindArgs.put("window", ServiceManager.getService("window")); 1784 mAppBindArgs.put(Context.ALARM_SERVICE, 1785 ServiceManager.getService(Context.ALARM_SERVICE)); 1786 } 1787 return mAppBindArgs; 1788 } 1789 1790 final void setFocusedActivityLocked(ActivityRecord r) { 1791 if (mFocusedActivity != r) { 1792 mFocusedActivity = r; 1793 if (r != null) { 1794 mWindowManager.setFocusedApp(r.appToken, true); 1795 } 1796 } 1797 } 1798 1799 private final void updateLruProcessInternalLocked(ProcessRecord app, 1800 boolean updateActivityTime, int bestPos) { 1801 // put it on the LRU to keep track of when it should be exited. 1802 int lrui = mLruProcesses.indexOf(app); 1803 if (lrui >= 0) mLruProcesses.remove(lrui); 1804 1805 int i = mLruProcesses.size()-1; 1806 int skipTop = 0; 1807 1808 app.lruSeq = mLruSeq; 1809 1810 // compute the new weight for this process. 1811 if (updateActivityTime) { 1812 app.lastActivityTime = SystemClock.uptimeMillis(); 1813 } 1814 if (app.activities.size() > 0) { 1815 // If this process has activities, we more strongly want to keep 1816 // it around. 1817 app.lruWeight = app.lastActivityTime; 1818 } else if (app.pubProviders.size() > 0) { 1819 // If this process contains content providers, we want to keep 1820 // it a little more strongly. 1821 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1822 // Also don't let it kick out the first few "real" hidden processes. 1823 skipTop = ProcessList.MIN_HIDDEN_APPS; 1824 } else { 1825 // If this process doesn't have activities, we less strongly 1826 // want to keep it around, and generally want to avoid getting 1827 // in front of any very recently used activities. 1828 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1829 // Also don't let it kick out the first few "real" hidden processes. 1830 skipTop = ProcessList.MIN_HIDDEN_APPS; 1831 } 1832 1833 while (i >= 0) { 1834 ProcessRecord p = mLruProcesses.get(i); 1835 // If this app shouldn't be in front of the first N background 1836 // apps, then skip over that many that are currently hidden. 1837 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1838 skipTop--; 1839 } 1840 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1841 mLruProcesses.add(i+1, app); 1842 break; 1843 } 1844 i--; 1845 } 1846 if (i < 0) { 1847 mLruProcesses.add(0, app); 1848 } 1849 1850 // If the app is currently using a content provider or service, 1851 // bump those processes as well. 1852 if (app.connections.size() > 0) { 1853 for (ConnectionRecord cr : app.connections) { 1854 if (cr.binding != null && cr.binding.service != null 1855 && cr.binding.service.app != null 1856 && cr.binding.service.app.lruSeq != mLruSeq) { 1857 updateLruProcessInternalLocked(cr.binding.service.app, 1858 updateActivityTime, i+1); 1859 } 1860 } 1861 } 1862 for (int j=app.conProviders.size()-1; j>=0; j--) { 1863 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1864 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1865 updateLruProcessInternalLocked(cpr.proc, 1866 updateActivityTime, i+1); 1867 } 1868 } 1869 } 1870 1871 final void updateLruProcessLocked(ProcessRecord app, 1872 boolean oomAdj, boolean updateActivityTime) { 1873 mLruSeq++; 1874 updateLruProcessInternalLocked(app, updateActivityTime, 0); 1875 1876 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1877 if (oomAdj) { 1878 updateOomAdjLocked(); 1879 } 1880 } 1881 1882 final ProcessRecord getProcessRecordLocked( 1883 String processName, int uid) { 1884 if (uid == Process.SYSTEM_UID) { 1885 // The system gets to run in any process. If there are multiple 1886 // processes with the same uid, just pick the first (this 1887 // should never happen). 1888 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1889 processName); 1890 if (procs == null) return null; 1891 final int N = procs.size(); 1892 for (int i = 0; i < N; i++) { 1893 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1894 } 1895 } 1896 ProcessRecord proc = mProcessNames.get(processName, uid); 1897 return proc; 1898 } 1899 1900 void ensurePackageDexOpt(String packageName) { 1901 IPackageManager pm = AppGlobals.getPackageManager(); 1902 try { 1903 if (pm.performDexOpt(packageName)) { 1904 mDidDexOpt = true; 1905 } 1906 } catch (RemoteException e) { 1907 } 1908 } 1909 1910 boolean isNextTransitionForward() { 1911 int transit = mWindowManager.getPendingAppTransition(); 1912 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1913 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1914 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1915 } 1916 1917 final ProcessRecord startProcessLocked(String processName, 1918 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1919 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1920 boolean isolated) { 1921 ProcessRecord app; 1922 if (!isolated) { 1923 app = getProcessRecordLocked(processName, info.uid); 1924 } else { 1925 // If this is an isolated process, it can't re-use an existing process. 1926 app = null; 1927 } 1928 // We don't have to do anything more if: 1929 // (1) There is an existing application record; and 1930 // (2) The caller doesn't think it is dead, OR there is no thread 1931 // object attached to it so we know it couldn't have crashed; and 1932 // (3) There is a pid assigned to it, so it is either starting or 1933 // already running. 1934 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1935 + " app=" + app + " knownToBeDead=" + knownToBeDead 1936 + " thread=" + (app != null ? app.thread : null) 1937 + " pid=" + (app != null ? app.pid : -1)); 1938 if (app != null && app.pid > 0) { 1939 if (!knownToBeDead || app.thread == null) { 1940 // We already have the app running, or are waiting for it to 1941 // come up (we have a pid but not yet its thread), so keep it. 1942 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1943 // If this is a new package in the process, add the package to the list 1944 app.addPackage(info.packageName); 1945 return app; 1946 } else { 1947 // An application record is attached to a previous process, 1948 // clean it up now. 1949 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1950 handleAppDiedLocked(app, true, true); 1951 } 1952 } 1953 1954 String hostingNameStr = hostingName != null 1955 ? hostingName.flattenToShortString() : null; 1956 1957 if (!isolated) { 1958 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1959 // If we are in the background, then check to see if this process 1960 // is bad. If so, we will just silently fail. 1961 if (mBadProcesses.get(info.processName, info.uid) != null) { 1962 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1963 + "/" + info.processName); 1964 return null; 1965 } 1966 } else { 1967 // When the user is explicitly starting a process, then clear its 1968 // crash count so that we won't make it bad until they see at 1969 // least one crash dialog again, and make the process good again 1970 // if it had been bad. 1971 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1972 + "/" + info.processName); 1973 mProcessCrashTimes.remove(info.processName, info.uid); 1974 if (mBadProcesses.get(info.processName, info.uid) != null) { 1975 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1976 info.processName); 1977 mBadProcesses.remove(info.processName, info.uid); 1978 if (app != null) { 1979 app.bad = false; 1980 } 1981 } 1982 } 1983 } 1984 1985 if (app == null) { 1986 app = newProcessRecordLocked(null, info, processName, isolated); 1987 if (app == null) { 1988 Slog.w(TAG, "Failed making new process record for " 1989 + processName + "/" + info.uid + " isolated=" + isolated); 1990 return null; 1991 } 1992 mProcessNames.put(processName, app.uid, app); 1993 if (isolated) { 1994 mIsolatedProcesses.put(app.uid, app); 1995 } 1996 } else { 1997 // If this is a new package in the process, add the package to the list 1998 app.addPackage(info.packageName); 1999 } 2000 2001 // If the system is not ready yet, then hold off on starting this 2002 // process until it is. 2003 if (!mProcessesReady 2004 && !isAllowedWhileBooting(info) 2005 && !allowWhileBooting) { 2006 if (!mProcessesOnHold.contains(app)) { 2007 mProcessesOnHold.add(app); 2008 } 2009 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2010 return app; 2011 } 2012 2013 startProcessLocked(app, hostingType, hostingNameStr); 2014 return (app.pid != 0) ? app : null; 2015 } 2016 2017 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2018 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2019 } 2020 2021 private final void startProcessLocked(ProcessRecord app, 2022 String hostingType, String hostingNameStr) { 2023 if (app.pid > 0 && app.pid != MY_PID) { 2024 synchronized (mPidsSelfLocked) { 2025 mPidsSelfLocked.remove(app.pid); 2026 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2027 } 2028 app.setPid(0); 2029 } 2030 2031 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2032 "startProcessLocked removing on hold: " + app); 2033 mProcessesOnHold.remove(app); 2034 2035 updateCpuStats(); 2036 2037 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2038 mProcDeaths[0] = 0; 2039 2040 try { 2041 int uid = app.uid; 2042 2043 int[] gids = null; 2044 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2045 if (!app.isolated) { 2046 int[] permGids = null; 2047 try { 2048 final PackageManager pm = mContext.getPackageManager(); 2049 permGids = pm.getPackageGids(app.info.packageName); 2050 2051 if (Environment.isExternalStorageEmulated()) { 2052 if (pm.checkPermission( 2053 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2054 app.info.packageName) == PERMISSION_GRANTED) { 2055 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2056 } else { 2057 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2058 } 2059 } 2060 } catch (PackageManager.NameNotFoundException e) { 2061 Slog.w(TAG, "Unable to retrieve gids", e); 2062 } 2063 2064 /* 2065 * Add shared application GID so applications can share some 2066 * resources like shared libraries 2067 */ 2068 if (permGids == null) { 2069 gids = new int[1]; 2070 } else { 2071 gids = new int[permGids.length + 1]; 2072 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2073 } 2074 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2075 } 2076 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2077 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2078 && mTopComponent != null 2079 && app.processName.equals(mTopComponent.getPackageName())) { 2080 uid = 0; 2081 } 2082 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2083 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2084 uid = 0; 2085 } 2086 } 2087 int debugFlags = 0; 2088 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2089 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2090 // Also turn on CheckJNI for debuggable apps. It's quite 2091 // awkward to turn on otherwise. 2092 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2093 } 2094 // Run the app in safe mode if its manifest requests so or the 2095 // system is booted in safe mode. 2096 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2097 Zygote.systemInSafeMode == true) { 2098 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2099 } 2100 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2101 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2102 } 2103 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2104 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2105 } 2106 if ("1".equals(SystemProperties.get("debug.assert"))) { 2107 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2108 } 2109 2110 // Start the process. It will either succeed and return a result containing 2111 // the PID of the new process, or else throw a RuntimeException. 2112 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2113 app.processName, uid, uid, gids, debugFlags, mountExternal, 2114 app.info.targetSdkVersion, null, null); 2115 2116 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2117 synchronized (bs) { 2118 if (bs.isOnBattery()) { 2119 app.batteryStats.incStartsLocked(); 2120 } 2121 } 2122 2123 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2124 app.processName, hostingType, 2125 hostingNameStr != null ? hostingNameStr : ""); 2126 2127 if (app.persistent) { 2128 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2129 } 2130 2131 StringBuilder buf = mStringBuilder; 2132 buf.setLength(0); 2133 buf.append("Start proc "); 2134 buf.append(app.processName); 2135 buf.append(" for "); 2136 buf.append(hostingType); 2137 if (hostingNameStr != null) { 2138 buf.append(" "); 2139 buf.append(hostingNameStr); 2140 } 2141 buf.append(": pid="); 2142 buf.append(startResult.pid); 2143 buf.append(" uid="); 2144 buf.append(uid); 2145 buf.append(" gids={"); 2146 if (gids != null) { 2147 for (int gi=0; gi<gids.length; gi++) { 2148 if (gi != 0) buf.append(", "); 2149 buf.append(gids[gi]); 2150 2151 } 2152 } 2153 buf.append("}"); 2154 Slog.i(TAG, buf.toString()); 2155 app.setPid(startResult.pid); 2156 app.usingWrapper = startResult.usingWrapper; 2157 app.removed = false; 2158 synchronized (mPidsSelfLocked) { 2159 this.mPidsSelfLocked.put(startResult.pid, app); 2160 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2161 msg.obj = app; 2162 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2163 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2164 } 2165 } catch (RuntimeException e) { 2166 // XXX do better error recovery. 2167 app.setPid(0); 2168 Slog.e(TAG, "Failure starting process " + app.processName, e); 2169 } 2170 } 2171 2172 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2173 if (resumed) { 2174 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2175 } else { 2176 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2177 } 2178 } 2179 2180 boolean startHomeActivityLocked(int userId) { 2181 if (mHeadless) { 2182 // Added because none of the other calls to ensureBootCompleted seem to fire 2183 // when running headless. 2184 ensureBootCompleted(); 2185 return false; 2186 } 2187 2188 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2189 && mTopAction == null) { 2190 // We are running in factory test mode, but unable to find 2191 // the factory test app, so just sit around displaying the 2192 // error message and don't try to start anything. 2193 return false; 2194 } 2195 Intent intent = new Intent( 2196 mTopAction, 2197 mTopData != null ? Uri.parse(mTopData) : null); 2198 intent.setComponent(mTopComponent); 2199 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2200 intent.addCategory(Intent.CATEGORY_HOME); 2201 } 2202 ActivityInfo aInfo = 2203 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2204 if (aInfo != null) { 2205 intent.setComponent(new ComponentName( 2206 aInfo.applicationInfo.packageName, aInfo.name)); 2207 // Don't do this if the home app is currently being 2208 // instrumented. 2209 aInfo = new ActivityInfo(aInfo); 2210 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2211 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2212 aInfo.applicationInfo.uid); 2213 if (app == null || app.instrumentationClass == null) { 2214 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2215 mMainStack.startActivityLocked(null, intent, null, aInfo, 2216 null, null, 0, 0, 0, 0, null, false, null); 2217 } 2218 } 2219 2220 return true; 2221 } 2222 2223 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2224 ActivityInfo ai = null; 2225 ComponentName comp = intent.getComponent(); 2226 try { 2227 if (comp != null) { 2228 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2229 } else { 2230 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2231 intent, 2232 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2233 flags, userId); 2234 2235 if (info != null) { 2236 ai = info.activityInfo; 2237 } 2238 } 2239 } catch (RemoteException e) { 2240 // ignore 2241 } 2242 2243 return ai; 2244 } 2245 2246 /** 2247 * Starts the "new version setup screen" if appropriate. 2248 */ 2249 void startSetupActivityLocked() { 2250 // Only do this once per boot. 2251 if (mCheckedForSetup) { 2252 return; 2253 } 2254 2255 // We will show this screen if the current one is a different 2256 // version than the last one shown, and we are not running in 2257 // low-level factory test mode. 2258 final ContentResolver resolver = mContext.getContentResolver(); 2259 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2260 Settings.Secure.getInt(resolver, 2261 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2262 mCheckedForSetup = true; 2263 2264 // See if we should be showing the platform update setup UI. 2265 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2266 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2267 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2268 2269 // We don't allow third party apps to replace this. 2270 ResolveInfo ri = null; 2271 for (int i=0; ris != null && i<ris.size(); i++) { 2272 if ((ris.get(i).activityInfo.applicationInfo.flags 2273 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2274 ri = ris.get(i); 2275 break; 2276 } 2277 } 2278 2279 if (ri != null) { 2280 String vers = ri.activityInfo.metaData != null 2281 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2282 : null; 2283 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2284 vers = ri.activityInfo.applicationInfo.metaData.getString( 2285 Intent.METADATA_SETUP_VERSION); 2286 } 2287 String lastVers = Settings.Secure.getString( 2288 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2289 if (vers != null && !vers.equals(lastVers)) { 2290 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2291 intent.setComponent(new ComponentName( 2292 ri.activityInfo.packageName, ri.activityInfo.name)); 2293 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2294 null, null, 0, 0, 0, 0, null, false, null); 2295 } 2296 } 2297 } 2298 } 2299 2300 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2301 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2302 } 2303 2304 void enforceNotIsolatedCaller(String caller) { 2305 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2306 throw new SecurityException("Isolated process not allowed to call " + caller); 2307 } 2308 } 2309 2310 public int getFrontActivityScreenCompatMode() { 2311 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2312 synchronized (this) { 2313 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2314 } 2315 } 2316 2317 public void setFrontActivityScreenCompatMode(int mode) { 2318 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2319 "setFrontActivityScreenCompatMode"); 2320 synchronized (this) { 2321 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2322 } 2323 } 2324 2325 public int getPackageScreenCompatMode(String packageName) { 2326 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2327 synchronized (this) { 2328 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2329 } 2330 } 2331 2332 public void setPackageScreenCompatMode(String packageName, int mode) { 2333 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2334 "setPackageScreenCompatMode"); 2335 synchronized (this) { 2336 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2337 } 2338 } 2339 2340 public boolean getPackageAskScreenCompat(String packageName) { 2341 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2342 synchronized (this) { 2343 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2344 } 2345 } 2346 2347 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2348 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2349 "setPackageAskScreenCompat"); 2350 synchronized (this) { 2351 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2352 } 2353 } 2354 2355 void reportResumedActivityLocked(ActivityRecord r) { 2356 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2357 updateUsageStats(r, true); 2358 } 2359 2360 private void dispatchProcessesChanged() { 2361 int N; 2362 synchronized (this) { 2363 N = mPendingProcessChanges.size(); 2364 if (mActiveProcessChanges.length < N) { 2365 mActiveProcessChanges = new ProcessChangeItem[N]; 2366 } 2367 mPendingProcessChanges.toArray(mActiveProcessChanges); 2368 mAvailProcessChanges.addAll(mPendingProcessChanges); 2369 mPendingProcessChanges.clear(); 2370 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2371 } 2372 int i = mProcessObservers.beginBroadcast(); 2373 while (i > 0) { 2374 i--; 2375 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2376 if (observer != null) { 2377 try { 2378 for (int j=0; j<N; j++) { 2379 ProcessChangeItem item = mActiveProcessChanges[j]; 2380 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2381 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2382 + item.pid + " uid=" + item.uid + ": " 2383 + item.foregroundActivities); 2384 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2385 item.foregroundActivities); 2386 } 2387 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2388 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2389 + item.pid + " uid=" + item.uid + ": " + item.importance); 2390 observer.onImportanceChanged(item.pid, item.uid, 2391 item.importance); 2392 } 2393 } 2394 } catch (RemoteException e) { 2395 } 2396 } 2397 } 2398 mProcessObservers.finishBroadcast(); 2399 } 2400 2401 private void dispatchProcessDied(int pid, int uid) { 2402 int i = mProcessObservers.beginBroadcast(); 2403 while (i > 0) { 2404 i--; 2405 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2406 if (observer != null) { 2407 try { 2408 observer.onProcessDied(pid, uid); 2409 } catch (RemoteException e) { 2410 } 2411 } 2412 } 2413 mProcessObservers.finishBroadcast(); 2414 } 2415 2416 final void doPendingActivityLaunchesLocked(boolean doResume) { 2417 final int N = mPendingActivityLaunches.size(); 2418 if (N <= 0) { 2419 return; 2420 } 2421 for (int i=0; i<N; i++) { 2422 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2423 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2424 pal.startFlags, doResume && i == (N-1), null); 2425 } 2426 mPendingActivityLaunches.clear(); 2427 } 2428 2429 public final int startActivity(IApplicationThread caller, 2430 Intent intent, String resolvedType, IBinder resultTo, 2431 String resultWho, int requestCode, int startFlags, 2432 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2433 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode, 2434 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2435 } 2436 2437 public final int startActivityAsUser(IApplicationThread caller, 2438 Intent intent, String resolvedType, IBinder resultTo, 2439 String resultWho, int requestCode, int startFlags, 2440 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2441 enforceNotIsolatedCaller("startActivity"); 2442 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2443 false, true, "startActivity", null); 2444 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2445 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2446 null, null, options, userId); 2447 } 2448 2449 public final WaitResult startActivityAndWait(IApplicationThread caller, 2450 Intent intent, String resolvedType, IBinder resultTo, 2451 String resultWho, int requestCode, int startFlags, String profileFile, 2452 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2453 enforceNotIsolatedCaller("startActivityAndWait"); 2454 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2455 false, true, "startActivityAndWait", null); 2456 WaitResult res = new WaitResult(); 2457 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2458 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2459 res, null, options, UserHandle.getCallingUserId()); 2460 return res; 2461 } 2462 2463 public final int startActivityWithConfig(IApplicationThread caller, 2464 Intent intent, String resolvedType, IBinder resultTo, 2465 String resultWho, int requestCode, int startFlags, Configuration config, 2466 Bundle options, int userId) { 2467 enforceNotIsolatedCaller("startActivityWithConfig"); 2468 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2469 false, true, "startActivityWithConfig", null); 2470 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2471 resultTo, resultWho, requestCode, startFlags, 2472 null, null, null, config, options, userId); 2473 return ret; 2474 } 2475 2476 public int startActivityIntentSender(IApplicationThread caller, 2477 IntentSender intent, Intent fillInIntent, String resolvedType, 2478 IBinder resultTo, String resultWho, int requestCode, 2479 int flagsMask, int flagsValues, Bundle options) { 2480 enforceNotIsolatedCaller("startActivityIntentSender"); 2481 // Refuse possible leaked file descriptors 2482 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2483 throw new IllegalArgumentException("File descriptors passed in Intent"); 2484 } 2485 2486 IIntentSender sender = intent.getTarget(); 2487 if (!(sender instanceof PendingIntentRecord)) { 2488 throw new IllegalArgumentException("Bad PendingIntent object"); 2489 } 2490 2491 PendingIntentRecord pir = (PendingIntentRecord)sender; 2492 2493 synchronized (this) { 2494 // If this is coming from the currently resumed activity, it is 2495 // effectively saying that app switches are allowed at this point. 2496 if (mMainStack.mResumedActivity != null 2497 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2498 Binder.getCallingUid()) { 2499 mAppSwitchesAllowedTime = 0; 2500 } 2501 } 2502 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2503 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2504 return ret; 2505 } 2506 2507 public boolean startNextMatchingActivity(IBinder callingActivity, 2508 Intent intent, Bundle options) { 2509 // Refuse possible leaked file descriptors 2510 if (intent != null && intent.hasFileDescriptors() == true) { 2511 throw new IllegalArgumentException("File descriptors passed in Intent"); 2512 } 2513 2514 synchronized (this) { 2515 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2516 if (r == null) { 2517 ActivityOptions.abort(options); 2518 return false; 2519 } 2520 if (r.app == null || r.app.thread == null) { 2521 // The caller is not running... d'oh! 2522 ActivityOptions.abort(options); 2523 return false; 2524 } 2525 intent = new Intent(intent); 2526 // The caller is not allowed to change the data. 2527 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2528 // And we are resetting to find the next component... 2529 intent.setComponent(null); 2530 2531 ActivityInfo aInfo = null; 2532 try { 2533 List<ResolveInfo> resolves = 2534 AppGlobals.getPackageManager().queryIntentActivities( 2535 intent, r.resolvedType, 2536 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2537 UserHandle.getCallingUserId()); 2538 2539 // Look for the original activity in the list... 2540 final int N = resolves != null ? resolves.size() : 0; 2541 for (int i=0; i<N; i++) { 2542 ResolveInfo rInfo = resolves.get(i); 2543 if (rInfo.activityInfo.packageName.equals(r.packageName) 2544 && rInfo.activityInfo.name.equals(r.info.name)) { 2545 // We found the current one... the next matching is 2546 // after it. 2547 i++; 2548 if (i<N) { 2549 aInfo = resolves.get(i).activityInfo; 2550 } 2551 break; 2552 } 2553 } 2554 } catch (RemoteException e) { 2555 } 2556 2557 if (aInfo == null) { 2558 // Nobody who is next! 2559 ActivityOptions.abort(options); 2560 return false; 2561 } 2562 2563 intent.setComponent(new ComponentName( 2564 aInfo.applicationInfo.packageName, aInfo.name)); 2565 intent.setFlags(intent.getFlags()&~( 2566 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2567 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2568 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2569 Intent.FLAG_ACTIVITY_NEW_TASK)); 2570 2571 // Okay now we need to start the new activity, replacing the 2572 // currently running activity. This is a little tricky because 2573 // we want to start the new one as if the current one is finished, 2574 // but not finish the current one first so that there is no flicker. 2575 // And thus... 2576 final boolean wasFinishing = r.finishing; 2577 r.finishing = true; 2578 2579 // Propagate reply information over to the new activity. 2580 final ActivityRecord resultTo = r.resultTo; 2581 final String resultWho = r.resultWho; 2582 final int requestCode = r.requestCode; 2583 r.resultTo = null; 2584 if (resultTo != null) { 2585 resultTo.removeResultsLocked(r, resultWho, requestCode); 2586 } 2587 2588 final long origId = Binder.clearCallingIdentity(); 2589 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2590 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2591 resultWho, requestCode, -1, r.launchedFromUid, 0, 2592 options, false, null); 2593 Binder.restoreCallingIdentity(origId); 2594 2595 r.finishing = wasFinishing; 2596 if (res != ActivityManager.START_SUCCESS) { 2597 return false; 2598 } 2599 return true; 2600 } 2601 } 2602 2603 final int startActivityInPackage(int uid, 2604 Intent intent, String resolvedType, IBinder resultTo, 2605 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 2606 2607 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2608 false, true, "startActivityInPackage", null); 2609 2610 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2611 resultTo, resultWho, requestCode, startFlags, 2612 null, null, null, null, options, userId); 2613 return ret; 2614 } 2615 2616 public final int startActivities(IApplicationThread caller, 2617 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2618 enforceNotIsolatedCaller("startActivities"); 2619 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2620 options, UserHandle.getCallingUserId()); 2621 return ret; 2622 } 2623 2624 final int startActivitiesInPackage(int uid, 2625 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2626 Bundle options, int userId) { 2627 2628 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2629 false, true, "startActivityInPackage", null); 2630 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2631 options, userId); 2632 return ret; 2633 } 2634 2635 final void addRecentTaskLocked(TaskRecord task) { 2636 int N = mRecentTasks.size(); 2637 // Quick case: check if the top-most recent task is the same. 2638 if (N > 0 && mRecentTasks.get(0) == task) { 2639 return; 2640 } 2641 // Remove any existing entries that are the same kind of task. 2642 for (int i=0; i<N; i++) { 2643 TaskRecord tr = mRecentTasks.get(i); 2644 if (task.userId == tr.userId 2645 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2646 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2647 mRecentTasks.remove(i); 2648 i--; 2649 N--; 2650 if (task.intent == null) { 2651 // If the new recent task we are adding is not fully 2652 // specified, then replace it with the existing recent task. 2653 task = tr; 2654 } 2655 } 2656 } 2657 if (N >= MAX_RECENT_TASKS) { 2658 mRecentTasks.remove(N-1); 2659 } 2660 mRecentTasks.add(0, task); 2661 } 2662 2663 public void setRequestedOrientation(IBinder token, 2664 int requestedOrientation) { 2665 synchronized (this) { 2666 ActivityRecord r = mMainStack.isInStackLocked(token); 2667 if (r == null) { 2668 return; 2669 } 2670 final long origId = Binder.clearCallingIdentity(); 2671 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2672 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2673 mConfiguration, 2674 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2675 if (config != null) { 2676 r.frozenBeforeDestroy = true; 2677 if (!updateConfigurationLocked(config, r, false, false)) { 2678 mMainStack.resumeTopActivityLocked(null); 2679 } 2680 } 2681 Binder.restoreCallingIdentity(origId); 2682 } 2683 } 2684 2685 public int getRequestedOrientation(IBinder token) { 2686 synchronized (this) { 2687 ActivityRecord r = mMainStack.isInStackLocked(token); 2688 if (r == null) { 2689 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2690 } 2691 return mWindowManager.getAppOrientation(r.appToken); 2692 } 2693 } 2694 2695 /** 2696 * This is the internal entry point for handling Activity.finish(). 2697 * 2698 * @param token The Binder token referencing the Activity we want to finish. 2699 * @param resultCode Result code, if any, from this Activity. 2700 * @param resultData Result data (Intent), if any, from this Activity. 2701 * 2702 * @return Returns true if the activity successfully finished, or false if it is still running. 2703 */ 2704 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2705 // Refuse possible leaked file descriptors 2706 if (resultData != null && resultData.hasFileDescriptors() == true) { 2707 throw new IllegalArgumentException("File descriptors passed in Intent"); 2708 } 2709 2710 synchronized(this) { 2711 if (mController != null) { 2712 // Find the first activity that is not finishing. 2713 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2714 if (next != null) { 2715 // ask watcher if this is allowed 2716 boolean resumeOK = true; 2717 try { 2718 resumeOK = mController.activityResuming(next.packageName); 2719 } catch (RemoteException e) { 2720 mController = null; 2721 } 2722 2723 if (!resumeOK) { 2724 return false; 2725 } 2726 } 2727 } 2728 final long origId = Binder.clearCallingIdentity(); 2729 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2730 resultData, "app-request", true); 2731 Binder.restoreCallingIdentity(origId); 2732 return res; 2733 } 2734 } 2735 2736 public final void finishHeavyWeightApp() { 2737 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2738 != PackageManager.PERMISSION_GRANTED) { 2739 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2740 + Binder.getCallingPid() 2741 + ", uid=" + Binder.getCallingUid() 2742 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2743 Slog.w(TAG, msg); 2744 throw new SecurityException(msg); 2745 } 2746 2747 synchronized(this) { 2748 if (mHeavyWeightProcess == null) { 2749 return; 2750 } 2751 2752 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2753 mHeavyWeightProcess.activities); 2754 for (int i=0; i<activities.size(); i++) { 2755 ActivityRecord r = activities.get(i); 2756 if (!r.finishing) { 2757 int index = mMainStack.indexOfTokenLocked(r.appToken); 2758 if (index >= 0) { 2759 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2760 null, "finish-heavy", true); 2761 } 2762 } 2763 } 2764 2765 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 2766 mHeavyWeightProcess.userId, 0)); 2767 mHeavyWeightProcess = null; 2768 } 2769 } 2770 2771 public void crashApplication(int uid, int initialPid, String packageName, 2772 String message) { 2773 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2774 != PackageManager.PERMISSION_GRANTED) { 2775 String msg = "Permission Denial: crashApplication() from pid=" 2776 + Binder.getCallingPid() 2777 + ", uid=" + Binder.getCallingUid() 2778 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2779 Slog.w(TAG, msg); 2780 throw new SecurityException(msg); 2781 } 2782 2783 synchronized(this) { 2784 ProcessRecord proc = null; 2785 2786 // Figure out which process to kill. We don't trust that initialPid 2787 // still has any relation to current pids, so must scan through the 2788 // list. 2789 synchronized (mPidsSelfLocked) { 2790 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2791 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2792 if (p.uid != uid) { 2793 continue; 2794 } 2795 if (p.pid == initialPid) { 2796 proc = p; 2797 break; 2798 } 2799 for (String str : p.pkgList) { 2800 if (str.equals(packageName)) { 2801 proc = p; 2802 } 2803 } 2804 } 2805 } 2806 2807 if (proc == null) { 2808 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2809 + " initialPid=" + initialPid 2810 + " packageName=" + packageName); 2811 return; 2812 } 2813 2814 if (proc.thread != null) { 2815 if (proc.pid == Process.myPid()) { 2816 Log.w(TAG, "crashApplication: trying to crash self!"); 2817 return; 2818 } 2819 long ident = Binder.clearCallingIdentity(); 2820 try { 2821 proc.thread.scheduleCrash(message); 2822 } catch (RemoteException e) { 2823 } 2824 Binder.restoreCallingIdentity(ident); 2825 } 2826 } 2827 } 2828 2829 public final void finishSubActivity(IBinder token, String resultWho, 2830 int requestCode) { 2831 synchronized(this) { 2832 final long origId = Binder.clearCallingIdentity(); 2833 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2834 Binder.restoreCallingIdentity(origId); 2835 } 2836 } 2837 2838 public boolean finishActivityAffinity(IBinder token) { 2839 synchronized(this) { 2840 final long origId = Binder.clearCallingIdentity(); 2841 boolean res = mMainStack.finishActivityAffinityLocked(token); 2842 Binder.restoreCallingIdentity(origId); 2843 return res; 2844 } 2845 } 2846 2847 public boolean willActivityBeVisible(IBinder token) { 2848 synchronized(this) { 2849 int i; 2850 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2851 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2852 if (r.appToken == token) { 2853 return true; 2854 } 2855 if (r.fullscreen && !r.finishing) { 2856 return false; 2857 } 2858 } 2859 return true; 2860 } 2861 } 2862 2863 public void overridePendingTransition(IBinder token, String packageName, 2864 int enterAnim, int exitAnim) { 2865 synchronized(this) { 2866 ActivityRecord self = mMainStack.isInStackLocked(token); 2867 if (self == null) { 2868 return; 2869 } 2870 2871 final long origId = Binder.clearCallingIdentity(); 2872 2873 if (self.state == ActivityState.RESUMED 2874 || self.state == ActivityState.PAUSING) { 2875 mWindowManager.overridePendingAppTransition(packageName, 2876 enterAnim, exitAnim, null); 2877 } 2878 2879 Binder.restoreCallingIdentity(origId); 2880 } 2881 } 2882 2883 /** 2884 * Main function for removing an existing process from the activity manager 2885 * as a result of that process going away. Clears out all connections 2886 * to the process. 2887 */ 2888 private final void handleAppDiedLocked(ProcessRecord app, 2889 boolean restarting, boolean allowRestart) { 2890 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2891 if (!restarting) { 2892 mLruProcesses.remove(app); 2893 } 2894 2895 if (mProfileProc == app) { 2896 clearProfilerLocked(); 2897 } 2898 2899 // Just in case... 2900 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2901 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2902 mMainStack.mPausingActivity = null; 2903 } 2904 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2905 mMainStack.mLastPausedActivity = null; 2906 } 2907 2908 // Remove this application's activities from active lists. 2909 mMainStack.removeHistoryRecordsForAppLocked(app); 2910 2911 boolean atTop = true; 2912 boolean hasVisibleActivities = false; 2913 2914 // Clean out the history list. 2915 int i = mMainStack.mHistory.size(); 2916 if (localLOGV) Slog.v( 2917 TAG, "Removing app " + app + " from history with " + i + " entries"); 2918 while (i > 0) { 2919 i--; 2920 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2921 if (localLOGV) Slog.v( 2922 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2923 if (r.app == app) { 2924 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2925 if (ActivityStack.DEBUG_ADD_REMOVE) { 2926 RuntimeException here = new RuntimeException("here"); 2927 here.fillInStackTrace(); 2928 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2929 + ": haveState=" + r.haveState 2930 + " stateNotNeeded=" + r.stateNotNeeded 2931 + " finishing=" + r.finishing 2932 + " state=" + r.state, here); 2933 } 2934 if (!r.finishing) { 2935 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2936 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2937 System.identityHashCode(r), 2938 r.task.taskId, r.shortComponentName, 2939 "proc died without state saved"); 2940 } 2941 mMainStack.removeActivityFromHistoryLocked(r); 2942 2943 } else { 2944 // We have the current state for this activity, so 2945 // it can be restarted later when needed. 2946 if (localLOGV) Slog.v( 2947 TAG, "Keeping entry, setting app to null"); 2948 if (r.visible) { 2949 hasVisibleActivities = true; 2950 } 2951 r.app = null; 2952 r.nowVisible = false; 2953 if (!r.haveState) { 2954 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2955 "App died, clearing saved state of " + r); 2956 r.icicle = null; 2957 } 2958 } 2959 2960 r.stack.cleanUpActivityLocked(r, true, true); 2961 } 2962 atTop = false; 2963 } 2964 2965 app.activities.clear(); 2966 2967 if (app.instrumentationClass != null) { 2968 Slog.w(TAG, "Crash of app " + app.processName 2969 + " running instrumentation " + app.instrumentationClass); 2970 Bundle info = new Bundle(); 2971 info.putString("shortMsg", "Process crashed."); 2972 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2973 } 2974 2975 if (!restarting) { 2976 if (!mMainStack.resumeTopActivityLocked(null)) { 2977 // If there was nothing to resume, and we are not already 2978 // restarting this process, but there is a visible activity that 2979 // is hosted by the process... then make sure all visible 2980 // activities are running, taking care of restarting this 2981 // process. 2982 if (hasVisibleActivities) { 2983 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2984 } 2985 } 2986 } 2987 } 2988 2989 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2990 IBinder threadBinder = thread.asBinder(); 2991 // Find the application record. 2992 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2993 ProcessRecord rec = mLruProcesses.get(i); 2994 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2995 return i; 2996 } 2997 } 2998 return -1; 2999 } 3000 3001 final ProcessRecord getRecordForAppLocked( 3002 IApplicationThread thread) { 3003 if (thread == null) { 3004 return null; 3005 } 3006 3007 int appIndex = getLRURecordIndexForAppLocked(thread); 3008 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3009 } 3010 3011 final void appDiedLocked(ProcessRecord app, int pid, 3012 IApplicationThread thread) { 3013 3014 mProcDeaths[0]++; 3015 3016 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3017 synchronized (stats) { 3018 stats.noteProcessDiedLocked(app.info.uid, pid); 3019 } 3020 3021 // Clean up already done if the process has been re-started. 3022 if (app.pid == pid && app.thread != null && 3023 app.thread.asBinder() == thread.asBinder()) { 3024 if (!app.killedBackground) { 3025 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3026 + ") has died."); 3027 } 3028 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3029 if (localLOGV) Slog.v( 3030 TAG, "Dying app: " + app + ", pid: " + pid 3031 + ", thread: " + thread.asBinder()); 3032 boolean doLowMem = app.instrumentationClass == null; 3033 handleAppDiedLocked(app, false, true); 3034 3035 if (doLowMem) { 3036 // If there are no longer any background processes running, 3037 // and the app that died was not running instrumentation, 3038 // then tell everyone we are now low on memory. 3039 boolean haveBg = false; 3040 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3041 ProcessRecord rec = mLruProcesses.get(i); 3042 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3043 haveBg = true; 3044 break; 3045 } 3046 } 3047 3048 if (!haveBg) { 3049 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3050 long now = SystemClock.uptimeMillis(); 3051 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3052 ProcessRecord rec = mLruProcesses.get(i); 3053 if (rec != app && rec.thread != null && 3054 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3055 // The low memory report is overriding any current 3056 // state for a GC request. Make sure to do 3057 // heavy/important/visible/foreground processes first. 3058 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3059 rec.lastRequestedGc = 0; 3060 } else { 3061 rec.lastRequestedGc = rec.lastLowMemory; 3062 } 3063 rec.reportLowMemory = true; 3064 rec.lastLowMemory = now; 3065 mProcessesToGc.remove(rec); 3066 addProcessToGcListLocked(rec); 3067 } 3068 } 3069 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3070 scheduleAppGcsLocked(); 3071 } 3072 } 3073 } else if (app.pid != pid) { 3074 // A new process has already been started. 3075 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3076 + ") has died and restarted (pid " + app.pid + ")."); 3077 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3078 } else if (DEBUG_PROCESSES) { 3079 Slog.d(TAG, "Received spurious death notification for thread " 3080 + thread.asBinder()); 3081 } 3082 } 3083 3084 /** 3085 * If a stack trace dump file is configured, dump process stack traces. 3086 * @param clearTraces causes the dump file to be erased prior to the new 3087 * traces being written, if true; when false, the new traces will be 3088 * appended to any existing file content. 3089 * @param firstPids of dalvik VM processes to dump stack traces for first 3090 * @param lastPids of dalvik VM processes to dump stack traces for last 3091 * @param nativeProcs optional list of native process names to dump stack crawls 3092 * @return file containing stack traces, or null if no dump file is configured 3093 */ 3094 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3095 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3096 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3097 if (tracesPath == null || tracesPath.length() == 0) { 3098 return null; 3099 } 3100 3101 File tracesFile = new File(tracesPath); 3102 try { 3103 File tracesDir = tracesFile.getParentFile(); 3104 if (!tracesDir.exists()) { 3105 tracesFile.mkdirs(); 3106 if (!SELinux.restorecon(tracesDir)) { 3107 return null; 3108 } 3109 } 3110 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3111 3112 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3113 tracesFile.createNewFile(); 3114 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3115 } catch (IOException e) { 3116 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3117 return null; 3118 } 3119 3120 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3121 return tracesFile; 3122 } 3123 3124 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3125 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3126 // Use a FileObserver to detect when traces finish writing. 3127 // The order of traces is considered important to maintain for legibility. 3128 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3129 public synchronized void onEvent(int event, String path) { notify(); } 3130 }; 3131 3132 try { 3133 observer.startWatching(); 3134 3135 // First collect all of the stacks of the most important pids. 3136 if (firstPids != null) { 3137 try { 3138 int num = firstPids.size(); 3139 for (int i = 0; i < num; i++) { 3140 synchronized (observer) { 3141 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3142 observer.wait(200); // Wait for write-close, give up after 200msec 3143 } 3144 } 3145 } catch (InterruptedException e) { 3146 Log.wtf(TAG, e); 3147 } 3148 } 3149 3150 // Next measure CPU usage. 3151 if (processStats != null) { 3152 processStats.init(); 3153 System.gc(); 3154 processStats.update(); 3155 try { 3156 synchronized (processStats) { 3157 processStats.wait(500); // measure over 1/2 second. 3158 } 3159 } catch (InterruptedException e) { 3160 } 3161 processStats.update(); 3162 3163 // We'll take the stack crawls of just the top apps using CPU. 3164 final int N = processStats.countWorkingStats(); 3165 int numProcs = 0; 3166 for (int i=0; i<N && numProcs<5; i++) { 3167 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3168 if (lastPids.indexOfKey(stats.pid) >= 0) { 3169 numProcs++; 3170 try { 3171 synchronized (observer) { 3172 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3173 observer.wait(200); // Wait for write-close, give up after 200msec 3174 } 3175 } catch (InterruptedException e) { 3176 Log.wtf(TAG, e); 3177 } 3178 3179 } 3180 } 3181 } 3182 3183 } finally { 3184 observer.stopWatching(); 3185 } 3186 3187 if (nativeProcs != null) { 3188 int[] pids = Process.getPidsForCommands(nativeProcs); 3189 if (pids != null) { 3190 for (int pid : pids) { 3191 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3192 } 3193 } 3194 } 3195 } 3196 3197 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3198 if (true || IS_USER_BUILD) { 3199 return; 3200 } 3201 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3202 if (tracesPath == null || tracesPath.length() == 0) { 3203 return; 3204 } 3205 3206 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3207 StrictMode.allowThreadDiskWrites(); 3208 try { 3209 final File tracesFile = new File(tracesPath); 3210 final File tracesDir = tracesFile.getParentFile(); 3211 final File tracesTmp = new File(tracesDir, "__tmp__"); 3212 try { 3213 if (!tracesDir.exists()) { 3214 tracesFile.mkdirs(); 3215 if (!SELinux.restorecon(tracesDir.getPath())) { 3216 return; 3217 } 3218 } 3219 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3220 3221 if (tracesFile.exists()) { 3222 tracesTmp.delete(); 3223 tracesFile.renameTo(tracesTmp); 3224 } 3225 StringBuilder sb = new StringBuilder(); 3226 Time tobj = new Time(); 3227 tobj.set(System.currentTimeMillis()); 3228 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3229 sb.append(": "); 3230 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3231 sb.append(" since "); 3232 sb.append(msg); 3233 FileOutputStream fos = new FileOutputStream(tracesFile); 3234 fos.write(sb.toString().getBytes()); 3235 if (app == null) { 3236 fos.write("\n*** No application process!".getBytes()); 3237 } 3238 fos.close(); 3239 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3240 } catch (IOException e) { 3241 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3242 return; 3243 } 3244 3245 if (app != null) { 3246 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3247 firstPids.add(app.pid); 3248 dumpStackTraces(tracesPath, firstPids, null, null, null); 3249 } 3250 3251 File lastTracesFile = null; 3252 File curTracesFile = null; 3253 for (int i=9; i>=0; i--) { 3254 String name = String.format("slow%02d.txt", i); 3255 curTracesFile = new File(tracesDir, name); 3256 if (curTracesFile.exists()) { 3257 if (lastTracesFile != null) { 3258 curTracesFile.renameTo(lastTracesFile); 3259 } else { 3260 curTracesFile.delete(); 3261 } 3262 } 3263 lastTracesFile = curTracesFile; 3264 } 3265 tracesFile.renameTo(curTracesFile); 3266 if (tracesTmp.exists()) { 3267 tracesTmp.renameTo(tracesFile); 3268 } 3269 } finally { 3270 StrictMode.setThreadPolicy(oldPolicy); 3271 } 3272 } 3273 3274 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3275 ActivityRecord parent, final String annotation) { 3276 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3277 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3278 3279 if (mController != null) { 3280 try { 3281 // 0 == continue, -1 = kill process immediately 3282 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3283 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3284 } catch (RemoteException e) { 3285 mController = null; 3286 } 3287 } 3288 3289 long anrTime = SystemClock.uptimeMillis(); 3290 if (MONITOR_CPU_USAGE) { 3291 updateCpuStatsNow(); 3292 } 3293 3294 synchronized (this) { 3295 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3296 if (mShuttingDown) { 3297 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3298 return; 3299 } else if (app.notResponding) { 3300 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3301 return; 3302 } else if (app.crashing) { 3303 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3304 return; 3305 } 3306 3307 // In case we come through here for the same app before completing 3308 // this one, mark as anring now so we will bail out. 3309 app.notResponding = true; 3310 3311 // Log the ANR to the event log. 3312 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3313 annotation); 3314 3315 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3316 firstPids.add(app.pid); 3317 3318 int parentPid = app.pid; 3319 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3320 if (parentPid != app.pid) firstPids.add(parentPid); 3321 3322 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3323 3324 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3325 ProcessRecord r = mLruProcesses.get(i); 3326 if (r != null && r.thread != null) { 3327 int pid = r.pid; 3328 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3329 if (r.persistent) { 3330 firstPids.add(pid); 3331 } else { 3332 lastPids.put(pid, Boolean.TRUE); 3333 } 3334 } 3335 } 3336 } 3337 } 3338 3339 // Log the ANR to the main log. 3340 StringBuilder info = new StringBuilder(); 3341 info.setLength(0); 3342 info.append("ANR in ").append(app.processName); 3343 if (activity != null && activity.shortComponentName != null) { 3344 info.append(" (").append(activity.shortComponentName).append(")"); 3345 } 3346 info.append("\n"); 3347 if (annotation != null) { 3348 info.append("Reason: ").append(annotation).append("\n"); 3349 } 3350 if (parent != null && parent != activity) { 3351 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3352 } 3353 3354 final ProcessStats processStats = new ProcessStats(true); 3355 3356 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3357 3358 String cpuInfo = null; 3359 if (MONITOR_CPU_USAGE) { 3360 updateCpuStatsNow(); 3361 synchronized (mProcessStatsThread) { 3362 cpuInfo = mProcessStats.printCurrentState(anrTime); 3363 } 3364 info.append(processStats.printCurrentLoad()); 3365 info.append(cpuInfo); 3366 } 3367 3368 info.append(processStats.printCurrentState(anrTime)); 3369 3370 Slog.e(TAG, info.toString()); 3371 if (tracesFile == null) { 3372 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3373 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3374 } 3375 3376 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3377 cpuInfo, tracesFile, null); 3378 3379 if (mController != null) { 3380 try { 3381 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3382 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3383 if (res != 0) { 3384 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3385 return; 3386 } 3387 } catch (RemoteException e) { 3388 mController = null; 3389 } 3390 } 3391 3392 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3393 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3394 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3395 3396 synchronized (this) { 3397 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3398 Slog.w(TAG, "Killing " + app + ": background ANR"); 3399 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3400 app.processName, app.setAdj, "background ANR"); 3401 Process.killProcessQuiet(app.pid); 3402 return; 3403 } 3404 3405 // Set the app's notResponding state, and look up the errorReportReceiver 3406 makeAppNotRespondingLocked(app, 3407 activity != null ? activity.shortComponentName : null, 3408 annotation != null ? "ANR " + annotation : "ANR", 3409 info.toString()); 3410 3411 // Bring up the infamous App Not Responding dialog 3412 Message msg = Message.obtain(); 3413 HashMap map = new HashMap(); 3414 msg.what = SHOW_NOT_RESPONDING_MSG; 3415 msg.obj = map; 3416 map.put("app", app); 3417 if (activity != null) { 3418 map.put("activity", activity); 3419 } 3420 3421 mHandler.sendMessage(msg); 3422 } 3423 } 3424 3425 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3426 if (!mLaunchWarningShown) { 3427 mLaunchWarningShown = true; 3428 mHandler.post(new Runnable() { 3429 @Override 3430 public void run() { 3431 synchronized (ActivityManagerService.this) { 3432 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3433 d.show(); 3434 mHandler.postDelayed(new Runnable() { 3435 @Override 3436 public void run() { 3437 synchronized (ActivityManagerService.this) { 3438 d.dismiss(); 3439 mLaunchWarningShown = false; 3440 } 3441 } 3442 }, 4000); 3443 } 3444 } 3445 }); 3446 } 3447 } 3448 3449 public boolean clearApplicationUserData(final String packageName, 3450 final IPackageDataObserver observer, int userId) { 3451 enforceNotIsolatedCaller("clearApplicationUserData"); 3452 int uid = Binder.getCallingUid(); 3453 int pid = Binder.getCallingPid(); 3454 userId = handleIncomingUserLocked(pid, uid, 3455 userId, false, true, "clearApplicationUserData", null); 3456 long callingId = Binder.clearCallingIdentity(); 3457 try { 3458 IPackageManager pm = AppGlobals.getPackageManager(); 3459 int pkgUid = -1; 3460 synchronized(this) { 3461 try { 3462 pkgUid = pm.getPackageUid(packageName, userId); 3463 } catch (RemoteException e) { 3464 } 3465 if (pkgUid == -1) { 3466 Slog.w(TAG, "Invalid packageName:" + packageName); 3467 return false; 3468 } 3469 if (uid == pkgUid || checkComponentPermission( 3470 android.Manifest.permission.CLEAR_APP_USER_DATA, 3471 pid, uid, -1, true) 3472 == PackageManager.PERMISSION_GRANTED) { 3473 forceStopPackageLocked(packageName, pkgUid); 3474 } else { 3475 throw new SecurityException(pid+" does not have permission:"+ 3476 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3477 "for process:"+packageName); 3478 } 3479 } 3480 3481 try { 3482 //clear application user data 3483 pm.clearApplicationUserData(packageName, observer, userId); 3484 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3485 Uri.fromParts("package", packageName, null)); 3486 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3487 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3488 null, null, 0, null, null, null, false, false, userId); 3489 } catch (RemoteException e) { 3490 } 3491 } finally { 3492 Binder.restoreCallingIdentity(callingId); 3493 } 3494 return true; 3495 } 3496 3497 public void killBackgroundProcesses(final String packageName, int userId) { 3498 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3499 != PackageManager.PERMISSION_GRANTED && 3500 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3501 != PackageManager.PERMISSION_GRANTED) { 3502 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3503 + Binder.getCallingPid() 3504 + ", uid=" + Binder.getCallingUid() 3505 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3506 Slog.w(TAG, msg); 3507 throw new SecurityException(msg); 3508 } 3509 3510 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3511 userId, true, true, "killBackgroundProcesses", null); 3512 long callingId = Binder.clearCallingIdentity(); 3513 try { 3514 IPackageManager pm = AppGlobals.getPackageManager(); 3515 synchronized(this) { 3516 int appId = -1; 3517 try { 3518 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 3519 } catch (RemoteException e) { 3520 } 3521 if (appId == -1) { 3522 Slog.w(TAG, "Invalid packageName: " + packageName); 3523 return; 3524 } 3525 killPackageProcessesLocked(packageName, appId, userId, 3526 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3527 } 3528 } finally { 3529 Binder.restoreCallingIdentity(callingId); 3530 } 3531 } 3532 3533 public void killAllBackgroundProcesses() { 3534 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3535 != PackageManager.PERMISSION_GRANTED) { 3536 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3537 + Binder.getCallingPid() 3538 + ", uid=" + Binder.getCallingUid() 3539 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3540 Slog.w(TAG, msg); 3541 throw new SecurityException(msg); 3542 } 3543 3544 long callingId = Binder.clearCallingIdentity(); 3545 try { 3546 synchronized(this) { 3547 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3548 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3549 final int NA = apps.size(); 3550 for (int ia=0; ia<NA; ia++) { 3551 ProcessRecord app = apps.valueAt(ia); 3552 if (app.persistent) { 3553 // we don't kill persistent processes 3554 continue; 3555 } 3556 if (app.removed) { 3557 procs.add(app); 3558 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3559 app.removed = true; 3560 procs.add(app); 3561 } 3562 } 3563 } 3564 3565 int N = procs.size(); 3566 for (int i=0; i<N; i++) { 3567 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3568 } 3569 } 3570 } finally { 3571 Binder.restoreCallingIdentity(callingId); 3572 } 3573 } 3574 3575 public void forceStopPackage(final String packageName, int userId) { 3576 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3577 != PackageManager.PERMISSION_GRANTED) { 3578 String msg = "Permission Denial: forceStopPackage() from pid=" 3579 + Binder.getCallingPid() 3580 + ", uid=" + Binder.getCallingUid() 3581 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3582 Slog.w(TAG, msg); 3583 throw new SecurityException(msg); 3584 } 3585 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 3586 userId, true, true, "forceStopPackage", null); 3587 long callingId = Binder.clearCallingIdentity(); 3588 try { 3589 IPackageManager pm = AppGlobals.getPackageManager(); 3590 synchronized(this) { 3591 int[] users = userId == UserHandle.USER_ALL 3592 ? getUsersLocked() : new int[] { userId }; 3593 for (int user : users) { 3594 int pkgUid = -1; 3595 try { 3596 pkgUid = pm.getPackageUid(packageName, user); 3597 } catch (RemoteException e) { 3598 } 3599 if (pkgUid == -1) { 3600 Slog.w(TAG, "Invalid packageName: " + packageName); 3601 continue; 3602 } 3603 try { 3604 pm.setPackageStoppedState(packageName, true, user); 3605 } catch (RemoteException e) { 3606 } catch (IllegalArgumentException e) { 3607 Slog.w(TAG, "Failed trying to unstop package " 3608 + packageName + ": " + e); 3609 } 3610 if (isUserRunningLocked(user)) { 3611 forceStopPackageLocked(packageName, pkgUid); 3612 } 3613 } 3614 } 3615 } finally { 3616 Binder.restoreCallingIdentity(callingId); 3617 } 3618 } 3619 3620 /* 3621 * The pkg name and app id have to be specified. 3622 */ 3623 public void killApplicationWithAppId(String pkg, int appid) { 3624 if (pkg == null) { 3625 return; 3626 } 3627 // Make sure the uid is valid. 3628 if (appid < 0) { 3629 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 3630 return; 3631 } 3632 int callerUid = Binder.getCallingUid(); 3633 // Only the system server can kill an application 3634 if (callerUid == Process.SYSTEM_UID) { 3635 // Post an aysnc message to kill the application 3636 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3637 msg.arg1 = appid; 3638 msg.arg2 = 0; 3639 msg.obj = pkg; 3640 mHandler.sendMessage(msg); 3641 } else { 3642 throw new SecurityException(callerUid + " cannot kill pkg: " + 3643 pkg); 3644 } 3645 } 3646 3647 public void closeSystemDialogs(String reason) { 3648 enforceNotIsolatedCaller("closeSystemDialogs"); 3649 3650 final int pid = Binder.getCallingPid(); 3651 final int uid = Binder.getCallingUid(); 3652 final long origId = Binder.clearCallingIdentity(); 3653 try { 3654 synchronized (this) { 3655 // Only allow this from foreground processes, so that background 3656 // applications can't abuse it to prevent system UI from being shown. 3657 if (uid >= Process.FIRST_APPLICATION_UID) { 3658 ProcessRecord proc; 3659 synchronized (mPidsSelfLocked) { 3660 proc = mPidsSelfLocked.get(pid); 3661 } 3662 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 3663 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 3664 + " from background process " + proc); 3665 return; 3666 } 3667 } 3668 closeSystemDialogsLocked(reason); 3669 } 3670 } finally { 3671 Binder.restoreCallingIdentity(origId); 3672 } 3673 } 3674 3675 void closeSystemDialogsLocked(String reason) { 3676 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3677 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3678 if (reason != null) { 3679 intent.putExtra("reason", reason); 3680 } 3681 mWindowManager.closeSystemDialogs(reason); 3682 3683 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3684 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3685 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3686 r.stack.finishActivityLocked(r, i, 3687 Activity.RESULT_CANCELED, null, "close-sys", true); 3688 } 3689 } 3690 3691 broadcastIntentLocked(null, null, intent, null, 3692 null, 0, null, null, null, false, false, -1, 3693 Process.SYSTEM_UID, UserHandle.USER_ALL); 3694 } 3695 3696 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3697 throws RemoteException { 3698 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3699 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3700 for (int i=pids.length-1; i>=0; i--) { 3701 infos[i] = new Debug.MemoryInfo(); 3702 Debug.getMemoryInfo(pids[i], infos[i]); 3703 } 3704 return infos; 3705 } 3706 3707 public long[] getProcessPss(int[] pids) throws RemoteException { 3708 enforceNotIsolatedCaller("getProcessPss"); 3709 long[] pss = new long[pids.length]; 3710 for (int i=pids.length-1; i>=0; i--) { 3711 pss[i] = Debug.getPss(pids[i]); 3712 } 3713 return pss; 3714 } 3715 3716 public void killApplicationProcess(String processName, int uid) { 3717 if (processName == null) { 3718 return; 3719 } 3720 3721 int callerUid = Binder.getCallingUid(); 3722 // Only the system server can kill an application 3723 if (callerUid == Process.SYSTEM_UID) { 3724 synchronized (this) { 3725 ProcessRecord app = getProcessRecordLocked(processName, uid); 3726 if (app != null && app.thread != null) { 3727 try { 3728 app.thread.scheduleSuicide(); 3729 } catch (RemoteException e) { 3730 // If the other end already died, then our work here is done. 3731 } 3732 } else { 3733 Slog.w(TAG, "Process/uid not found attempting kill of " 3734 + processName + " / " + uid); 3735 } 3736 } 3737 } else { 3738 throw new SecurityException(callerUid + " cannot kill app process: " + 3739 processName); 3740 } 3741 } 3742 3743 private void forceStopPackageLocked(final String packageName, int uid) { 3744 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 3745 false, true, false, UserHandle.getUserId(uid)); 3746 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3747 Uri.fromParts("package", packageName, null)); 3748 if (!mProcessesReady) { 3749 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3750 } 3751 intent.putExtra(Intent.EXTRA_UID, uid); 3752 broadcastIntentLocked(null, null, intent, 3753 null, null, 0, null, null, null, 3754 false, false, 3755 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 3756 } 3757 3758 private void forceStopUserLocked(int userId) { 3759 forceStopPackageLocked(null, -1, false, false, true, false, userId); 3760 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 3761 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3762 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 3763 broadcastIntentLocked(null, null, intent, 3764 null, null, 0, null, null, null, 3765 false, false, 3766 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 3767 } 3768 3769 private final boolean killPackageProcessesLocked(String packageName, int appId, 3770 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 3771 boolean doit, boolean evenPersistent, String reason) { 3772 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3773 3774 // Remove all processes this package may have touched: all with the 3775 // same UID (except for the system or root user), and all whose name 3776 // matches the package name. 3777 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 3778 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3779 final int NA = apps.size(); 3780 for (int ia=0; ia<NA; ia++) { 3781 ProcessRecord app = apps.valueAt(ia); 3782 if (app.persistent && !evenPersistent) { 3783 // we don't kill persistent processes 3784 continue; 3785 } 3786 if (app.removed) { 3787 if (doit) { 3788 procs.add(app); 3789 } 3790 continue; 3791 } 3792 3793 // Skip process if it doesn't meet our oom adj requirement. 3794 if (app.setAdj < minOomAdj) { 3795 continue; 3796 } 3797 3798 // If no package is specified, we call all processes under the 3799 // give user id. 3800 if (packageName == null) { 3801 if (app.userId != userId) { 3802 continue; 3803 } 3804 // Package has been specified, we want to hit all processes 3805 // that match it. We need to qualify this by the processes 3806 // that are running under the specified app and user ID. 3807 } else { 3808 if (UserHandle.getAppId(app.uid) != appId) { 3809 continue; 3810 } 3811 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3812 continue; 3813 } 3814 if (!app.pkgList.contains(packageName)) { 3815 continue; 3816 } 3817 } 3818 3819 // Process has passed all conditions, kill it! 3820 if (!doit) { 3821 return true; 3822 } 3823 app.removed = true; 3824 procs.add(app); 3825 } 3826 } 3827 3828 int N = procs.size(); 3829 for (int i=0; i<N; i++) { 3830 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3831 } 3832 return N > 0; 3833 } 3834 3835 private final boolean forceStopPackageLocked(String name, int appId, 3836 boolean callerWillRestart, boolean purgeCache, boolean doit, 3837 boolean evenPersistent, int userId) { 3838 int i; 3839 int N; 3840 3841 if (userId == UserHandle.USER_ALL && name == null) { 3842 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 3843 } 3844 3845 if (appId < 0 && name != null) { 3846 try { 3847 appId = UserHandle.getAppId( 3848 AppGlobals.getPackageManager().getPackageUid(name, 0)); 3849 } catch (RemoteException e) { 3850 } 3851 } 3852 3853 if (doit) { 3854 if (name != null) { 3855 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId 3856 + " user=" + userId); 3857 } else { 3858 Slog.i(TAG, "Force stopping user " + userId); 3859 } 3860 3861 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3862 while (badApps.hasNext()) { 3863 SparseArray<Long> ba = badApps.next(); 3864 for (i=ba.size()-1; i>=0; i--) { 3865 boolean remove = false; 3866 final int entUid = ba.keyAt(i); 3867 if (name != null) { 3868 if (userId == UserHandle.USER_ALL) { 3869 if (UserHandle.getAppId(entUid) == appId) { 3870 remove = true; 3871 } 3872 } else { 3873 if (entUid == UserHandle.getUid(userId, appId)) { 3874 remove = true; 3875 } 3876 } 3877 } else if (UserHandle.getUserId(entUid) == userId) { 3878 remove = true; 3879 } 3880 if (remove) { 3881 ba.removeAt(i); 3882 } 3883 } 3884 if (ba.size() == 0) { 3885 badApps.remove(); 3886 } 3887 } 3888 } 3889 3890 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 3891 -100, callerWillRestart, false, doit, evenPersistent, 3892 name == null ? ("force stop user " + userId) : ("force stop " + name)); 3893 3894 TaskRecord lastTask = null; 3895 for (i=0; i<mMainStack.mHistory.size(); i++) { 3896 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3897 final boolean samePackage = r.packageName.equals(name) 3898 || (name == null && r.userId == userId); 3899 if ((userId == UserHandle.USER_ALL || r.userId == userId) 3900 && (samePackage || r.task == lastTask) 3901 && (r.app == null || evenPersistent || !r.app.persistent)) { 3902 if (!doit) { 3903 if (r.finishing) { 3904 // If this activity is just finishing, then it is not 3905 // interesting as far as something to stop. 3906 continue; 3907 } 3908 return true; 3909 } 3910 didSomething = true; 3911 Slog.i(TAG, " Force finishing activity " + r); 3912 if (samePackage) { 3913 if (r.app != null) { 3914 r.app.removed = true; 3915 } 3916 r.app = null; 3917 } 3918 lastTask = r.task; 3919 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3920 null, "force-stop", true)) { 3921 i--; 3922 } 3923 } 3924 } 3925 3926 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 3927 if (!doit) { 3928 return true; 3929 } 3930 didSomething = true; 3931 } 3932 3933 if (name == null) { 3934 // Remove all sticky broadcasts from this user. 3935 mStickyBroadcasts.remove(userId); 3936 } 3937 3938 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3939 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 3940 userId, providers)) { 3941 if (!doit) { 3942 return true; 3943 } 3944 didSomething = true; 3945 } 3946 N = providers.size(); 3947 for (i=0; i<N; i++) { 3948 removeDyingProviderLocked(null, providers.get(i), true); 3949 } 3950 3951 if (mIntentSenderRecords.size() > 0) { 3952 Iterator<WeakReference<PendingIntentRecord>> it 3953 = mIntentSenderRecords.values().iterator(); 3954 while (it.hasNext()) { 3955 WeakReference<PendingIntentRecord> wpir = it.next(); 3956 if (wpir == null) { 3957 it.remove(); 3958 continue; 3959 } 3960 PendingIntentRecord pir = wpir.get(); 3961 if (pir == null) { 3962 it.remove(); 3963 continue; 3964 } 3965 if (name == null) { 3966 // Stopping user, remove all objects for the user. 3967 if (pir.key.userId != userId) { 3968 // Not the same user, skip it. 3969 continue; 3970 } 3971 } else { 3972 if (UserHandle.getAppId(pir.uid) != appId) { 3973 // Different app id, skip it. 3974 continue; 3975 } 3976 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 3977 // Different user, skip it. 3978 continue; 3979 } 3980 if (!pir.key.packageName.equals(name)) { 3981 // Different package, skip it. 3982 continue; 3983 } 3984 } 3985 if (!doit) { 3986 return true; 3987 } 3988 didSomething = true; 3989 it.remove(); 3990 pir.canceled = true; 3991 if (pir.key.activity != null) { 3992 pir.key.activity.pendingResults.remove(pir.ref); 3993 } 3994 } 3995 } 3996 3997 if (doit) { 3998 if (purgeCache && name != null) { 3999 AttributeCache ac = AttributeCache.instance(); 4000 if (ac != null) { 4001 ac.removePackage(name); 4002 } 4003 } 4004 if (mBooted) { 4005 mMainStack.resumeTopActivityLocked(null); 4006 mMainStack.scheduleIdleLocked(); 4007 } 4008 } 4009 4010 return didSomething; 4011 } 4012 4013 private final boolean removeProcessLocked(ProcessRecord app, 4014 boolean callerWillRestart, boolean allowRestart, String reason) { 4015 final String name = app.processName; 4016 final int uid = app.uid; 4017 if (DEBUG_PROCESSES) Slog.d( 4018 TAG, "Force removing proc " + app.toShortString() + " (" + name 4019 + "/" + uid + ")"); 4020 4021 mProcessNames.remove(name, uid); 4022 mIsolatedProcesses.remove(app.uid); 4023 if (mHeavyWeightProcess == app) { 4024 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4025 mHeavyWeightProcess.userId, 0)); 4026 mHeavyWeightProcess = null; 4027 } 4028 boolean needRestart = false; 4029 if (app.pid > 0 && app.pid != MY_PID) { 4030 int pid = app.pid; 4031 synchronized (mPidsSelfLocked) { 4032 mPidsSelfLocked.remove(pid); 4033 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4034 } 4035 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 4036 handleAppDiedLocked(app, true, allowRestart); 4037 mLruProcesses.remove(app); 4038 Process.killProcessQuiet(pid); 4039 4040 if (app.persistent && !app.isolated) { 4041 if (!callerWillRestart) { 4042 addAppLocked(app.info, false); 4043 } else { 4044 needRestart = true; 4045 } 4046 } 4047 } else { 4048 mRemovedProcesses.add(app); 4049 } 4050 4051 return needRestart; 4052 } 4053 4054 private final void processStartTimedOutLocked(ProcessRecord app) { 4055 final int pid = app.pid; 4056 boolean gone = false; 4057 synchronized (mPidsSelfLocked) { 4058 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4059 if (knownApp != null && knownApp.thread == null) { 4060 mPidsSelfLocked.remove(pid); 4061 gone = true; 4062 } 4063 } 4064 4065 if (gone) { 4066 Slog.w(TAG, "Process " + app + " failed to attach"); 4067 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 4068 app.processName); 4069 mProcessNames.remove(app.processName, app.uid); 4070 mIsolatedProcesses.remove(app.uid); 4071 if (mHeavyWeightProcess == app) { 4072 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4073 mHeavyWeightProcess.userId, 0)); 4074 mHeavyWeightProcess = null; 4075 } 4076 // Take care of any launching providers waiting for this process. 4077 checkAppInLaunchingProvidersLocked(app, true); 4078 // Take care of any services that are waiting for the process. 4079 mServices.processStartTimedOutLocked(app); 4080 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 4081 app.processName, app.setAdj, "start timeout"); 4082 Process.killProcessQuiet(pid); 4083 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4084 Slog.w(TAG, "Unattached app died before backup, skipping"); 4085 try { 4086 IBackupManager bm = IBackupManager.Stub.asInterface( 4087 ServiceManager.getService(Context.BACKUP_SERVICE)); 4088 bm.agentDisconnected(app.info.packageName); 4089 } catch (RemoteException e) { 4090 // Can't happen; the backup manager is local 4091 } 4092 } 4093 if (isPendingBroadcastProcessLocked(pid)) { 4094 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4095 skipPendingBroadcastLocked(pid); 4096 } 4097 } else { 4098 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4099 } 4100 } 4101 4102 private final boolean attachApplicationLocked(IApplicationThread thread, 4103 int pid) { 4104 4105 // Find the application record that is being attached... either via 4106 // the pid if we are running in multiple processes, or just pull the 4107 // next app record if we are emulating process with anonymous threads. 4108 ProcessRecord app; 4109 if (pid != MY_PID && pid >= 0) { 4110 synchronized (mPidsSelfLocked) { 4111 app = mPidsSelfLocked.get(pid); 4112 } 4113 } else { 4114 app = null; 4115 } 4116 4117 if (app == null) { 4118 Slog.w(TAG, "No pending application record for pid " + pid 4119 + " (IApplicationThread " + thread + "); dropping process"); 4120 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4121 if (pid > 0 && pid != MY_PID) { 4122 Process.killProcessQuiet(pid); 4123 } else { 4124 try { 4125 thread.scheduleExit(); 4126 } catch (Exception e) { 4127 // Ignore exceptions. 4128 } 4129 } 4130 return false; 4131 } 4132 4133 // If this application record is still attached to a previous 4134 // process, clean it up now. 4135 if (app.thread != null) { 4136 handleAppDiedLocked(app, true, true); 4137 } 4138 4139 // Tell the process all about itself. 4140 4141 if (localLOGV) Slog.v( 4142 TAG, "Binding process pid " + pid + " to record " + app); 4143 4144 String processName = app.processName; 4145 try { 4146 AppDeathRecipient adr = new AppDeathRecipient( 4147 app, pid, thread); 4148 thread.asBinder().linkToDeath(adr, 0); 4149 app.deathRecipient = adr; 4150 } catch (RemoteException e) { 4151 app.resetPackageList(); 4152 startProcessLocked(app, "link fail", processName); 4153 return false; 4154 } 4155 4156 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 4157 4158 app.thread = thread; 4159 app.curAdj = app.setAdj = -100; 4160 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 4161 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 4162 app.forcingToForeground = null; 4163 app.foregroundServices = false; 4164 app.hasShownUi = false; 4165 app.debugging = false; 4166 4167 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4168 4169 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4170 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4171 4172 if (!normalMode) { 4173 Slog.i(TAG, "Launching preboot mode app: " + app); 4174 } 4175 4176 if (localLOGV) Slog.v( 4177 TAG, "New app record " + app 4178 + " thread=" + thread.asBinder() + " pid=" + pid); 4179 try { 4180 int testMode = IApplicationThread.DEBUG_OFF; 4181 if (mDebugApp != null && mDebugApp.equals(processName)) { 4182 testMode = mWaitForDebugger 4183 ? IApplicationThread.DEBUG_WAIT 4184 : IApplicationThread.DEBUG_ON; 4185 app.debugging = true; 4186 if (mDebugTransient) { 4187 mDebugApp = mOrigDebugApp; 4188 mWaitForDebugger = mOrigWaitForDebugger; 4189 } 4190 } 4191 String profileFile = app.instrumentationProfileFile; 4192 ParcelFileDescriptor profileFd = null; 4193 boolean profileAutoStop = false; 4194 if (mProfileApp != null && mProfileApp.equals(processName)) { 4195 mProfileProc = app; 4196 profileFile = mProfileFile; 4197 profileFd = mProfileFd; 4198 profileAutoStop = mAutoStopProfiler; 4199 } 4200 boolean enableOpenGlTrace = false; 4201 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4202 enableOpenGlTrace = true; 4203 mOpenGlTraceApp = null; 4204 } 4205 4206 // If the app is being launched for restore or full backup, set it up specially 4207 boolean isRestrictedBackupMode = false; 4208 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4209 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4210 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4211 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4212 } 4213 4214 ensurePackageDexOpt(app.instrumentationInfo != null 4215 ? app.instrumentationInfo.packageName 4216 : app.info.packageName); 4217 if (app.instrumentationClass != null) { 4218 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4219 } 4220 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4221 + processName + " with config " + mConfiguration); 4222 ApplicationInfo appInfo = app.instrumentationInfo != null 4223 ? app.instrumentationInfo : app.info; 4224 app.compat = compatibilityInfoForPackageLocked(appInfo); 4225 if (profileFd != null) { 4226 profileFd = profileFd.dup(); 4227 } 4228 thread.bindApplication(processName, appInfo, providers, 4229 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4230 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4231 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4232 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4233 mCoreSettingsObserver.getCoreSettingsLocked()); 4234 updateLruProcessLocked(app, false, true); 4235 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4236 } catch (Exception e) { 4237 // todo: Yikes! What should we do? For now we will try to 4238 // start another process, but that could easily get us in 4239 // an infinite loop of restarting processes... 4240 Slog.w(TAG, "Exception thrown during bind!", e); 4241 4242 app.resetPackageList(); 4243 app.unlinkDeathRecipient(); 4244 startProcessLocked(app, "bind fail", processName); 4245 return false; 4246 } 4247 4248 // Remove this record from the list of starting applications. 4249 mPersistentStartingProcesses.remove(app); 4250 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4251 "Attach application locked removing on hold: " + app); 4252 mProcessesOnHold.remove(app); 4253 4254 boolean badApp = false; 4255 boolean didSomething = false; 4256 4257 // See if the top visible activity is waiting to run in this process... 4258 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4259 if (hr != null && normalMode) { 4260 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4261 && processName.equals(hr.processName)) { 4262 try { 4263 if (mHeadless) { 4264 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4265 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4266 didSomething = true; 4267 } 4268 } catch (Exception e) { 4269 Slog.w(TAG, "Exception in new application when starting activity " 4270 + hr.intent.getComponent().flattenToShortString(), e); 4271 badApp = true; 4272 } 4273 } else { 4274 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4275 } 4276 } 4277 4278 // Find any services that should be running in this process... 4279 if (!badApp) { 4280 try { 4281 didSomething |= mServices.attachApplicationLocked(app, processName); 4282 } catch (Exception e) { 4283 badApp = true; 4284 } 4285 } 4286 4287 // Check if a next-broadcast receiver is in this process... 4288 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4289 try { 4290 didSomething = sendPendingBroadcastsLocked(app); 4291 } catch (Exception e) { 4292 // If the app died trying to launch the receiver we declare it 'bad' 4293 badApp = true; 4294 } 4295 } 4296 4297 // Check whether the next backup agent is in this process... 4298 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4299 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4300 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4301 try { 4302 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4303 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4304 mBackupTarget.backupMode); 4305 } catch (Exception e) { 4306 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4307 e.printStackTrace(); 4308 } 4309 } 4310 4311 if (badApp) { 4312 // todo: Also need to kill application to deal with all 4313 // kinds of exceptions. 4314 handleAppDiedLocked(app, false, true); 4315 return false; 4316 } 4317 4318 if (!didSomething) { 4319 updateOomAdjLocked(); 4320 } 4321 4322 return true; 4323 } 4324 4325 public final void attachApplication(IApplicationThread thread) { 4326 synchronized (this) { 4327 int callingPid = Binder.getCallingPid(); 4328 final long origId = Binder.clearCallingIdentity(); 4329 attachApplicationLocked(thread, callingPid); 4330 Binder.restoreCallingIdentity(origId); 4331 } 4332 } 4333 4334 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4335 final long origId = Binder.clearCallingIdentity(); 4336 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4337 if (stopProfiling) { 4338 synchronized (this) { 4339 if (mProfileProc == r.app) { 4340 if (mProfileFd != null) { 4341 try { 4342 mProfileFd.close(); 4343 } catch (IOException e) { 4344 } 4345 clearProfilerLocked(); 4346 } 4347 } 4348 } 4349 } 4350 Binder.restoreCallingIdentity(origId); 4351 } 4352 4353 void enableScreenAfterBoot() { 4354 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4355 SystemClock.uptimeMillis()); 4356 mWindowManager.enableScreenAfterBoot(); 4357 4358 synchronized (this) { 4359 updateEventDispatchingLocked(); 4360 } 4361 } 4362 4363 public void showBootMessage(final CharSequence msg, final boolean always) { 4364 enforceNotIsolatedCaller("showBootMessage"); 4365 mWindowManager.showBootMessage(msg, always); 4366 } 4367 4368 public void dismissKeyguardOnNextActivity() { 4369 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4370 final long token = Binder.clearCallingIdentity(); 4371 try { 4372 synchronized (this) { 4373 if (mLockScreenShown) { 4374 mLockScreenShown = false; 4375 comeOutOfSleepIfNeededLocked(); 4376 } 4377 mMainStack.dismissKeyguardOnNextActivityLocked(); 4378 } 4379 } finally { 4380 Binder.restoreCallingIdentity(token); 4381 } 4382 } 4383 4384 final void finishBooting() { 4385 IntentFilter pkgFilter = new IntentFilter(); 4386 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4387 pkgFilter.addDataScheme("package"); 4388 mContext.registerReceiver(new BroadcastReceiver() { 4389 @Override 4390 public void onReceive(Context context, Intent intent) { 4391 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4392 if (pkgs != null) { 4393 for (String pkg : pkgs) { 4394 synchronized (ActivityManagerService.this) { 4395 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4396 setResultCode(Activity.RESULT_OK); 4397 return; 4398 } 4399 } 4400 } 4401 } 4402 } 4403 }, pkgFilter); 4404 4405 synchronized (this) { 4406 // Ensure that any processes we had put on hold are now started 4407 // up. 4408 final int NP = mProcessesOnHold.size(); 4409 if (NP > 0) { 4410 ArrayList<ProcessRecord> procs = 4411 new ArrayList<ProcessRecord>(mProcessesOnHold); 4412 for (int ip=0; ip<NP; ip++) { 4413 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4414 + procs.get(ip)); 4415 startProcessLocked(procs.get(ip), "on-hold", null); 4416 } 4417 } 4418 4419 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4420 // Start looking for apps that are abusing wake locks. 4421 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4422 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4423 // Tell anyone interested that we are done booting! 4424 SystemProperties.set("sys.boot_completed", "1"); 4425 SystemProperties.set("dev.bootcomplete", "1"); 4426 for (int i=0; i<mStartedUsers.size(); i++) { 4427 UserStartedState uss = mStartedUsers.valueAt(i); 4428 if (uss.mState == UserStartedState.STATE_BOOTING) { 4429 uss.mState = UserStartedState.STATE_RUNNING; 4430 final int userId = mStartedUsers.keyAt(i); 4431 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 4432 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4433 broadcastIntentLocked(null, null, intent, 4434 null, null, 0, null, null, 4435 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4436 false, false, MY_PID, Process.SYSTEM_UID, userId); 4437 } 4438 } 4439 } 4440 } 4441 } 4442 4443 final void ensureBootCompleted() { 4444 boolean booting; 4445 boolean enableScreen; 4446 synchronized (this) { 4447 booting = mBooting; 4448 mBooting = false; 4449 enableScreen = !mBooted; 4450 mBooted = true; 4451 } 4452 4453 if (booting) { 4454 finishBooting(); 4455 } 4456 4457 if (enableScreen) { 4458 enableScreenAfterBoot(); 4459 } 4460 } 4461 4462 public final void activityResumed(IBinder token) { 4463 final long origId = Binder.clearCallingIdentity(); 4464 mMainStack.activityResumed(token); 4465 Binder.restoreCallingIdentity(origId); 4466 } 4467 4468 public final void activityPaused(IBinder token) { 4469 final long origId = Binder.clearCallingIdentity(); 4470 mMainStack.activityPaused(token, false); 4471 Binder.restoreCallingIdentity(origId); 4472 } 4473 4474 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4475 CharSequence description) { 4476 if (localLOGV) Slog.v( 4477 TAG, "Activity stopped: token=" + token); 4478 4479 // Refuse possible leaked file descriptors 4480 if (icicle != null && icicle.hasFileDescriptors()) { 4481 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4482 } 4483 4484 ActivityRecord r = null; 4485 4486 final long origId = Binder.clearCallingIdentity(); 4487 4488 synchronized (this) { 4489 r = mMainStack.isInStackLocked(token); 4490 if (r != null) { 4491 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4492 } 4493 } 4494 4495 if (r != null) { 4496 sendPendingThumbnail(r, null, null, null, false); 4497 } 4498 4499 trimApplications(); 4500 4501 Binder.restoreCallingIdentity(origId); 4502 } 4503 4504 public final void activityDestroyed(IBinder token) { 4505 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4506 mMainStack.activityDestroyed(token); 4507 } 4508 4509 public String getCallingPackage(IBinder token) { 4510 synchronized (this) { 4511 ActivityRecord r = getCallingRecordLocked(token); 4512 return r != null && r.app != null ? r.info.packageName : null; 4513 } 4514 } 4515 4516 public ComponentName getCallingActivity(IBinder token) { 4517 synchronized (this) { 4518 ActivityRecord r = getCallingRecordLocked(token); 4519 return r != null ? r.intent.getComponent() : null; 4520 } 4521 } 4522 4523 private ActivityRecord getCallingRecordLocked(IBinder token) { 4524 ActivityRecord r = mMainStack.isInStackLocked(token); 4525 if (r == null) { 4526 return null; 4527 } 4528 return r.resultTo; 4529 } 4530 4531 public ComponentName getActivityClassForToken(IBinder token) { 4532 synchronized(this) { 4533 ActivityRecord r = mMainStack.isInStackLocked(token); 4534 if (r == null) { 4535 return null; 4536 } 4537 return r.intent.getComponent(); 4538 } 4539 } 4540 4541 public String getPackageForToken(IBinder token) { 4542 synchronized(this) { 4543 ActivityRecord r = mMainStack.isInStackLocked(token); 4544 if (r == null) { 4545 return null; 4546 } 4547 return r.packageName; 4548 } 4549 } 4550 4551 public IIntentSender getIntentSender(int type, 4552 String packageName, IBinder token, String resultWho, 4553 int requestCode, Intent[] intents, String[] resolvedTypes, 4554 int flags, Bundle options, int userId) { 4555 enforceNotIsolatedCaller("getIntentSender"); 4556 // Refuse possible leaked file descriptors 4557 if (intents != null) { 4558 if (intents.length < 1) { 4559 throw new IllegalArgumentException("Intents array length must be >= 1"); 4560 } 4561 for (int i=0; i<intents.length; i++) { 4562 Intent intent = intents[i]; 4563 if (intent != null) { 4564 if (intent.hasFileDescriptors()) { 4565 throw new IllegalArgumentException("File descriptors passed in Intent"); 4566 } 4567 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4568 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4569 throw new IllegalArgumentException( 4570 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4571 } 4572 intents[i] = new Intent(intent); 4573 } 4574 } 4575 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4576 throw new IllegalArgumentException( 4577 "Intent array length does not match resolvedTypes length"); 4578 } 4579 } 4580 if (options != null) { 4581 if (options.hasFileDescriptors()) { 4582 throw new IllegalArgumentException("File descriptors passed in options"); 4583 } 4584 } 4585 4586 synchronized(this) { 4587 int callingUid = Binder.getCallingUid(); 4588 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId, 4589 false, true, "getIntentSender", null); 4590 try { 4591 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4592 int uid = AppGlobals.getPackageManager() 4593 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 4594 if (!UserHandle.isSameApp(callingUid, uid)) { 4595 String msg = "Permission Denial: getIntentSender() from pid=" 4596 + Binder.getCallingPid() 4597 + ", uid=" + Binder.getCallingUid() 4598 + ", (need uid=" + uid + ")" 4599 + " is not allowed to send as package " + packageName; 4600 Slog.w(TAG, msg); 4601 throw new SecurityException(msg); 4602 } 4603 } 4604 4605 return getIntentSenderLocked(type, packageName, callingUid, userId, 4606 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4607 4608 } catch (RemoteException e) { 4609 throw new SecurityException(e); 4610 } 4611 } 4612 } 4613 4614 IIntentSender getIntentSenderLocked(int type, String packageName, 4615 int callingUid, int userId, IBinder token, String resultWho, 4616 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4617 Bundle options) { 4618 if (DEBUG_MU) 4619 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4620 ActivityRecord activity = null; 4621 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4622 activity = mMainStack.isInStackLocked(token); 4623 if (activity == null) { 4624 return null; 4625 } 4626 if (activity.finishing) { 4627 return null; 4628 } 4629 } 4630 4631 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4632 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4633 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4634 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4635 |PendingIntent.FLAG_UPDATE_CURRENT); 4636 4637 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4638 type, packageName, activity, resultWho, 4639 requestCode, intents, resolvedTypes, flags, options, userId); 4640 WeakReference<PendingIntentRecord> ref; 4641 ref = mIntentSenderRecords.get(key); 4642 PendingIntentRecord rec = ref != null ? ref.get() : null; 4643 if (rec != null) { 4644 if (!cancelCurrent) { 4645 if (updateCurrent) { 4646 if (rec.key.requestIntent != null) { 4647 rec.key.requestIntent.replaceExtras(intents != null ? 4648 intents[intents.length - 1] : null); 4649 } 4650 if (intents != null) { 4651 intents[intents.length-1] = rec.key.requestIntent; 4652 rec.key.allIntents = intents; 4653 rec.key.allResolvedTypes = resolvedTypes; 4654 } else { 4655 rec.key.allIntents = null; 4656 rec.key.allResolvedTypes = null; 4657 } 4658 } 4659 return rec; 4660 } 4661 rec.canceled = true; 4662 mIntentSenderRecords.remove(key); 4663 } 4664 if (noCreate) { 4665 return rec; 4666 } 4667 rec = new PendingIntentRecord(this, key, callingUid); 4668 mIntentSenderRecords.put(key, rec.ref); 4669 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4670 if (activity.pendingResults == null) { 4671 activity.pendingResults 4672 = new HashSet<WeakReference<PendingIntentRecord>>(); 4673 } 4674 activity.pendingResults.add(rec.ref); 4675 } 4676 return rec; 4677 } 4678 4679 public void cancelIntentSender(IIntentSender sender) { 4680 if (!(sender instanceof PendingIntentRecord)) { 4681 return; 4682 } 4683 synchronized(this) { 4684 PendingIntentRecord rec = (PendingIntentRecord)sender; 4685 try { 4686 int uid = AppGlobals.getPackageManager() 4687 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 4688 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 4689 String msg = "Permission Denial: cancelIntentSender() from pid=" 4690 + Binder.getCallingPid() 4691 + ", uid=" + Binder.getCallingUid() 4692 + " is not allowed to cancel packges " 4693 + rec.key.packageName; 4694 Slog.w(TAG, msg); 4695 throw new SecurityException(msg); 4696 } 4697 } catch (RemoteException e) { 4698 throw new SecurityException(e); 4699 } 4700 cancelIntentSenderLocked(rec, true); 4701 } 4702 } 4703 4704 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4705 rec.canceled = true; 4706 mIntentSenderRecords.remove(rec.key); 4707 if (cleanActivity && rec.key.activity != null) { 4708 rec.key.activity.pendingResults.remove(rec.ref); 4709 } 4710 } 4711 4712 public String getPackageForIntentSender(IIntentSender pendingResult) { 4713 if (!(pendingResult instanceof PendingIntentRecord)) { 4714 return null; 4715 } 4716 try { 4717 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4718 return res.key.packageName; 4719 } catch (ClassCastException e) { 4720 } 4721 return null; 4722 } 4723 4724 public int getUidForIntentSender(IIntentSender sender) { 4725 if (sender instanceof PendingIntentRecord) { 4726 try { 4727 PendingIntentRecord res = (PendingIntentRecord)sender; 4728 return res.uid; 4729 } catch (ClassCastException e) { 4730 } 4731 } 4732 return -1; 4733 } 4734 4735 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4736 if (!(pendingResult instanceof PendingIntentRecord)) { 4737 return false; 4738 } 4739 try { 4740 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4741 if (res.key.allIntents == null) { 4742 return false; 4743 } 4744 for (int i=0; i<res.key.allIntents.length; i++) { 4745 Intent intent = res.key.allIntents[i]; 4746 if (intent.getPackage() != null && intent.getComponent() != null) { 4747 return false; 4748 } 4749 } 4750 return true; 4751 } catch (ClassCastException e) { 4752 } 4753 return false; 4754 } 4755 4756 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4757 if (!(pendingResult instanceof PendingIntentRecord)) { 4758 return false; 4759 } 4760 try { 4761 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4762 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4763 return true; 4764 } 4765 return false; 4766 } catch (ClassCastException e) { 4767 } 4768 return false; 4769 } 4770 4771 public void setProcessLimit(int max) { 4772 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4773 "setProcessLimit()"); 4774 synchronized (this) { 4775 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4776 mProcessLimitOverride = max; 4777 } 4778 trimApplications(); 4779 } 4780 4781 public int getProcessLimit() { 4782 synchronized (this) { 4783 return mProcessLimitOverride; 4784 } 4785 } 4786 4787 void foregroundTokenDied(ForegroundToken token) { 4788 synchronized (ActivityManagerService.this) { 4789 synchronized (mPidsSelfLocked) { 4790 ForegroundToken cur 4791 = mForegroundProcesses.get(token.pid); 4792 if (cur != token) { 4793 return; 4794 } 4795 mForegroundProcesses.remove(token.pid); 4796 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4797 if (pr == null) { 4798 return; 4799 } 4800 pr.forcingToForeground = null; 4801 pr.foregroundServices = false; 4802 } 4803 updateOomAdjLocked(); 4804 } 4805 } 4806 4807 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4808 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4809 "setProcessForeground()"); 4810 synchronized(this) { 4811 boolean changed = false; 4812 4813 synchronized (mPidsSelfLocked) { 4814 ProcessRecord pr = mPidsSelfLocked.get(pid); 4815 if (pr == null && isForeground) { 4816 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4817 return; 4818 } 4819 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4820 if (oldToken != null) { 4821 oldToken.token.unlinkToDeath(oldToken, 0); 4822 mForegroundProcesses.remove(pid); 4823 if (pr != null) { 4824 pr.forcingToForeground = null; 4825 } 4826 changed = true; 4827 } 4828 if (isForeground && token != null) { 4829 ForegroundToken newToken = new ForegroundToken() { 4830 public void binderDied() { 4831 foregroundTokenDied(this); 4832 } 4833 }; 4834 newToken.pid = pid; 4835 newToken.token = token; 4836 try { 4837 token.linkToDeath(newToken, 0); 4838 mForegroundProcesses.put(pid, newToken); 4839 pr.forcingToForeground = token; 4840 changed = true; 4841 } catch (RemoteException e) { 4842 // If the process died while doing this, we will later 4843 // do the cleanup with the process death link. 4844 } 4845 } 4846 } 4847 4848 if (changed) { 4849 updateOomAdjLocked(); 4850 } 4851 } 4852 } 4853 4854 // ========================================================= 4855 // PERMISSIONS 4856 // ========================================================= 4857 4858 static class PermissionController extends IPermissionController.Stub { 4859 ActivityManagerService mActivityManagerService; 4860 PermissionController(ActivityManagerService activityManagerService) { 4861 mActivityManagerService = activityManagerService; 4862 } 4863 4864 public boolean checkPermission(String permission, int pid, int uid) { 4865 return mActivityManagerService.checkPermission(permission, pid, 4866 uid) == PackageManager.PERMISSION_GRANTED; 4867 } 4868 } 4869 4870 /** 4871 * This can be called with or without the global lock held. 4872 */ 4873 int checkComponentPermission(String permission, int pid, int uid, 4874 int owningUid, boolean exported) { 4875 // We might be performing an operation on behalf of an indirect binder 4876 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4877 // client identity accordingly before proceeding. 4878 Identity tlsIdentity = sCallerIdentity.get(); 4879 if (tlsIdentity != null) { 4880 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4881 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4882 uid = tlsIdentity.uid; 4883 pid = tlsIdentity.pid; 4884 } 4885 4886 if (pid == MY_PID) { 4887 return PackageManager.PERMISSION_GRANTED; 4888 } 4889 4890 return ActivityManager.checkComponentPermission(permission, uid, 4891 owningUid, exported); 4892 } 4893 4894 /** 4895 * As the only public entry point for permissions checking, this method 4896 * can enforce the semantic that requesting a check on a null global 4897 * permission is automatically denied. (Internally a null permission 4898 * string is used when calling {@link #checkComponentPermission} in cases 4899 * when only uid-based security is needed.) 4900 * 4901 * This can be called with or without the global lock held. 4902 */ 4903 public int checkPermission(String permission, int pid, int uid) { 4904 if (permission == null) { 4905 return PackageManager.PERMISSION_DENIED; 4906 } 4907 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 4908 } 4909 4910 /** 4911 * Binder IPC calls go through the public entry point. 4912 * This can be called with or without the global lock held. 4913 */ 4914 int checkCallingPermission(String permission) { 4915 return checkPermission(permission, 4916 Binder.getCallingPid(), 4917 UserHandle.getAppId(Binder.getCallingUid())); 4918 } 4919 4920 /** 4921 * This can be called with or without the global lock held. 4922 */ 4923 void enforceCallingPermission(String permission, String func) { 4924 if (checkCallingPermission(permission) 4925 == PackageManager.PERMISSION_GRANTED) { 4926 return; 4927 } 4928 4929 String msg = "Permission Denial: " + func + " from pid=" 4930 + Binder.getCallingPid() 4931 + ", uid=" + Binder.getCallingUid() 4932 + " requires " + permission; 4933 Slog.w(TAG, msg); 4934 throw new SecurityException(msg); 4935 } 4936 4937 /** 4938 * Determine if UID is holding permissions required to access {@link Uri} in 4939 * the given {@link ProviderInfo}. Final permission checking is always done 4940 * in {@link ContentProvider}. 4941 */ 4942 private final boolean checkHoldingPermissionsLocked( 4943 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4944 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4945 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4946 4947 if (pi.applicationInfo.uid == uid) { 4948 return true; 4949 } else if (!pi.exported) { 4950 return false; 4951 } 4952 4953 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4954 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4955 try { 4956 // check if target holds top-level <provider> permissions 4957 if (!readMet && pi.readPermission != null 4958 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4959 readMet = true; 4960 } 4961 if (!writeMet && pi.writePermission != null 4962 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4963 writeMet = true; 4964 } 4965 4966 // track if unprotected read/write is allowed; any denied 4967 // <path-permission> below removes this ability 4968 boolean allowDefaultRead = pi.readPermission == null; 4969 boolean allowDefaultWrite = pi.writePermission == null; 4970 4971 // check if target holds any <path-permission> that match uri 4972 final PathPermission[] pps = pi.pathPermissions; 4973 if (pps != null) { 4974 final String path = uri.getPath(); 4975 int i = pps.length; 4976 while (i > 0 && (!readMet || !writeMet)) { 4977 i--; 4978 PathPermission pp = pps[i]; 4979 if (pp.match(path)) { 4980 if (!readMet) { 4981 final String pprperm = pp.getReadPermission(); 4982 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4983 + pprperm + " for " + pp.getPath() 4984 + ": match=" + pp.match(path) 4985 + " check=" + pm.checkUidPermission(pprperm, uid)); 4986 if (pprperm != null) { 4987 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4988 readMet = true; 4989 } else { 4990 allowDefaultRead = false; 4991 } 4992 } 4993 } 4994 if (!writeMet) { 4995 final String ppwperm = pp.getWritePermission(); 4996 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4997 + ppwperm + " for " + pp.getPath() 4998 + ": match=" + pp.match(path) 4999 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5000 if (ppwperm != null) { 5001 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5002 writeMet = true; 5003 } else { 5004 allowDefaultWrite = false; 5005 } 5006 } 5007 } 5008 } 5009 } 5010 } 5011 5012 // grant unprotected <provider> read/write, if not blocked by 5013 // <path-permission> above 5014 if (allowDefaultRead) readMet = true; 5015 if (allowDefaultWrite) writeMet = true; 5016 5017 } catch (RemoteException e) { 5018 return false; 5019 } 5020 5021 return readMet && writeMet; 5022 } 5023 5024 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5025 int modeFlags) { 5026 // Root gets to do everything. 5027 if (uid == 0) { 5028 return true; 5029 } 5030 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5031 if (perms == null) return false; 5032 UriPermission perm = perms.get(uri); 5033 if (perm == null) return false; 5034 return (modeFlags&perm.modeFlags) == modeFlags; 5035 } 5036 5037 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5038 enforceNotIsolatedCaller("checkUriPermission"); 5039 5040 // Another redirected-binder-call permissions check as in 5041 // {@link checkComponentPermission}. 5042 Identity tlsIdentity = sCallerIdentity.get(); 5043 if (tlsIdentity != null) { 5044 uid = tlsIdentity.uid; 5045 pid = tlsIdentity.pid; 5046 } 5047 5048 // Our own process gets to do everything. 5049 if (pid == MY_PID) { 5050 return PackageManager.PERMISSION_GRANTED; 5051 } 5052 synchronized(this) { 5053 return checkUriPermissionLocked(uri, uid, modeFlags) 5054 ? PackageManager.PERMISSION_GRANTED 5055 : PackageManager.PERMISSION_DENIED; 5056 } 5057 } 5058 5059 /** 5060 * Check if the targetPkg can be granted permission to access uri by 5061 * the callingUid using the given modeFlags. Throws a security exception 5062 * if callingUid is not allowed to do this. Returns the uid of the target 5063 * if the URI permission grant should be performed; returns -1 if it is not 5064 * needed (for example targetPkg already has permission to access the URI). 5065 * If you already know the uid of the target, you can supply it in 5066 * lastTargetUid else set that to -1. 5067 */ 5068 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5069 Uri uri, int modeFlags, int lastTargetUid) { 5070 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5071 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5072 if (modeFlags == 0) { 5073 return -1; 5074 } 5075 5076 if (targetPkg != null) { 5077 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5078 "Checking grant " + targetPkg + " permission to " + uri); 5079 } 5080 5081 final IPackageManager pm = AppGlobals.getPackageManager(); 5082 5083 // If this is not a content: uri, we can't do anything with it. 5084 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5085 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5086 "Can't grant URI permission for non-content URI: " + uri); 5087 return -1; 5088 } 5089 5090 String name = uri.getAuthority(); 5091 ProviderInfo pi = null; 5092 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 5093 UserHandle.getUserId(callingUid)); 5094 if (cpr != null) { 5095 pi = cpr.info; 5096 } else { 5097 try { 5098 pi = pm.resolveContentProvider(name, 5099 PackageManager.GET_URI_PERMISSION_PATTERNS, 5100 UserHandle.getUserId(callingUid)); 5101 } catch (RemoteException ex) { 5102 } 5103 } 5104 if (pi == null) { 5105 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5106 return -1; 5107 } 5108 5109 int targetUid = lastTargetUid; 5110 if (targetUid < 0 && targetPkg != null) { 5111 try { 5112 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5113 if (targetUid < 0) { 5114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5115 "Can't grant URI permission no uid for: " + targetPkg); 5116 return -1; 5117 } 5118 } catch (RemoteException ex) { 5119 return -1; 5120 } 5121 } 5122 5123 if (targetUid >= 0) { 5124 // First... does the target actually need this permission? 5125 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5126 // No need to grant the target this permission. 5127 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5128 "Target " + targetPkg + " already has full permission to " + uri); 5129 return -1; 5130 } 5131 } else { 5132 // First... there is no target package, so can anyone access it? 5133 boolean allowed = pi.exported; 5134 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5135 if (pi.readPermission != null) { 5136 allowed = false; 5137 } 5138 } 5139 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5140 if (pi.writePermission != null) { 5141 allowed = false; 5142 } 5143 } 5144 if (allowed) { 5145 return -1; 5146 } 5147 } 5148 5149 // Second... is the provider allowing granting of URI permissions? 5150 if (!pi.grantUriPermissions) { 5151 throw new SecurityException("Provider " + pi.packageName 5152 + "/" + pi.name 5153 + " does not allow granting of Uri permissions (uri " 5154 + uri + ")"); 5155 } 5156 if (pi.uriPermissionPatterns != null) { 5157 final int N = pi.uriPermissionPatterns.length; 5158 boolean allowed = false; 5159 for (int i=0; i<N; i++) { 5160 if (pi.uriPermissionPatterns[i] != null 5161 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5162 allowed = true; 5163 break; 5164 } 5165 } 5166 if (!allowed) { 5167 throw new SecurityException("Provider " + pi.packageName 5168 + "/" + pi.name 5169 + " does not allow granting of permission to path of Uri " 5170 + uri); 5171 } 5172 } 5173 5174 // Third... does the caller itself have permission to access 5175 // this uri? 5176 if (callingUid != Process.myUid()) { 5177 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5178 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5179 throw new SecurityException("Uid " + callingUid 5180 + " does not have permission to uri " + uri); 5181 } 5182 } 5183 } 5184 5185 return targetUid; 5186 } 5187 5188 public int checkGrantUriPermission(int callingUid, String targetPkg, 5189 Uri uri, int modeFlags) { 5190 enforceNotIsolatedCaller("checkGrantUriPermission"); 5191 synchronized(this) { 5192 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5193 } 5194 } 5195 5196 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5197 Uri uri, int modeFlags, UriPermissionOwner owner) { 5198 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5199 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5200 if (modeFlags == 0) { 5201 return; 5202 } 5203 5204 // So here we are: the caller has the assumed permission 5205 // to the uri, and the target doesn't. Let's now give this to 5206 // the target. 5207 5208 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5209 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5210 5211 HashMap<Uri, UriPermission> targetUris 5212 = mGrantedUriPermissions.get(targetUid); 5213 if (targetUris == null) { 5214 targetUris = new HashMap<Uri, UriPermission>(); 5215 mGrantedUriPermissions.put(targetUid, targetUris); 5216 } 5217 5218 UriPermission perm = targetUris.get(uri); 5219 if (perm == null) { 5220 perm = new UriPermission(targetUid, uri); 5221 targetUris.put(uri, perm); 5222 } 5223 5224 perm.modeFlags |= modeFlags; 5225 if (owner == null) { 5226 perm.globalModeFlags |= modeFlags; 5227 } else { 5228 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5229 perm.readOwners.add(owner); 5230 owner.addReadPermission(perm); 5231 } 5232 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5233 perm.writeOwners.add(owner); 5234 owner.addWritePermission(perm); 5235 } 5236 } 5237 } 5238 5239 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5240 int modeFlags, UriPermissionOwner owner) { 5241 if (targetPkg == null) { 5242 throw new NullPointerException("targetPkg"); 5243 } 5244 5245 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5246 if (targetUid < 0) { 5247 return; 5248 } 5249 5250 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5251 } 5252 5253 static class NeededUriGrants extends ArrayList<Uri> { 5254 final String targetPkg; 5255 final int targetUid; 5256 final int flags; 5257 5258 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5259 targetPkg = _targetPkg; 5260 targetUid = _targetUid; 5261 flags = _flags; 5262 } 5263 } 5264 5265 /** 5266 * Like checkGrantUriPermissionLocked, but takes an Intent. 5267 */ 5268 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5269 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5270 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5271 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5272 + " clip=" + (intent != null ? intent.getClipData() : null) 5273 + " from " + intent + "; flags=0x" 5274 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5275 5276 if (targetPkg == null) { 5277 throw new NullPointerException("targetPkg"); 5278 } 5279 5280 if (intent == null) { 5281 return null; 5282 } 5283 Uri data = intent.getData(); 5284 ClipData clip = intent.getClipData(); 5285 if (data == null && clip == null) { 5286 return null; 5287 } 5288 if (data != null) { 5289 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5290 mode, needed != null ? needed.targetUid : -1); 5291 if (target > 0) { 5292 if (needed == null) { 5293 needed = new NeededUriGrants(targetPkg, target, mode); 5294 } 5295 needed.add(data); 5296 } 5297 } 5298 if (clip != null) { 5299 for (int i=0; i<clip.getItemCount(); i++) { 5300 Uri uri = clip.getItemAt(i).getUri(); 5301 if (uri != null) { 5302 int target = -1; 5303 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5304 mode, needed != null ? needed.targetUid : -1); 5305 if (target > 0) { 5306 if (needed == null) { 5307 needed = new NeededUriGrants(targetPkg, target, mode); 5308 } 5309 needed.add(uri); 5310 } 5311 } else { 5312 Intent clipIntent = clip.getItemAt(i).getIntent(); 5313 if (clipIntent != null) { 5314 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5315 callingUid, targetPkg, clipIntent, mode, needed); 5316 if (newNeeded != null) { 5317 needed = newNeeded; 5318 } 5319 } 5320 } 5321 } 5322 } 5323 5324 return needed; 5325 } 5326 5327 /** 5328 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5329 */ 5330 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5331 UriPermissionOwner owner) { 5332 if (needed != null) { 5333 for (int i=0; i<needed.size(); i++) { 5334 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5335 needed.get(i), needed.flags, owner); 5336 } 5337 } 5338 } 5339 5340 void grantUriPermissionFromIntentLocked(int callingUid, 5341 String targetPkg, Intent intent, UriPermissionOwner owner) { 5342 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5343 intent, intent != null ? intent.getFlags() : 0, null); 5344 if (needed == null) { 5345 return; 5346 } 5347 5348 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5349 } 5350 5351 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5352 Uri uri, int modeFlags) { 5353 enforceNotIsolatedCaller("grantUriPermission"); 5354 synchronized(this) { 5355 final ProcessRecord r = getRecordForAppLocked(caller); 5356 if (r == null) { 5357 throw new SecurityException("Unable to find app for caller " 5358 + caller 5359 + " when granting permission to uri " + uri); 5360 } 5361 if (targetPkg == null) { 5362 throw new IllegalArgumentException("null target"); 5363 } 5364 if (uri == null) { 5365 throw new IllegalArgumentException("null uri"); 5366 } 5367 5368 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5369 null); 5370 } 5371 } 5372 5373 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5374 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5375 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5376 HashMap<Uri, UriPermission> perms 5377 = mGrantedUriPermissions.get(perm.uid); 5378 if (perms != null) { 5379 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5380 "Removing " + perm.uid + " permission to " + perm.uri); 5381 perms.remove(perm.uri); 5382 if (perms.size() == 0) { 5383 mGrantedUriPermissions.remove(perm.uid); 5384 } 5385 } 5386 } 5387 } 5388 5389 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5390 int modeFlags) { 5391 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5392 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5393 if (modeFlags == 0) { 5394 return; 5395 } 5396 5397 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5398 "Revoking all granted permissions to " + uri); 5399 5400 final IPackageManager pm = AppGlobals.getPackageManager(); 5401 5402 final String authority = uri.getAuthority(); 5403 ProviderInfo pi = null; 5404 int userId = UserHandle.getUserId(callingUid); 5405 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5406 if (cpr != null) { 5407 pi = cpr.info; 5408 } else { 5409 try { 5410 pi = pm.resolveContentProvider(authority, 5411 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5412 } catch (RemoteException ex) { 5413 } 5414 } 5415 if (pi == null) { 5416 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5417 return; 5418 } 5419 5420 // Does the caller have this permission on the URI? 5421 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5422 // Right now, if you are not the original owner of the permission, 5423 // you are not allowed to revoke it. 5424 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5425 throw new SecurityException("Uid " + callingUid 5426 + " does not have permission to uri " + uri); 5427 //} 5428 } 5429 5430 // Go through all of the permissions and remove any that match. 5431 final List<String> SEGMENTS = uri.getPathSegments(); 5432 if (SEGMENTS != null) { 5433 final int NS = SEGMENTS.size(); 5434 int N = mGrantedUriPermissions.size(); 5435 for (int i=0; i<N; i++) { 5436 HashMap<Uri, UriPermission> perms 5437 = mGrantedUriPermissions.valueAt(i); 5438 Iterator<UriPermission> it = perms.values().iterator(); 5439 toploop: 5440 while (it.hasNext()) { 5441 UriPermission perm = it.next(); 5442 Uri targetUri = perm.uri; 5443 if (!authority.equals(targetUri.getAuthority())) { 5444 continue; 5445 } 5446 List<String> targetSegments = targetUri.getPathSegments(); 5447 if (targetSegments == null) { 5448 continue; 5449 } 5450 if (targetSegments.size() < NS) { 5451 continue; 5452 } 5453 for (int j=0; j<NS; j++) { 5454 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5455 continue toploop; 5456 } 5457 } 5458 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5459 "Revoking " + perm.uid + " permission to " + perm.uri); 5460 perm.clearModes(modeFlags); 5461 if (perm.modeFlags == 0) { 5462 it.remove(); 5463 } 5464 } 5465 if (perms.size() == 0) { 5466 mGrantedUriPermissions.remove( 5467 mGrantedUriPermissions.keyAt(i)); 5468 N--; 5469 i--; 5470 } 5471 } 5472 } 5473 } 5474 5475 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5476 int modeFlags) { 5477 enforceNotIsolatedCaller("revokeUriPermission"); 5478 synchronized(this) { 5479 final ProcessRecord r = getRecordForAppLocked(caller); 5480 if (r == null) { 5481 throw new SecurityException("Unable to find app for caller " 5482 + caller 5483 + " when revoking permission to uri " + uri); 5484 } 5485 if (uri == null) { 5486 Slog.w(TAG, "revokeUriPermission: null uri"); 5487 return; 5488 } 5489 5490 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5491 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5492 if (modeFlags == 0) { 5493 return; 5494 } 5495 5496 final IPackageManager pm = AppGlobals.getPackageManager(); 5497 5498 final String authority = uri.getAuthority(); 5499 ProviderInfo pi = null; 5500 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5501 if (cpr != null) { 5502 pi = cpr.info; 5503 } else { 5504 try { 5505 pi = pm.resolveContentProvider(authority, 5506 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5507 } catch (RemoteException ex) { 5508 } 5509 } 5510 if (pi == null) { 5511 Slog.w(TAG, "No content provider found for permission revoke: " 5512 + uri.toSafeString()); 5513 return; 5514 } 5515 5516 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5517 } 5518 } 5519 5520 @Override 5521 public IBinder newUriPermissionOwner(String name) { 5522 enforceNotIsolatedCaller("newUriPermissionOwner"); 5523 synchronized(this) { 5524 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5525 return owner.getExternalTokenLocked(); 5526 } 5527 } 5528 5529 @Override 5530 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5531 Uri uri, int modeFlags) { 5532 synchronized(this) { 5533 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5534 if (owner == null) { 5535 throw new IllegalArgumentException("Unknown owner: " + token); 5536 } 5537 if (fromUid != Binder.getCallingUid()) { 5538 if (Binder.getCallingUid() != Process.myUid()) { 5539 // Only system code can grant URI permissions on behalf 5540 // of other users. 5541 throw new SecurityException("nice try"); 5542 } 5543 } 5544 if (targetPkg == null) { 5545 throw new IllegalArgumentException("null target"); 5546 } 5547 if (uri == null) { 5548 throw new IllegalArgumentException("null uri"); 5549 } 5550 5551 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5552 } 5553 } 5554 5555 @Override 5556 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5557 synchronized(this) { 5558 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5559 if (owner == null) { 5560 throw new IllegalArgumentException("Unknown owner: " + token); 5561 } 5562 5563 if (uri == null) { 5564 owner.removeUriPermissionsLocked(mode); 5565 } else { 5566 owner.removeUriPermissionLocked(uri, mode); 5567 } 5568 } 5569 } 5570 5571 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5572 synchronized (this) { 5573 ProcessRecord app = 5574 who != null ? getRecordForAppLocked(who) : null; 5575 if (app == null) return; 5576 5577 Message msg = Message.obtain(); 5578 msg.what = WAIT_FOR_DEBUGGER_MSG; 5579 msg.obj = app; 5580 msg.arg1 = waiting ? 1 : 0; 5581 mHandler.sendMessage(msg); 5582 } 5583 } 5584 5585 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5586 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5587 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5588 outInfo.availMem = Process.getFreeMemory(); 5589 outInfo.totalMem = Process.getTotalMemory(); 5590 outInfo.threshold = homeAppMem; 5591 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5592 outInfo.hiddenAppThreshold = hiddenAppMem; 5593 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5594 ProcessList.SERVICE_ADJ); 5595 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5596 ProcessList.VISIBLE_APP_ADJ); 5597 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5598 ProcessList.FOREGROUND_APP_ADJ); 5599 } 5600 5601 // ========================================================= 5602 // TASK MANAGEMENT 5603 // ========================================================= 5604 5605 public List getTasks(int maxNum, int flags, 5606 IThumbnailReceiver receiver) { 5607 ArrayList list = new ArrayList(); 5608 5609 PendingThumbnailsRecord pending = null; 5610 IApplicationThread topThumbnail = null; 5611 ActivityRecord topRecord = null; 5612 5613 synchronized(this) { 5614 if (localLOGV) Slog.v( 5615 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5616 + ", receiver=" + receiver); 5617 5618 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5619 != PackageManager.PERMISSION_GRANTED) { 5620 if (receiver != null) { 5621 // If the caller wants to wait for pending thumbnails, 5622 // it ain't gonna get them. 5623 try { 5624 receiver.finished(); 5625 } catch (RemoteException ex) { 5626 } 5627 } 5628 String msg = "Permission Denial: getTasks() from pid=" 5629 + Binder.getCallingPid() 5630 + ", uid=" + Binder.getCallingUid() 5631 + " requires " + android.Manifest.permission.GET_TASKS; 5632 Slog.w(TAG, msg); 5633 throw new SecurityException(msg); 5634 } 5635 5636 int pos = mMainStack.mHistory.size()-1; 5637 ActivityRecord next = 5638 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5639 ActivityRecord top = null; 5640 TaskRecord curTask = null; 5641 int numActivities = 0; 5642 int numRunning = 0; 5643 while (pos >= 0 && maxNum > 0) { 5644 final ActivityRecord r = next; 5645 pos--; 5646 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5647 5648 // Initialize state for next task if needed. 5649 if (top == null || 5650 (top.state == ActivityState.INITIALIZING 5651 && top.task == r.task)) { 5652 top = r; 5653 curTask = r.task; 5654 numActivities = numRunning = 0; 5655 } 5656 5657 // Add 'r' into the current task. 5658 numActivities++; 5659 if (r.app != null && r.app.thread != null) { 5660 numRunning++; 5661 } 5662 5663 if (localLOGV) Slog.v( 5664 TAG, r.intent.getComponent().flattenToShortString() 5665 + ": task=" + r.task); 5666 5667 // If the next one is a different task, generate a new 5668 // TaskInfo entry for what we have. 5669 if (next == null || next.task != curTask) { 5670 ActivityManager.RunningTaskInfo ci 5671 = new ActivityManager.RunningTaskInfo(); 5672 ci.id = curTask.taskId; 5673 ci.baseActivity = r.intent.getComponent(); 5674 ci.topActivity = top.intent.getComponent(); 5675 if (top.thumbHolder != null) { 5676 ci.description = top.thumbHolder.lastDescription; 5677 } 5678 ci.numActivities = numActivities; 5679 ci.numRunning = numRunning; 5680 //System.out.println( 5681 // "#" + maxNum + ": " + " descr=" + ci.description); 5682 if (ci.thumbnail == null && receiver != null) { 5683 if (localLOGV) Slog.v( 5684 TAG, "State=" + top.state + "Idle=" + top.idle 5685 + " app=" + top.app 5686 + " thr=" + (top.app != null ? top.app.thread : null)); 5687 if (top.state == ActivityState.RESUMED 5688 || top.state == ActivityState.PAUSING) { 5689 if (top.idle && top.app != null 5690 && top.app.thread != null) { 5691 topRecord = top; 5692 topThumbnail = top.app.thread; 5693 } else { 5694 top.thumbnailNeeded = true; 5695 } 5696 } 5697 if (pending == null) { 5698 pending = new PendingThumbnailsRecord(receiver); 5699 } 5700 pending.pendingRecords.add(top); 5701 } 5702 list.add(ci); 5703 maxNum--; 5704 top = null; 5705 } 5706 } 5707 5708 if (pending != null) { 5709 mPendingThumbnails.add(pending); 5710 } 5711 } 5712 5713 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5714 5715 if (topThumbnail != null) { 5716 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5717 try { 5718 topThumbnail.requestThumbnail(topRecord.appToken); 5719 } catch (Exception e) { 5720 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5721 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5722 } 5723 } 5724 5725 if (pending == null && receiver != null) { 5726 // In this case all thumbnails were available and the client 5727 // is being asked to be told when the remaining ones come in... 5728 // which is unusually, since the top-most currently running 5729 // activity should never have a canned thumbnail! Oh well. 5730 try { 5731 receiver.finished(); 5732 } catch (RemoteException ex) { 5733 } 5734 } 5735 5736 return list; 5737 } 5738 5739 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5740 int flags, int userId) { 5741 final int callingUid = Binder.getCallingUid(); 5742 if (userId != UserHandle.getCallingUserId()) { 5743 // Check if the caller is holding permissions for cross-user requests. 5744 if (checkComponentPermission( 5745 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5746 Binder.getCallingPid(), callingUid, -1, true) 5747 != PackageManager.PERMISSION_GRANTED) { 5748 String msg = "Permission Denial: " 5749 + "Request to get recent tasks for user " + userId 5750 + " but is calling from user " + UserHandle.getUserId(callingUid) 5751 + "; this requires " 5752 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 5753 Slog.w(TAG, msg); 5754 throw new SecurityException(msg); 5755 } else { 5756 if (userId == UserHandle.USER_CURRENT) { 5757 userId = mCurrentUserId; 5758 } 5759 } 5760 } 5761 5762 synchronized (this) { 5763 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5764 "getRecentTasks()"); 5765 final boolean detailed = checkCallingPermission( 5766 android.Manifest.permission.GET_DETAILED_TASKS) 5767 == PackageManager.PERMISSION_GRANTED; 5768 5769 IPackageManager pm = AppGlobals.getPackageManager(); 5770 5771 final int N = mRecentTasks.size(); 5772 ArrayList<ActivityManager.RecentTaskInfo> res 5773 = new ArrayList<ActivityManager.RecentTaskInfo>( 5774 maxNum < N ? maxNum : N); 5775 for (int i=0; i<N && maxNum > 0; i++) { 5776 TaskRecord tr = mRecentTasks.get(i); 5777 // Only add calling user's recent tasks 5778 if (tr.userId != userId) continue; 5779 // Return the entry if desired by the caller. We always return 5780 // the first entry, because callers always expect this to be the 5781 // foreground app. We may filter others if the caller has 5782 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5783 // we should exclude the entry. 5784 5785 if (i == 0 5786 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5787 || (tr.intent == null) 5788 || ((tr.intent.getFlags() 5789 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5790 ActivityManager.RecentTaskInfo rti 5791 = new ActivityManager.RecentTaskInfo(); 5792 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5793 rti.persistentId = tr.taskId; 5794 rti.baseIntent = new Intent( 5795 tr.intent != null ? tr.intent : tr.affinityIntent); 5796 if (!detailed) { 5797 rti.baseIntent.replaceExtras((Bundle)null); 5798 } 5799 rti.origActivity = tr.origActivity; 5800 rti.description = tr.lastDescription; 5801 5802 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5803 // Check whether this activity is currently available. 5804 try { 5805 if (rti.origActivity != null) { 5806 if (pm.getActivityInfo(rti.origActivity, 0, userId) 5807 == null) { 5808 continue; 5809 } 5810 } else if (rti.baseIntent != null) { 5811 if (pm.queryIntentActivities(rti.baseIntent, 5812 null, 0, userId) == null) { 5813 continue; 5814 } 5815 } 5816 } catch (RemoteException e) { 5817 // Will never happen. 5818 } 5819 } 5820 5821 res.add(rti); 5822 maxNum--; 5823 } 5824 } 5825 return res; 5826 } 5827 } 5828 5829 private TaskRecord taskForIdLocked(int id) { 5830 final int N = mRecentTasks.size(); 5831 for (int i=0; i<N; i++) { 5832 TaskRecord tr = mRecentTasks.get(i); 5833 if (tr.taskId == id) { 5834 return tr; 5835 } 5836 } 5837 return null; 5838 } 5839 5840 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5841 synchronized (this) { 5842 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5843 "getTaskThumbnails()"); 5844 TaskRecord tr = taskForIdLocked(id); 5845 if (tr != null) { 5846 return mMainStack.getTaskThumbnailsLocked(tr); 5847 } 5848 } 5849 return null; 5850 } 5851 5852 public boolean removeSubTask(int taskId, int subTaskIndex) { 5853 synchronized (this) { 5854 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5855 "removeSubTask()"); 5856 long ident = Binder.clearCallingIdentity(); 5857 try { 5858 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5859 true) != null; 5860 } finally { 5861 Binder.restoreCallingIdentity(ident); 5862 } 5863 } 5864 } 5865 5866 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5867 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5868 Intent baseIntent = new Intent( 5869 tr.intent != null ? tr.intent : tr.affinityIntent); 5870 ComponentName component = baseIntent.getComponent(); 5871 if (component == null) { 5872 Slog.w(TAG, "Now component for base intent of task: " + tr); 5873 return; 5874 } 5875 5876 // Find any running services associated with this app. 5877 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 5878 5879 if (killProcesses) { 5880 // Find any running processes associated with this app. 5881 final String pkg = component.getPackageName(); 5882 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5883 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5884 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5885 for (int i=0; i<uids.size(); i++) { 5886 ProcessRecord proc = uids.valueAt(i); 5887 if (proc.userId != tr.userId) { 5888 continue; 5889 } 5890 if (!proc.pkgList.contains(pkg)) { 5891 continue; 5892 } 5893 procs.add(proc); 5894 } 5895 } 5896 5897 // Kill the running processes. 5898 for (int i=0; i<procs.size(); i++) { 5899 ProcessRecord pr = procs.get(i); 5900 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5901 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5902 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5903 pr.processName, pr.setAdj, "remove task"); 5904 pr.killedBackground = true; 5905 Process.killProcessQuiet(pr.pid); 5906 } else { 5907 pr.waitingToKill = "remove task"; 5908 } 5909 } 5910 } 5911 } 5912 5913 public boolean removeTask(int taskId, int flags) { 5914 synchronized (this) { 5915 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5916 "removeTask()"); 5917 long ident = Binder.clearCallingIdentity(); 5918 try { 5919 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5920 false); 5921 if (r != null) { 5922 mRecentTasks.remove(r.task); 5923 cleanUpRemovedTaskLocked(r.task, flags); 5924 return true; 5925 } else { 5926 TaskRecord tr = null; 5927 int i=0; 5928 while (i < mRecentTasks.size()) { 5929 TaskRecord t = mRecentTasks.get(i); 5930 if (t.taskId == taskId) { 5931 tr = t; 5932 break; 5933 } 5934 i++; 5935 } 5936 if (tr != null) { 5937 if (tr.numActivities <= 0) { 5938 // Caller is just removing a recent task that is 5939 // not actively running. That is easy! 5940 mRecentTasks.remove(i); 5941 cleanUpRemovedTaskLocked(tr, flags); 5942 return true; 5943 } else { 5944 Slog.w(TAG, "removeTask: task " + taskId 5945 + " does not have activities to remove, " 5946 + " but numActivities=" + tr.numActivities 5947 + ": " + tr); 5948 } 5949 } 5950 } 5951 } finally { 5952 Binder.restoreCallingIdentity(ident); 5953 } 5954 } 5955 return false; 5956 } 5957 5958 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5959 int j; 5960 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5961 TaskRecord jt = startTask; 5962 5963 // First look backwards 5964 for (j=startIndex-1; j>=0; j--) { 5965 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5966 if (r.task != jt) { 5967 jt = r.task; 5968 if (affinity.equals(jt.affinity)) { 5969 return j; 5970 } 5971 } 5972 } 5973 5974 // Now look forwards 5975 final int N = mMainStack.mHistory.size(); 5976 jt = startTask; 5977 for (j=startIndex+1; j<N; j++) { 5978 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5979 if (r.task != jt) { 5980 if (affinity.equals(jt.affinity)) { 5981 return j; 5982 } 5983 jt = r.task; 5984 } 5985 } 5986 5987 // Might it be at the top? 5988 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5989 return N-1; 5990 } 5991 5992 return -1; 5993 } 5994 5995 /** 5996 * TODO: Add mController hook 5997 */ 5998 public void moveTaskToFront(int task, int flags, Bundle options) { 5999 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6000 "moveTaskToFront()"); 6001 6002 synchronized(this) { 6003 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6004 Binder.getCallingUid(), "Task to front")) { 6005 ActivityOptions.abort(options); 6006 return; 6007 } 6008 final long origId = Binder.clearCallingIdentity(); 6009 try { 6010 TaskRecord tr = taskForIdLocked(task); 6011 if (tr != null) { 6012 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6013 mMainStack.mUserLeaving = true; 6014 } 6015 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6016 // Caller wants the home activity moved with it. To accomplish this, 6017 // we'll just move the home task to the top first. 6018 mMainStack.moveHomeToFrontLocked(); 6019 } 6020 mMainStack.moveTaskToFrontLocked(tr, null, options); 6021 return; 6022 } 6023 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 6024 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 6025 if (hr.task.taskId == task) { 6026 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 6027 mMainStack.mUserLeaving = true; 6028 } 6029 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 6030 // Caller wants the home activity moved with it. To accomplish this, 6031 // we'll just move the home task to the top first. 6032 mMainStack.moveHomeToFrontLocked(); 6033 } 6034 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 6035 return; 6036 } 6037 } 6038 } finally { 6039 Binder.restoreCallingIdentity(origId); 6040 } 6041 ActivityOptions.abort(options); 6042 } 6043 } 6044 6045 public void moveTaskToBack(int task) { 6046 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6047 "moveTaskToBack()"); 6048 6049 synchronized(this) { 6050 if (mMainStack.mResumedActivity != null 6051 && mMainStack.mResumedActivity.task.taskId == task) { 6052 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6053 Binder.getCallingUid(), "Task to back")) { 6054 return; 6055 } 6056 } 6057 final long origId = Binder.clearCallingIdentity(); 6058 mMainStack.moveTaskToBackLocked(task, null); 6059 Binder.restoreCallingIdentity(origId); 6060 } 6061 } 6062 6063 /** 6064 * Moves an activity, and all of the other activities within the same task, to the bottom 6065 * of the history stack. The activity's order within the task is unchanged. 6066 * 6067 * @param token A reference to the activity we wish to move 6068 * @param nonRoot If false then this only works if the activity is the root 6069 * of a task; if true it will work for any activity in a task. 6070 * @return Returns true if the move completed, false if not. 6071 */ 6072 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6073 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6074 synchronized(this) { 6075 final long origId = Binder.clearCallingIdentity(); 6076 int taskId = getTaskForActivityLocked(token, !nonRoot); 6077 if (taskId >= 0) { 6078 return mMainStack.moveTaskToBackLocked(taskId, null); 6079 } 6080 Binder.restoreCallingIdentity(origId); 6081 } 6082 return false; 6083 } 6084 6085 public void moveTaskBackwards(int task) { 6086 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6087 "moveTaskBackwards()"); 6088 6089 synchronized(this) { 6090 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6091 Binder.getCallingUid(), "Task backwards")) { 6092 return; 6093 } 6094 final long origId = Binder.clearCallingIdentity(); 6095 moveTaskBackwardsLocked(task); 6096 Binder.restoreCallingIdentity(origId); 6097 } 6098 } 6099 6100 private final void moveTaskBackwardsLocked(int task) { 6101 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6102 } 6103 6104 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6105 synchronized(this) { 6106 return getTaskForActivityLocked(token, onlyRoot); 6107 } 6108 } 6109 6110 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6111 final int N = mMainStack.mHistory.size(); 6112 TaskRecord lastTask = null; 6113 for (int i=0; i<N; i++) { 6114 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 6115 if (r.appToken == token) { 6116 if (!onlyRoot || lastTask != r.task) { 6117 return r.task.taskId; 6118 } 6119 return -1; 6120 } 6121 lastTask = r.task; 6122 } 6123 6124 return -1; 6125 } 6126 6127 // ========================================================= 6128 // THUMBNAILS 6129 // ========================================================= 6130 6131 public void reportThumbnail(IBinder token, 6132 Bitmap thumbnail, CharSequence description) { 6133 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6134 final long origId = Binder.clearCallingIdentity(); 6135 sendPendingThumbnail(null, token, thumbnail, description, true); 6136 Binder.restoreCallingIdentity(origId); 6137 } 6138 6139 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 6140 Bitmap thumbnail, CharSequence description, boolean always) { 6141 TaskRecord task = null; 6142 ArrayList receivers = null; 6143 6144 //System.out.println("Send pending thumbnail: " + r); 6145 6146 synchronized(this) { 6147 if (r == null) { 6148 r = mMainStack.isInStackLocked(token); 6149 if (r == null) { 6150 return; 6151 } 6152 } 6153 if (thumbnail == null && r.thumbHolder != null) { 6154 thumbnail = r.thumbHolder.lastThumbnail; 6155 description = r.thumbHolder.lastDescription; 6156 } 6157 if (thumbnail == null && !always) { 6158 // If there is no thumbnail, and this entry is not actually 6159 // going away, then abort for now and pick up the next 6160 // thumbnail we get. 6161 return; 6162 } 6163 task = r.task; 6164 6165 int N = mPendingThumbnails.size(); 6166 int i=0; 6167 while (i<N) { 6168 PendingThumbnailsRecord pr = 6169 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6170 //System.out.println("Looking in " + pr.pendingRecords); 6171 if (pr.pendingRecords.remove(r)) { 6172 if (receivers == null) { 6173 receivers = new ArrayList(); 6174 } 6175 receivers.add(pr); 6176 if (pr.pendingRecords.size() == 0) { 6177 pr.finished = true; 6178 mPendingThumbnails.remove(i); 6179 N--; 6180 continue; 6181 } 6182 } 6183 i++; 6184 } 6185 } 6186 6187 if (receivers != null) { 6188 final int N = receivers.size(); 6189 for (int i=0; i<N; i++) { 6190 try { 6191 PendingThumbnailsRecord pr = 6192 (PendingThumbnailsRecord)receivers.get(i); 6193 pr.receiver.newThumbnail( 6194 task != null ? task.taskId : -1, thumbnail, description); 6195 if (pr.finished) { 6196 pr.receiver.finished(); 6197 } 6198 } catch (Exception e) { 6199 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6200 } 6201 } 6202 } 6203 } 6204 6205 // ========================================================= 6206 // CONTENT PROVIDERS 6207 // ========================================================= 6208 6209 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6210 List<ProviderInfo> providers = null; 6211 try { 6212 providers = AppGlobals.getPackageManager(). 6213 queryContentProviders(app.processName, app.uid, 6214 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6215 } catch (RemoteException ex) { 6216 } 6217 if (DEBUG_MU) 6218 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6219 int userId = app.userId; 6220 if (providers != null) { 6221 int N = providers.size(); 6222 for (int i=0; i<N; i++) { 6223 ProviderInfo cpi = 6224 (ProviderInfo)providers.get(i); 6225 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6226 cpi.name, cpi.flags); 6227 if (singleton && UserHandle.getUserId(app.uid) != 0) { 6228 // This is a singleton provider, but a user besides the 6229 // default user is asking to initialize a process it runs 6230 // in... well, no, it doesn't actually run in this process, 6231 // it runs in the process of the default user. Get rid of it. 6232 providers.remove(i); 6233 N--; 6234 continue; 6235 } 6236 6237 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6238 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6239 if (cpr == null) { 6240 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 6241 mProviderMap.putProviderByClass(comp, cpr); 6242 } 6243 if (DEBUG_MU) 6244 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6245 app.pubProviders.put(cpi.name, cpr); 6246 app.addPackage(cpi.applicationInfo.packageName); 6247 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6248 } 6249 } 6250 return providers; 6251 } 6252 6253 /** 6254 * Check if {@link ProcessRecord} has a possible chance at accessing the 6255 * given {@link ProviderInfo}. Final permission checking is always done 6256 * in {@link ContentProvider}. 6257 */ 6258 private final String checkContentProviderPermissionLocked( 6259 ProviderInfo cpi, ProcessRecord r) { 6260 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6261 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6262 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6263 cpi.applicationInfo.uid, cpi.exported) 6264 == PackageManager.PERMISSION_GRANTED) { 6265 return null; 6266 } 6267 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6268 cpi.applicationInfo.uid, cpi.exported) 6269 == PackageManager.PERMISSION_GRANTED) { 6270 return null; 6271 } 6272 6273 PathPermission[] pps = cpi.pathPermissions; 6274 if (pps != null) { 6275 int i = pps.length; 6276 while (i > 0) { 6277 i--; 6278 PathPermission pp = pps[i]; 6279 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6280 cpi.applicationInfo.uid, cpi.exported) 6281 == PackageManager.PERMISSION_GRANTED) { 6282 return null; 6283 } 6284 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6285 cpi.applicationInfo.uid, cpi.exported) 6286 == PackageManager.PERMISSION_GRANTED) { 6287 return null; 6288 } 6289 } 6290 } 6291 6292 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6293 if (perms != null) { 6294 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6295 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6296 return null; 6297 } 6298 } 6299 } 6300 6301 String msg; 6302 if (!cpi.exported) { 6303 msg = "Permission Denial: opening provider " + cpi.name 6304 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6305 + ", uid=" + callingUid + ") that is not exported from uid " 6306 + cpi.applicationInfo.uid; 6307 } else { 6308 msg = "Permission Denial: opening provider " + cpi.name 6309 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6310 + ", uid=" + callingUid + ") requires " 6311 + cpi.readPermission + " or " + cpi.writePermission; 6312 } 6313 Slog.w(TAG, msg); 6314 return msg; 6315 } 6316 6317 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6318 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6319 if (r != null) { 6320 for (int i=0; i<r.conProviders.size(); i++) { 6321 ContentProviderConnection conn = r.conProviders.get(i); 6322 if (conn.provider == cpr) { 6323 if (DEBUG_PROVIDER) Slog.v(TAG, 6324 "Adding provider requested by " 6325 + r.processName + " from process " 6326 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6327 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6328 if (stable) { 6329 conn.stableCount++; 6330 conn.numStableIncs++; 6331 } else { 6332 conn.unstableCount++; 6333 conn.numUnstableIncs++; 6334 } 6335 return conn; 6336 } 6337 } 6338 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6339 if (stable) { 6340 conn.stableCount = 1; 6341 conn.numStableIncs = 1; 6342 } else { 6343 conn.unstableCount = 1; 6344 conn.numUnstableIncs = 1; 6345 } 6346 cpr.connections.add(conn); 6347 r.conProviders.add(conn); 6348 return conn; 6349 } 6350 cpr.addExternalProcessHandleLocked(externalProcessToken); 6351 return null; 6352 } 6353 6354 boolean decProviderCountLocked(ContentProviderConnection conn, 6355 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6356 if (conn != null) { 6357 cpr = conn.provider; 6358 if (DEBUG_PROVIDER) Slog.v(TAG, 6359 "Removing provider requested by " 6360 + conn.client.processName + " from process " 6361 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6362 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6363 if (stable) { 6364 conn.stableCount--; 6365 } else { 6366 conn.unstableCount--; 6367 } 6368 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6369 cpr.connections.remove(conn); 6370 conn.client.conProviders.remove(conn); 6371 return true; 6372 } 6373 return false; 6374 } 6375 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6376 return false; 6377 } 6378 6379 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6380 String name, IBinder token, boolean stable, int userId) { 6381 ContentProviderRecord cpr; 6382 ContentProviderConnection conn = null; 6383 ProviderInfo cpi = null; 6384 6385 synchronized(this) { 6386 ProcessRecord r = null; 6387 if (caller != null) { 6388 r = getRecordForAppLocked(caller); 6389 if (r == null) { 6390 throw new SecurityException( 6391 "Unable to find app for caller " + caller 6392 + " (pid=" + Binder.getCallingPid() 6393 + ") when getting content provider " + name); 6394 } 6395 if (r.userId != userId) { 6396 throw new SecurityException("Calling requested user " + userId 6397 + " but app is user " + r.userId); 6398 } 6399 } 6400 6401 // First check if this content provider has been published... 6402 cpr = mProviderMap.getProviderByName(name, userId); 6403 boolean providerRunning = cpr != null; 6404 if (providerRunning) { 6405 cpi = cpr.info; 6406 String msg; 6407 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6408 throw new SecurityException(msg); 6409 } 6410 6411 if (r != null && cpr.canRunHere(r)) { 6412 // This provider has been published or is in the process 6413 // of being published... but it is also allowed to run 6414 // in the caller's process, so don't make a connection 6415 // and just let the caller instantiate its own instance. 6416 ContentProviderHolder holder = cpr.newHolder(null); 6417 // don't give caller the provider object, it needs 6418 // to make its own. 6419 holder.provider = null; 6420 return holder; 6421 } 6422 6423 final long origId = Binder.clearCallingIdentity(); 6424 6425 // In this case the provider instance already exists, so we can 6426 // return it right away. 6427 conn = incProviderCountLocked(r, cpr, token, stable); 6428 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6429 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6430 // If this is a perceptible app accessing the provider, 6431 // make sure to count it as being accessed and thus 6432 // back up on the LRU list. This is good because 6433 // content providers are often expensive to start. 6434 updateLruProcessLocked(cpr.proc, false, true); 6435 } 6436 } 6437 6438 if (cpr.proc != null) { 6439 if (false) { 6440 if (cpr.name.flattenToShortString().equals( 6441 "com.android.providers.calendar/.CalendarProvider2")) { 6442 Slog.v(TAG, "****************** KILLING " 6443 + cpr.name.flattenToShortString()); 6444 Process.killProcess(cpr.proc.pid); 6445 } 6446 } 6447 boolean success = updateOomAdjLocked(cpr.proc); 6448 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6449 // NOTE: there is still a race here where a signal could be 6450 // pending on the process even though we managed to update its 6451 // adj level. Not sure what to do about this, but at least 6452 // the race is now smaller. 6453 if (!success) { 6454 // Uh oh... it looks like the provider's process 6455 // has been killed on us. We need to wait for a new 6456 // process to be started, and make sure its death 6457 // doesn't kill our process. 6458 Slog.i(TAG, 6459 "Existing provider " + cpr.name.flattenToShortString() 6460 + " is crashing; detaching " + r); 6461 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6462 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6463 if (!lastRef) { 6464 // This wasn't the last ref our process had on 6465 // the provider... we have now been killed, bail. 6466 return null; 6467 } 6468 providerRunning = false; 6469 conn = null; 6470 } 6471 } 6472 6473 Binder.restoreCallingIdentity(origId); 6474 } 6475 6476 boolean singleton; 6477 if (!providerRunning) { 6478 try { 6479 cpi = AppGlobals.getPackageManager(). 6480 resolveContentProvider(name, 6481 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6482 } catch (RemoteException ex) { 6483 } 6484 if (cpi == null) { 6485 return null; 6486 } 6487 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 6488 cpi.name, cpi.flags); 6489 if (singleton) { 6490 userId = 0; 6491 } 6492 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6493 6494 String msg; 6495 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6496 throw new SecurityException(msg); 6497 } 6498 6499 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6500 && !cpi.processName.equals("system")) { 6501 // If this content provider does not run in the system 6502 // process, and the system is not yet ready to run other 6503 // processes, then fail fast instead of hanging. 6504 throw new IllegalArgumentException( 6505 "Attempt to launch content provider before system ready"); 6506 } 6507 6508 // Make sure that the user who owns this provider is started. If not, 6509 // we don't want to allow it to run. 6510 if (mStartedUsers.get(userId) == null) { 6511 Slog.w(TAG, "Unable to launch app " 6512 + cpi.applicationInfo.packageName + "/" 6513 + cpi.applicationInfo.uid + " for provider " 6514 + name + ": user " + userId + " is stopped"); 6515 return null; 6516 } 6517 6518 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6519 cpr = mProviderMap.getProviderByClass(comp, userId); 6520 final boolean firstClass = cpr == null; 6521 if (firstClass) { 6522 try { 6523 ApplicationInfo ai = 6524 AppGlobals.getPackageManager(). 6525 getApplicationInfo( 6526 cpi.applicationInfo.packageName, 6527 STOCK_PM_FLAGS, userId); 6528 if (ai == null) { 6529 Slog.w(TAG, "No package info for content provider " 6530 + cpi.name); 6531 return null; 6532 } 6533 ai = getAppInfoForUser(ai, userId); 6534 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 6535 } catch (RemoteException ex) { 6536 // pm is in same process, this will never happen. 6537 } 6538 } 6539 6540 if (r != null && cpr.canRunHere(r)) { 6541 // If this is a multiprocess provider, then just return its 6542 // info and allow the caller to instantiate it. Only do 6543 // this if the provider is the same user as the caller's 6544 // process, or can run as root (so can be in any process). 6545 return cpr.newHolder(null); 6546 } 6547 6548 if (DEBUG_PROVIDER) { 6549 RuntimeException e = new RuntimeException("here"); 6550 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6551 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6552 } 6553 6554 // This is single process, and our app is now connecting to it. 6555 // See if we are already in the process of launching this 6556 // provider. 6557 final int N = mLaunchingProviders.size(); 6558 int i; 6559 for (i=0; i<N; i++) { 6560 if (mLaunchingProviders.get(i) == cpr) { 6561 break; 6562 } 6563 } 6564 6565 // If the provider is not already being launched, then get it 6566 // started. 6567 if (i >= N) { 6568 final long origId = Binder.clearCallingIdentity(); 6569 6570 try { 6571 // Content provider is now in use, its package can't be stopped. 6572 try { 6573 AppGlobals.getPackageManager().setPackageStoppedState( 6574 cpr.appInfo.packageName, false, userId); 6575 } catch (RemoteException e) { 6576 } catch (IllegalArgumentException e) { 6577 Slog.w(TAG, "Failed trying to unstop package " 6578 + cpr.appInfo.packageName + ": " + e); 6579 } 6580 6581 ProcessRecord proc = startProcessLocked(cpi.processName, 6582 cpr.appInfo, false, 0, "content provider", 6583 new ComponentName(cpi.applicationInfo.packageName, 6584 cpi.name), false, false); 6585 if (proc == null) { 6586 Slog.w(TAG, "Unable to launch app " 6587 + cpi.applicationInfo.packageName + "/" 6588 + cpi.applicationInfo.uid + " for provider " 6589 + name + ": process is bad"); 6590 return null; 6591 } 6592 cpr.launchingApp = proc; 6593 mLaunchingProviders.add(cpr); 6594 } finally { 6595 Binder.restoreCallingIdentity(origId); 6596 } 6597 } 6598 6599 // Make sure the provider is published (the same provider class 6600 // may be published under multiple names). 6601 if (firstClass) { 6602 mProviderMap.putProviderByClass(comp, cpr); 6603 } 6604 6605 mProviderMap.putProviderByName(name, cpr); 6606 conn = incProviderCountLocked(r, cpr, token, stable); 6607 if (conn != null) { 6608 conn.waiting = true; 6609 } 6610 } 6611 } 6612 6613 // Wait for the provider to be published... 6614 synchronized (cpr) { 6615 while (cpr.provider == null) { 6616 if (cpr.launchingApp == null) { 6617 Slog.w(TAG, "Unable to launch app " 6618 + cpi.applicationInfo.packageName + "/" 6619 + cpi.applicationInfo.uid + " for provider " 6620 + name + ": launching app became null"); 6621 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6622 cpi.applicationInfo.packageName, 6623 cpi.applicationInfo.uid, name); 6624 return null; 6625 } 6626 try { 6627 if (DEBUG_MU) { 6628 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6629 + cpr.launchingApp); 6630 } 6631 if (conn != null) { 6632 conn.waiting = true; 6633 } 6634 cpr.wait(); 6635 } catch (InterruptedException ex) { 6636 } finally { 6637 if (conn != null) { 6638 conn.waiting = false; 6639 } 6640 } 6641 } 6642 } 6643 return cpr != null ? cpr.newHolder(conn) : null; 6644 } 6645 6646 public final ContentProviderHolder getContentProvider( 6647 IApplicationThread caller, String name, boolean stable) { 6648 enforceNotIsolatedCaller("getContentProvider"); 6649 if (caller == null) { 6650 String msg = "null IApplicationThread when getting content provider " 6651 + name; 6652 Slog.w(TAG, msg); 6653 throw new SecurityException(msg); 6654 } 6655 6656 return getContentProviderImpl(caller, name, null, stable, 6657 UserHandle.getCallingUserId()); 6658 } 6659 6660 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6661 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6662 "Do not have permission in call getContentProviderExternal()"); 6663 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6664 } 6665 6666 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 6667 IBinder token, int userId) { 6668 return getContentProviderImpl(null, name, token, true, userId); 6669 } 6670 6671 /** 6672 * Drop a content provider from a ProcessRecord's bookkeeping 6673 * @param cpr 6674 */ 6675 public void removeContentProvider(IBinder connection, boolean stable) { 6676 enforceNotIsolatedCaller("removeContentProvider"); 6677 synchronized (this) { 6678 ContentProviderConnection conn; 6679 try { 6680 conn = (ContentProviderConnection)connection; 6681 } catch (ClassCastException e) { 6682 String msg ="removeContentProvider: " + connection 6683 + " not a ContentProviderConnection"; 6684 Slog.w(TAG, msg); 6685 throw new IllegalArgumentException(msg); 6686 } 6687 if (conn == null) { 6688 throw new NullPointerException("connection is null"); 6689 } 6690 if (decProviderCountLocked(conn, null, null, stable)) { 6691 updateOomAdjLocked(); 6692 } 6693 } 6694 } 6695 6696 public void removeContentProviderExternal(String name, IBinder token) { 6697 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6698 "Do not have permission in call removeContentProviderExternal()"); 6699 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 6700 } 6701 6702 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 6703 synchronized (this) { 6704 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 6705 if(cpr == null) { 6706 //remove from mProvidersByClass 6707 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6708 return; 6709 } 6710 6711 //update content provider record entry info 6712 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6713 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 6714 if (localCpr.hasExternalProcessHandles()) { 6715 if (localCpr.removeExternalProcessHandleLocked(token)) { 6716 updateOomAdjLocked(); 6717 } else { 6718 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6719 + " with no external reference for token: " 6720 + token + "."); 6721 } 6722 } else { 6723 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6724 + " with no external references."); 6725 } 6726 } 6727 } 6728 6729 public final void publishContentProviders(IApplicationThread caller, 6730 List<ContentProviderHolder> providers) { 6731 if (providers == null) { 6732 return; 6733 } 6734 6735 enforceNotIsolatedCaller("publishContentProviders"); 6736 synchronized (this) { 6737 final ProcessRecord r = getRecordForAppLocked(caller); 6738 if (DEBUG_MU) 6739 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6740 if (r == null) { 6741 throw new SecurityException( 6742 "Unable to find app for caller " + caller 6743 + " (pid=" + Binder.getCallingPid() 6744 + ") when publishing content providers"); 6745 } 6746 6747 final long origId = Binder.clearCallingIdentity(); 6748 6749 final int N = providers.size(); 6750 for (int i=0; i<N; i++) { 6751 ContentProviderHolder src = providers.get(i); 6752 if (src == null || src.info == null || src.provider == null) { 6753 continue; 6754 } 6755 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6756 if (DEBUG_MU) 6757 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6758 if (dst != null) { 6759 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6760 mProviderMap.putProviderByClass(comp, dst); 6761 String names[] = dst.info.authority.split(";"); 6762 for (int j = 0; j < names.length; j++) { 6763 mProviderMap.putProviderByName(names[j], dst); 6764 } 6765 6766 int NL = mLaunchingProviders.size(); 6767 int j; 6768 for (j=0; j<NL; j++) { 6769 if (mLaunchingProviders.get(j) == dst) { 6770 mLaunchingProviders.remove(j); 6771 j--; 6772 NL--; 6773 } 6774 } 6775 synchronized (dst) { 6776 dst.provider = src.provider; 6777 dst.proc = r; 6778 dst.notifyAll(); 6779 } 6780 updateOomAdjLocked(r); 6781 } 6782 } 6783 6784 Binder.restoreCallingIdentity(origId); 6785 } 6786 } 6787 6788 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6789 ContentProviderConnection conn; 6790 try { 6791 conn = (ContentProviderConnection)connection; 6792 } catch (ClassCastException e) { 6793 String msg ="refContentProvider: " + connection 6794 + " not a ContentProviderConnection"; 6795 Slog.w(TAG, msg); 6796 throw new IllegalArgumentException(msg); 6797 } 6798 if (conn == null) { 6799 throw new NullPointerException("connection is null"); 6800 } 6801 6802 synchronized (this) { 6803 if (stable > 0) { 6804 conn.numStableIncs += stable; 6805 } 6806 stable = conn.stableCount + stable; 6807 if (stable < 0) { 6808 throw new IllegalStateException("stableCount < 0: " + stable); 6809 } 6810 6811 if (unstable > 0) { 6812 conn.numUnstableIncs += unstable; 6813 } 6814 unstable = conn.unstableCount + unstable; 6815 if (unstable < 0) { 6816 throw new IllegalStateException("unstableCount < 0: " + unstable); 6817 } 6818 6819 if ((stable+unstable) <= 0) { 6820 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6821 + stable + " unstable=" + unstable); 6822 } 6823 conn.stableCount = stable; 6824 conn.unstableCount = unstable; 6825 return !conn.dead; 6826 } 6827 } 6828 6829 public void unstableProviderDied(IBinder connection) { 6830 ContentProviderConnection conn; 6831 try { 6832 conn = (ContentProviderConnection)connection; 6833 } catch (ClassCastException e) { 6834 String msg ="refContentProvider: " + connection 6835 + " not a ContentProviderConnection"; 6836 Slog.w(TAG, msg); 6837 throw new IllegalArgumentException(msg); 6838 } 6839 if (conn == null) { 6840 throw new NullPointerException("connection is null"); 6841 } 6842 6843 // Safely retrieve the content provider associated with the connection. 6844 IContentProvider provider; 6845 synchronized (this) { 6846 provider = conn.provider.provider; 6847 } 6848 6849 if (provider == null) { 6850 // Um, yeah, we're way ahead of you. 6851 return; 6852 } 6853 6854 // Make sure the caller is being honest with us. 6855 if (provider.asBinder().pingBinder()) { 6856 // Er, no, still looks good to us. 6857 synchronized (this) { 6858 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6859 + " says " + conn + " died, but we don't agree"); 6860 return; 6861 } 6862 } 6863 6864 // Well look at that! It's dead! 6865 synchronized (this) { 6866 if (conn.provider.provider != provider) { 6867 // But something changed... good enough. 6868 return; 6869 } 6870 6871 ProcessRecord proc = conn.provider.proc; 6872 if (proc == null || proc.thread == null) { 6873 // Seems like the process is already cleaned up. 6874 return; 6875 } 6876 6877 // As far as we're concerned, this is just like receiving a 6878 // death notification... just a bit prematurely. 6879 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6880 + ") early provider death"); 6881 final long ident = Binder.clearCallingIdentity(); 6882 try { 6883 appDiedLocked(proc, proc.pid, proc.thread); 6884 } finally { 6885 Binder.restoreCallingIdentity(ident); 6886 } 6887 } 6888 } 6889 6890 public static final void installSystemProviders() { 6891 List<ProviderInfo> providers; 6892 synchronized (mSelf) { 6893 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6894 providers = mSelf.generateApplicationProvidersLocked(app); 6895 if (providers != null) { 6896 for (int i=providers.size()-1; i>=0; i--) { 6897 ProviderInfo pi = (ProviderInfo)providers.get(i); 6898 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6899 Slog.w(TAG, "Not installing system proc provider " + pi.name 6900 + ": not system .apk"); 6901 providers.remove(i); 6902 } 6903 } 6904 } 6905 } 6906 if (providers != null) { 6907 mSystemThread.installSystemProviders(providers); 6908 } 6909 6910 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6911 6912 mSelf.mUsageStatsService.monitorPackages(); 6913 } 6914 6915 /** 6916 * Allows app to retrieve the MIME type of a URI without having permission 6917 * to access its content provider. 6918 * 6919 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6920 * 6921 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6922 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6923 */ 6924 public String getProviderMimeType(Uri uri, int userId) { 6925 enforceNotIsolatedCaller("getProviderMimeType"); 6926 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 6927 userId, false, true, "getProviderMimeType", null); 6928 final String name = uri.getAuthority(); 6929 final long ident = Binder.clearCallingIdentity(); 6930 ContentProviderHolder holder = null; 6931 6932 try { 6933 holder = getContentProviderExternalUnchecked(name, null, userId); 6934 if (holder != null) { 6935 return holder.provider.getType(uri); 6936 } 6937 } catch (RemoteException e) { 6938 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6939 return null; 6940 } finally { 6941 if (holder != null) { 6942 removeContentProviderExternalUnchecked(name, null, userId); 6943 } 6944 Binder.restoreCallingIdentity(ident); 6945 } 6946 6947 return null; 6948 } 6949 6950 // ========================================================= 6951 // GLOBAL MANAGEMENT 6952 // ========================================================= 6953 6954 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6955 ApplicationInfo info, String customProcess, boolean isolated) { 6956 String proc = customProcess != null ? customProcess : info.processName; 6957 BatteryStatsImpl.Uid.Proc ps = null; 6958 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6959 int uid = info.uid; 6960 if (isolated) { 6961 int userId = UserHandle.getUserId(uid); 6962 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6963 uid = 0; 6964 while (true) { 6965 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6966 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6967 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6968 } 6969 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 6970 mNextIsolatedProcessUid++; 6971 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6972 // No process for this uid, use it. 6973 break; 6974 } 6975 stepsLeft--; 6976 if (stepsLeft <= 0) { 6977 return null; 6978 } 6979 } 6980 } 6981 synchronized (stats) { 6982 ps = stats.getProcessStatsLocked(info.uid, proc); 6983 } 6984 return new ProcessRecord(ps, thread, info, proc, uid); 6985 } 6986 6987 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6988 ProcessRecord app; 6989 if (!isolated) { 6990 app = getProcessRecordLocked(info.processName, info.uid); 6991 } else { 6992 app = null; 6993 } 6994 6995 if (app == null) { 6996 app = newProcessRecordLocked(null, info, null, isolated); 6997 mProcessNames.put(info.processName, app.uid, app); 6998 if (isolated) { 6999 mIsolatedProcesses.put(app.uid, app); 7000 } 7001 updateLruProcessLocked(app, true, true); 7002 } 7003 7004 // This package really, really can not be stopped. 7005 try { 7006 AppGlobals.getPackageManager().setPackageStoppedState( 7007 info.packageName, false, UserHandle.getUserId(app.uid)); 7008 } catch (RemoteException e) { 7009 } catch (IllegalArgumentException e) { 7010 Slog.w(TAG, "Failed trying to unstop package " 7011 + info.packageName + ": " + e); 7012 } 7013 7014 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7015 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7016 app.persistent = true; 7017 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 7018 } 7019 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7020 mPersistentStartingProcesses.add(app); 7021 startProcessLocked(app, "added application", app.processName); 7022 } 7023 7024 return app; 7025 } 7026 7027 public void unhandledBack() { 7028 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7029 "unhandledBack()"); 7030 7031 synchronized(this) { 7032 int count = mMainStack.mHistory.size(); 7033 if (DEBUG_SWITCH) Slog.d( 7034 TAG, "Performing unhandledBack(): stack size = " + count); 7035 if (count > 1) { 7036 final long origId = Binder.clearCallingIdentity(); 7037 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 7038 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); 7039 Binder.restoreCallingIdentity(origId); 7040 } 7041 } 7042 } 7043 7044 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7045 enforceNotIsolatedCaller("openContentUri"); 7046 final int userId = UserHandle.getCallingUserId(); 7047 String name = uri.getAuthority(); 7048 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 7049 ParcelFileDescriptor pfd = null; 7050 if (cph != null) { 7051 // We record the binder invoker's uid in thread-local storage before 7052 // going to the content provider to open the file. Later, in the code 7053 // that handles all permissions checks, we look for this uid and use 7054 // that rather than the Activity Manager's own uid. The effect is that 7055 // we do the check against the caller's permissions even though it looks 7056 // to the content provider like the Activity Manager itself is making 7057 // the request. 7058 sCallerIdentity.set(new Identity( 7059 Binder.getCallingPid(), Binder.getCallingUid())); 7060 try { 7061 pfd = cph.provider.openFile(uri, "r"); 7062 } catch (FileNotFoundException e) { 7063 // do nothing; pfd will be returned null 7064 } finally { 7065 // Ensure that whatever happens, we clean up the identity state 7066 sCallerIdentity.remove(); 7067 } 7068 7069 // We've got the fd now, so we're done with the provider. 7070 removeContentProviderExternalUnchecked(name, null, userId); 7071 } else { 7072 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 7073 } 7074 return pfd; 7075 } 7076 7077 // Actually is sleeping or shutting down or whatever else in the future 7078 // is an inactive state. 7079 public boolean isSleeping() { 7080 return mSleeping || mShuttingDown; 7081 } 7082 7083 public void goingToSleep() { 7084 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7085 != PackageManager.PERMISSION_GRANTED) { 7086 throw new SecurityException("Requires permission " 7087 + android.Manifest.permission.DEVICE_POWER); 7088 } 7089 7090 synchronized(this) { 7091 mWentToSleep = true; 7092 updateEventDispatchingLocked(); 7093 7094 if (!mSleeping) { 7095 mSleeping = true; 7096 mMainStack.stopIfSleepingLocked(); 7097 7098 // Initialize the wake times of all processes. 7099 checkExcessivePowerUsageLocked(false); 7100 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7101 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 7102 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 7103 } 7104 } 7105 } 7106 7107 public boolean shutdown(int timeout) { 7108 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7109 != PackageManager.PERMISSION_GRANTED) { 7110 throw new SecurityException("Requires permission " 7111 + android.Manifest.permission.SHUTDOWN); 7112 } 7113 7114 boolean timedout = false; 7115 7116 synchronized(this) { 7117 mShuttingDown = true; 7118 updateEventDispatchingLocked(); 7119 7120 if (mMainStack.mResumedActivity != null) { 7121 mMainStack.stopIfSleepingLocked(); 7122 final long endTime = System.currentTimeMillis() + timeout; 7123 while (mMainStack.mResumedActivity != null 7124 || mMainStack.mPausingActivity != null) { 7125 long delay = endTime - System.currentTimeMillis(); 7126 if (delay <= 0) { 7127 Slog.w(TAG, "Activity manager shutdown timed out"); 7128 timedout = true; 7129 break; 7130 } 7131 try { 7132 this.wait(); 7133 } catch (InterruptedException e) { 7134 } 7135 } 7136 } 7137 } 7138 7139 mUsageStatsService.shutdown(); 7140 mBatteryStatsService.shutdown(); 7141 7142 return timedout; 7143 } 7144 7145 public final void activitySlept(IBinder token) { 7146 if (localLOGV) Slog.v( 7147 TAG, "Activity slept: token=" + token); 7148 7149 ActivityRecord r = null; 7150 7151 final long origId = Binder.clearCallingIdentity(); 7152 7153 synchronized (this) { 7154 r = mMainStack.isInStackLocked(token); 7155 if (r != null) { 7156 mMainStack.activitySleptLocked(r); 7157 } 7158 } 7159 7160 Binder.restoreCallingIdentity(origId); 7161 } 7162 7163 private void comeOutOfSleepIfNeededLocked() { 7164 if (!mWentToSleep && !mLockScreenShown) { 7165 if (mSleeping) { 7166 mSleeping = false; 7167 mMainStack.awakeFromSleepingLocked(); 7168 mMainStack.resumeTopActivityLocked(null); 7169 } 7170 } 7171 } 7172 7173 public void wakingUp() { 7174 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7175 != PackageManager.PERMISSION_GRANTED) { 7176 throw new SecurityException("Requires permission " 7177 + android.Manifest.permission.DEVICE_POWER); 7178 } 7179 7180 synchronized(this) { 7181 mWentToSleep = false; 7182 updateEventDispatchingLocked(); 7183 comeOutOfSleepIfNeededLocked(); 7184 } 7185 } 7186 7187 private void updateEventDispatchingLocked() { 7188 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 7189 } 7190 7191 public void setLockScreenShown(boolean shown) { 7192 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 7193 != PackageManager.PERMISSION_GRANTED) { 7194 throw new SecurityException("Requires permission " 7195 + android.Manifest.permission.DEVICE_POWER); 7196 } 7197 7198 synchronized(this) { 7199 mLockScreenShown = shown; 7200 comeOutOfSleepIfNeededLocked(); 7201 } 7202 } 7203 7204 public void stopAppSwitches() { 7205 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7206 != PackageManager.PERMISSION_GRANTED) { 7207 throw new SecurityException("Requires permission " 7208 + android.Manifest.permission.STOP_APP_SWITCHES); 7209 } 7210 7211 synchronized(this) { 7212 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7213 + APP_SWITCH_DELAY_TIME; 7214 mDidAppSwitch = false; 7215 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7216 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7217 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7218 } 7219 } 7220 7221 public void resumeAppSwitches() { 7222 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7223 != PackageManager.PERMISSION_GRANTED) { 7224 throw new SecurityException("Requires permission " 7225 + android.Manifest.permission.STOP_APP_SWITCHES); 7226 } 7227 7228 synchronized(this) { 7229 // Note that we don't execute any pending app switches... we will 7230 // let those wait until either the timeout, or the next start 7231 // activity request. 7232 mAppSwitchesAllowedTime = 0; 7233 } 7234 } 7235 7236 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7237 String name) { 7238 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7239 return true; 7240 } 7241 7242 final int perm = checkComponentPermission( 7243 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7244 callingUid, -1, true); 7245 if (perm == PackageManager.PERMISSION_GRANTED) { 7246 return true; 7247 } 7248 7249 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7250 return false; 7251 } 7252 7253 public void setDebugApp(String packageName, boolean waitForDebugger, 7254 boolean persistent) { 7255 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7256 "setDebugApp()"); 7257 7258 // Note that this is not really thread safe if there are multiple 7259 // callers into it at the same time, but that's not a situation we 7260 // care about. 7261 if (persistent) { 7262 final ContentResolver resolver = mContext.getContentResolver(); 7263 Settings.System.putString( 7264 resolver, Settings.System.DEBUG_APP, 7265 packageName); 7266 Settings.System.putInt( 7267 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7268 waitForDebugger ? 1 : 0); 7269 } 7270 7271 synchronized (this) { 7272 if (!persistent) { 7273 mOrigDebugApp = mDebugApp; 7274 mOrigWaitForDebugger = mWaitForDebugger; 7275 } 7276 mDebugApp = packageName; 7277 mWaitForDebugger = waitForDebugger; 7278 mDebugTransient = !persistent; 7279 if (packageName != null) { 7280 final long origId = Binder.clearCallingIdentity(); 7281 forceStopPackageLocked(packageName, -1, false, false, true, true, 7282 UserHandle.USER_ALL); 7283 Binder.restoreCallingIdentity(origId); 7284 } 7285 } 7286 } 7287 7288 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7289 synchronized (this) { 7290 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7291 if (!isDebuggable) { 7292 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7293 throw new SecurityException("Process not debuggable: " + app.packageName); 7294 } 7295 } 7296 7297 mOpenGlTraceApp = processName; 7298 } 7299 } 7300 7301 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7302 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7303 synchronized (this) { 7304 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7305 if (!isDebuggable) { 7306 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7307 throw new SecurityException("Process not debuggable: " + app.packageName); 7308 } 7309 } 7310 mProfileApp = processName; 7311 mProfileFile = profileFile; 7312 if (mProfileFd != null) { 7313 try { 7314 mProfileFd.close(); 7315 } catch (IOException e) { 7316 } 7317 mProfileFd = null; 7318 } 7319 mProfileFd = profileFd; 7320 mProfileType = 0; 7321 mAutoStopProfiler = autoStopProfiler; 7322 } 7323 } 7324 7325 public void setAlwaysFinish(boolean enabled) { 7326 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7327 "setAlwaysFinish()"); 7328 7329 Settings.System.putInt( 7330 mContext.getContentResolver(), 7331 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7332 7333 synchronized (this) { 7334 mAlwaysFinishActivities = enabled; 7335 } 7336 } 7337 7338 public void setActivityController(IActivityController controller) { 7339 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7340 "setActivityController()"); 7341 synchronized (this) { 7342 mController = controller; 7343 } 7344 } 7345 7346 public boolean isUserAMonkey() { 7347 // For now the fact that there is a controller implies 7348 // we have a monkey. 7349 synchronized (this) { 7350 return mController != null; 7351 } 7352 } 7353 7354 public void registerProcessObserver(IProcessObserver observer) { 7355 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7356 "registerProcessObserver()"); 7357 synchronized (this) { 7358 mProcessObservers.register(observer); 7359 } 7360 } 7361 7362 public void unregisterProcessObserver(IProcessObserver observer) { 7363 synchronized (this) { 7364 mProcessObservers.unregister(observer); 7365 } 7366 } 7367 7368 public void setImmersive(IBinder token, boolean immersive) { 7369 synchronized(this) { 7370 ActivityRecord r = mMainStack.isInStackLocked(token); 7371 if (r == null) { 7372 throw new IllegalArgumentException(); 7373 } 7374 r.immersive = immersive; 7375 } 7376 } 7377 7378 public boolean isImmersive(IBinder token) { 7379 synchronized (this) { 7380 ActivityRecord r = mMainStack.isInStackLocked(token); 7381 if (r == null) { 7382 throw new IllegalArgumentException(); 7383 } 7384 return r.immersive; 7385 } 7386 } 7387 7388 public boolean isTopActivityImmersive() { 7389 enforceNotIsolatedCaller("startActivity"); 7390 synchronized (this) { 7391 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7392 return (r != null) ? r.immersive : false; 7393 } 7394 } 7395 7396 public final void enterSafeMode() { 7397 synchronized(this) { 7398 // It only makes sense to do this before the system is ready 7399 // and started launching other packages. 7400 if (!mSystemReady) { 7401 try { 7402 AppGlobals.getPackageManager().enterSafeMode(); 7403 } catch (RemoteException e) { 7404 } 7405 } 7406 } 7407 } 7408 7409 public final void showSafeModeOverlay() { 7410 View v = LayoutInflater.from(mContext).inflate( 7411 com.android.internal.R.layout.safe_mode, null); 7412 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7413 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7414 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7415 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7416 lp.gravity = Gravity.BOTTOM | Gravity.START; 7417 lp.format = v.getBackground().getOpacity(); 7418 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7419 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7420 ((WindowManager)mContext.getSystemService( 7421 Context.WINDOW_SERVICE)).addView(v, lp); 7422 } 7423 7424 public void noteWakeupAlarm(IIntentSender sender) { 7425 if (!(sender instanceof PendingIntentRecord)) { 7426 return; 7427 } 7428 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7429 synchronized (stats) { 7430 if (mBatteryStatsService.isOnBattery()) { 7431 mBatteryStatsService.enforceCallingPermission(); 7432 PendingIntentRecord rec = (PendingIntentRecord)sender; 7433 int MY_UID = Binder.getCallingUid(); 7434 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7435 BatteryStatsImpl.Uid.Pkg pkg = 7436 stats.getPackageStatsLocked(uid, rec.key.packageName); 7437 pkg.incWakeupsLocked(); 7438 } 7439 } 7440 } 7441 7442 public boolean killPids(int[] pids, String pReason, boolean secure) { 7443 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7444 throw new SecurityException("killPids only available to the system"); 7445 } 7446 String reason = (pReason == null) ? "Unknown" : pReason; 7447 // XXX Note: don't acquire main activity lock here, because the window 7448 // manager calls in with its locks held. 7449 7450 boolean killed = false; 7451 synchronized (mPidsSelfLocked) { 7452 int[] types = new int[pids.length]; 7453 int worstType = 0; 7454 for (int i=0; i<pids.length; i++) { 7455 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7456 if (proc != null) { 7457 int type = proc.setAdj; 7458 types[i] = type; 7459 if (type > worstType) { 7460 worstType = type; 7461 } 7462 } 7463 } 7464 7465 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7466 // then constrain it so we will kill all hidden procs. 7467 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7468 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7469 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7470 } 7471 7472 // If this is not a secure call, don't let it kill processes that 7473 // are important. 7474 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7475 worstType = ProcessList.SERVICE_ADJ; 7476 } 7477 7478 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7479 for (int i=0; i<pids.length; i++) { 7480 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7481 if (proc == null) { 7482 continue; 7483 } 7484 int adj = proc.setAdj; 7485 if (adj >= worstType && !proc.killedBackground) { 7486 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7487 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7488 proc.processName, adj, reason); 7489 killed = true; 7490 proc.killedBackground = true; 7491 Process.killProcessQuiet(pids[i]); 7492 } 7493 } 7494 } 7495 return killed; 7496 } 7497 7498 @Override 7499 public boolean killProcessesBelowForeground(String reason) { 7500 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7501 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7502 } 7503 7504 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7505 } 7506 7507 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7508 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7509 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7510 } 7511 7512 boolean killed = false; 7513 synchronized (mPidsSelfLocked) { 7514 final int size = mPidsSelfLocked.size(); 7515 for (int i = 0; i < size; i++) { 7516 final int pid = mPidsSelfLocked.keyAt(i); 7517 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7518 if (proc == null) continue; 7519 7520 final int adj = proc.setAdj; 7521 if (adj > belowAdj && !proc.killedBackground) { 7522 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7523 EventLog.writeEvent( 7524 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7525 killed = true; 7526 proc.killedBackground = true; 7527 Process.killProcessQuiet(pid); 7528 } 7529 } 7530 } 7531 return killed; 7532 } 7533 7534 public final void startRunning(String pkg, String cls, String action, 7535 String data) { 7536 synchronized(this) { 7537 if (mStartRunning) { 7538 return; 7539 } 7540 mStartRunning = true; 7541 mTopComponent = pkg != null && cls != null 7542 ? new ComponentName(pkg, cls) : null; 7543 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7544 mTopData = data; 7545 if (!mSystemReady) { 7546 return; 7547 } 7548 } 7549 7550 systemReady(null); 7551 } 7552 7553 private void retrieveSettings() { 7554 final ContentResolver resolver = mContext.getContentResolver(); 7555 String debugApp = Settings.System.getString( 7556 resolver, Settings.System.DEBUG_APP); 7557 boolean waitForDebugger = Settings.System.getInt( 7558 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7559 boolean alwaysFinishActivities = Settings.System.getInt( 7560 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7561 7562 Configuration configuration = new Configuration(); 7563 Settings.System.getConfiguration(resolver, configuration); 7564 7565 synchronized (this) { 7566 mDebugApp = mOrigDebugApp = debugApp; 7567 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7568 mAlwaysFinishActivities = alwaysFinishActivities; 7569 // This happens before any activities are started, so we can 7570 // change mConfiguration in-place. 7571 updateConfigurationLocked(configuration, null, false, true); 7572 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7573 } 7574 } 7575 7576 public boolean testIsSystemReady() { 7577 // no need to synchronize(this) just to read & return the value 7578 return mSystemReady; 7579 } 7580 7581 private static File getCalledPreBootReceiversFile() { 7582 File dataDir = Environment.getDataDirectory(); 7583 File systemDir = new File(dataDir, "system"); 7584 File fname = new File(systemDir, "called_pre_boots.dat"); 7585 return fname; 7586 } 7587 7588 static final int LAST_DONE_VERSION = 10000; 7589 7590 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7591 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7592 File file = getCalledPreBootReceiversFile(); 7593 FileInputStream fis = null; 7594 try { 7595 fis = new FileInputStream(file); 7596 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7597 int fvers = dis.readInt(); 7598 if (fvers == LAST_DONE_VERSION) { 7599 String vers = dis.readUTF(); 7600 String codename = dis.readUTF(); 7601 String build = dis.readUTF(); 7602 if (android.os.Build.VERSION.RELEASE.equals(vers) 7603 && android.os.Build.VERSION.CODENAME.equals(codename) 7604 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7605 int num = dis.readInt(); 7606 while (num > 0) { 7607 num--; 7608 String pkg = dis.readUTF(); 7609 String cls = dis.readUTF(); 7610 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7611 } 7612 } 7613 } 7614 } catch (FileNotFoundException e) { 7615 } catch (IOException e) { 7616 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7617 } finally { 7618 if (fis != null) { 7619 try { 7620 fis.close(); 7621 } catch (IOException e) { 7622 } 7623 } 7624 } 7625 return lastDoneReceivers; 7626 } 7627 7628 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7629 File file = getCalledPreBootReceiversFile(); 7630 FileOutputStream fos = null; 7631 DataOutputStream dos = null; 7632 try { 7633 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7634 fos = new FileOutputStream(file); 7635 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7636 dos.writeInt(LAST_DONE_VERSION); 7637 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7638 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7639 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7640 dos.writeInt(list.size()); 7641 for (int i=0; i<list.size(); i++) { 7642 dos.writeUTF(list.get(i).getPackageName()); 7643 dos.writeUTF(list.get(i).getClassName()); 7644 } 7645 } catch (IOException e) { 7646 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7647 file.delete(); 7648 } finally { 7649 FileUtils.sync(fos); 7650 if (dos != null) { 7651 try { 7652 dos.close(); 7653 } catch (IOException e) { 7654 // TODO Auto-generated catch block 7655 e.printStackTrace(); 7656 } 7657 } 7658 } 7659 } 7660 7661 public void systemReady(final Runnable goingCallback) { 7662 synchronized(this) { 7663 if (mSystemReady) { 7664 if (goingCallback != null) goingCallback.run(); 7665 return; 7666 } 7667 7668 // Check to see if there are any update receivers to run. 7669 if (!mDidUpdate) { 7670 if (mWaitingUpdate) { 7671 return; 7672 } 7673 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7674 List<ResolveInfo> ris = null; 7675 try { 7676 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7677 intent, null, 0, 0); 7678 } catch (RemoteException e) { 7679 } 7680 if (ris != null) { 7681 for (int i=ris.size()-1; i>=0; i--) { 7682 if ((ris.get(i).activityInfo.applicationInfo.flags 7683 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7684 ris.remove(i); 7685 } 7686 } 7687 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7688 7689 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7690 7691 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7692 for (int i=0; i<ris.size(); i++) { 7693 ActivityInfo ai = ris.get(i).activityInfo; 7694 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7695 if (lastDoneReceivers.contains(comp)) { 7696 ris.remove(i); 7697 i--; 7698 } 7699 } 7700 7701 final int[] users = getUsersLocked(); 7702 for (int i=0; i<ris.size(); i++) { 7703 ActivityInfo ai = ris.get(i).activityInfo; 7704 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7705 doneReceivers.add(comp); 7706 intent.setComponent(comp); 7707 for (int j=0; j<users.length; j++) { 7708 IIntentReceiver finisher = null; 7709 if (i == ris.size()-1 && j == users.length-1) { 7710 finisher = new IIntentReceiver.Stub() { 7711 public void performReceive(Intent intent, int resultCode, 7712 String data, Bundle extras, boolean ordered, 7713 boolean sticky, int sendingUser) { 7714 // The raw IIntentReceiver interface is called 7715 // with the AM lock held, so redispatch to 7716 // execute our code without the lock. 7717 mHandler.post(new Runnable() { 7718 public void run() { 7719 synchronized (ActivityManagerService.this) { 7720 mDidUpdate = true; 7721 } 7722 writeLastDonePreBootReceivers(doneReceivers); 7723 showBootMessage(mContext.getText( 7724 R.string.android_upgrading_complete), 7725 false); 7726 systemReady(goingCallback); 7727 } 7728 }); 7729 } 7730 }; 7731 } 7732 Slog.i(TAG, "Sending system update to " + intent.getComponent() 7733 + " for user " + users[j]); 7734 broadcastIntentLocked(null, null, intent, null, finisher, 7735 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7736 users[j]); 7737 if (finisher != null) { 7738 mWaitingUpdate = true; 7739 } 7740 } 7741 } 7742 } 7743 if (mWaitingUpdate) { 7744 return; 7745 } 7746 mDidUpdate = true; 7747 } 7748 7749 mSystemReady = true; 7750 if (!mStartRunning) { 7751 return; 7752 } 7753 } 7754 7755 ArrayList<ProcessRecord> procsToKill = null; 7756 synchronized(mPidsSelfLocked) { 7757 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7758 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7759 if (!isAllowedWhileBooting(proc.info)){ 7760 if (procsToKill == null) { 7761 procsToKill = new ArrayList<ProcessRecord>(); 7762 } 7763 procsToKill.add(proc); 7764 } 7765 } 7766 } 7767 7768 synchronized(this) { 7769 if (procsToKill != null) { 7770 for (int i=procsToKill.size()-1; i>=0; i--) { 7771 ProcessRecord proc = procsToKill.get(i); 7772 Slog.i(TAG, "Removing system update proc: " + proc); 7773 removeProcessLocked(proc, true, false, "system update done"); 7774 } 7775 } 7776 7777 // Now that we have cleaned up any update processes, we 7778 // are ready to start launching real processes and know that 7779 // we won't trample on them any more. 7780 mProcessesReady = true; 7781 } 7782 7783 Slog.i(TAG, "System now ready"); 7784 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7785 SystemClock.uptimeMillis()); 7786 7787 synchronized(this) { 7788 // Make sure we have no pre-ready processes sitting around. 7789 7790 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7791 ResolveInfo ri = mContext.getPackageManager() 7792 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7793 STOCK_PM_FLAGS); 7794 CharSequence errorMsg = null; 7795 if (ri != null) { 7796 ActivityInfo ai = ri.activityInfo; 7797 ApplicationInfo app = ai.applicationInfo; 7798 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7799 mTopAction = Intent.ACTION_FACTORY_TEST; 7800 mTopData = null; 7801 mTopComponent = new ComponentName(app.packageName, 7802 ai.name); 7803 } else { 7804 errorMsg = mContext.getResources().getText( 7805 com.android.internal.R.string.factorytest_not_system); 7806 } 7807 } else { 7808 errorMsg = mContext.getResources().getText( 7809 com.android.internal.R.string.factorytest_no_action); 7810 } 7811 if (errorMsg != null) { 7812 mTopAction = null; 7813 mTopData = null; 7814 mTopComponent = null; 7815 Message msg = Message.obtain(); 7816 msg.what = SHOW_FACTORY_ERROR_MSG; 7817 msg.getData().putCharSequence("msg", errorMsg); 7818 mHandler.sendMessage(msg); 7819 } 7820 } 7821 } 7822 7823 retrieveSettings(); 7824 7825 if (goingCallback != null) goingCallback.run(); 7826 7827 synchronized (this) { 7828 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7829 try { 7830 List apps = AppGlobals.getPackageManager(). 7831 getPersistentApplications(STOCK_PM_FLAGS); 7832 if (apps != null) { 7833 int N = apps.size(); 7834 int i; 7835 for (i=0; i<N; i++) { 7836 ApplicationInfo info 7837 = (ApplicationInfo)apps.get(i); 7838 if (info != null && 7839 !info.packageName.equals("android")) { 7840 addAppLocked(info, false); 7841 } 7842 } 7843 } 7844 } catch (RemoteException ex) { 7845 // pm is in same process, this will never happen. 7846 } 7847 } 7848 7849 // Start up initial activity. 7850 mBooting = true; 7851 7852 try { 7853 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7854 Message msg = Message.obtain(); 7855 msg.what = SHOW_UID_ERROR_MSG; 7856 mHandler.sendMessage(msg); 7857 } 7858 } catch (RemoteException e) { 7859 } 7860 7861 long ident = Binder.clearCallingIdentity(); 7862 try { 7863 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 7864 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 7865 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 7866 broadcastIntentLocked(null, null, intent, 7867 null, null, 0, null, null, null, 7868 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 7869 } finally { 7870 Binder.restoreCallingIdentity(ident); 7871 } 7872 mMainStack.resumeTopActivityLocked(null); 7873 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 7874 } 7875 } 7876 7877 private boolean makeAppCrashingLocked(ProcessRecord app, 7878 String shortMsg, String longMsg, String stackTrace) { 7879 app.crashing = true; 7880 app.crashingReport = generateProcessError(app, 7881 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7882 startAppProblemLocked(app); 7883 app.stopFreezingAllLocked(); 7884 return handleAppCrashLocked(app); 7885 } 7886 7887 private void makeAppNotRespondingLocked(ProcessRecord app, 7888 String activity, String shortMsg, String longMsg) { 7889 app.notResponding = true; 7890 app.notRespondingReport = generateProcessError(app, 7891 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7892 activity, shortMsg, longMsg, null); 7893 startAppProblemLocked(app); 7894 app.stopFreezingAllLocked(); 7895 } 7896 7897 /** 7898 * Generate a process error record, suitable for attachment to a ProcessRecord. 7899 * 7900 * @param app The ProcessRecord in which the error occurred. 7901 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7902 * ActivityManager.AppErrorStateInfo 7903 * @param activity The activity associated with the crash, if known. 7904 * @param shortMsg Short message describing the crash. 7905 * @param longMsg Long message describing the crash. 7906 * @param stackTrace Full crash stack trace, may be null. 7907 * 7908 * @return Returns a fully-formed AppErrorStateInfo record. 7909 */ 7910 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7911 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7912 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7913 7914 report.condition = condition; 7915 report.processName = app.processName; 7916 report.pid = app.pid; 7917 report.uid = app.info.uid; 7918 report.tag = activity; 7919 report.shortMsg = shortMsg; 7920 report.longMsg = longMsg; 7921 report.stackTrace = stackTrace; 7922 7923 return report; 7924 } 7925 7926 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7927 synchronized (this) { 7928 app.crashing = false; 7929 app.crashingReport = null; 7930 app.notResponding = false; 7931 app.notRespondingReport = null; 7932 if (app.anrDialog == fromDialog) { 7933 app.anrDialog = null; 7934 } 7935 if (app.waitDialog == fromDialog) { 7936 app.waitDialog = null; 7937 } 7938 if (app.pid > 0 && app.pid != MY_PID) { 7939 handleAppCrashLocked(app); 7940 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7941 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7942 app.processName, app.setAdj, "user's request after error"); 7943 Process.killProcessQuiet(app.pid); 7944 } 7945 } 7946 } 7947 7948 private boolean handleAppCrashLocked(ProcessRecord app) { 7949 if (mHeadless) { 7950 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7951 return false; 7952 } 7953 long now = SystemClock.uptimeMillis(); 7954 7955 Long crashTime; 7956 if (!app.isolated) { 7957 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7958 } else { 7959 crashTime = null; 7960 } 7961 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7962 // This process loses! 7963 Slog.w(TAG, "Process " + app.info.processName 7964 + " has crashed too many times: killing!"); 7965 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7966 app.info.processName, app.uid); 7967 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7968 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7969 if (r.app == app) { 7970 Slog.w(TAG, " Force finishing activity " 7971 + r.intent.getComponent().flattenToShortString()); 7972 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7973 null, "crashed", false); 7974 } 7975 } 7976 if (!app.persistent) { 7977 // We don't want to start this process again until the user 7978 // explicitly does so... but for persistent process, we really 7979 // need to keep it running. If a persistent process is actually 7980 // repeatedly crashing, then badness for everyone. 7981 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7982 app.info.processName); 7983 if (!app.isolated) { 7984 // XXX We don't have a way to mark isolated processes 7985 // as bad, since they don't have a peristent identity. 7986 mBadProcesses.put(app.info.processName, app.uid, now); 7987 mProcessCrashTimes.remove(app.info.processName, app.uid); 7988 } 7989 app.bad = true; 7990 app.removed = true; 7991 // Don't let services in this process be restarted and potentially 7992 // annoy the user repeatedly. Unless it is persistent, since those 7993 // processes run critical code. 7994 removeProcessLocked(app, false, false, "crash"); 7995 mMainStack.resumeTopActivityLocked(null); 7996 return false; 7997 } 7998 mMainStack.resumeTopActivityLocked(null); 7999 } else { 8000 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 8001 if (r != null && r.app == app) { 8002 // If the top running activity is from this crashing 8003 // process, then terminate it to avoid getting in a loop. 8004 Slog.w(TAG, " Force finishing activity " 8005 + r.intent.getComponent().flattenToShortString()); 8006 int index = mMainStack.indexOfActivityLocked(r); 8007 r.stack.finishActivityLocked(r, index, 8008 Activity.RESULT_CANCELED, null, "crashed", false); 8009 // Also terminate any activities below it that aren't yet 8010 // stopped, to avoid a situation where one will get 8011 // re-start our crashing activity once it gets resumed again. 8012 index--; 8013 if (index >= 0) { 8014 r = (ActivityRecord)mMainStack.mHistory.get(index); 8015 if (r.state == ActivityState.RESUMED 8016 || r.state == ActivityState.PAUSING 8017 || r.state == ActivityState.PAUSED) { 8018 if (!r.isHomeActivity || mHomeProcess != r.app) { 8019 Slog.w(TAG, " Force finishing activity " 8020 + r.intent.getComponent().flattenToShortString()); 8021 r.stack.finishActivityLocked(r, index, 8022 Activity.RESULT_CANCELED, null, "crashed", false); 8023 } 8024 } 8025 } 8026 } 8027 } 8028 8029 // Bump up the crash count of any services currently running in the proc. 8030 if (app.services.size() != 0) { 8031 // Any services running in the application need to be placed 8032 // back in the pending list. 8033 Iterator<ServiceRecord> it = app.services.iterator(); 8034 while (it.hasNext()) { 8035 ServiceRecord sr = it.next(); 8036 sr.crashCount++; 8037 } 8038 } 8039 8040 // If the crashing process is what we consider to be the "home process" and it has been 8041 // replaced by a third-party app, clear the package preferred activities from packages 8042 // with a home activity running in the process to prevent a repeatedly crashing app 8043 // from blocking the user to manually clear the list. 8044 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 8045 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 8046 Iterator it = mHomeProcess.activities.iterator(); 8047 while (it.hasNext()) { 8048 ActivityRecord r = (ActivityRecord)it.next(); 8049 if (r.isHomeActivity) { 8050 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 8051 try { 8052 ActivityThread.getPackageManager() 8053 .clearPackagePreferredActivities(r.packageName); 8054 } catch (RemoteException c) { 8055 // pm is in same process, this will never happen. 8056 } 8057 } 8058 } 8059 } 8060 8061 if (!app.isolated) { 8062 // XXX Can't keep track of crash times for isolated processes, 8063 // because they don't have a perisistent identity. 8064 mProcessCrashTimes.put(app.info.processName, app.uid, now); 8065 } 8066 8067 return true; 8068 } 8069 8070 void startAppProblemLocked(ProcessRecord app) { 8071 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 8072 mContext, app.info.packageName, app.info.flags); 8073 skipCurrentReceiverLocked(app); 8074 } 8075 8076 void skipCurrentReceiverLocked(ProcessRecord app) { 8077 for (BroadcastQueue queue : mBroadcastQueues) { 8078 queue.skipCurrentReceiverLocked(app); 8079 } 8080 } 8081 8082 /** 8083 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8084 * The application process will exit immediately after this call returns. 8085 * @param app object of the crashing app, null for the system server 8086 * @param crashInfo describing the exception 8087 */ 8088 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8089 ProcessRecord r = findAppProcess(app, "Crash"); 8090 final String processName = app == null ? "system_server" 8091 : (r == null ? "unknown" : r.processName); 8092 8093 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8094 processName, 8095 r == null ? -1 : r.info.flags, 8096 crashInfo.exceptionClassName, 8097 crashInfo.exceptionMessage, 8098 crashInfo.throwFileName, 8099 crashInfo.throwLineNumber); 8100 8101 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 8102 8103 crashApplication(r, crashInfo); 8104 } 8105 8106 public void handleApplicationStrictModeViolation( 8107 IBinder app, 8108 int violationMask, 8109 StrictMode.ViolationInfo info) { 8110 ProcessRecord r = findAppProcess(app, "StrictMode"); 8111 if (r == null) { 8112 return; 8113 } 8114 8115 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 8116 Integer stackFingerprint = info.hashCode(); 8117 boolean logIt = true; 8118 synchronized (mAlreadyLoggedViolatedStacks) { 8119 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 8120 logIt = false; 8121 // TODO: sub-sample into EventLog for these, with 8122 // the info.durationMillis? Then we'd get 8123 // the relative pain numbers, without logging all 8124 // the stack traces repeatedly. We'd want to do 8125 // likewise in the client code, which also does 8126 // dup suppression, before the Binder call. 8127 } else { 8128 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 8129 mAlreadyLoggedViolatedStacks.clear(); 8130 } 8131 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 8132 } 8133 } 8134 if (logIt) { 8135 logStrictModeViolationToDropBox(r, info); 8136 } 8137 } 8138 8139 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 8140 AppErrorResult result = new AppErrorResult(); 8141 synchronized (this) { 8142 final long origId = Binder.clearCallingIdentity(); 8143 8144 Message msg = Message.obtain(); 8145 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 8146 HashMap<String, Object> data = new HashMap<String, Object>(); 8147 data.put("result", result); 8148 data.put("app", r); 8149 data.put("violationMask", violationMask); 8150 data.put("info", info); 8151 msg.obj = data; 8152 mHandler.sendMessage(msg); 8153 8154 Binder.restoreCallingIdentity(origId); 8155 } 8156 int res = result.get(); 8157 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 8158 } 8159 } 8160 8161 // Depending on the policy in effect, there could be a bunch of 8162 // these in quick succession so we try to batch these together to 8163 // minimize disk writes, number of dropbox entries, and maximize 8164 // compression, by having more fewer, larger records. 8165 private void logStrictModeViolationToDropBox( 8166 ProcessRecord process, 8167 StrictMode.ViolationInfo info) { 8168 if (info == null) { 8169 return; 8170 } 8171 final boolean isSystemApp = process == null || 8172 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 8173 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 8174 final String processName = process == null ? "unknown" : process.processName; 8175 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 8176 final DropBoxManager dbox = (DropBoxManager) 8177 mContext.getSystemService(Context.DROPBOX_SERVICE); 8178 8179 // Exit early if the dropbox isn't configured to accept this report type. 8180 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8181 8182 boolean bufferWasEmpty; 8183 boolean needsFlush; 8184 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 8185 synchronized (sb) { 8186 bufferWasEmpty = sb.length() == 0; 8187 appendDropBoxProcessHeaders(process, processName, sb); 8188 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8189 sb.append("System-App: ").append(isSystemApp).append("\n"); 8190 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 8191 if (info.violationNumThisLoop != 0) { 8192 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 8193 } 8194 if (info.numAnimationsRunning != 0) { 8195 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 8196 } 8197 if (info.broadcastIntentAction != null) { 8198 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 8199 } 8200 if (info.durationMillis != -1) { 8201 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 8202 } 8203 if (info.numInstances != -1) { 8204 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 8205 } 8206 if (info.tags != null) { 8207 for (String tag : info.tags) { 8208 sb.append("Span-Tag: ").append(tag).append("\n"); 8209 } 8210 } 8211 sb.append("\n"); 8212 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 8213 sb.append(info.crashInfo.stackTrace); 8214 } 8215 sb.append("\n"); 8216 8217 // Only buffer up to ~64k. Various logging bits truncate 8218 // things at 128k. 8219 needsFlush = (sb.length() > 64 * 1024); 8220 } 8221 8222 // Flush immediately if the buffer's grown too large, or this 8223 // is a non-system app. Non-system apps are isolated with a 8224 // different tag & policy and not batched. 8225 // 8226 // Batching is useful during internal testing with 8227 // StrictMode settings turned up high. Without batching, 8228 // thousands of separate files could be created on boot. 8229 if (!isSystemApp || needsFlush) { 8230 new Thread("Error dump: " + dropboxTag) { 8231 @Override 8232 public void run() { 8233 String report; 8234 synchronized (sb) { 8235 report = sb.toString(); 8236 sb.delete(0, sb.length()); 8237 sb.trimToSize(); 8238 } 8239 if (report.length() != 0) { 8240 dbox.addText(dropboxTag, report); 8241 } 8242 } 8243 }.start(); 8244 return; 8245 } 8246 8247 // System app batching: 8248 if (!bufferWasEmpty) { 8249 // An existing dropbox-writing thread is outstanding, so 8250 // we don't need to start it up. The existing thread will 8251 // catch the buffer appends we just did. 8252 return; 8253 } 8254 8255 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8256 // (After this point, we shouldn't access AMS internal data structures.) 8257 new Thread("Error dump: " + dropboxTag) { 8258 @Override 8259 public void run() { 8260 // 5 second sleep to let stacks arrive and be batched together 8261 try { 8262 Thread.sleep(5000); // 5 seconds 8263 } catch (InterruptedException e) {} 8264 8265 String errorReport; 8266 synchronized (mStrictModeBuffer) { 8267 errorReport = mStrictModeBuffer.toString(); 8268 if (errorReport.length() == 0) { 8269 return; 8270 } 8271 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8272 mStrictModeBuffer.trimToSize(); 8273 } 8274 dbox.addText(dropboxTag, errorReport); 8275 } 8276 }.start(); 8277 } 8278 8279 /** 8280 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8281 * @param app object of the crashing app, null for the system server 8282 * @param tag reported by the caller 8283 * @param crashInfo describing the context of the error 8284 * @return true if the process should exit immediately (WTF is fatal) 8285 */ 8286 public boolean handleApplicationWtf(IBinder app, String tag, 8287 ApplicationErrorReport.CrashInfo crashInfo) { 8288 ProcessRecord r = findAppProcess(app, "WTF"); 8289 final String processName = app == null ? "system_server" 8290 : (r == null ? "unknown" : r.processName); 8291 8292 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8293 processName, 8294 r == null ? -1 : r.info.flags, 8295 tag, crashInfo.exceptionMessage); 8296 8297 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8298 8299 if (r != null && r.pid != Process.myPid() && 8300 Settings.Secure.getInt(mContext.getContentResolver(), 8301 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8302 crashApplication(r, crashInfo); 8303 return true; 8304 } else { 8305 return false; 8306 } 8307 } 8308 8309 /** 8310 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8311 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8312 */ 8313 private ProcessRecord findAppProcess(IBinder app, String reason) { 8314 if (app == null) { 8315 return null; 8316 } 8317 8318 synchronized (this) { 8319 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8320 final int NA = apps.size(); 8321 for (int ia=0; ia<NA; ia++) { 8322 ProcessRecord p = apps.valueAt(ia); 8323 if (p.thread != null && p.thread.asBinder() == app) { 8324 return p; 8325 } 8326 } 8327 } 8328 8329 Slog.w(TAG, "Can't find mystery application for " + reason 8330 + " from pid=" + Binder.getCallingPid() 8331 + " uid=" + Binder.getCallingUid() + ": " + app); 8332 return null; 8333 } 8334 } 8335 8336 /** 8337 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8338 * to append various headers to the dropbox log text. 8339 */ 8340 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8341 StringBuilder sb) { 8342 // Watchdog thread ends up invoking this function (with 8343 // a null ProcessRecord) to add the stack file to dropbox. 8344 // Do not acquire a lock on this (am) in such cases, as it 8345 // could cause a potential deadlock, if and when watchdog 8346 // is invoked due to unavailability of lock on am and it 8347 // would prevent watchdog from killing system_server. 8348 if (process == null) { 8349 sb.append("Process: ").append(processName).append("\n"); 8350 return; 8351 } 8352 // Note: ProcessRecord 'process' is guarded by the service 8353 // instance. (notably process.pkgList, which could otherwise change 8354 // concurrently during execution of this method) 8355 synchronized (this) { 8356 sb.append("Process: ").append(processName).append("\n"); 8357 int flags = process.info.flags; 8358 IPackageManager pm = AppGlobals.getPackageManager(); 8359 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8360 for (String pkg : process.pkgList) { 8361 sb.append("Package: ").append(pkg); 8362 try { 8363 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 8364 if (pi != null) { 8365 sb.append(" v").append(pi.versionCode); 8366 if (pi.versionName != null) { 8367 sb.append(" (").append(pi.versionName).append(")"); 8368 } 8369 } 8370 } catch (RemoteException e) { 8371 Slog.e(TAG, "Error getting package info: " + pkg, e); 8372 } 8373 sb.append("\n"); 8374 } 8375 } 8376 } 8377 8378 private static String processClass(ProcessRecord process) { 8379 if (process == null || process.pid == MY_PID) { 8380 return "system_server"; 8381 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8382 return "system_app"; 8383 } else { 8384 return "data_app"; 8385 } 8386 } 8387 8388 /** 8389 * Write a description of an error (crash, WTF, ANR) to the drop box. 8390 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8391 * @param process which caused the error, null means the system server 8392 * @param activity which triggered the error, null if unknown 8393 * @param parent activity related to the error, null if unknown 8394 * @param subject line related to the error, null if absent 8395 * @param report in long form describing the error, null if absent 8396 * @param logFile to include in the report, null if none 8397 * @param crashInfo giving an application stack trace, null if absent 8398 */ 8399 public void addErrorToDropBox(String eventType, 8400 ProcessRecord process, String processName, ActivityRecord activity, 8401 ActivityRecord parent, String subject, 8402 final String report, final File logFile, 8403 final ApplicationErrorReport.CrashInfo crashInfo) { 8404 // NOTE -- this must never acquire the ActivityManagerService lock, 8405 // otherwise the watchdog may be prevented from resetting the system. 8406 8407 final String dropboxTag = processClass(process) + "_" + eventType; 8408 final DropBoxManager dbox = (DropBoxManager) 8409 mContext.getSystemService(Context.DROPBOX_SERVICE); 8410 8411 // Exit early if the dropbox isn't configured to accept this report type. 8412 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8413 8414 final StringBuilder sb = new StringBuilder(1024); 8415 appendDropBoxProcessHeaders(process, processName, sb); 8416 if (activity != null) { 8417 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8418 } 8419 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8420 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8421 } 8422 if (parent != null && parent != activity) { 8423 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8424 } 8425 if (subject != null) { 8426 sb.append("Subject: ").append(subject).append("\n"); 8427 } 8428 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8429 if (Debug.isDebuggerConnected()) { 8430 sb.append("Debugger: Connected\n"); 8431 } 8432 sb.append("\n"); 8433 8434 // Do the rest in a worker thread to avoid blocking the caller on I/O 8435 // (After this point, we shouldn't access AMS internal data structures.) 8436 Thread worker = new Thread("Error dump: " + dropboxTag) { 8437 @Override 8438 public void run() { 8439 if (report != null) { 8440 sb.append(report); 8441 } 8442 if (logFile != null) { 8443 try { 8444 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8445 } catch (IOException e) { 8446 Slog.e(TAG, "Error reading " + logFile, e); 8447 } 8448 } 8449 if (crashInfo != null && crashInfo.stackTrace != null) { 8450 sb.append(crashInfo.stackTrace); 8451 } 8452 8453 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8454 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8455 if (lines > 0) { 8456 sb.append("\n"); 8457 8458 // Merge several logcat streams, and take the last N lines 8459 InputStreamReader input = null; 8460 try { 8461 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8462 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8463 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8464 8465 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8466 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8467 input = new InputStreamReader(logcat.getInputStream()); 8468 8469 int num; 8470 char[] buf = new char[8192]; 8471 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8472 } catch (IOException e) { 8473 Slog.e(TAG, "Error running logcat", e); 8474 } finally { 8475 if (input != null) try { input.close(); } catch (IOException e) {} 8476 } 8477 } 8478 8479 dbox.addText(dropboxTag, sb.toString()); 8480 } 8481 }; 8482 8483 if (process == null) { 8484 // If process is null, we are being called from some internal code 8485 // and may be about to die -- run this synchronously. 8486 worker.run(); 8487 } else { 8488 worker.start(); 8489 } 8490 } 8491 8492 /** 8493 * Bring up the "unexpected error" dialog box for a crashing app. 8494 * Deal with edge cases (intercepts from instrumented applications, 8495 * ActivityController, error intent receivers, that sort of thing). 8496 * @param r the application crashing 8497 * @param crashInfo describing the failure 8498 */ 8499 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8500 long timeMillis = System.currentTimeMillis(); 8501 String shortMsg = crashInfo.exceptionClassName; 8502 String longMsg = crashInfo.exceptionMessage; 8503 String stackTrace = crashInfo.stackTrace; 8504 if (shortMsg != null && longMsg != null) { 8505 longMsg = shortMsg + ": " + longMsg; 8506 } else if (shortMsg != null) { 8507 longMsg = shortMsg; 8508 } 8509 8510 AppErrorResult result = new AppErrorResult(); 8511 synchronized (this) { 8512 if (mController != null) { 8513 try { 8514 String name = r != null ? r.processName : null; 8515 int pid = r != null ? r.pid : Binder.getCallingPid(); 8516 if (!mController.appCrashed(name, pid, 8517 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8518 Slog.w(TAG, "Force-killing crashed app " + name 8519 + " at watcher's request"); 8520 Process.killProcess(pid); 8521 return; 8522 } 8523 } catch (RemoteException e) { 8524 mController = null; 8525 } 8526 } 8527 8528 final long origId = Binder.clearCallingIdentity(); 8529 8530 // If this process is running instrumentation, finish it. 8531 if (r != null && r.instrumentationClass != null) { 8532 Slog.w(TAG, "Error in app " + r.processName 8533 + " running instrumentation " + r.instrumentationClass + ":"); 8534 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8535 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8536 Bundle info = new Bundle(); 8537 info.putString("shortMsg", shortMsg); 8538 info.putString("longMsg", longMsg); 8539 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8540 Binder.restoreCallingIdentity(origId); 8541 return; 8542 } 8543 8544 // If we can't identify the process or it's already exceeded its crash quota, 8545 // quit right away without showing a crash dialog. 8546 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8547 Binder.restoreCallingIdentity(origId); 8548 return; 8549 } 8550 8551 Message msg = Message.obtain(); 8552 msg.what = SHOW_ERROR_MSG; 8553 HashMap data = new HashMap(); 8554 data.put("result", result); 8555 data.put("app", r); 8556 msg.obj = data; 8557 mHandler.sendMessage(msg); 8558 8559 Binder.restoreCallingIdentity(origId); 8560 } 8561 8562 int res = result.get(); 8563 8564 Intent appErrorIntent = null; 8565 synchronized (this) { 8566 if (r != null && !r.isolated) { 8567 // XXX Can't keep track of crash time for isolated processes, 8568 // since they don't have a persistent identity. 8569 mProcessCrashTimes.put(r.info.processName, r.uid, 8570 SystemClock.uptimeMillis()); 8571 } 8572 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8573 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8574 } 8575 } 8576 8577 if (appErrorIntent != null) { 8578 try { 8579 mContext.startActivity(appErrorIntent); 8580 } catch (ActivityNotFoundException e) { 8581 Slog.w(TAG, "bug report receiver dissappeared", e); 8582 } 8583 } 8584 } 8585 8586 Intent createAppErrorIntentLocked(ProcessRecord r, 8587 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8588 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8589 if (report == null) { 8590 return null; 8591 } 8592 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8593 result.setComponent(r.errorReportReceiver); 8594 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8595 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8596 return result; 8597 } 8598 8599 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8600 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8601 if (r.errorReportReceiver == null) { 8602 return null; 8603 } 8604 8605 if (!r.crashing && !r.notResponding) { 8606 return null; 8607 } 8608 8609 ApplicationErrorReport report = new ApplicationErrorReport(); 8610 report.packageName = r.info.packageName; 8611 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8612 report.processName = r.processName; 8613 report.time = timeMillis; 8614 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8615 8616 if (r.crashing) { 8617 report.type = ApplicationErrorReport.TYPE_CRASH; 8618 report.crashInfo = crashInfo; 8619 } else if (r.notResponding) { 8620 report.type = ApplicationErrorReport.TYPE_ANR; 8621 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8622 8623 report.anrInfo.activity = r.notRespondingReport.tag; 8624 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8625 report.anrInfo.info = r.notRespondingReport.longMsg; 8626 } 8627 8628 return report; 8629 } 8630 8631 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8632 enforceNotIsolatedCaller("getProcessesInErrorState"); 8633 // assume our apps are happy - lazy create the list 8634 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8635 8636 final boolean allUsers = ActivityManager.checkUidPermission( 8637 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8638 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8639 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8640 8641 synchronized (this) { 8642 8643 // iterate across all processes 8644 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8645 ProcessRecord app = mLruProcesses.get(i); 8646 if (!allUsers && app.userId != userId) { 8647 continue; 8648 } 8649 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8650 // This one's in trouble, so we'll generate a report for it 8651 // crashes are higher priority (in case there's a crash *and* an anr) 8652 ActivityManager.ProcessErrorStateInfo report = null; 8653 if (app.crashing) { 8654 report = app.crashingReport; 8655 } else if (app.notResponding) { 8656 report = app.notRespondingReport; 8657 } 8658 8659 if (report != null) { 8660 if (errList == null) { 8661 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8662 } 8663 errList.add(report); 8664 } else { 8665 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8666 " crashing = " + app.crashing + 8667 " notResponding = " + app.notResponding); 8668 } 8669 } 8670 } 8671 } 8672 8673 return errList; 8674 } 8675 8676 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8677 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8678 if (currApp != null) { 8679 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8680 } 8681 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8682 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8683 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8684 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8685 if (currApp != null) { 8686 currApp.lru = 0; 8687 } 8688 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8689 } else if (adj >= ProcessList.SERVICE_ADJ) { 8690 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8691 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8692 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8693 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8694 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8695 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8696 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8697 } else { 8698 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8699 } 8700 } 8701 8702 private void fillInProcMemInfo(ProcessRecord app, 8703 ActivityManager.RunningAppProcessInfo outInfo) { 8704 outInfo.pid = app.pid; 8705 outInfo.uid = app.info.uid; 8706 if (mHeavyWeightProcess == app) { 8707 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8708 } 8709 if (app.persistent) { 8710 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8711 } 8712 if (app.hasActivities) { 8713 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 8714 } 8715 outInfo.lastTrimLevel = app.trimMemoryLevel; 8716 int adj = app.curAdj; 8717 outInfo.importance = oomAdjToImportance(adj, outInfo); 8718 outInfo.importanceReasonCode = app.adjTypeCode; 8719 } 8720 8721 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8722 enforceNotIsolatedCaller("getRunningAppProcesses"); 8723 // Lazy instantiation of list 8724 List<ActivityManager.RunningAppProcessInfo> runList = null; 8725 final boolean allUsers = ActivityManager.checkUidPermission( 8726 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 8727 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 8728 int userId = UserHandle.getUserId(Binder.getCallingUid()); 8729 synchronized (this) { 8730 // Iterate across all processes 8731 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8732 ProcessRecord app = mLruProcesses.get(i); 8733 if (!allUsers && app.userId != userId) { 8734 continue; 8735 } 8736 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8737 // Generate process state info for running application 8738 ActivityManager.RunningAppProcessInfo currApp = 8739 new ActivityManager.RunningAppProcessInfo(app.processName, 8740 app.pid, app.getPackageList()); 8741 fillInProcMemInfo(app, currApp); 8742 if (app.adjSource instanceof ProcessRecord) { 8743 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8744 currApp.importanceReasonImportance = oomAdjToImportance( 8745 app.adjSourceOom, null); 8746 } else if (app.adjSource instanceof ActivityRecord) { 8747 ActivityRecord r = (ActivityRecord)app.adjSource; 8748 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8749 } 8750 if (app.adjTarget instanceof ComponentName) { 8751 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8752 } 8753 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8754 // + " lru=" + currApp.lru); 8755 if (runList == null) { 8756 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8757 } 8758 runList.add(currApp); 8759 } 8760 } 8761 } 8762 return runList; 8763 } 8764 8765 public List<ApplicationInfo> getRunningExternalApplications() { 8766 enforceNotIsolatedCaller("getRunningExternalApplications"); 8767 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8768 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8769 if (runningApps != null && runningApps.size() > 0) { 8770 Set<String> extList = new HashSet<String>(); 8771 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8772 if (app.pkgList != null) { 8773 for (String pkg : app.pkgList) { 8774 extList.add(pkg); 8775 } 8776 } 8777 } 8778 IPackageManager pm = AppGlobals.getPackageManager(); 8779 for (String pkg : extList) { 8780 try { 8781 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 8782 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8783 retList.add(info); 8784 } 8785 } catch (RemoteException e) { 8786 } 8787 } 8788 } 8789 return retList; 8790 } 8791 8792 @Override 8793 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8794 enforceNotIsolatedCaller("getMyMemoryState"); 8795 synchronized (this) { 8796 ProcessRecord proc; 8797 synchronized (mPidsSelfLocked) { 8798 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8799 } 8800 fillInProcMemInfo(proc, outInfo); 8801 } 8802 } 8803 8804 @Override 8805 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8806 if (checkCallingPermission(android.Manifest.permission.DUMP) 8807 != PackageManager.PERMISSION_GRANTED) { 8808 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8809 + Binder.getCallingPid() 8810 + ", uid=" + Binder.getCallingUid() 8811 + " without permission " 8812 + android.Manifest.permission.DUMP); 8813 return; 8814 } 8815 8816 boolean dumpAll = false; 8817 boolean dumpClient = false; 8818 String dumpPackage = null; 8819 8820 int opti = 0; 8821 while (opti < args.length) { 8822 String opt = args[opti]; 8823 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8824 break; 8825 } 8826 opti++; 8827 if ("-a".equals(opt)) { 8828 dumpAll = true; 8829 } else if ("-c".equals(opt)) { 8830 dumpClient = true; 8831 } else if ("-h".equals(opt)) { 8832 pw.println("Activity manager dump options:"); 8833 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8834 pw.println(" cmd may be one of:"); 8835 pw.println(" a[ctivities]: activity stack state"); 8836 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8837 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8838 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8839 pw.println(" o[om]: out of memory management"); 8840 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8841 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8842 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8843 pw.println(" service [COMP_SPEC]: service client-side state"); 8844 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8845 pw.println(" all: dump all activities"); 8846 pw.println(" top: dump the top activity"); 8847 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8848 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8849 pw.println(" a partial substring in a component name, a"); 8850 pw.println(" hex object identifier."); 8851 pw.println(" -a: include all available server state."); 8852 pw.println(" -c: include client state."); 8853 return; 8854 } else { 8855 pw.println("Unknown argument: " + opt + "; use -h for help"); 8856 } 8857 } 8858 8859 long origId = Binder.clearCallingIdentity(); 8860 boolean more = false; 8861 // Is the caller requesting to dump a particular piece of data? 8862 if (opti < args.length) { 8863 String cmd = args[opti]; 8864 opti++; 8865 if ("activities".equals(cmd) || "a".equals(cmd)) { 8866 synchronized (this) { 8867 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8868 } 8869 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8870 String[] newArgs; 8871 String name; 8872 if (opti >= args.length) { 8873 name = null; 8874 newArgs = EMPTY_STRING_ARRAY; 8875 } else { 8876 name = args[opti]; 8877 opti++; 8878 newArgs = new String[args.length - opti]; 8879 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8880 args.length - opti); 8881 } 8882 synchronized (this) { 8883 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8884 } 8885 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8886 String[] newArgs; 8887 String name; 8888 if (opti >= args.length) { 8889 name = null; 8890 newArgs = EMPTY_STRING_ARRAY; 8891 } else { 8892 name = args[opti]; 8893 opti++; 8894 newArgs = new String[args.length - opti]; 8895 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8896 args.length - opti); 8897 } 8898 synchronized (this) { 8899 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8900 } 8901 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8902 String[] newArgs; 8903 String name; 8904 if (opti >= args.length) { 8905 name = null; 8906 newArgs = EMPTY_STRING_ARRAY; 8907 } else { 8908 name = args[opti]; 8909 opti++; 8910 newArgs = new String[args.length - opti]; 8911 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8912 args.length - opti); 8913 } 8914 synchronized (this) { 8915 dumpProcessesLocked(fd, pw, args, opti, true, name); 8916 } 8917 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8918 synchronized (this) { 8919 dumpOomLocked(fd, pw, args, opti, true); 8920 } 8921 } else if ("provider".equals(cmd)) { 8922 String[] newArgs; 8923 String name; 8924 if (opti >= args.length) { 8925 name = null; 8926 newArgs = EMPTY_STRING_ARRAY; 8927 } else { 8928 name = args[opti]; 8929 opti++; 8930 newArgs = new String[args.length - opti]; 8931 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8932 } 8933 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8934 pw.println("No providers match: " + name); 8935 pw.println("Use -h for help."); 8936 } 8937 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8938 synchronized (this) { 8939 dumpProvidersLocked(fd, pw, args, opti, true, null); 8940 } 8941 } else if ("service".equals(cmd)) { 8942 String[] newArgs; 8943 String name; 8944 if (opti >= args.length) { 8945 name = null; 8946 newArgs = EMPTY_STRING_ARRAY; 8947 } else { 8948 name = args[opti]; 8949 opti++; 8950 newArgs = new String[args.length - opti]; 8951 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8952 args.length - opti); 8953 } 8954 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8955 pw.println("No services match: " + name); 8956 pw.println("Use -h for help."); 8957 } 8958 } else if ("package".equals(cmd)) { 8959 String[] newArgs; 8960 if (opti >= args.length) { 8961 pw.println("package: no package name specified"); 8962 pw.println("Use -h for help."); 8963 } else { 8964 dumpPackage = args[opti]; 8965 opti++; 8966 newArgs = new String[args.length - opti]; 8967 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8968 args.length - opti); 8969 args = newArgs; 8970 opti = 0; 8971 more = true; 8972 } 8973 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8974 synchronized (this) { 8975 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8976 } 8977 } else { 8978 // Dumping a single activity? 8979 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8980 pw.println("Bad activity command, or no activities match: " + cmd); 8981 pw.println("Use -h for help."); 8982 } 8983 } 8984 if (!more) { 8985 Binder.restoreCallingIdentity(origId); 8986 return; 8987 } 8988 } 8989 8990 // No piece of data specified, dump everything. 8991 synchronized (this) { 8992 boolean needSep; 8993 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8994 if (needSep) { 8995 pw.println(" "); 8996 } 8997 if (dumpAll) { 8998 pw.println("-------------------------------------------------------------------------------"); 8999 } 9000 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9001 if (needSep) { 9002 pw.println(" "); 9003 } 9004 if (dumpAll) { 9005 pw.println("-------------------------------------------------------------------------------"); 9006 } 9007 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9008 if (needSep) { 9009 pw.println(" "); 9010 } 9011 if (dumpAll) { 9012 pw.println("-------------------------------------------------------------------------------"); 9013 } 9014 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9015 if (needSep) { 9016 pw.println(" "); 9017 } 9018 if (dumpAll) { 9019 pw.println("-------------------------------------------------------------------------------"); 9020 } 9021 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 9022 if (needSep) { 9023 pw.println(" "); 9024 } 9025 if (dumpAll) { 9026 pw.println("-------------------------------------------------------------------------------"); 9027 } 9028 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 9029 } 9030 Binder.restoreCallingIdentity(origId); 9031 } 9032 9033 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9034 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9035 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 9036 pw.println(" Main stack:"); 9037 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 9038 dumpPackage); 9039 pw.println(" "); 9040 pw.println(" Running activities (most recent first):"); 9041 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 9042 dumpPackage); 9043 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 9044 pw.println(" "); 9045 pw.println(" Activities waiting for another to become visible:"); 9046 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 9047 !dumpAll, false, dumpPackage); 9048 } 9049 if (mMainStack.mStoppingActivities.size() > 0) { 9050 pw.println(" "); 9051 pw.println(" Activities waiting to stop:"); 9052 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 9053 !dumpAll, false, dumpPackage); 9054 } 9055 if (mMainStack.mGoingToSleepActivities.size() > 0) { 9056 pw.println(" "); 9057 pw.println(" Activities waiting to sleep:"); 9058 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 9059 !dumpAll, false, dumpPackage); 9060 } 9061 if (mMainStack.mFinishingActivities.size() > 0) { 9062 pw.println(" "); 9063 pw.println(" Activities waiting to finish:"); 9064 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 9065 !dumpAll, false, dumpPackage); 9066 } 9067 9068 pw.println(" "); 9069 if (mMainStack.mPausingActivity != null) { 9070 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 9071 } 9072 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 9073 pw.println(" mFocusedActivity: " + mFocusedActivity); 9074 if (dumpAll) { 9075 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 9076 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 9077 pw.println(" mDismissKeyguardOnNextActivity: " 9078 + mMainStack.mDismissKeyguardOnNextActivity); 9079 } 9080 9081 if (mRecentTasks.size() > 0) { 9082 pw.println(); 9083 pw.println(" Recent tasks:"); 9084 9085 final int N = mRecentTasks.size(); 9086 for (int i=0; i<N; i++) { 9087 TaskRecord tr = mRecentTasks.get(i); 9088 if (dumpPackage != null) { 9089 if (tr.realActivity == null || 9090 !dumpPackage.equals(tr.realActivity)) { 9091 continue; 9092 } 9093 } 9094 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9095 pw.println(tr); 9096 if (dumpAll) { 9097 mRecentTasks.get(i).dump(pw, " "); 9098 } 9099 } 9100 } 9101 9102 if (dumpAll) { 9103 pw.println(" "); 9104 pw.println(" mCurTask: " + mCurTask); 9105 } 9106 9107 return true; 9108 } 9109 9110 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9111 int opti, boolean dumpAll, String dumpPackage) { 9112 boolean needSep = false; 9113 int numPers = 0; 9114 9115 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 9116 9117 if (dumpAll) { 9118 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9119 final int NA = procs.size(); 9120 for (int ia=0; ia<NA; ia++) { 9121 ProcessRecord r = procs.valueAt(ia); 9122 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9123 continue; 9124 } 9125 if (!needSep) { 9126 pw.println(" All known processes:"); 9127 needSep = true; 9128 } 9129 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9130 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9131 pw.print(" "); pw.println(r); 9132 r.dump(pw, " "); 9133 if (r.persistent) { 9134 numPers++; 9135 } 9136 } 9137 } 9138 } 9139 9140 if (mIsolatedProcesses.size() > 0) { 9141 if (needSep) pw.println(" "); 9142 needSep = true; 9143 pw.println(" Isolated process list (sorted by uid):"); 9144 for (int i=0; i<mIsolatedProcesses.size(); i++) { 9145 ProcessRecord r = mIsolatedProcesses.valueAt(i); 9146 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9147 continue; 9148 } 9149 pw.println(String.format("%sIsolated #%2d: %s", 9150 " ", i, r.toString())); 9151 } 9152 } 9153 9154 if (mLruProcesses.size() > 0) { 9155 if (needSep) pw.println(" "); 9156 needSep = true; 9157 pw.println(" Process LRU list (sorted by oom_adj):"); 9158 dumpProcessOomList(pw, this, mLruProcesses, " ", 9159 "Proc", "PERS", false, dumpPackage); 9160 needSep = true; 9161 } 9162 9163 if (dumpAll) { 9164 synchronized (mPidsSelfLocked) { 9165 boolean printed = false; 9166 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9167 ProcessRecord r = mPidsSelfLocked.valueAt(i); 9168 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9169 continue; 9170 } 9171 if (!printed) { 9172 if (needSep) pw.println(" "); 9173 needSep = true; 9174 pw.println(" PID mappings:"); 9175 printed = true; 9176 } 9177 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9178 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9179 } 9180 } 9181 } 9182 9183 if (mForegroundProcesses.size() > 0) { 9184 synchronized (mPidsSelfLocked) { 9185 boolean printed = false; 9186 for (int i=0; i<mForegroundProcesses.size(); i++) { 9187 ProcessRecord r = mPidsSelfLocked.get( 9188 mForegroundProcesses.valueAt(i).pid); 9189 if (dumpPackage != null && (r == null 9190 || !dumpPackage.equals(r.info.packageName))) { 9191 continue; 9192 } 9193 if (!printed) { 9194 if (needSep) pw.println(" "); 9195 needSep = true; 9196 pw.println(" Foreground Processes:"); 9197 printed = true; 9198 } 9199 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9200 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9201 } 9202 } 9203 } 9204 9205 if (mPersistentStartingProcesses.size() > 0) { 9206 if (needSep) pw.println(" "); 9207 needSep = true; 9208 pw.println(" Persisent processes that are starting:"); 9209 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9210 "Starting Norm", "Restarting PERS", dumpPackage); 9211 } 9212 9213 if (mRemovedProcesses.size() > 0) { 9214 if (needSep) pw.println(" "); 9215 needSep = true; 9216 pw.println(" Processes that are being removed:"); 9217 dumpProcessList(pw, this, mRemovedProcesses, " ", 9218 "Removed Norm", "Removed PERS", dumpPackage); 9219 } 9220 9221 if (mProcessesOnHold.size() > 0) { 9222 if (needSep) pw.println(" "); 9223 needSep = true; 9224 pw.println(" Processes that are on old until the system is ready:"); 9225 dumpProcessList(pw, this, mProcessesOnHold, " ", 9226 "OnHold Norm", "OnHold PERS", dumpPackage); 9227 } 9228 9229 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 9230 9231 if (mProcessCrashTimes.getMap().size() > 0) { 9232 boolean printed = false; 9233 long now = SystemClock.uptimeMillis(); 9234 for (Map.Entry<String, SparseArray<Long>> procs 9235 : mProcessCrashTimes.getMap().entrySet()) { 9236 String pname = procs.getKey(); 9237 SparseArray<Long> uids = procs.getValue(); 9238 final int N = uids.size(); 9239 for (int i=0; i<N; i++) { 9240 int puid = uids.keyAt(i); 9241 ProcessRecord r = mProcessNames.get(pname, puid); 9242 if (dumpPackage != null && (r == null 9243 || !dumpPackage.equals(r.info.packageName))) { 9244 continue; 9245 } 9246 if (!printed) { 9247 if (needSep) pw.println(" "); 9248 needSep = true; 9249 pw.println(" Time since processes crashed:"); 9250 printed = true; 9251 } 9252 pw.print(" Process "); pw.print(pname); 9253 pw.print(" uid "); pw.print(puid); 9254 pw.print(": last crashed "); 9255 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9256 pw.println(" ago"); 9257 } 9258 } 9259 } 9260 9261 if (mBadProcesses.getMap().size() > 0) { 9262 boolean printed = false; 9263 for (Map.Entry<String, SparseArray<Long>> procs 9264 : mBadProcesses.getMap().entrySet()) { 9265 String pname = procs.getKey(); 9266 SparseArray<Long> uids = procs.getValue(); 9267 final int N = uids.size(); 9268 for (int i=0; i<N; i++) { 9269 int puid = uids.keyAt(i); 9270 ProcessRecord r = mProcessNames.get(pname, puid); 9271 if (dumpPackage != null && (r == null 9272 || !dumpPackage.equals(r.info.packageName))) { 9273 continue; 9274 } 9275 if (!printed) { 9276 if (needSep) pw.println(" "); 9277 needSep = true; 9278 pw.println(" Bad processes:"); 9279 } 9280 pw.print(" Bad process "); pw.print(pname); 9281 pw.print(" uid "); pw.print(puid); 9282 pw.print(": crashed at time "); 9283 pw.println(uids.valueAt(i)); 9284 } 9285 } 9286 } 9287 9288 pw.println(); 9289 pw.println(" mStartedUsers:"); 9290 for (int i=0; i<mStartedUsers.size(); i++) { 9291 UserStartedState uss = mStartedUsers.valueAt(i); 9292 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 9293 pw.print(": "); uss.dump("", pw); 9294 } 9295 pw.print(" mUserLru: ["); 9296 for (int i=0; i<mUserLru.size(); i++) { 9297 if (i > 0) pw.print(", "); 9298 pw.print(mUserLru.get(i)); 9299 } 9300 pw.println("]"); 9301 pw.println(" mHomeProcess: " + mHomeProcess); 9302 pw.println(" mPreviousProcess: " + mPreviousProcess); 9303 if (dumpAll) { 9304 StringBuilder sb = new StringBuilder(128); 9305 sb.append(" mPreviousProcessVisibleTime: "); 9306 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9307 pw.println(sb); 9308 } 9309 if (mHeavyWeightProcess != null) { 9310 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9311 } 9312 pw.println(" mConfiguration: " + mConfiguration); 9313 if (dumpAll) { 9314 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9315 if (mCompatModePackages.getPackages().size() > 0) { 9316 boolean printed = false; 9317 for (Map.Entry<String, Integer> entry 9318 : mCompatModePackages.getPackages().entrySet()) { 9319 String pkg = entry.getKey(); 9320 int mode = entry.getValue(); 9321 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9322 continue; 9323 } 9324 if (!printed) { 9325 pw.println(" mScreenCompatPackages:"); 9326 printed = true; 9327 } 9328 pw.print(" "); pw.print(pkg); pw.print(": "); 9329 pw.print(mode); pw.println(); 9330 } 9331 } 9332 } 9333 if (mSleeping || mWentToSleep || mLockScreenShown) { 9334 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9335 + " mLockScreenShown " + mLockScreenShown); 9336 } 9337 if (mShuttingDown) { 9338 pw.println(" mShuttingDown=" + mShuttingDown); 9339 } 9340 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9341 || mOrigWaitForDebugger) { 9342 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9343 + " mDebugTransient=" + mDebugTransient 9344 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9345 } 9346 if (mOpenGlTraceApp != null) { 9347 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9348 } 9349 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9350 || mProfileFd != null) { 9351 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9352 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9353 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9354 + mAutoStopProfiler); 9355 } 9356 if (mAlwaysFinishActivities || mController != null) { 9357 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9358 + " mController=" + mController); 9359 } 9360 if (dumpAll) { 9361 pw.println(" Total persistent processes: " + numPers); 9362 pw.println(" mStartRunning=" + mStartRunning 9363 + " mProcessesReady=" + mProcessesReady 9364 + " mSystemReady=" + mSystemReady); 9365 pw.println(" mBooting=" + mBooting 9366 + " mBooted=" + mBooted 9367 + " mFactoryTest=" + mFactoryTest); 9368 pw.print(" mLastPowerCheckRealtime="); 9369 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9370 pw.println(""); 9371 pw.print(" mLastPowerCheckUptime="); 9372 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9373 pw.println(""); 9374 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9375 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9376 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9377 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs 9378 + " mNumHiddenProcs=" + mNumHiddenProcs 9379 + " mNumServiceProcs=" + mNumServiceProcs 9380 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9381 } 9382 9383 return true; 9384 } 9385 9386 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9387 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9388 if (mProcessesToGc.size() > 0) { 9389 boolean printed = false; 9390 long now = SystemClock.uptimeMillis(); 9391 for (int i=0; i<mProcessesToGc.size(); i++) { 9392 ProcessRecord proc = mProcessesToGc.get(i); 9393 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9394 continue; 9395 } 9396 if (!printed) { 9397 if (needSep) pw.println(" "); 9398 needSep = true; 9399 pw.println(" Processes that are waiting to GC:"); 9400 printed = true; 9401 } 9402 pw.print(" Process "); pw.println(proc); 9403 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9404 pw.print(", last gced="); 9405 pw.print(now-proc.lastRequestedGc); 9406 pw.print(" ms ago, last lowMem="); 9407 pw.print(now-proc.lastLowMemory); 9408 pw.println(" ms ago"); 9409 9410 } 9411 } 9412 return needSep; 9413 } 9414 9415 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9416 int opti, boolean dumpAll) { 9417 boolean needSep = false; 9418 9419 if (mLruProcesses.size() > 0) { 9420 if (needSep) pw.println(" "); 9421 needSep = true; 9422 pw.println(" OOM levels:"); 9423 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9424 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9425 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9426 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9427 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9428 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9429 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9430 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9431 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9432 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9433 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9434 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9435 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9436 9437 if (needSep) pw.println(" "); 9438 needSep = true; 9439 pw.println(" Process OOM control:"); 9440 dumpProcessOomList(pw, this, mLruProcesses, " ", 9441 "Proc", "PERS", true, null); 9442 needSep = true; 9443 } 9444 9445 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9446 9447 pw.println(); 9448 pw.println(" mHomeProcess: " + mHomeProcess); 9449 pw.println(" mPreviousProcess: " + mPreviousProcess); 9450 if (mHeavyWeightProcess != null) { 9451 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9452 } 9453 9454 return true; 9455 } 9456 9457 /** 9458 * There are three ways to call this: 9459 * - no provider specified: dump all the providers 9460 * - a flattened component name that matched an existing provider was specified as the 9461 * first arg: dump that one provider 9462 * - the first arg isn't the flattened component name of an existing provider: 9463 * dump all providers whose component contains the first arg as a substring 9464 */ 9465 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9466 int opti, boolean dumpAll) { 9467 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9468 } 9469 9470 static class ItemMatcher { 9471 ArrayList<ComponentName> components; 9472 ArrayList<String> strings; 9473 ArrayList<Integer> objects; 9474 boolean all; 9475 9476 ItemMatcher() { 9477 all = true; 9478 } 9479 9480 void build(String name) { 9481 ComponentName componentName = ComponentName.unflattenFromString(name); 9482 if (componentName != null) { 9483 if (components == null) { 9484 components = new ArrayList<ComponentName>(); 9485 } 9486 components.add(componentName); 9487 all = false; 9488 } else { 9489 int objectId = 0; 9490 // Not a '/' separated full component name; maybe an object ID? 9491 try { 9492 objectId = Integer.parseInt(name, 16); 9493 if (objects == null) { 9494 objects = new ArrayList<Integer>(); 9495 } 9496 objects.add(objectId); 9497 all = false; 9498 } catch (RuntimeException e) { 9499 // Not an integer; just do string match. 9500 if (strings == null) { 9501 strings = new ArrayList<String>(); 9502 } 9503 strings.add(name); 9504 all = false; 9505 } 9506 } 9507 } 9508 9509 int build(String[] args, int opti) { 9510 for (; opti<args.length; opti++) { 9511 String name = args[opti]; 9512 if ("--".equals(name)) { 9513 return opti+1; 9514 } 9515 build(name); 9516 } 9517 return opti; 9518 } 9519 9520 boolean match(Object object, ComponentName comp) { 9521 if (all) { 9522 return true; 9523 } 9524 if (components != null) { 9525 for (int i=0; i<components.size(); i++) { 9526 if (components.get(i).equals(comp)) { 9527 return true; 9528 } 9529 } 9530 } 9531 if (objects != null) { 9532 for (int i=0; i<objects.size(); i++) { 9533 if (System.identityHashCode(object) == objects.get(i)) { 9534 return true; 9535 } 9536 } 9537 } 9538 if (strings != null) { 9539 String flat = comp.flattenToString(); 9540 for (int i=0; i<strings.size(); i++) { 9541 if (flat.contains(strings.get(i))) { 9542 return true; 9543 } 9544 } 9545 } 9546 return false; 9547 } 9548 } 9549 9550 /** 9551 * There are three things that cmd can be: 9552 * - a flattened component name that matches an existing activity 9553 * - the cmd arg isn't the flattened component name of an existing activity: 9554 * dump all activity whose component contains the cmd as a substring 9555 * - A hex number of the ActivityRecord object instance. 9556 */ 9557 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9558 int opti, boolean dumpAll) { 9559 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9560 9561 if ("all".equals(name)) { 9562 synchronized (this) { 9563 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9564 activities.add(r1); 9565 } 9566 } 9567 } else if ("top".equals(name)) { 9568 synchronized (this) { 9569 final int N = mMainStack.mHistory.size(); 9570 if (N > 0) { 9571 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9572 } 9573 } 9574 } else { 9575 ItemMatcher matcher = new ItemMatcher(); 9576 matcher.build(name); 9577 9578 synchronized (this) { 9579 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9580 if (matcher.match(r1, r1.intent.getComponent())) { 9581 activities.add(r1); 9582 } 9583 } 9584 } 9585 } 9586 9587 if (activities.size() <= 0) { 9588 return false; 9589 } 9590 9591 String[] newArgs = new String[args.length - opti]; 9592 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9593 9594 TaskRecord lastTask = null; 9595 boolean needSep = false; 9596 for (int i=activities.size()-1; i>=0; i--) { 9597 ActivityRecord r = (ActivityRecord)activities.get(i); 9598 if (needSep) { 9599 pw.println(); 9600 } 9601 needSep = true; 9602 synchronized (this) { 9603 if (lastTask != r.task) { 9604 lastTask = r.task; 9605 pw.print("TASK "); pw.print(lastTask.affinity); 9606 pw.print(" id="); pw.println(lastTask.taskId); 9607 if (dumpAll) { 9608 lastTask.dump(pw, " "); 9609 } 9610 } 9611 } 9612 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9613 } 9614 return true; 9615 } 9616 9617 /** 9618 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9619 * there is a thread associated with the activity. 9620 */ 9621 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9622 final ActivityRecord r, String[] args, boolean dumpAll) { 9623 String innerPrefix = prefix + " "; 9624 synchronized (this) { 9625 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9626 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9627 pw.print(" pid="); 9628 if (r.app != null) pw.println(r.app.pid); 9629 else pw.println("(not running)"); 9630 if (dumpAll) { 9631 r.dump(pw, innerPrefix); 9632 } 9633 } 9634 if (r.app != null && r.app.thread != null) { 9635 // flush anything that is already in the PrintWriter since the thread is going 9636 // to write to the file descriptor directly 9637 pw.flush(); 9638 try { 9639 TransferPipe tp = new TransferPipe(); 9640 try { 9641 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9642 r.appToken, innerPrefix, args); 9643 tp.go(fd); 9644 } finally { 9645 tp.kill(); 9646 } 9647 } catch (IOException e) { 9648 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9649 } catch (RemoteException e) { 9650 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9651 } 9652 } 9653 } 9654 9655 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9656 int opti, boolean dumpAll, String dumpPackage) { 9657 boolean needSep = false; 9658 boolean onlyHistory = false; 9659 9660 if ("history".equals(dumpPackage)) { 9661 onlyHistory = true; 9662 dumpPackage = null; 9663 } 9664 9665 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9666 if (!onlyHistory && dumpAll) { 9667 if (mRegisteredReceivers.size() > 0) { 9668 boolean printed = false; 9669 Iterator it = mRegisteredReceivers.values().iterator(); 9670 while (it.hasNext()) { 9671 ReceiverList r = (ReceiverList)it.next(); 9672 if (dumpPackage != null && (r.app == null || 9673 !dumpPackage.equals(r.app.info.packageName))) { 9674 continue; 9675 } 9676 if (!printed) { 9677 pw.println(" Registered Receivers:"); 9678 needSep = true; 9679 printed = true; 9680 } 9681 pw.print(" * "); pw.println(r); 9682 r.dump(pw, " "); 9683 } 9684 } 9685 9686 if (mReceiverResolver.dump(pw, needSep ? 9687 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9688 " ", dumpPackage, false)) { 9689 needSep = true; 9690 } 9691 } 9692 9693 for (BroadcastQueue q : mBroadcastQueues) { 9694 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9695 } 9696 9697 needSep = true; 9698 9699 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 9700 for (int user=0; user<mStickyBroadcasts.size(); user++) { 9701 if (needSep) { 9702 pw.println(); 9703 } 9704 needSep = true; 9705 pw.print(" Sticky broadcasts for user "); 9706 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 9707 StringBuilder sb = new StringBuilder(128); 9708 for (Map.Entry<String, ArrayList<Intent>> ent 9709 : mStickyBroadcasts.valueAt(user).entrySet()) { 9710 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9711 if (dumpAll) { 9712 pw.println(":"); 9713 ArrayList<Intent> intents = ent.getValue(); 9714 final int N = intents.size(); 9715 for (int i=0; i<N; i++) { 9716 sb.setLength(0); 9717 sb.append(" Intent: "); 9718 intents.get(i).toShortString(sb, false, true, false, false); 9719 pw.println(sb.toString()); 9720 Bundle bundle = intents.get(i).getExtras(); 9721 if (bundle != null) { 9722 pw.print(" "); 9723 pw.println(bundle.toString()); 9724 } 9725 } 9726 } else { 9727 pw.println(""); 9728 } 9729 } 9730 } 9731 } 9732 9733 if (!onlyHistory && dumpAll) { 9734 pw.println(); 9735 for (BroadcastQueue queue : mBroadcastQueues) { 9736 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9737 + queue.mBroadcastsScheduled); 9738 } 9739 pw.println(" mHandler:"); 9740 mHandler.dump(new PrintWriterPrinter(pw), " "); 9741 needSep = true; 9742 } 9743 9744 return needSep; 9745 } 9746 9747 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9748 int opti, boolean dumpAll, String dumpPackage) { 9749 boolean needSep = true; 9750 9751 ItemMatcher matcher = new ItemMatcher(); 9752 matcher.build(args, opti); 9753 9754 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9755 9756 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9757 9758 if (mLaunchingProviders.size() > 0) { 9759 boolean printed = false; 9760 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9761 ContentProviderRecord r = mLaunchingProviders.get(i); 9762 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9763 continue; 9764 } 9765 if (!printed) { 9766 if (needSep) pw.println(" "); 9767 needSep = true; 9768 pw.println(" Launching content providers:"); 9769 printed = true; 9770 } 9771 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9772 pw.println(r); 9773 } 9774 } 9775 9776 if (mGrantedUriPermissions.size() > 0) { 9777 if (needSep) pw.println(); 9778 needSep = true; 9779 pw.println("Granted Uri Permissions:"); 9780 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9781 int uid = mGrantedUriPermissions.keyAt(i); 9782 HashMap<Uri, UriPermission> perms 9783 = mGrantedUriPermissions.valueAt(i); 9784 pw.print(" * UID "); pw.print(uid); 9785 pw.println(" holds:"); 9786 for (UriPermission perm : perms.values()) { 9787 pw.print(" "); pw.println(perm); 9788 if (dumpAll) { 9789 perm.dump(pw, " "); 9790 } 9791 } 9792 } 9793 needSep = true; 9794 } 9795 9796 return needSep; 9797 } 9798 9799 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9800 int opti, boolean dumpAll, String dumpPackage) { 9801 boolean needSep = false; 9802 9803 if (mIntentSenderRecords.size() > 0) { 9804 boolean printed = false; 9805 Iterator<WeakReference<PendingIntentRecord>> it 9806 = mIntentSenderRecords.values().iterator(); 9807 while (it.hasNext()) { 9808 WeakReference<PendingIntentRecord> ref = it.next(); 9809 PendingIntentRecord rec = ref != null ? ref.get(): null; 9810 if (dumpPackage != null && (rec == null 9811 || !dumpPackage.equals(rec.key.packageName))) { 9812 continue; 9813 } 9814 if (!printed) { 9815 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9816 printed = true; 9817 } 9818 needSep = true; 9819 if (rec != null) { 9820 pw.print(" * "); pw.println(rec); 9821 if (dumpAll) { 9822 rec.dump(pw, " "); 9823 } 9824 } else { 9825 pw.print(" * "); pw.println(ref); 9826 } 9827 } 9828 } 9829 9830 return needSep; 9831 } 9832 9833 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9834 String prefix, String label, boolean complete, boolean brief, boolean client, 9835 String dumpPackage) { 9836 TaskRecord lastTask = null; 9837 boolean needNL = false; 9838 final String innerPrefix = prefix + " "; 9839 final String[] args = new String[0]; 9840 for (int i=list.size()-1; i>=0; i--) { 9841 final ActivityRecord r = (ActivityRecord)list.get(i); 9842 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9843 continue; 9844 } 9845 final boolean full = !brief && (complete || !r.isInHistory()); 9846 if (needNL) { 9847 pw.println(" "); 9848 needNL = false; 9849 } 9850 if (lastTask != r.task) { 9851 lastTask = r.task; 9852 pw.print(prefix); 9853 pw.print(full ? "* " : " "); 9854 pw.println(lastTask); 9855 if (full) { 9856 lastTask.dump(pw, prefix + " "); 9857 } else if (complete) { 9858 // Complete + brief == give a summary. Isn't that obvious?!? 9859 if (lastTask.intent != null) { 9860 pw.print(prefix); pw.print(" "); 9861 pw.println(lastTask.intent.toInsecureStringWithClip()); 9862 } 9863 } 9864 } 9865 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9866 pw.print(" #"); pw.print(i); pw.print(": "); 9867 pw.println(r); 9868 if (full) { 9869 r.dump(pw, innerPrefix); 9870 } else if (complete) { 9871 // Complete + brief == give a summary. Isn't that obvious?!? 9872 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9873 if (r.app != null) { 9874 pw.print(innerPrefix); pw.println(r.app); 9875 } 9876 } 9877 if (client && r.app != null && r.app.thread != null) { 9878 // flush anything that is already in the PrintWriter since the thread is going 9879 // to write to the file descriptor directly 9880 pw.flush(); 9881 try { 9882 TransferPipe tp = new TransferPipe(); 9883 try { 9884 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9885 r.appToken, innerPrefix, args); 9886 // Short timeout, since blocking here can 9887 // deadlock with the application. 9888 tp.go(fd, 2000); 9889 } finally { 9890 tp.kill(); 9891 } 9892 } catch (IOException e) { 9893 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9894 } catch (RemoteException e) { 9895 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9896 } 9897 needNL = true; 9898 } 9899 } 9900 } 9901 9902 private static String buildOomTag(String prefix, String space, int val, int base) { 9903 if (val == base) { 9904 if (space == null) return prefix; 9905 return prefix + " "; 9906 } 9907 return prefix + "+" + Integer.toString(val-base); 9908 } 9909 9910 private static final int dumpProcessList(PrintWriter pw, 9911 ActivityManagerService service, List list, 9912 String prefix, String normalLabel, String persistentLabel, 9913 String dumpPackage) { 9914 int numPers = 0; 9915 final int N = list.size()-1; 9916 for (int i=N; i>=0; i--) { 9917 ProcessRecord r = (ProcessRecord)list.get(i); 9918 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9919 continue; 9920 } 9921 pw.println(String.format("%s%s #%2d: %s", 9922 prefix, (r.persistent ? persistentLabel : normalLabel), 9923 i, r.toString())); 9924 if (r.persistent) { 9925 numPers++; 9926 } 9927 } 9928 return numPers; 9929 } 9930 9931 private static final boolean dumpProcessOomList(PrintWriter pw, 9932 ActivityManagerService service, List<ProcessRecord> origList, 9933 String prefix, String normalLabel, String persistentLabel, 9934 boolean inclDetails, String dumpPackage) { 9935 9936 ArrayList<Pair<ProcessRecord, Integer>> list 9937 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9938 for (int i=0; i<origList.size(); i++) { 9939 ProcessRecord r = origList.get(i); 9940 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9941 continue; 9942 } 9943 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9944 } 9945 9946 if (list.size() <= 0) { 9947 return false; 9948 } 9949 9950 Comparator<Pair<ProcessRecord, Integer>> comparator 9951 = new Comparator<Pair<ProcessRecord, Integer>>() { 9952 @Override 9953 public int compare(Pair<ProcessRecord, Integer> object1, 9954 Pair<ProcessRecord, Integer> object2) { 9955 if (object1.first.setAdj != object2.first.setAdj) { 9956 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9957 } 9958 if (object1.second.intValue() != object2.second.intValue()) { 9959 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9960 } 9961 return 0; 9962 } 9963 }; 9964 9965 Collections.sort(list, comparator); 9966 9967 final long curRealtime = SystemClock.elapsedRealtime(); 9968 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 9969 final long curUptime = SystemClock.uptimeMillis(); 9970 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 9971 9972 for (int i=list.size()-1; i>=0; i--) { 9973 ProcessRecord r = list.get(i).first; 9974 String oomAdj; 9975 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 9976 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 9977 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 9978 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 9979 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 9980 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 9981 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 9982 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 9983 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 9984 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 9985 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 9986 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 9987 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 9988 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 9989 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 9990 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 9991 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 9992 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 9993 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 9994 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 9995 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 9996 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 9997 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 9998 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 9999 } else { 10000 oomAdj = Integer.toString(r.setAdj); 10001 } 10002 String schedGroup; 10003 switch (r.setSchedGroup) { 10004 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10005 schedGroup = "B"; 10006 break; 10007 case Process.THREAD_GROUP_DEFAULT: 10008 schedGroup = "F"; 10009 break; 10010 default: 10011 schedGroup = Integer.toString(r.setSchedGroup); 10012 break; 10013 } 10014 String foreground; 10015 if (r.foregroundActivities) { 10016 foreground = "A"; 10017 } else if (r.foregroundServices) { 10018 foreground = "S"; 10019 } else { 10020 foreground = " "; 10021 } 10022 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10023 prefix, (r.persistent ? persistentLabel : normalLabel), 10024 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10025 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10026 if (r.adjSource != null || r.adjTarget != null) { 10027 pw.print(prefix); 10028 pw.print(" "); 10029 if (r.adjTarget instanceof ComponentName) { 10030 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10031 } else if (r.adjTarget != null) { 10032 pw.print(r.adjTarget.toString()); 10033 } else { 10034 pw.print("{null}"); 10035 } 10036 pw.print("<="); 10037 if (r.adjSource instanceof ProcessRecord) { 10038 pw.print("Proc{"); 10039 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10040 pw.println("}"); 10041 } else if (r.adjSource != null) { 10042 pw.println(r.adjSource.toString()); 10043 } else { 10044 pw.println("{null}"); 10045 } 10046 } 10047 if (inclDetails) { 10048 pw.print(prefix); 10049 pw.print(" "); 10050 pw.print("oom: max="); pw.print(r.maxAdj); 10051 pw.print(" hidden="); pw.print(r.hiddenAdj); 10052 pw.print(" empty="); pw.print(r.emptyAdj); 10053 pw.print(" curRaw="); pw.print(r.curRawAdj); 10054 pw.print(" setRaw="); pw.print(r.setRawAdj); 10055 pw.print(" cur="); pw.print(r.curAdj); 10056 pw.print(" set="); pw.println(r.setAdj); 10057 pw.print(prefix); 10058 pw.print(" "); 10059 pw.print("keeping="); pw.print(r.keeping); 10060 pw.print(" hidden="); pw.print(r.hidden); 10061 pw.print(" empty="); pw.print(r.empty); 10062 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10063 10064 if (!r.keeping) { 10065 if (r.lastWakeTime != 0) { 10066 long wtime; 10067 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10068 synchronized (stats) { 10069 wtime = stats.getProcessWakeTime(r.info.uid, 10070 r.pid, curRealtime); 10071 } 10072 long timeUsed = wtime - r.lastWakeTime; 10073 pw.print(prefix); 10074 pw.print(" "); 10075 pw.print("keep awake over "); 10076 TimeUtils.formatDuration(realtimeSince, pw); 10077 pw.print(" used "); 10078 TimeUtils.formatDuration(timeUsed, pw); 10079 pw.print(" ("); 10080 pw.print((timeUsed*100)/realtimeSince); 10081 pw.println("%)"); 10082 } 10083 if (r.lastCpuTime != 0) { 10084 long timeUsed = r.curCpuTime - r.lastCpuTime; 10085 pw.print(prefix); 10086 pw.print(" "); 10087 pw.print("run cpu over "); 10088 TimeUtils.formatDuration(uptimeSince, pw); 10089 pw.print(" used "); 10090 TimeUtils.formatDuration(timeUsed, pw); 10091 pw.print(" ("); 10092 pw.print((timeUsed*100)/uptimeSince); 10093 pw.println("%)"); 10094 } 10095 } 10096 } 10097 } 10098 return true; 10099 } 10100 10101 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10102 ArrayList<ProcessRecord> procs; 10103 synchronized (this) { 10104 if (args != null && args.length > start 10105 && args[start].charAt(0) != '-') { 10106 procs = new ArrayList<ProcessRecord>(); 10107 int pid = -1; 10108 try { 10109 pid = Integer.parseInt(args[start]); 10110 } catch (NumberFormatException e) { 10111 10112 } 10113 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10114 ProcessRecord proc = mLruProcesses.get(i); 10115 if (proc.pid == pid) { 10116 procs.add(proc); 10117 } else if (proc.processName.equals(args[start])) { 10118 procs.add(proc); 10119 } 10120 } 10121 if (procs.size() <= 0) { 10122 pw.println("No process found for: " + args[start]); 10123 return null; 10124 } 10125 } else { 10126 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10127 } 10128 } 10129 return procs; 10130 } 10131 10132 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10133 PrintWriter pw, String[] args) { 10134 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10135 if (procs == null) { 10136 return; 10137 } 10138 10139 long uptime = SystemClock.uptimeMillis(); 10140 long realtime = SystemClock.elapsedRealtime(); 10141 pw.println("Applications Graphics Acceleration Info:"); 10142 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10143 10144 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10145 ProcessRecord r = procs.get(i); 10146 if (r.thread != null) { 10147 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10148 pw.flush(); 10149 try { 10150 TransferPipe tp = new TransferPipe(); 10151 try { 10152 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10153 tp.go(fd); 10154 } finally { 10155 tp.kill(); 10156 } 10157 } catch (IOException e) { 10158 pw.println("Failure while dumping the app: " + r); 10159 pw.flush(); 10160 } catch (RemoteException e) { 10161 pw.println("Got a RemoteException while dumping the app " + r); 10162 pw.flush(); 10163 } 10164 } 10165 } 10166 } 10167 10168 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10169 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10170 if (procs == null) { 10171 return; 10172 } 10173 10174 pw.println("Applications Database Info:"); 10175 10176 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10177 ProcessRecord r = procs.get(i); 10178 if (r.thread != null) { 10179 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10180 pw.flush(); 10181 try { 10182 TransferPipe tp = new TransferPipe(); 10183 try { 10184 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10185 tp.go(fd); 10186 } finally { 10187 tp.kill(); 10188 } 10189 } catch (IOException e) { 10190 pw.println("Failure while dumping the app: " + r); 10191 pw.flush(); 10192 } catch (RemoteException e) { 10193 pw.println("Got a RemoteException while dumping the app " + r); 10194 pw.flush(); 10195 } 10196 } 10197 } 10198 } 10199 10200 final static class MemItem { 10201 final String label; 10202 final String shortLabel; 10203 final long pss; 10204 final int id; 10205 ArrayList<MemItem> subitems; 10206 10207 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10208 label = _label; 10209 shortLabel = _shortLabel; 10210 pss = _pss; 10211 id = _id; 10212 } 10213 } 10214 10215 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10216 boolean sort) { 10217 if (sort) { 10218 Collections.sort(items, new Comparator<MemItem>() { 10219 @Override 10220 public int compare(MemItem lhs, MemItem rhs) { 10221 if (lhs.pss < rhs.pss) { 10222 return 1; 10223 } else if (lhs.pss > rhs.pss) { 10224 return -1; 10225 } 10226 return 0; 10227 } 10228 }); 10229 } 10230 10231 for (int i=0; i<items.size(); i++) { 10232 MemItem mi = items.get(i); 10233 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10234 if (mi.subitems != null) { 10235 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10236 } 10237 } 10238 } 10239 10240 // These are in KB. 10241 static final long[] DUMP_MEM_BUCKETS = new long[] { 10242 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10243 120*1024, 160*1024, 200*1024, 10244 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10245 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10246 }; 10247 10248 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10249 boolean stackLike) { 10250 int start = label.lastIndexOf('.'); 10251 if (start >= 0) start++; 10252 else start = 0; 10253 int end = label.length(); 10254 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10255 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10256 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10257 out.append(bucket); 10258 out.append(stackLike ? "MB." : "MB "); 10259 out.append(label, start, end); 10260 return; 10261 } 10262 } 10263 out.append(memKB/1024); 10264 out.append(stackLike ? "MB." : "MB "); 10265 out.append(label, start, end); 10266 } 10267 10268 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10269 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10270 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10271 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10272 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10273 }; 10274 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10275 "System", "Persistent", "Foreground", 10276 "Visible", "Perceptible", "Heavy Weight", 10277 "Backup", "A Services", "Home", "Previous", 10278 "B Services", "Background" 10279 }; 10280 10281 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10282 PrintWriter pw, String prefix, String[] args, boolean brief, 10283 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10284 boolean dumpAll = false; 10285 boolean oomOnly = false; 10286 10287 int opti = 0; 10288 while (opti < args.length) { 10289 String opt = args[opti]; 10290 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10291 break; 10292 } 10293 opti++; 10294 if ("-a".equals(opt)) { 10295 dumpAll = true; 10296 } else if ("--oom".equals(opt)) { 10297 oomOnly = true; 10298 } else if ("-h".equals(opt)) { 10299 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10300 pw.println(" -a: include all available information for each process."); 10301 pw.println(" --oom: only show processes organized by oom adj."); 10302 pw.println("If [process] is specified it can be the name or "); 10303 pw.println("pid of a specific process to dump."); 10304 return; 10305 } else { 10306 pw.println("Unknown argument: " + opt + "; use -h for help"); 10307 } 10308 } 10309 10310 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10311 if (procs == null) { 10312 return; 10313 } 10314 10315 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10316 long uptime = SystemClock.uptimeMillis(); 10317 long realtime = SystemClock.elapsedRealtime(); 10318 10319 if (procs.size() == 1 || isCheckinRequest) { 10320 dumpAll = true; 10321 } 10322 10323 if (isCheckinRequest) { 10324 // short checkin version 10325 pw.println(uptime + "," + realtime); 10326 pw.flush(); 10327 } else { 10328 pw.println("Applications Memory Usage (kB):"); 10329 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10330 } 10331 10332 String[] innerArgs = new String[args.length-opti]; 10333 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10334 10335 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10336 long nativePss=0, dalvikPss=0, otherPss=0; 10337 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10338 10339 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10340 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10341 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10342 10343 long totalPss = 0; 10344 10345 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10346 ProcessRecord r = procs.get(i); 10347 if (r.thread != null) { 10348 if (!isCheckinRequest && dumpAll) { 10349 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10350 pw.flush(); 10351 } 10352 Debug.MemoryInfo mi = null; 10353 if (dumpAll) { 10354 try { 10355 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10356 } catch (RemoteException e) { 10357 if (!isCheckinRequest) { 10358 pw.println("Got RemoteException!"); 10359 pw.flush(); 10360 } 10361 } 10362 } else { 10363 mi = new Debug.MemoryInfo(); 10364 Debug.getMemoryInfo(r.pid, mi); 10365 } 10366 10367 if (!isCheckinRequest && mi != null) { 10368 long myTotalPss = mi.getTotalPss(); 10369 totalPss += myTotalPss; 10370 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10371 r.processName, myTotalPss, 0); 10372 procMems.add(pssItem); 10373 10374 nativePss += mi.nativePss; 10375 dalvikPss += mi.dalvikPss; 10376 otherPss += mi.otherPss; 10377 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10378 long mem = mi.getOtherPss(j); 10379 miscPss[j] += mem; 10380 otherPss -= mem; 10381 } 10382 10383 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10384 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10385 || oomIndex == (oomPss.length-1)) { 10386 oomPss[oomIndex] += myTotalPss; 10387 if (oomProcs[oomIndex] == null) { 10388 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10389 } 10390 oomProcs[oomIndex].add(pssItem); 10391 break; 10392 } 10393 } 10394 } 10395 } 10396 } 10397 10398 if (!isCheckinRequest && procs.size() > 1) { 10399 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10400 10401 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10402 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10403 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10404 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10405 String label = Debug.MemoryInfo.getOtherLabel(j); 10406 catMems.add(new MemItem(label, label, miscPss[j], j)); 10407 } 10408 10409 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10410 for (int j=0; j<oomPss.length; j++) { 10411 if (oomPss[j] != 0) { 10412 String label = DUMP_MEM_OOM_LABEL[j]; 10413 MemItem item = new MemItem(label, label, oomPss[j], 10414 DUMP_MEM_OOM_ADJ[j]); 10415 item.subitems = oomProcs[j]; 10416 oomMems.add(item); 10417 } 10418 } 10419 10420 if (outTag != null || outStack != null) { 10421 if (outTag != null) { 10422 appendMemBucket(outTag, totalPss, "total", false); 10423 } 10424 if (outStack != null) { 10425 appendMemBucket(outStack, totalPss, "total", true); 10426 } 10427 boolean firstLine = true; 10428 for (int i=0; i<oomMems.size(); i++) { 10429 MemItem miCat = oomMems.get(i); 10430 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10431 continue; 10432 } 10433 if (miCat.id < ProcessList.SERVICE_ADJ 10434 || miCat.id == ProcessList.HOME_APP_ADJ 10435 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10436 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10437 outTag.append(" / "); 10438 } 10439 if (outStack != null) { 10440 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10441 if (firstLine) { 10442 outStack.append(":"); 10443 firstLine = false; 10444 } 10445 outStack.append("\n\t at "); 10446 } else { 10447 outStack.append("$"); 10448 } 10449 } 10450 for (int j=0; j<miCat.subitems.size(); j++) { 10451 MemItem mi = miCat.subitems.get(j); 10452 if (j > 0) { 10453 if (outTag != null) { 10454 outTag.append(" "); 10455 } 10456 if (outStack != null) { 10457 outStack.append("$"); 10458 } 10459 } 10460 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10461 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10462 } 10463 if (outStack != null) { 10464 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10465 } 10466 } 10467 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10468 outStack.append("("); 10469 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10470 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10471 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10472 outStack.append(":"); 10473 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10474 } 10475 } 10476 outStack.append(")"); 10477 } 10478 } 10479 } 10480 } 10481 10482 if (!brief && !oomOnly) { 10483 pw.println(); 10484 pw.println("Total PSS by process:"); 10485 dumpMemItems(pw, " ", procMems, true); 10486 pw.println(); 10487 } 10488 pw.println("Total PSS by OOM adjustment:"); 10489 dumpMemItems(pw, " ", oomMems, false); 10490 if (!oomOnly) { 10491 PrintWriter out = categoryPw != null ? categoryPw : pw; 10492 out.println(); 10493 out.println("Total PSS by category:"); 10494 dumpMemItems(out, " ", catMems, true); 10495 } 10496 pw.println(); 10497 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10498 final int[] SINGLE_LONG_FORMAT = new int[] { 10499 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10500 }; 10501 long[] longOut = new long[1]; 10502 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10503 SINGLE_LONG_FORMAT, null, longOut, null); 10504 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10505 longOut[0] = 0; 10506 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10507 SINGLE_LONG_FORMAT, null, longOut, null); 10508 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10509 longOut[0] = 0; 10510 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10511 SINGLE_LONG_FORMAT, null, longOut, null); 10512 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10513 longOut[0] = 0; 10514 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10515 SINGLE_LONG_FORMAT, null, longOut, null); 10516 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10517 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10518 pw.print(shared); pw.println(" kB"); 10519 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10520 pw.print(voltile); pw.println(" kB volatile"); 10521 } 10522 } 10523 10524 /** 10525 * Searches array of arguments for the specified string 10526 * @param args array of argument strings 10527 * @param value value to search for 10528 * @return true if the value is contained in the array 10529 */ 10530 private static boolean scanArgs(String[] args, String value) { 10531 if (args != null) { 10532 for (String arg : args) { 10533 if (value.equals(arg)) { 10534 return true; 10535 } 10536 } 10537 } 10538 return false; 10539 } 10540 10541 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10542 ContentProviderRecord cpr, boolean always) { 10543 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10544 10545 if (!inLaunching || always) { 10546 synchronized (cpr) { 10547 cpr.launchingApp = null; 10548 cpr.notifyAll(); 10549 } 10550 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 10551 String names[] = cpr.info.authority.split(";"); 10552 for (int j = 0; j < names.length; j++) { 10553 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 10554 } 10555 } 10556 10557 for (int i=0; i<cpr.connections.size(); i++) { 10558 ContentProviderConnection conn = cpr.connections.get(i); 10559 if (conn.waiting) { 10560 // If this connection is waiting for the provider, then we don't 10561 // need to mess with its process unless we are always removing 10562 // or for some reason the provider is not currently launching. 10563 if (inLaunching && !always) { 10564 continue; 10565 } 10566 } 10567 ProcessRecord capp = conn.client; 10568 conn.dead = true; 10569 if (conn.stableCount > 0) { 10570 if (!capp.persistent && capp.thread != null 10571 && capp.pid != 0 10572 && capp.pid != MY_PID) { 10573 Slog.i(TAG, "Kill " + capp.processName 10574 + " (pid " + capp.pid + "): provider " + cpr.info.name 10575 + " in dying process " + (proc != null ? proc.processName : "??")); 10576 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10577 capp.processName, capp.setAdj, "dying provider " 10578 + cpr.name.toShortString()); 10579 Process.killProcessQuiet(capp.pid); 10580 } 10581 } else if (capp.thread != null && conn.provider.provider != null) { 10582 try { 10583 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10584 } catch (RemoteException e) { 10585 } 10586 // In the protocol here, we don't expect the client to correctly 10587 // clean up this connection, we'll just remove it. 10588 cpr.connections.remove(i); 10589 conn.client.conProviders.remove(conn); 10590 } 10591 } 10592 10593 if (inLaunching && always) { 10594 mLaunchingProviders.remove(cpr); 10595 } 10596 return inLaunching; 10597 } 10598 10599 /** 10600 * Main code for cleaning up a process when it has gone away. This is 10601 * called both as a result of the process dying, or directly when stopping 10602 * a process when running in single process mode. 10603 */ 10604 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10605 boolean restarting, boolean allowRestart, int index) { 10606 if (index >= 0) { 10607 mLruProcesses.remove(index); 10608 } 10609 10610 mProcessesToGc.remove(app); 10611 10612 // Dismiss any open dialogs. 10613 if (app.crashDialog != null) { 10614 app.crashDialog.dismiss(); 10615 app.crashDialog = null; 10616 } 10617 if (app.anrDialog != null) { 10618 app.anrDialog.dismiss(); 10619 app.anrDialog = null; 10620 } 10621 if (app.waitDialog != null) { 10622 app.waitDialog.dismiss(); 10623 app.waitDialog = null; 10624 } 10625 10626 app.crashing = false; 10627 app.notResponding = false; 10628 10629 app.resetPackageList(); 10630 app.unlinkDeathRecipient(); 10631 app.thread = null; 10632 app.forcingToForeground = null; 10633 app.foregroundServices = false; 10634 app.foregroundActivities = false; 10635 app.hasShownUi = false; 10636 app.hasAboveClient = false; 10637 10638 mServices.killServicesLocked(app, allowRestart); 10639 10640 boolean restart = false; 10641 10642 // Remove published content providers. 10643 if (!app.pubProviders.isEmpty()) { 10644 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10645 while (it.hasNext()) { 10646 ContentProviderRecord cpr = it.next(); 10647 10648 final boolean always = app.bad || !allowRestart; 10649 if (removeDyingProviderLocked(app, cpr, always) || always) { 10650 // We left the provider in the launching list, need to 10651 // restart it. 10652 restart = true; 10653 } 10654 10655 cpr.provider = null; 10656 cpr.proc = null; 10657 } 10658 app.pubProviders.clear(); 10659 } 10660 10661 // Take care of any launching providers waiting for this process. 10662 if (checkAppInLaunchingProvidersLocked(app, false)) { 10663 restart = true; 10664 } 10665 10666 // Unregister from connected content providers. 10667 if (!app.conProviders.isEmpty()) { 10668 for (int i=0; i<app.conProviders.size(); i++) { 10669 ContentProviderConnection conn = app.conProviders.get(i); 10670 conn.provider.connections.remove(conn); 10671 } 10672 app.conProviders.clear(); 10673 } 10674 10675 // At this point there may be remaining entries in mLaunchingProviders 10676 // where we were the only one waiting, so they are no longer of use. 10677 // Look for these and clean up if found. 10678 // XXX Commented out for now. Trying to figure out a way to reproduce 10679 // the actual situation to identify what is actually going on. 10680 if (false) { 10681 for (int i=0; i<mLaunchingProviders.size(); i++) { 10682 ContentProviderRecord cpr = (ContentProviderRecord) 10683 mLaunchingProviders.get(i); 10684 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10685 synchronized (cpr) { 10686 cpr.launchingApp = null; 10687 cpr.notifyAll(); 10688 } 10689 } 10690 } 10691 } 10692 10693 skipCurrentReceiverLocked(app); 10694 10695 // Unregister any receivers. 10696 if (app.receivers.size() > 0) { 10697 Iterator<ReceiverList> it = app.receivers.iterator(); 10698 while (it.hasNext()) { 10699 removeReceiverLocked(it.next()); 10700 } 10701 app.receivers.clear(); 10702 } 10703 10704 // If the app is undergoing backup, tell the backup manager about it 10705 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10706 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10707 try { 10708 IBackupManager bm = IBackupManager.Stub.asInterface( 10709 ServiceManager.getService(Context.BACKUP_SERVICE)); 10710 bm.agentDisconnected(app.info.packageName); 10711 } catch (RemoteException e) { 10712 // can't happen; backup manager is local 10713 } 10714 } 10715 10716 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10717 ProcessChangeItem item = mPendingProcessChanges.get(i); 10718 if (item.pid == app.pid) { 10719 mPendingProcessChanges.remove(i); 10720 mAvailProcessChanges.add(item); 10721 } 10722 } 10723 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10724 10725 // If the caller is restarting this app, then leave it in its 10726 // current lists and let the caller take care of it. 10727 if (restarting) { 10728 return; 10729 } 10730 10731 if (!app.persistent || app.isolated) { 10732 if (DEBUG_PROCESSES) Slog.v(TAG, 10733 "Removing non-persistent process during cleanup: " + app); 10734 mProcessNames.remove(app.processName, app.uid); 10735 mIsolatedProcesses.remove(app.uid); 10736 if (mHeavyWeightProcess == app) { 10737 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 10738 mHeavyWeightProcess.userId, 0)); 10739 mHeavyWeightProcess = null; 10740 } 10741 } else if (!app.removed) { 10742 // This app is persistent, so we need to keep its record around. 10743 // If it is not already on the pending app list, add it there 10744 // and start a new process for it. 10745 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10746 mPersistentStartingProcesses.add(app); 10747 restart = true; 10748 } 10749 } 10750 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10751 "Clean-up removing on hold: " + app); 10752 mProcessesOnHold.remove(app); 10753 10754 if (app == mHomeProcess) { 10755 mHomeProcess = null; 10756 } 10757 if (app == mPreviousProcess) { 10758 mPreviousProcess = null; 10759 } 10760 10761 if (restart && !app.isolated) { 10762 // We have components that still need to be running in the 10763 // process, so re-launch it. 10764 mProcessNames.put(app.processName, app.uid, app); 10765 startProcessLocked(app, "restart", app.processName); 10766 } else if (app.pid > 0 && app.pid != MY_PID) { 10767 // Goodbye! 10768 synchronized (mPidsSelfLocked) { 10769 mPidsSelfLocked.remove(app.pid); 10770 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10771 } 10772 app.setPid(0); 10773 } 10774 } 10775 10776 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10777 // Look through the content providers we are waiting to have launched, 10778 // and if any run in this process then either schedule a restart of 10779 // the process or kill the client waiting for it if this process has 10780 // gone bad. 10781 int NL = mLaunchingProviders.size(); 10782 boolean restart = false; 10783 for (int i=0; i<NL; i++) { 10784 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10785 if (cpr.launchingApp == app) { 10786 if (!alwaysBad && !app.bad) { 10787 restart = true; 10788 } else { 10789 removeDyingProviderLocked(app, cpr, true); 10790 // cpr should have been removed from mLaunchingProviders 10791 NL = mLaunchingProviders.size(); 10792 i--; 10793 } 10794 } 10795 } 10796 return restart; 10797 } 10798 10799 // ========================================================= 10800 // SERVICES 10801 // ========================================================= 10802 10803 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10804 int flags) { 10805 enforceNotIsolatedCaller("getServices"); 10806 synchronized (this) { 10807 return mServices.getRunningServiceInfoLocked(maxNum, flags); 10808 } 10809 } 10810 10811 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10812 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 10813 synchronized (this) { 10814 return mServices.getRunningServiceControlPanelLocked(name); 10815 } 10816 } 10817 10818 public ComponentName startService(IApplicationThread caller, Intent service, 10819 String resolvedType, int userId) { 10820 enforceNotIsolatedCaller("startService"); 10821 // Refuse possible leaked file descriptors 10822 if (service != null && service.hasFileDescriptors() == true) { 10823 throw new IllegalArgumentException("File descriptors passed in Intent"); 10824 } 10825 10826 if (DEBUG_SERVICE) 10827 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 10828 synchronized(this) { 10829 final int callingPid = Binder.getCallingPid(); 10830 final int callingUid = Binder.getCallingUid(); 10831 checkValidCaller(callingUid, userId); 10832 final long origId = Binder.clearCallingIdentity(); 10833 ComponentName res = mServices.startServiceLocked(caller, service, 10834 resolvedType, callingPid, callingUid, userId); 10835 Binder.restoreCallingIdentity(origId); 10836 return res; 10837 } 10838 } 10839 10840 ComponentName startServiceInPackage(int uid, 10841 Intent service, String resolvedType, int userId) { 10842 synchronized(this) { 10843 if (DEBUG_SERVICE) 10844 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 10845 final long origId = Binder.clearCallingIdentity(); 10846 ComponentName res = mServices.startServiceLocked(null, service, 10847 resolvedType, -1, uid, userId); 10848 Binder.restoreCallingIdentity(origId); 10849 return res; 10850 } 10851 } 10852 10853 public int stopService(IApplicationThread caller, Intent service, 10854 String resolvedType, int userId) { 10855 enforceNotIsolatedCaller("stopService"); 10856 // Refuse possible leaked file descriptors 10857 if (service != null && service.hasFileDescriptors() == true) { 10858 throw new IllegalArgumentException("File descriptors passed in Intent"); 10859 } 10860 10861 checkValidCaller(Binder.getCallingUid(), userId); 10862 10863 synchronized(this) { 10864 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 10865 } 10866 } 10867 10868 public IBinder peekService(Intent service, String resolvedType) { 10869 enforceNotIsolatedCaller("peekService"); 10870 // Refuse possible leaked file descriptors 10871 if (service != null && service.hasFileDescriptors() == true) { 10872 throw new IllegalArgumentException("File descriptors passed in Intent"); 10873 } 10874 synchronized(this) { 10875 return mServices.peekServiceLocked(service, resolvedType); 10876 } 10877 } 10878 10879 public boolean stopServiceToken(ComponentName className, IBinder token, 10880 int startId) { 10881 synchronized(this) { 10882 return mServices.stopServiceTokenLocked(className, token, startId); 10883 } 10884 } 10885 10886 public void setServiceForeground(ComponentName className, IBinder token, 10887 int id, Notification notification, boolean removeNotification) { 10888 synchronized(this) { 10889 mServices.setServiceForegroundLocked(className, token, id, notification, 10890 removeNotification); 10891 } 10892 } 10893 10894 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 10895 boolean requireFull, String name, String callerPackage) { 10896 synchronized(this) { 10897 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll, 10898 requireFull, name, callerPackage); 10899 } 10900 } 10901 10902 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll, 10903 boolean requireFull, String name, String callerPackage) { 10904 final int callingUserId = UserHandle.getUserId(callingUid); 10905 if (callingUserId != userId) { 10906 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10907 if ((requireFull || checkComponentPermission( 10908 android.Manifest.permission.INTERACT_ACROSS_USERS, 10909 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 10910 && checkComponentPermission( 10911 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10912 callingPid, callingUid, -1, true) 10913 != PackageManager.PERMISSION_GRANTED) { 10914 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 10915 // In this case, they would like to just execute as their 10916 // owner user instead of failing. 10917 userId = callingUserId; 10918 } else { 10919 StringBuilder builder = new StringBuilder(128); 10920 builder.append("Permission Denial: "); 10921 builder.append(name); 10922 if (callerPackage != null) { 10923 builder.append(" from "); 10924 builder.append(callerPackage); 10925 } 10926 builder.append(" asks to run as user "); 10927 builder.append(userId); 10928 builder.append(" but is calling from user "); 10929 builder.append(UserHandle.getUserId(callingUid)); 10930 builder.append("; this requires "); 10931 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 10932 if (!requireFull) { 10933 builder.append(" or "); 10934 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 10935 } 10936 String msg = builder.toString(); 10937 Slog.w(TAG, msg); 10938 throw new SecurityException(msg); 10939 } 10940 } 10941 } 10942 if (userId == UserHandle.USER_CURRENT 10943 || userId == UserHandle.USER_CURRENT_OR_SELF) { 10944 userId = mCurrentUserId; 10945 } 10946 if (!allowAll && userId < 0) { 10947 throw new IllegalArgumentException( 10948 "Call does not support special user #" + userId); 10949 } 10950 } 10951 return userId; 10952 } 10953 10954 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 10955 String className, int flags) { 10956 boolean result = false; 10957 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 10958 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 10959 if (ActivityManager.checkUidPermission( 10960 android.Manifest.permission.INTERACT_ACROSS_USERS, 10961 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 10962 ComponentName comp = new ComponentName(aInfo.packageName, className); 10963 String msg = "Permission Denial: Component " + comp.flattenToShortString() 10964 + " requests FLAG_SINGLE_USER, but app does not hold " 10965 + android.Manifest.permission.INTERACT_ACROSS_USERS; 10966 Slog.w(TAG, msg); 10967 throw new SecurityException(msg); 10968 } 10969 result = true; 10970 } 10971 } else if (componentProcessName == aInfo.packageName) { 10972 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 10973 } else if ("system".equals(componentProcessName)) { 10974 result = true; 10975 } 10976 if (DEBUG_MU) { 10977 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 10978 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 10979 } 10980 return result; 10981 } 10982 10983 public int bindService(IApplicationThread caller, IBinder token, 10984 Intent service, String resolvedType, 10985 IServiceConnection connection, int flags, int userId) { 10986 enforceNotIsolatedCaller("bindService"); 10987 // Refuse possible leaked file descriptors 10988 if (service != null && service.hasFileDescriptors() == true) { 10989 throw new IllegalArgumentException("File descriptors passed in Intent"); 10990 } 10991 10992 synchronized(this) { 10993 return mServices.bindServiceLocked(caller, token, service, resolvedType, 10994 connection, flags, userId); 10995 } 10996 } 10997 10998 public boolean unbindService(IServiceConnection connection) { 10999 synchronized (this) { 11000 return mServices.unbindServiceLocked(connection); 11001 } 11002 } 11003 11004 public void publishService(IBinder token, Intent intent, IBinder service) { 11005 // Refuse possible leaked file descriptors 11006 if (intent != null && intent.hasFileDescriptors() == true) { 11007 throw new IllegalArgumentException("File descriptors passed in Intent"); 11008 } 11009 11010 synchronized(this) { 11011 if (!(token instanceof ServiceRecord)) { 11012 throw new IllegalArgumentException("Invalid service token"); 11013 } 11014 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 11015 } 11016 } 11017 11018 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11019 // Refuse possible leaked file descriptors 11020 if (intent != null && intent.hasFileDescriptors() == true) { 11021 throw new IllegalArgumentException("File descriptors passed in Intent"); 11022 } 11023 11024 synchronized(this) { 11025 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 11026 } 11027 } 11028 11029 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11030 synchronized(this) { 11031 if (!(token instanceof ServiceRecord)) { 11032 throw new IllegalArgumentException("Invalid service token"); 11033 } 11034 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 11035 } 11036 } 11037 11038 // ========================================================= 11039 // BACKUP AND RESTORE 11040 // ========================================================= 11041 11042 // Cause the target app to be launched if necessary and its backup agent 11043 // instantiated. The backup agent will invoke backupAgentCreated() on the 11044 // activity manager to announce its creation. 11045 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11046 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11047 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11048 11049 synchronized(this) { 11050 // !!! TODO: currently no check here that we're already bound 11051 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11052 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11053 synchronized (stats) { 11054 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11055 } 11056 11057 // Backup agent is now in use, its package can't be stopped. 11058 try { 11059 AppGlobals.getPackageManager().setPackageStoppedState( 11060 app.packageName, false, UserHandle.getUserId(app.uid)); 11061 } catch (RemoteException e) { 11062 } catch (IllegalArgumentException e) { 11063 Slog.w(TAG, "Failed trying to unstop package " 11064 + app.packageName + ": " + e); 11065 } 11066 11067 BackupRecord r = new BackupRecord(ss, app, backupMode); 11068 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 11069 ? new ComponentName(app.packageName, app.backupAgentName) 11070 : new ComponentName("android", "FullBackupAgent"); 11071 // startProcessLocked() returns existing proc's record if it's already running 11072 ProcessRecord proc = startProcessLocked(app.processName, app, 11073 false, 0, "backup", hostingName, false, false); 11074 if (proc == null) { 11075 Slog.e(TAG, "Unable to start backup agent process " + r); 11076 return false; 11077 } 11078 11079 r.app = proc; 11080 mBackupTarget = r; 11081 mBackupAppName = app.packageName; 11082 11083 // Try not to kill the process during backup 11084 updateOomAdjLocked(proc); 11085 11086 // If the process is already attached, schedule the creation of the backup agent now. 11087 // If it is not yet live, this will be done when it attaches to the framework. 11088 if (proc.thread != null) { 11089 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 11090 try { 11091 proc.thread.scheduleCreateBackupAgent(app, 11092 compatibilityInfoForPackageLocked(app), backupMode); 11093 } catch (RemoteException e) { 11094 // Will time out on the backup manager side 11095 } 11096 } else { 11097 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 11098 } 11099 // Invariants: at this point, the target app process exists and the application 11100 // is either already running or in the process of coming up. mBackupTarget and 11101 // mBackupAppName describe the app, so that when it binds back to the AM we 11102 // know that it's scheduled for a backup-agent operation. 11103 } 11104 11105 return true; 11106 } 11107 11108 // A backup agent has just come up 11109 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11110 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 11111 + " = " + agent); 11112 11113 synchronized(this) { 11114 if (!agentPackageName.equals(mBackupAppName)) { 11115 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11116 return; 11117 } 11118 } 11119 11120 long oldIdent = Binder.clearCallingIdentity(); 11121 try { 11122 IBackupManager bm = IBackupManager.Stub.asInterface( 11123 ServiceManager.getService(Context.BACKUP_SERVICE)); 11124 bm.agentConnected(agentPackageName, agent); 11125 } catch (RemoteException e) { 11126 // can't happen; the backup manager service is local 11127 } catch (Exception e) { 11128 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11129 e.printStackTrace(); 11130 } finally { 11131 Binder.restoreCallingIdentity(oldIdent); 11132 } 11133 } 11134 11135 // done with this agent 11136 public void unbindBackupAgent(ApplicationInfo appInfo) { 11137 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 11138 if (appInfo == null) { 11139 Slog.w(TAG, "unbind backup agent for null app"); 11140 return; 11141 } 11142 11143 synchronized(this) { 11144 if (mBackupAppName == null) { 11145 Slog.w(TAG, "Unbinding backup agent with no active backup"); 11146 return; 11147 } 11148 11149 if (!mBackupAppName.equals(appInfo.packageName)) { 11150 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11151 return; 11152 } 11153 11154 ProcessRecord proc = mBackupTarget.app; 11155 mBackupTarget = null; 11156 mBackupAppName = null; 11157 11158 // Not backing this app up any more; reset its OOM adjustment 11159 updateOomAdjLocked(proc); 11160 11161 // If the app crashed during backup, 'thread' will be null here 11162 if (proc.thread != null) { 11163 try { 11164 proc.thread.scheduleDestroyBackupAgent(appInfo, 11165 compatibilityInfoForPackageLocked(appInfo)); 11166 } catch (Exception e) { 11167 Slog.e(TAG, "Exception when unbinding backup agent:"); 11168 e.printStackTrace(); 11169 } 11170 } 11171 } 11172 } 11173 // ========================================================= 11174 // BROADCASTS 11175 // ========================================================= 11176 11177 private final List getStickiesLocked(String action, IntentFilter filter, 11178 List cur, int userId) { 11179 final ContentResolver resolver = mContext.getContentResolver(); 11180 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11181 if (stickies == null) { 11182 return cur; 11183 } 11184 final ArrayList<Intent> list = stickies.get(action); 11185 if (list == null) { 11186 return cur; 11187 } 11188 int N = list.size(); 11189 for (int i=0; i<N; i++) { 11190 Intent intent = list.get(i); 11191 if (filter.match(resolver, intent, true, TAG) >= 0) { 11192 if (cur == null) { 11193 cur = new ArrayList<Intent>(); 11194 } 11195 cur.add(intent); 11196 } 11197 } 11198 return cur; 11199 } 11200 11201 boolean isPendingBroadcastProcessLocked(int pid) { 11202 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 11203 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 11204 } 11205 11206 void skipPendingBroadcastLocked(int pid) { 11207 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 11208 for (BroadcastQueue queue : mBroadcastQueues) { 11209 queue.skipPendingBroadcastLocked(pid); 11210 } 11211 } 11212 11213 // The app just attached; send any pending broadcasts that it should receive 11214 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 11215 boolean didSomething = false; 11216 for (BroadcastQueue queue : mBroadcastQueues) { 11217 didSomething |= queue.sendPendingBroadcastsLocked(app); 11218 } 11219 return didSomething; 11220 } 11221 11222 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 11223 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 11224 enforceNotIsolatedCaller("registerReceiver"); 11225 int callingUid; 11226 int callingPid; 11227 synchronized(this) { 11228 ProcessRecord callerApp = null; 11229 if (caller != null) { 11230 callerApp = getRecordForAppLocked(caller); 11231 if (callerApp == null) { 11232 throw new SecurityException( 11233 "Unable to find app for caller " + caller 11234 + " (pid=" + Binder.getCallingPid() 11235 + ") when registering receiver " + receiver); 11236 } 11237 if (callerApp.info.uid != Process.SYSTEM_UID && 11238 !callerApp.pkgList.contains(callerPackage)) { 11239 throw new SecurityException("Given caller package " + callerPackage 11240 + " is not running in process " + callerApp); 11241 } 11242 callingUid = callerApp.info.uid; 11243 callingPid = callerApp.pid; 11244 } else { 11245 callerPackage = null; 11246 callingUid = Binder.getCallingUid(); 11247 callingPid = Binder.getCallingPid(); 11248 } 11249 11250 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId, 11251 true, true, "registerReceiver", callerPackage); 11252 11253 List allSticky = null; 11254 11255 // Look for any matching sticky broadcasts... 11256 Iterator actions = filter.actionsIterator(); 11257 if (actions != null) { 11258 while (actions.hasNext()) { 11259 String action = (String)actions.next(); 11260 allSticky = getStickiesLocked(action, filter, allSticky, 11261 UserHandle.USER_ALL); 11262 allSticky = getStickiesLocked(action, filter, allSticky, 11263 UserHandle.getUserId(callingUid)); 11264 } 11265 } else { 11266 allSticky = getStickiesLocked(null, filter, allSticky, 11267 UserHandle.USER_ALL); 11268 allSticky = getStickiesLocked(null, filter, allSticky, 11269 UserHandle.getUserId(callingUid)); 11270 } 11271 11272 // The first sticky in the list is returned directly back to 11273 // the client. 11274 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11275 11276 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 11277 + ": " + sticky); 11278 11279 if (receiver == null) { 11280 return sticky; 11281 } 11282 11283 ReceiverList rl 11284 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11285 if (rl == null) { 11286 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 11287 userId, receiver); 11288 if (rl.app != null) { 11289 rl.app.receivers.add(rl); 11290 } else { 11291 try { 11292 receiver.asBinder().linkToDeath(rl, 0); 11293 } catch (RemoteException e) { 11294 return sticky; 11295 } 11296 rl.linkedToDeath = true; 11297 } 11298 mRegisteredReceivers.put(receiver.asBinder(), rl); 11299 } else if (rl.uid != callingUid) { 11300 throw new IllegalArgumentException( 11301 "Receiver requested to register for uid " + callingUid 11302 + " was previously registered for uid " + rl.uid); 11303 } else if (rl.pid != callingPid) { 11304 throw new IllegalArgumentException( 11305 "Receiver requested to register for pid " + callingPid 11306 + " was previously registered for pid " + rl.pid); 11307 } else if (rl.userId != userId) { 11308 throw new IllegalArgumentException( 11309 "Receiver requested to register for user " + userId 11310 + " was previously registered for user " + rl.userId); 11311 } 11312 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 11313 permission, callingUid, userId); 11314 rl.add(bf); 11315 if (!bf.debugCheck()) { 11316 Slog.w(TAG, "==> For Dynamic broadast"); 11317 } 11318 mReceiverResolver.addFilter(bf); 11319 11320 // Enqueue broadcasts for all existing stickies that match 11321 // this filter. 11322 if (allSticky != null) { 11323 ArrayList receivers = new ArrayList(); 11324 receivers.add(bf); 11325 11326 int N = allSticky.size(); 11327 for (int i=0; i<N; i++) { 11328 Intent intent = (Intent)allSticky.get(i); 11329 BroadcastQueue queue = broadcastQueueForIntent(intent); 11330 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 11331 null, -1, -1, null, receivers, null, 0, null, null, 11332 false, true, true, -1); 11333 queue.enqueueParallelBroadcastLocked(r); 11334 queue.scheduleBroadcastsLocked(); 11335 } 11336 } 11337 11338 return sticky; 11339 } 11340 } 11341 11342 public void unregisterReceiver(IIntentReceiver receiver) { 11343 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 11344 11345 final long origId = Binder.clearCallingIdentity(); 11346 try { 11347 boolean doTrim = false; 11348 11349 synchronized(this) { 11350 ReceiverList rl 11351 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11352 if (rl != null) { 11353 if (rl.curBroadcast != null) { 11354 BroadcastRecord r = rl.curBroadcast; 11355 final boolean doNext = finishReceiverLocked( 11356 receiver.asBinder(), r.resultCode, r.resultData, 11357 r.resultExtras, r.resultAbort, true); 11358 if (doNext) { 11359 doTrim = true; 11360 r.queue.processNextBroadcast(false); 11361 } 11362 } 11363 11364 if (rl.app != null) { 11365 rl.app.receivers.remove(rl); 11366 } 11367 removeReceiverLocked(rl); 11368 if (rl.linkedToDeath) { 11369 rl.linkedToDeath = false; 11370 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11371 } 11372 } 11373 } 11374 11375 // If we actually concluded any broadcasts, we might now be able 11376 // to trim the recipients' apps from our working set 11377 if (doTrim) { 11378 trimApplications(); 11379 return; 11380 } 11381 11382 } finally { 11383 Binder.restoreCallingIdentity(origId); 11384 } 11385 } 11386 11387 void removeReceiverLocked(ReceiverList rl) { 11388 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11389 int N = rl.size(); 11390 for (int i=0; i<N; i++) { 11391 mReceiverResolver.removeFilter(rl.get(i)); 11392 } 11393 } 11394 11395 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 11396 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 11397 ProcessRecord r = mLruProcesses.get(i); 11398 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 11399 try { 11400 r.thread.dispatchPackageBroadcast(cmd, packages); 11401 } catch (RemoteException ex) { 11402 } 11403 } 11404 } 11405 } 11406 11407 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 11408 int[] users) { 11409 List<ResolveInfo> receivers = null; 11410 try { 11411 HashSet<ComponentName> singleUserReceivers = null; 11412 boolean scannedFirstReceivers = false; 11413 for (int user : users) { 11414 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 11415 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 11416 if (newReceivers != null && newReceivers.size() == 0) { 11417 newReceivers = null; 11418 } 11419 if (receivers == null) { 11420 receivers = newReceivers; 11421 } else if (newReceivers != null) { 11422 // We need to concatenate the additional receivers 11423 // found with what we have do far. This would be easy, 11424 // but we also need to de-dup any receivers that are 11425 // singleUser. 11426 if (!scannedFirstReceivers) { 11427 // Collect any single user receivers we had already retrieved. 11428 scannedFirstReceivers = true; 11429 for (int i=0; i<receivers.size(); i++) { 11430 ResolveInfo ri = receivers.get(i); 11431 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11432 ComponentName cn = new ComponentName( 11433 ri.activityInfo.packageName, ri.activityInfo.name); 11434 if (singleUserReceivers == null) { 11435 singleUserReceivers = new HashSet<ComponentName>(); 11436 } 11437 singleUserReceivers.add(cn); 11438 } 11439 } 11440 } 11441 // Add the new results to the existing results, tracking 11442 // and de-dupping single user receivers. 11443 for (int i=0; i<newReceivers.size(); i++) { 11444 ResolveInfo ri = newReceivers.get(i); 11445 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 11446 ComponentName cn = new ComponentName( 11447 ri.activityInfo.packageName, ri.activityInfo.name); 11448 if (singleUserReceivers == null) { 11449 singleUserReceivers = new HashSet<ComponentName>(); 11450 } 11451 if (!singleUserReceivers.contains(cn)) { 11452 singleUserReceivers.add(cn); 11453 receivers.add(ri); 11454 } 11455 } else { 11456 receivers.add(ri); 11457 } 11458 } 11459 } 11460 } 11461 } catch (RemoteException ex) { 11462 // pm is in same process, this will never happen. 11463 } 11464 return receivers; 11465 } 11466 11467 private final int broadcastIntentLocked(ProcessRecord callerApp, 11468 String callerPackage, Intent intent, String resolvedType, 11469 IIntentReceiver resultTo, int resultCode, String resultData, 11470 Bundle map, String requiredPermission, 11471 boolean ordered, boolean sticky, int callingPid, int callingUid, 11472 int userId) { 11473 intent = new Intent(intent); 11474 11475 // By default broadcasts do not go to stopped apps. 11476 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 11477 11478 if (DEBUG_BROADCAST_LIGHT) Slog.v( 11479 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11480 + " ordered=" + ordered + " userid=" + userId); 11481 if ((resultTo != null) && !ordered) { 11482 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11483 } 11484 11485 userId = handleIncomingUserLocked(callingPid, callingUid, userId, 11486 true, false, "broadcast", callerPackage); 11487 11488 // Make sure that the user who is receiving this broadcast is started 11489 // If not, we will just skip it. 11490 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 11491 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 11492 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 11493 Slog.w(TAG, "Skipping broadcast of " + intent 11494 + ": user " + userId + " is stopped"); 11495 return ActivityManager.BROADCAST_SUCCESS; 11496 } 11497 } 11498 11499 /* 11500 * Prevent non-system code (defined here to be non-persistent 11501 * processes) from sending protected broadcasts. 11502 */ 11503 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11504 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID || 11505 callingUid == 0) { 11506 // Always okay. 11507 } else if (callerApp == null || !callerApp.persistent) { 11508 try { 11509 if (AppGlobals.getPackageManager().isProtectedBroadcast( 11510 intent.getAction())) { 11511 String msg = "Permission Denial: not allowed to send broadcast " 11512 + intent.getAction() + " from pid=" 11513 + callingPid + ", uid=" + callingUid; 11514 Slog.w(TAG, msg); 11515 throw new SecurityException(msg); 11516 } 11517 } catch (RemoteException e) { 11518 Slog.w(TAG, "Remote exception", e); 11519 return ActivityManager.BROADCAST_SUCCESS; 11520 } 11521 } 11522 11523 // Handle special intents: if this broadcast is from the package 11524 // manager about a package being removed, we need to remove all of 11525 // its activities from the history stack. 11526 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 11527 intent.getAction()); 11528 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11529 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11530 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11531 || uidRemoved) { 11532 if (checkComponentPermission( 11533 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11534 callingPid, callingUid, -1, true) 11535 == PackageManager.PERMISSION_GRANTED) { 11536 if (uidRemoved) { 11537 final Bundle intentExtras = intent.getExtras(); 11538 final int uid = intentExtras != null 11539 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11540 if (uid >= 0) { 11541 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11542 synchronized (bs) { 11543 bs.removeUidStatsLocked(uid); 11544 } 11545 } 11546 } else { 11547 // If resources are unavailable just force stop all 11548 // those packages and flush the attribute cache as well. 11549 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11550 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11551 if (list != null && (list.length > 0)) { 11552 for (String pkg : list) { 11553 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 11554 } 11555 sendPackageBroadcastLocked( 11556 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 11557 } 11558 } else { 11559 Uri data = intent.getData(); 11560 String ssp; 11561 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11562 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11563 forceStopPackageLocked(ssp, 11564 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 11565 false, userId); 11566 } 11567 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 11568 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 11569 new String[] {ssp}, userId); 11570 } 11571 } 11572 } 11573 } 11574 } else { 11575 String msg = "Permission Denial: " + intent.getAction() 11576 + " broadcast from " + callerPackage + " (pid=" + callingPid 11577 + ", uid=" + callingUid + ")" 11578 + " requires " 11579 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11580 Slog.w(TAG, msg); 11581 throw new SecurityException(msg); 11582 } 11583 11584 // Special case for adding a package: by default turn on compatibility 11585 // mode. 11586 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11587 Uri data = intent.getData(); 11588 String ssp; 11589 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11590 mCompatModePackages.handlePackageAddedLocked(ssp, 11591 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 11592 } 11593 } 11594 11595 /* 11596 * If this is the time zone changed action, queue up a message that will reset the timezone 11597 * of all currently running processes. This message will get queued up before the broadcast 11598 * happens. 11599 */ 11600 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11601 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11602 } 11603 11604 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 11605 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 11606 } 11607 11608 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 11609 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 11610 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 11611 } 11612 11613 // Add to the sticky list if requested. 11614 if (sticky) { 11615 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11616 callingPid, callingUid) 11617 != PackageManager.PERMISSION_GRANTED) { 11618 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11619 + callingPid + ", uid=" + callingUid 11620 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11621 Slog.w(TAG, msg); 11622 throw new SecurityException(msg); 11623 } 11624 if (requiredPermission != null) { 11625 Slog.w(TAG, "Can't broadcast sticky intent " + intent 11626 + " and enforce permission " + requiredPermission); 11627 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11628 } 11629 if (intent.getComponent() != null) { 11630 throw new SecurityException( 11631 "Sticky broadcasts can't target a specific component"); 11632 } 11633 // We use userId directly here, since the "all" target is maintained 11634 // as a separate set of sticky broadcasts. 11635 if (userId != UserHandle.USER_ALL) { 11636 // But first, if this is not a broadcast to all users, then 11637 // make sure it doesn't conflict with an existing broadcast to 11638 // all users. 11639 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 11640 UserHandle.USER_ALL); 11641 if (stickies != null) { 11642 ArrayList<Intent> list = stickies.get(intent.getAction()); 11643 if (list != null) { 11644 int N = list.size(); 11645 int i; 11646 for (i=0; i<N; i++) { 11647 if (intent.filterEquals(list.get(i))) { 11648 throw new IllegalArgumentException( 11649 "Sticky broadcast " + intent + " for user " 11650 + userId + " conflicts with existing global broadcast"); 11651 } 11652 } 11653 } 11654 } 11655 } 11656 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11657 if (stickies == null) { 11658 stickies = new HashMap<String, ArrayList<Intent>>(); 11659 mStickyBroadcasts.put(userId, stickies); 11660 } 11661 ArrayList<Intent> list = stickies.get(intent.getAction()); 11662 if (list == null) { 11663 list = new ArrayList<Intent>(); 11664 stickies.put(intent.getAction(), list); 11665 } 11666 int N = list.size(); 11667 int i; 11668 for (i=0; i<N; i++) { 11669 if (intent.filterEquals(list.get(i))) { 11670 // This sticky already exists, replace it. 11671 list.set(i, new Intent(intent)); 11672 break; 11673 } 11674 } 11675 if (i >= N) { 11676 list.add(new Intent(intent)); 11677 } 11678 } 11679 11680 int[] users; 11681 if (userId == UserHandle.USER_ALL) { 11682 // Caller wants broadcast to go to all started users. 11683 users = new int[mStartedUsers.size()]; 11684 for (int i=0; i<mStartedUsers.size(); i++) { 11685 users[i] = mStartedUsers.keyAt(i); 11686 } 11687 } else { 11688 // Caller wants broadcast to go to one specific user. 11689 users = new int[] {userId}; 11690 } 11691 11692 // Figure out who all will receive this broadcast. 11693 List receivers = null; 11694 List<BroadcastFilter> registeredReceivers = null; 11695 // Need to resolve the intent to interested receivers... 11696 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11697 == 0) { 11698 receivers = collectReceiverComponents(intent, resolvedType, users); 11699 } 11700 if (intent.getComponent() == null) { 11701 registeredReceivers = mReceiverResolver.queryIntent(intent, 11702 resolvedType, false, userId); 11703 } 11704 11705 final boolean replacePending = 11706 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 11707 11708 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 11709 + " replacePending=" + replacePending); 11710 11711 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11712 if (!ordered && NR > 0) { 11713 // If we are not serializing this broadcast, then send the 11714 // registered receivers separately so they don't wait for the 11715 // components to be launched. 11716 final BroadcastQueue queue = broadcastQueueForIntent(intent); 11717 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11718 callerPackage, callingPid, callingUid, requiredPermission, 11719 registeredReceivers, resultTo, resultCode, resultData, map, 11720 ordered, sticky, false, userId); 11721 if (DEBUG_BROADCAST) Slog.v( 11722 TAG, "Enqueueing parallel broadcast " + r); 11723 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 11724 if (!replaced) { 11725 queue.enqueueParallelBroadcastLocked(r); 11726 queue.scheduleBroadcastsLocked(); 11727 } 11728 registeredReceivers = null; 11729 NR = 0; 11730 } 11731 11732 // Merge into one list. 11733 int ir = 0; 11734 if (receivers != null) { 11735 // A special case for PACKAGE_ADDED: do not allow the package 11736 // being added to see this broadcast. This prevents them from 11737 // using this as a back door to get run as soon as they are 11738 // installed. Maybe in the future we want to have a special install 11739 // broadcast or such for apps, but we'd like to deliberately make 11740 // this decision. 11741 String skipPackages[] = null; 11742 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 11743 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 11744 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11745 Uri data = intent.getData(); 11746 if (data != null) { 11747 String pkgName = data.getSchemeSpecificPart(); 11748 if (pkgName != null) { 11749 skipPackages = new String[] { pkgName }; 11750 } 11751 } 11752 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 11753 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11754 } 11755 if (skipPackages != null && (skipPackages.length > 0)) { 11756 for (String skipPackage : skipPackages) { 11757 if (skipPackage != null) { 11758 int NT = receivers.size(); 11759 for (int it=0; it<NT; it++) { 11760 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11761 if (curt.activityInfo.packageName.equals(skipPackage)) { 11762 receivers.remove(it); 11763 it--; 11764 NT--; 11765 } 11766 } 11767 } 11768 } 11769 } 11770 11771 int NT = receivers != null ? receivers.size() : 0; 11772 int it = 0; 11773 ResolveInfo curt = null; 11774 BroadcastFilter curr = null; 11775 while (it < NT && ir < NR) { 11776 if (curt == null) { 11777 curt = (ResolveInfo)receivers.get(it); 11778 } 11779 if (curr == null) { 11780 curr = registeredReceivers.get(ir); 11781 } 11782 if (curr.getPriority() >= curt.priority) { 11783 // Insert this broadcast record into the final list. 11784 receivers.add(it, curr); 11785 ir++; 11786 curr = null; 11787 it++; 11788 NT++; 11789 } else { 11790 // Skip to the next ResolveInfo in the final list. 11791 it++; 11792 curt = null; 11793 } 11794 } 11795 } 11796 while (ir < NR) { 11797 if (receivers == null) { 11798 receivers = new ArrayList(); 11799 } 11800 receivers.add(registeredReceivers.get(ir)); 11801 ir++; 11802 } 11803 11804 if ((receivers != null && receivers.size() > 0) 11805 || resultTo != null) { 11806 BroadcastQueue queue = broadcastQueueForIntent(intent); 11807 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 11808 callerPackage, callingPid, callingUid, requiredPermission, 11809 receivers, resultTo, resultCode, resultData, map, ordered, 11810 sticky, false, userId); 11811 if (DEBUG_BROADCAST) Slog.v( 11812 TAG, "Enqueueing ordered broadcast " + r 11813 + ": prev had " + queue.mOrderedBroadcasts.size()); 11814 if (DEBUG_BROADCAST) { 11815 int seq = r.intent.getIntExtra("seq", -1); 11816 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11817 } 11818 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 11819 if (!replaced) { 11820 queue.enqueueOrderedBroadcastLocked(r); 11821 queue.scheduleBroadcastsLocked(); 11822 } 11823 } 11824 11825 return ActivityManager.BROADCAST_SUCCESS; 11826 } 11827 11828 final Intent verifyBroadcastLocked(Intent intent) { 11829 // Refuse possible leaked file descriptors 11830 if (intent != null && intent.hasFileDescriptors() == true) { 11831 throw new IllegalArgumentException("File descriptors passed in Intent"); 11832 } 11833 11834 int flags = intent.getFlags(); 11835 11836 if (!mProcessesReady) { 11837 // if the caller really truly claims to know what they're doing, go 11838 // ahead and allow the broadcast without launching any receivers 11839 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11840 intent = new Intent(intent); 11841 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11842 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 11843 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11844 + " before boot completion"); 11845 throw new IllegalStateException("Cannot broadcast before boot completed"); 11846 } 11847 } 11848 11849 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11850 throw new IllegalArgumentException( 11851 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11852 } 11853 11854 return intent; 11855 } 11856 11857 public final int broadcastIntent(IApplicationThread caller, 11858 Intent intent, String resolvedType, IIntentReceiver resultTo, 11859 int resultCode, String resultData, Bundle map, 11860 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11861 enforceNotIsolatedCaller("broadcastIntent"); 11862 synchronized(this) { 11863 intent = verifyBroadcastLocked(intent); 11864 11865 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11866 final int callingPid = Binder.getCallingPid(); 11867 final int callingUid = Binder.getCallingUid(); 11868 final long origId = Binder.clearCallingIdentity(); 11869 int res = broadcastIntentLocked(callerApp, 11870 callerApp != null ? callerApp.info.packageName : null, 11871 intent, resolvedType, resultTo, 11872 resultCode, resultData, map, requiredPermission, serialized, sticky, 11873 callingPid, callingUid, userId); 11874 Binder.restoreCallingIdentity(origId); 11875 return res; 11876 } 11877 } 11878 11879 int broadcastIntentInPackage(String packageName, int uid, 11880 Intent intent, String resolvedType, IIntentReceiver resultTo, 11881 int resultCode, String resultData, Bundle map, 11882 String requiredPermission, boolean serialized, boolean sticky, int userId) { 11883 synchronized(this) { 11884 intent = verifyBroadcastLocked(intent); 11885 11886 final long origId = Binder.clearCallingIdentity(); 11887 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11888 resultTo, resultCode, resultData, map, requiredPermission, 11889 serialized, sticky, -1, uid, userId); 11890 Binder.restoreCallingIdentity(origId); 11891 return res; 11892 } 11893 } 11894 11895 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 11896 // Refuse possible leaked file descriptors 11897 if (intent != null && intent.hasFileDescriptors() == true) { 11898 throw new IllegalArgumentException("File descriptors passed in Intent"); 11899 } 11900 11901 userId = handleIncomingUserLocked(Binder.getCallingPid(), 11902 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 11903 11904 synchronized(this) { 11905 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11906 != PackageManager.PERMISSION_GRANTED) { 11907 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11908 + Binder.getCallingPid() 11909 + ", uid=" + Binder.getCallingUid() 11910 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11911 Slog.w(TAG, msg); 11912 throw new SecurityException(msg); 11913 } 11914 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 11915 if (stickies != null) { 11916 ArrayList<Intent> list = stickies.get(intent.getAction()); 11917 if (list != null) { 11918 int N = list.size(); 11919 int i; 11920 for (i=0; i<N; i++) { 11921 if (intent.filterEquals(list.get(i))) { 11922 list.remove(i); 11923 break; 11924 } 11925 } 11926 if (list.size() <= 0) { 11927 stickies.remove(intent.getAction()); 11928 } 11929 } 11930 if (stickies.size() <= 0) { 11931 mStickyBroadcasts.remove(userId); 11932 } 11933 } 11934 } 11935 } 11936 11937 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11938 String resultData, Bundle resultExtras, boolean resultAbort, 11939 boolean explicit) { 11940 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 11941 if (r == null) { 11942 Slog.w(TAG, "finishReceiver called but not found on queue"); 11943 return false; 11944 } 11945 11946 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 11947 explicit); 11948 } 11949 11950 public void finishReceiver(IBinder who, int resultCode, String resultData, 11951 Bundle resultExtras, boolean resultAbort) { 11952 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 11953 11954 // Refuse possible leaked file descriptors 11955 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 11956 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11957 } 11958 11959 final long origId = Binder.clearCallingIdentity(); 11960 try { 11961 boolean doNext = false; 11962 BroadcastRecord r = null; 11963 11964 synchronized(this) { 11965 r = broadcastRecordForReceiverLocked(who); 11966 if (r != null) { 11967 doNext = r.queue.finishReceiverLocked(r, resultCode, 11968 resultData, resultExtras, resultAbort, true); 11969 } 11970 } 11971 11972 if (doNext) { 11973 r.queue.processNextBroadcast(false); 11974 } 11975 trimApplications(); 11976 } finally { 11977 Binder.restoreCallingIdentity(origId); 11978 } 11979 } 11980 11981 // ========================================================= 11982 // INSTRUMENTATION 11983 // ========================================================= 11984 11985 public boolean startInstrumentation(ComponentName className, 11986 String profileFile, int flags, Bundle arguments, 11987 IInstrumentationWatcher watcher, int userId) { 11988 enforceNotIsolatedCaller("startInstrumentation"); 11989 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 11990 userId, false, true, "startInstrumentation", null); 11991 // Refuse possible leaked file descriptors 11992 if (arguments != null && arguments.hasFileDescriptors()) { 11993 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11994 } 11995 11996 synchronized(this) { 11997 InstrumentationInfo ii = null; 11998 ApplicationInfo ai = null; 11999 try { 12000 ii = mContext.getPackageManager().getInstrumentationInfo( 12001 className, STOCK_PM_FLAGS); 12002 ai = AppGlobals.getPackageManager().getApplicationInfo( 12003 ii.targetPackage, STOCK_PM_FLAGS, userId); 12004 } catch (PackageManager.NameNotFoundException e) { 12005 } catch (RemoteException e) { 12006 } 12007 if (ii == null) { 12008 reportStartInstrumentationFailure(watcher, className, 12009 "Unable to find instrumentation info for: " + className); 12010 return false; 12011 } 12012 if (ai == null) { 12013 reportStartInstrumentationFailure(watcher, className, 12014 "Unable to find instrumentation target package: " + ii.targetPackage); 12015 return false; 12016 } 12017 12018 int match = mContext.getPackageManager().checkSignatures( 12019 ii.targetPackage, ii.packageName); 12020 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12021 String msg = "Permission Denial: starting instrumentation " 12022 + className + " from pid=" 12023 + Binder.getCallingPid() 12024 + ", uid=" + Binder.getCallingPid() 12025 + " not allowed because package " + ii.packageName 12026 + " does not have a signature matching the target " 12027 + ii.targetPackage; 12028 reportStartInstrumentationFailure(watcher, className, msg); 12029 throw new SecurityException(msg); 12030 } 12031 12032 final long origId = Binder.clearCallingIdentity(); 12033 // Instrumentation can kill and relaunch even persistent processes 12034 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 12035 ProcessRecord app = addAppLocked(ai, false); 12036 app.instrumentationClass = className; 12037 app.instrumentationInfo = ai; 12038 app.instrumentationProfileFile = profileFile; 12039 app.instrumentationArguments = arguments; 12040 app.instrumentationWatcher = watcher; 12041 app.instrumentationResultClass = className; 12042 Binder.restoreCallingIdentity(origId); 12043 } 12044 12045 return true; 12046 } 12047 12048 /** 12049 * Report errors that occur while attempting to start Instrumentation. Always writes the 12050 * error to the logs, but if somebody is watching, send the report there too. This enables 12051 * the "am" command to report errors with more information. 12052 * 12053 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12054 * @param cn The component name of the instrumentation. 12055 * @param report The error report. 12056 */ 12057 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12058 ComponentName cn, String report) { 12059 Slog.w(TAG, report); 12060 try { 12061 if (watcher != null) { 12062 Bundle results = new Bundle(); 12063 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12064 results.putString("Error", report); 12065 watcher.instrumentationStatus(cn, -1, results); 12066 } 12067 } catch (RemoteException e) { 12068 Slog.w(TAG, e); 12069 } 12070 } 12071 12072 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12073 if (app.instrumentationWatcher != null) { 12074 try { 12075 // NOTE: IInstrumentationWatcher *must* be oneway here 12076 app.instrumentationWatcher.instrumentationFinished( 12077 app.instrumentationClass, 12078 resultCode, 12079 results); 12080 } catch (RemoteException e) { 12081 } 12082 } 12083 app.instrumentationWatcher = null; 12084 app.instrumentationClass = null; 12085 app.instrumentationInfo = null; 12086 app.instrumentationProfileFile = null; 12087 app.instrumentationArguments = null; 12088 12089 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId); 12090 } 12091 12092 public void finishInstrumentation(IApplicationThread target, 12093 int resultCode, Bundle results) { 12094 int userId = UserHandle.getCallingUserId(); 12095 // Refuse possible leaked file descriptors 12096 if (results != null && results.hasFileDescriptors()) { 12097 throw new IllegalArgumentException("File descriptors passed in Intent"); 12098 } 12099 12100 synchronized(this) { 12101 ProcessRecord app = getRecordForAppLocked(target); 12102 if (app == null) { 12103 Slog.w(TAG, "finishInstrumentation: no app for " + target); 12104 return; 12105 } 12106 final long origId = Binder.clearCallingIdentity(); 12107 finishInstrumentationLocked(app, resultCode, results); 12108 Binder.restoreCallingIdentity(origId); 12109 } 12110 } 12111 12112 // ========================================================= 12113 // CONFIGURATION 12114 // ========================================================= 12115 12116 public ConfigurationInfo getDeviceConfigurationInfo() { 12117 ConfigurationInfo config = new ConfigurationInfo(); 12118 synchronized (this) { 12119 config.reqTouchScreen = mConfiguration.touchscreen; 12120 config.reqKeyboardType = mConfiguration.keyboard; 12121 config.reqNavigation = mConfiguration.navigation; 12122 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12123 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12124 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12125 } 12126 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12127 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12128 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12129 } 12130 config.reqGlEsVersion = GL_ES_VERSION; 12131 } 12132 return config; 12133 } 12134 12135 public Configuration getConfiguration() { 12136 Configuration ci; 12137 synchronized(this) { 12138 ci = new Configuration(mConfiguration); 12139 } 12140 return ci; 12141 } 12142 12143 public void updatePersistentConfiguration(Configuration values) { 12144 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12145 "updateConfiguration()"); 12146 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 12147 "updateConfiguration()"); 12148 if (values == null) { 12149 throw new NullPointerException("Configuration must not be null"); 12150 } 12151 12152 synchronized(this) { 12153 final long origId = Binder.clearCallingIdentity(); 12154 updateConfigurationLocked(values, null, true, false); 12155 Binder.restoreCallingIdentity(origId); 12156 } 12157 } 12158 12159 public void updateConfiguration(Configuration values) { 12160 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12161 "updateConfiguration()"); 12162 12163 synchronized(this) { 12164 if (values == null && mWindowManager != null) { 12165 // sentinel: fetch the current configuration from the window manager 12166 values = mWindowManager.computeNewConfiguration(); 12167 } 12168 12169 if (mWindowManager != null) { 12170 mProcessList.applyDisplaySize(mWindowManager); 12171 } 12172 12173 final long origId = Binder.clearCallingIdentity(); 12174 if (values != null) { 12175 Settings.System.clearConfiguration(values); 12176 } 12177 updateConfigurationLocked(values, null, false, false); 12178 Binder.restoreCallingIdentity(origId); 12179 } 12180 } 12181 12182 /** 12183 * Do either or both things: (1) change the current configuration, and (2) 12184 * make sure the given activity is running with the (now) current 12185 * configuration. Returns true if the activity has been left running, or 12186 * false if <var>starting</var> is being destroyed to match the new 12187 * configuration. 12188 * @param persistent TODO 12189 */ 12190 boolean updateConfigurationLocked(Configuration values, 12191 ActivityRecord starting, boolean persistent, boolean initLocale) { 12192 // do nothing if we are headless 12193 if (mHeadless) return true; 12194 12195 int changes = 0; 12196 12197 boolean kept = true; 12198 12199 if (values != null) { 12200 Configuration newConfig = new Configuration(mConfiguration); 12201 changes = newConfig.updateFrom(values); 12202 if (changes != 0) { 12203 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12204 Slog.i(TAG, "Updating configuration to: " + values); 12205 } 12206 12207 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 12208 12209 if (values.locale != null && !initLocale) { 12210 saveLocaleLocked(values.locale, 12211 !values.locale.equals(mConfiguration.locale), 12212 values.userSetLocale); 12213 } 12214 12215 mConfigurationSeq++; 12216 if (mConfigurationSeq <= 0) { 12217 mConfigurationSeq = 1; 12218 } 12219 newConfig.seq = mConfigurationSeq; 12220 mConfiguration = newConfig; 12221 Slog.i(TAG, "Config changed: " + newConfig); 12222 12223 final Configuration configCopy = new Configuration(mConfiguration); 12224 12225 // TODO: If our config changes, should we auto dismiss any currently 12226 // showing dialogs? 12227 mShowDialogs = shouldShowDialogs(newConfig); 12228 12229 AttributeCache ac = AttributeCache.instance(); 12230 if (ac != null) { 12231 ac.updateConfiguration(configCopy); 12232 } 12233 12234 // Make sure all resources in our process are updated 12235 // right now, so that anyone who is going to retrieve 12236 // resource values after we return will be sure to get 12237 // the new ones. This is especially important during 12238 // boot, where the first config change needs to guarantee 12239 // all resources have that config before following boot 12240 // code is executed. 12241 mSystemThread.applyConfigurationToResources(configCopy); 12242 12243 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 12244 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12245 msg.obj = new Configuration(configCopy); 12246 mHandler.sendMessage(msg); 12247 } 12248 12249 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12250 ProcessRecord app = mLruProcesses.get(i); 12251 try { 12252 if (app.thread != null) { 12253 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 12254 + app.processName + " new config " + mConfiguration); 12255 app.thread.scheduleConfigurationChanged(configCopy); 12256 } 12257 } catch (Exception e) { 12258 } 12259 } 12260 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12261 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 12262 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 12263 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12264 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12265 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 12266 broadcastIntentLocked(null, null, 12267 new Intent(Intent.ACTION_LOCALE_CHANGED), 12268 null, null, 0, null, null, 12269 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 12270 } 12271 } 12272 } 12273 12274 if (changes != 0 && starting == null) { 12275 // If the configuration changed, and the caller is not already 12276 // in the process of starting an activity, then find the top 12277 // activity to check if its configuration needs to change. 12278 starting = mMainStack.topRunningActivityLocked(null); 12279 } 12280 12281 if (starting != null) { 12282 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 12283 // And we need to make sure at this point that all other activities 12284 // are made visible with the correct configuration. 12285 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 12286 } 12287 12288 if (values != null && mWindowManager != null) { 12289 mWindowManager.setNewConfiguration(mConfiguration); 12290 } 12291 12292 return kept; 12293 } 12294 12295 /** 12296 * Decide based on the configuration whether we should shouw the ANR, 12297 * crash, etc dialogs. The idea is that if there is no affordnace to 12298 * press the on-screen buttons, we shouldn't show the dialog. 12299 * 12300 * A thought: SystemUI might also want to get told about this, the Power 12301 * dialog / global actions also might want different behaviors. 12302 */ 12303 private static final boolean shouldShowDialogs(Configuration config) { 12304 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 12305 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 12306 } 12307 12308 /** 12309 * Save the locale. You must be inside a synchronized (this) block. 12310 */ 12311 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12312 if(isDiff) { 12313 SystemProperties.set("user.language", l.getLanguage()); 12314 SystemProperties.set("user.region", l.getCountry()); 12315 } 12316 12317 if(isPersist) { 12318 SystemProperties.set("persist.sys.language", l.getLanguage()); 12319 SystemProperties.set("persist.sys.country", l.getCountry()); 12320 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12321 } 12322 } 12323 12324 @Override 12325 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 12326 ActivityRecord srec = ActivityRecord.forToken(token); 12327 return srec != null && srec.task.affinity != null && 12328 srec.task.affinity.equals(destAffinity); 12329 } 12330 12331 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 12332 Intent resultData) { 12333 ComponentName dest = destIntent.getComponent(); 12334 12335 synchronized (this) { 12336 ActivityRecord srec = ActivityRecord.forToken(token); 12337 if (srec == null) { 12338 return false; 12339 } 12340 ArrayList<ActivityRecord> history = srec.stack.mHistory; 12341 final int start = history.indexOf(srec); 12342 if (start < 0) { 12343 // Current activity is not in history stack; do nothing. 12344 return false; 12345 } 12346 int finishTo = start - 1; 12347 ActivityRecord parent = null; 12348 boolean foundParentInTask = false; 12349 if (dest != null) { 12350 TaskRecord tr = srec.task; 12351 for (int i = start - 1; i >= 0; i--) { 12352 ActivityRecord r = history.get(i); 12353 if (tr != r.task) { 12354 // Couldn't find parent in the same task; stop at the one above this. 12355 // (Root of current task; in-app "home" behavior) 12356 // Always at least finish the current activity. 12357 finishTo = Math.min(start - 1, i + 1); 12358 parent = history.get(finishTo); 12359 break; 12360 } else if (r.info.packageName.equals(dest.getPackageName()) && 12361 r.info.name.equals(dest.getClassName())) { 12362 finishTo = i; 12363 parent = r; 12364 foundParentInTask = true; 12365 break; 12366 } 12367 } 12368 } 12369 12370 if (mController != null) { 12371 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 12372 if (next != null) { 12373 // ask watcher if this is allowed 12374 boolean resumeOK = true; 12375 try { 12376 resumeOK = mController.activityResuming(next.packageName); 12377 } catch (RemoteException e) { 12378 mController = null; 12379 } 12380 12381 if (!resumeOK) { 12382 return false; 12383 } 12384 } 12385 } 12386 final long origId = Binder.clearCallingIdentity(); 12387 for (int i = start; i > finishTo; i--) { 12388 ActivityRecord r = history.get(i); 12389 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 12390 "navigate-up", true); 12391 // Only return the supplied result for the first activity finished 12392 resultCode = Activity.RESULT_CANCELED; 12393 resultData = null; 12394 } 12395 12396 if (parent != null && foundParentInTask) { 12397 final int parentLaunchMode = parent.info.launchMode; 12398 final int destIntentFlags = destIntent.getFlags(); 12399 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 12400 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 12401 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 12402 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 12403 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 12404 } else { 12405 try { 12406 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 12407 destIntent.getComponent(), 0, UserHandle.getCallingUserId()); 12408 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 12409 null, aInfo, parent.appToken, null, 12410 0, -1, parent.launchedFromUid, 0, null, true, null); 12411 foundParentInTask = res == ActivityManager.START_SUCCESS; 12412 } catch (RemoteException e) { 12413 foundParentInTask = false; 12414 } 12415 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 12416 resultData, "navigate-up", true); 12417 } 12418 } 12419 Binder.restoreCallingIdentity(origId); 12420 return foundParentInTask; 12421 } 12422 } 12423 12424 public int getLaunchedFromUid(IBinder activityToken) { 12425 ActivityRecord srec = ActivityRecord.forToken(activityToken); 12426 if (srec == null) { 12427 return -1; 12428 } 12429 return srec.launchedFromUid; 12430 } 12431 12432 // ========================================================= 12433 // LIFETIME MANAGEMENT 12434 // ========================================================= 12435 12436 // Returns which broadcast queue the app is the current [or imminent] receiver 12437 // on, or 'null' if the app is not an active broadcast recipient. 12438 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 12439 BroadcastRecord r = app.curReceiver; 12440 if (r != null) { 12441 return r.queue; 12442 } 12443 12444 // It's not the current receiver, but it might be starting up to become one 12445 synchronized (this) { 12446 for (BroadcastQueue queue : mBroadcastQueues) { 12447 r = queue.mPendingBroadcast; 12448 if (r != null && r.curApp == app) { 12449 // found it; report which queue it's in 12450 return queue; 12451 } 12452 } 12453 } 12454 12455 return null; 12456 } 12457 12458 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 12459 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 12460 if (mAdjSeq == app.adjSeq) { 12461 // This adjustment has already been computed. If we are calling 12462 // from the top, we may have already computed our adjustment with 12463 // an earlier hidden adjustment that isn't really for us... if 12464 // so, use the new hidden adjustment. 12465 if (!recursed && app.hidden) { 12466 app.curAdj = app.curRawAdj = app.nonStoppingAdj = 12467 app.hasActivities ? hiddenAdj : emptyAdj; 12468 } 12469 return app.curRawAdj; 12470 } 12471 12472 if (app.thread == null) { 12473 app.adjSeq = mAdjSeq; 12474 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12475 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 12476 } 12477 12478 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12479 app.adjSource = null; 12480 app.adjTarget = null; 12481 app.empty = false; 12482 app.hidden = false; 12483 12484 final int activitiesSize = app.activities.size(); 12485 12486 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 12487 // The max adjustment doesn't allow this app to be anything 12488 // below foreground, so it is not worth doing work for it. 12489 app.adjType = "fixed"; 12490 app.adjSeq = mAdjSeq; 12491 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 12492 app.hasActivities = false; 12493 app.foregroundActivities = false; 12494 app.keeping = true; 12495 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12496 // System process can do UI, and when they do we want to have 12497 // them trim their memory after the user leaves the UI. To 12498 // facilitate this, here we need to determine whether or not it 12499 // is currently showing UI. 12500 app.systemNoUi = true; 12501 if (app == TOP_APP) { 12502 app.systemNoUi = false; 12503 app.hasActivities = true; 12504 } else if (activitiesSize > 0) { 12505 for (int j = 0; j < activitiesSize; j++) { 12506 final ActivityRecord r = app.activities.get(j); 12507 if (r.visible) { 12508 app.systemNoUi = false; 12509 } 12510 if (r.app == app) { 12511 app.hasActivities = true; 12512 } 12513 } 12514 } 12515 return (app.curAdj=app.maxAdj); 12516 } 12517 12518 app.keeping = false; 12519 app.systemNoUi = false; 12520 app.hasActivities = false; 12521 12522 // Determine the importance of the process, starting with most 12523 // important to least, and assign an appropriate OOM adjustment. 12524 int adj; 12525 int schedGroup; 12526 boolean foregroundActivities = false; 12527 boolean interesting = false; 12528 BroadcastQueue queue; 12529 if (app == TOP_APP) { 12530 // The last app on the list is the foreground app. 12531 adj = ProcessList.FOREGROUND_APP_ADJ; 12532 schedGroup = Process.THREAD_GROUP_DEFAULT; 12533 app.adjType = "top-activity"; 12534 foregroundActivities = true; 12535 interesting = true; 12536 app.hasActivities = true; 12537 } else if (app.instrumentationClass != null) { 12538 // Don't want to kill running instrumentation. 12539 adj = ProcessList.FOREGROUND_APP_ADJ; 12540 schedGroup = Process.THREAD_GROUP_DEFAULT; 12541 app.adjType = "instrumentation"; 12542 interesting = true; 12543 } else if ((queue = isReceivingBroadcast(app)) != null) { 12544 // An app that is currently receiving a broadcast also 12545 // counts as being in the foreground for OOM killer purposes. 12546 // It's placed in a sched group based on the nature of the 12547 // broadcast as reflected by which queue it's active in. 12548 adj = ProcessList.FOREGROUND_APP_ADJ; 12549 schedGroup = (queue == mFgBroadcastQueue) 12550 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 12551 app.adjType = "broadcast"; 12552 } else if (app.executingServices.size() > 0) { 12553 // An app that is currently executing a service callback also 12554 // counts as being in the foreground. 12555 adj = ProcessList.FOREGROUND_APP_ADJ; 12556 schedGroup = Process.THREAD_GROUP_DEFAULT; 12557 app.adjType = "exec-service"; 12558 } else { 12559 // Assume process is hidden (has activities); we will correct 12560 // later if this is not the case. 12561 adj = hiddenAdj; 12562 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12563 app.hidden = true; 12564 app.adjType = "bg-activities"; 12565 } 12566 12567 boolean hasStoppingActivities = false; 12568 12569 // Examine all activities if not already foreground. 12570 if (!foregroundActivities && activitiesSize > 0) { 12571 for (int j = 0; j < activitiesSize; j++) { 12572 final ActivityRecord r = app.activities.get(j); 12573 if (r.visible) { 12574 // App has a visible activity; only upgrade adjustment. 12575 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12576 adj = ProcessList.VISIBLE_APP_ADJ; 12577 app.adjType = "visible"; 12578 } 12579 schedGroup = Process.THREAD_GROUP_DEFAULT; 12580 app.hidden = false; 12581 app.hasActivities = true; 12582 foregroundActivities = true; 12583 break; 12584 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 12585 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12586 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12587 app.adjType = "pausing"; 12588 } 12589 app.hidden = false; 12590 foregroundActivities = true; 12591 } else if (r.state == ActivityState.STOPPING) { 12592 // We will apply the actual adjustment later, because 12593 // we want to allow this process to immediately go through 12594 // any memory trimming that is in effect. 12595 app.hidden = false; 12596 foregroundActivities = true; 12597 hasStoppingActivities = true; 12598 } 12599 if (r.app == app) { 12600 app.hasActivities = true; 12601 } 12602 } 12603 } 12604 12605 if (adj == hiddenAdj && !app.hasActivities) { 12606 // Whoops, this process is completely empty as far as we know 12607 // at this point. 12608 adj = emptyAdj; 12609 app.empty = true; 12610 app.adjType = "bg-empty"; 12611 } 12612 12613 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12614 if (app.foregroundServices) { 12615 // The user is aware of this app, so make it visible. 12616 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12617 app.hidden = false; 12618 app.adjType = "foreground-service"; 12619 schedGroup = Process.THREAD_GROUP_DEFAULT; 12620 } else if (app.forcingToForeground != null) { 12621 // The user is aware of this app, so make it visible. 12622 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12623 app.hidden = false; 12624 app.adjType = "force-foreground"; 12625 app.adjSource = app.forcingToForeground; 12626 schedGroup = Process.THREAD_GROUP_DEFAULT; 12627 } 12628 } 12629 12630 if (app.foregroundServices) { 12631 interesting = true; 12632 } 12633 12634 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 12635 // We don't want to kill the current heavy-weight process. 12636 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 12637 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12638 app.hidden = false; 12639 app.adjType = "heavy"; 12640 } 12641 12642 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 12643 // This process is hosting what we currently consider to be the 12644 // home app, so we don't want to let it go into the background. 12645 adj = ProcessList.HOME_APP_ADJ; 12646 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12647 app.hidden = false; 12648 app.adjType = "home"; 12649 } 12650 12651 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 12652 && app.activities.size() > 0) { 12653 // This was the previous process that showed UI to the user. 12654 // We want to try to keep it around more aggressively, to give 12655 // a good experience around switching between two apps. 12656 adj = ProcessList.PREVIOUS_APP_ADJ; 12657 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 12658 app.hidden = false; 12659 app.adjType = "previous"; 12660 } 12661 12662 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 12663 + " reason=" + app.adjType); 12664 12665 // By default, we use the computed adjustment. It may be changed if 12666 // there are applications dependent on our services or providers, but 12667 // this gives us a baseline and makes sure we don't get into an 12668 // infinite recursion. 12669 app.adjSeq = mAdjSeq; 12670 app.curRawAdj = app.nonStoppingAdj = adj; 12671 12672 if (mBackupTarget != null && app == mBackupTarget.app) { 12673 // If possible we want to avoid killing apps while they're being backed up 12674 if (adj > ProcessList.BACKUP_APP_ADJ) { 12675 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 12676 adj = ProcessList.BACKUP_APP_ADJ; 12677 app.adjType = "backup"; 12678 app.hidden = false; 12679 } 12680 } 12681 12682 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12683 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12684 final long now = SystemClock.uptimeMillis(); 12685 // This process is more important if the top activity is 12686 // bound to the service. 12687 Iterator<ServiceRecord> jt = app.services.iterator(); 12688 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12689 ServiceRecord s = jt.next(); 12690 if (s.startRequested) { 12691 if (app.hasShownUi && app != mHomeProcess) { 12692 // If this process has shown some UI, let it immediately 12693 // go to the LRU list because it may be pretty heavy with 12694 // UI stuff. We'll tag it with a label just to help 12695 // debug and understand what is going on. 12696 if (adj > ProcessList.SERVICE_ADJ) { 12697 app.adjType = "started-bg-ui-services"; 12698 } 12699 } else { 12700 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12701 // This service has seen some activity within 12702 // recent memory, so we will keep its process ahead 12703 // of the background processes. 12704 if (adj > ProcessList.SERVICE_ADJ) { 12705 adj = ProcessList.SERVICE_ADJ; 12706 app.adjType = "started-services"; 12707 app.hidden = false; 12708 } 12709 } 12710 // If we have let the service slide into the background 12711 // state, still have some text describing what it is doing 12712 // even though the service no longer has an impact. 12713 if (adj > ProcessList.SERVICE_ADJ) { 12714 app.adjType = "started-bg-services"; 12715 } 12716 } 12717 // Don't kill this process because it is doing work; it 12718 // has said it is doing work. 12719 app.keeping = true; 12720 } 12721 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12722 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12723 Iterator<ArrayList<ConnectionRecord>> kt 12724 = s.connections.values().iterator(); 12725 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 12726 ArrayList<ConnectionRecord> clist = kt.next(); 12727 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 12728 // XXX should compute this based on the max of 12729 // all connected clients. 12730 ConnectionRecord cr = clist.get(i); 12731 if (cr.binding.client == app) { 12732 // Binding to ourself is not interesting. 12733 continue; 12734 } 12735 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 12736 ProcessRecord client = cr.binding.client; 12737 int clientAdj = adj; 12738 int myHiddenAdj = hiddenAdj; 12739 if (myHiddenAdj > client.hiddenAdj) { 12740 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 12741 myHiddenAdj = client.hiddenAdj; 12742 } else { 12743 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 12744 } 12745 } 12746 int myEmptyAdj = emptyAdj; 12747 if (myEmptyAdj > client.emptyAdj) { 12748 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) { 12749 myEmptyAdj = client.emptyAdj; 12750 } else { 12751 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ; 12752 } 12753 } 12754 clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12755 myEmptyAdj, TOP_APP, true, doingAll); 12756 String adjType = null; 12757 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 12758 // Not doing bind OOM management, so treat 12759 // this guy more like a started service. 12760 if (app.hasShownUi && app != mHomeProcess) { 12761 // If this process has shown some UI, let it immediately 12762 // go to the LRU list because it may be pretty heavy with 12763 // UI stuff. We'll tag it with a label just to help 12764 // debug and understand what is going on. 12765 if (adj > clientAdj) { 12766 adjType = "bound-bg-ui-services"; 12767 } 12768 app.hidden = false; 12769 clientAdj = adj; 12770 } else { 12771 if (now >= (s.lastActivity 12772 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 12773 // This service has not seen activity within 12774 // recent memory, so allow it to drop to the 12775 // LRU list if there is no other reason to keep 12776 // it around. We'll also tag it with a label just 12777 // to help debug and undertand what is going on. 12778 if (adj > clientAdj) { 12779 adjType = "bound-bg-services"; 12780 } 12781 clientAdj = adj; 12782 } 12783 } 12784 } 12785 if (adj > clientAdj) { 12786 // If this process has recently shown UI, and 12787 // the process that is binding to it is less 12788 // important than being visible, then we don't 12789 // care about the binding as much as we care 12790 // about letting this process get into the LRU 12791 // list to be killed and restarted if needed for 12792 // memory. 12793 if (app.hasShownUi && app != mHomeProcess 12794 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12795 adjType = "bound-bg-ui-services"; 12796 } else { 12797 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 12798 |Context.BIND_IMPORTANT)) != 0) { 12799 adj = clientAdj; 12800 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 12801 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 12802 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12803 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12804 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 12805 adj = clientAdj; 12806 } else { 12807 app.pendingUiClean = true; 12808 if (adj > ProcessList.VISIBLE_APP_ADJ) { 12809 adj = ProcessList.VISIBLE_APP_ADJ; 12810 } 12811 } 12812 if (!client.hidden) { 12813 app.hidden = false; 12814 } 12815 if (client.keeping) { 12816 app.keeping = true; 12817 } 12818 adjType = "service"; 12819 } 12820 } 12821 if (adjType != null) { 12822 app.adjType = adjType; 12823 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12824 .REASON_SERVICE_IN_USE; 12825 app.adjSource = cr.binding.client; 12826 app.adjSourceOom = clientAdj; 12827 app.adjTarget = s.name; 12828 } 12829 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12830 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12831 schedGroup = Process.THREAD_GROUP_DEFAULT; 12832 } 12833 } 12834 } 12835 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 12836 ActivityRecord a = cr.activity; 12837 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 12838 (a.visible || a.state == ActivityState.RESUMED 12839 || a.state == ActivityState.PAUSING)) { 12840 adj = ProcessList.FOREGROUND_APP_ADJ; 12841 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 12842 schedGroup = Process.THREAD_GROUP_DEFAULT; 12843 } 12844 app.hidden = false; 12845 app.adjType = "service"; 12846 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12847 .REASON_SERVICE_IN_USE; 12848 app.adjSource = a; 12849 app.adjSourceOom = adj; 12850 app.adjTarget = s.name; 12851 } 12852 } 12853 } 12854 } 12855 } 12856 } 12857 12858 // Finally, if this process has active services running in it, we 12859 // would like to avoid killing it unless it would prevent the current 12860 // application from running. By default we put the process in 12861 // with the rest of the background processes; as we scan through 12862 // its services we may bump it up from there. 12863 if (adj > hiddenAdj) { 12864 adj = hiddenAdj; 12865 app.hidden = false; 12866 app.adjType = "bg-services"; 12867 } 12868 } 12869 12870 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12871 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12872 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 12873 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 12874 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 12875 ContentProviderRecord cpr = jt.next(); 12876 for (int i = cpr.connections.size()-1; 12877 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 12878 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 12879 i--) { 12880 ContentProviderConnection conn = cpr.connections.get(i); 12881 ProcessRecord client = conn.client; 12882 if (client == app) { 12883 // Being our own client is not interesting. 12884 continue; 12885 } 12886 int myHiddenAdj = hiddenAdj; 12887 if (myHiddenAdj > client.hiddenAdj) { 12888 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 12889 myHiddenAdj = client.hiddenAdj; 12890 } else { 12891 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 12892 } 12893 } 12894 int myEmptyAdj = emptyAdj; 12895 if (myEmptyAdj > client.emptyAdj) { 12896 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) { 12897 myEmptyAdj = client.emptyAdj; 12898 } else { 12899 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ; 12900 } 12901 } 12902 int clientAdj = computeOomAdjLocked(client, myHiddenAdj, 12903 myEmptyAdj, TOP_APP, true, doingAll); 12904 if (adj > clientAdj) { 12905 if (app.hasShownUi && app != mHomeProcess 12906 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12907 app.adjType = "bg-ui-provider"; 12908 } else { 12909 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 12910 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 12911 app.adjType = "provider"; 12912 } 12913 if (!client.hidden) { 12914 app.hidden = false; 12915 } 12916 if (client.keeping) { 12917 app.keeping = true; 12918 } 12919 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 12920 .REASON_PROVIDER_IN_USE; 12921 app.adjSource = client; 12922 app.adjSourceOom = clientAdj; 12923 app.adjTarget = cpr.name; 12924 } 12925 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 12926 schedGroup = Process.THREAD_GROUP_DEFAULT; 12927 } 12928 } 12929 // If the provider has external (non-framework) process 12930 // dependencies, ensure that its adjustment is at least 12931 // FOREGROUND_APP_ADJ. 12932 if (cpr.hasExternalProcessHandles()) { 12933 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 12934 adj = ProcessList.FOREGROUND_APP_ADJ; 12935 schedGroup = Process.THREAD_GROUP_DEFAULT; 12936 app.hidden = false; 12937 app.keeping = true; 12938 app.adjType = "provider"; 12939 app.adjTarget = cpr.name; 12940 } 12941 } 12942 } 12943 } 12944 12945 if (adj == ProcessList.SERVICE_ADJ) { 12946 if (doingAll) { 12947 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 12948 mNewNumServiceProcs++; 12949 } 12950 if (app.serviceb) { 12951 adj = ProcessList.SERVICE_B_ADJ; 12952 } 12953 } else { 12954 app.serviceb = false; 12955 } 12956 12957 app.nonStoppingAdj = adj; 12958 12959 if (hasStoppingActivities) { 12960 // Only upgrade adjustment. 12961 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 12962 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12963 app.adjType = "stopping"; 12964 } 12965 } 12966 12967 app.curRawAdj = adj; 12968 12969 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12970 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12971 if (adj > app.maxAdj) { 12972 adj = app.maxAdj; 12973 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 12974 schedGroup = Process.THREAD_GROUP_DEFAULT; 12975 } 12976 } 12977 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12978 app.keeping = true; 12979 } 12980 12981 if (app.hasAboveClient) { 12982 // If this process has bound to any services with BIND_ABOVE_CLIENT, 12983 // then we need to drop its adjustment to be lower than the service's 12984 // in order to honor the request. We want to drop it by one adjustment 12985 // level... but there is special meaning applied to various levels so 12986 // we will skip some of them. 12987 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 12988 // System process will not get dropped, ever 12989 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 12990 adj = ProcessList.VISIBLE_APP_ADJ; 12991 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 12992 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 12993 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 12994 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 12995 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 12996 adj++; 12997 } 12998 } 12999 13000 int importance = app.memImportance; 13001 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 13002 app.curAdj = adj; 13003 app.curSchedGroup = schedGroup; 13004 if (!interesting) { 13005 // For this reporting, if there is not something explicitly 13006 // interesting in this process then we will push it to the 13007 // background importance. 13008 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13009 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13010 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13011 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 13012 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13013 } else if (adj >= ProcessList.HOME_APP_ADJ) { 13014 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 13015 } else if (adj >= ProcessList.SERVICE_ADJ) { 13016 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 13017 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13018 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 13019 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 13020 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 13021 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 13022 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 13023 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 13024 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 13025 } else { 13026 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 13027 } 13028 } 13029 13030 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 13031 if (foregroundActivities != app.foregroundActivities) { 13032 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 13033 } 13034 if (changes != 0) { 13035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 13036 app.memImportance = importance; 13037 app.foregroundActivities = foregroundActivities; 13038 int i = mPendingProcessChanges.size()-1; 13039 ProcessChangeItem item = null; 13040 while (i >= 0) { 13041 item = mPendingProcessChanges.get(i); 13042 if (item.pid == app.pid) { 13043 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 13044 break; 13045 } 13046 i--; 13047 } 13048 if (i < 0) { 13049 // No existing item in pending changes; need a new one. 13050 final int NA = mAvailProcessChanges.size(); 13051 if (NA > 0) { 13052 item = mAvailProcessChanges.remove(NA-1); 13053 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 13054 } else { 13055 item = new ProcessChangeItem(); 13056 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 13057 } 13058 item.changes = 0; 13059 item.pid = app.pid; 13060 item.uid = app.info.uid; 13061 if (mPendingProcessChanges.size() == 0) { 13062 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 13063 "*** Enqueueing dispatch processes changed!"); 13064 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 13065 } 13066 mPendingProcessChanges.add(item); 13067 } 13068 item.changes |= changes; 13069 item.importance = importance; 13070 item.foregroundActivities = foregroundActivities; 13071 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 13072 + Integer.toHexString(System.identityHashCode(item)) 13073 + " " + app.toShortString() + ": changes=" + item.changes 13074 + " importance=" + item.importance 13075 + " foreground=" + item.foregroundActivities 13076 + " type=" + app.adjType + " source=" + app.adjSource 13077 + " target=" + app.adjTarget); 13078 } 13079 13080 return app.curRawAdj; 13081 } 13082 13083 /** 13084 * Ask a given process to GC right now. 13085 */ 13086 final void performAppGcLocked(ProcessRecord app) { 13087 try { 13088 app.lastRequestedGc = SystemClock.uptimeMillis(); 13089 if (app.thread != null) { 13090 if (app.reportLowMemory) { 13091 app.reportLowMemory = false; 13092 app.thread.scheduleLowMemory(); 13093 } else { 13094 app.thread.processInBackground(); 13095 } 13096 } 13097 } catch (Exception e) { 13098 // whatever. 13099 } 13100 } 13101 13102 /** 13103 * Returns true if things are idle enough to perform GCs. 13104 */ 13105 private final boolean canGcNowLocked() { 13106 boolean processingBroadcasts = false; 13107 for (BroadcastQueue q : mBroadcastQueues) { 13108 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 13109 processingBroadcasts = true; 13110 } 13111 } 13112 return !processingBroadcasts 13113 && (mSleeping || (mMainStack.mResumedActivity != null && 13114 mMainStack.mResumedActivity.idle)); 13115 } 13116 13117 /** 13118 * Perform GCs on all processes that are waiting for it, but only 13119 * if things are idle. 13120 */ 13121 final void performAppGcsLocked() { 13122 final int N = mProcessesToGc.size(); 13123 if (N <= 0) { 13124 return; 13125 } 13126 if (canGcNowLocked()) { 13127 while (mProcessesToGc.size() > 0) { 13128 ProcessRecord proc = mProcessesToGc.remove(0); 13129 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 13130 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13131 <= SystemClock.uptimeMillis()) { 13132 // To avoid spamming the system, we will GC processes one 13133 // at a time, waiting a few seconds between each. 13134 performAppGcLocked(proc); 13135 scheduleAppGcsLocked(); 13136 return; 13137 } else { 13138 // It hasn't been long enough since we last GCed this 13139 // process... put it in the list to wait for its time. 13140 addProcessToGcListLocked(proc); 13141 break; 13142 } 13143 } 13144 } 13145 13146 scheduleAppGcsLocked(); 13147 } 13148 } 13149 13150 /** 13151 * If all looks good, perform GCs on all processes waiting for them. 13152 */ 13153 final void performAppGcsIfAppropriateLocked() { 13154 if (canGcNowLocked()) { 13155 performAppGcsLocked(); 13156 return; 13157 } 13158 // Still not idle, wait some more. 13159 scheduleAppGcsLocked(); 13160 } 13161 13162 /** 13163 * Schedule the execution of all pending app GCs. 13164 */ 13165 final void scheduleAppGcsLocked() { 13166 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13167 13168 if (mProcessesToGc.size() > 0) { 13169 // Schedule a GC for the time to the next process. 13170 ProcessRecord proc = mProcessesToGc.get(0); 13171 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13172 13173 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 13174 long now = SystemClock.uptimeMillis(); 13175 if (when < (now+GC_TIMEOUT)) { 13176 when = now + GC_TIMEOUT; 13177 } 13178 mHandler.sendMessageAtTime(msg, when); 13179 } 13180 } 13181 13182 /** 13183 * Add a process to the array of processes waiting to be GCed. Keeps the 13184 * list in sorted order by the last GC time. The process can't already be 13185 * on the list. 13186 */ 13187 final void addProcessToGcListLocked(ProcessRecord proc) { 13188 boolean added = false; 13189 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13190 if (mProcessesToGc.get(i).lastRequestedGc < 13191 proc.lastRequestedGc) { 13192 added = true; 13193 mProcessesToGc.add(i+1, proc); 13194 break; 13195 } 13196 } 13197 if (!added) { 13198 mProcessesToGc.add(0, proc); 13199 } 13200 } 13201 13202 /** 13203 * Set up to ask a process to GC itself. This will either do it 13204 * immediately, or put it on the list of processes to gc the next 13205 * time things are idle. 13206 */ 13207 final void scheduleAppGcLocked(ProcessRecord app) { 13208 long now = SystemClock.uptimeMillis(); 13209 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13210 return; 13211 } 13212 if (!mProcessesToGc.contains(app)) { 13213 addProcessToGcListLocked(app); 13214 scheduleAppGcsLocked(); 13215 } 13216 } 13217 13218 final void checkExcessivePowerUsageLocked(boolean doKills) { 13219 updateCpuStatsNow(); 13220 13221 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13222 boolean doWakeKills = doKills; 13223 boolean doCpuKills = doKills; 13224 if (mLastPowerCheckRealtime == 0) { 13225 doWakeKills = false; 13226 } 13227 if (mLastPowerCheckUptime == 0) { 13228 doCpuKills = false; 13229 } 13230 if (stats.isScreenOn()) { 13231 doWakeKills = false; 13232 } 13233 final long curRealtime = SystemClock.elapsedRealtime(); 13234 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 13235 final long curUptime = SystemClock.uptimeMillis(); 13236 final long uptimeSince = curUptime - mLastPowerCheckUptime; 13237 mLastPowerCheckRealtime = curRealtime; 13238 mLastPowerCheckUptime = curUptime; 13239 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 13240 doWakeKills = false; 13241 } 13242 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 13243 doCpuKills = false; 13244 } 13245 int i = mLruProcesses.size(); 13246 while (i > 0) { 13247 i--; 13248 ProcessRecord app = mLruProcesses.get(i); 13249 if (!app.keeping) { 13250 long wtime; 13251 synchronized (stats) { 13252 wtime = stats.getProcessWakeTime(app.info.uid, 13253 app.pid, curRealtime); 13254 } 13255 long wtimeUsed = wtime - app.lastWakeTime; 13256 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 13257 if (DEBUG_POWER) { 13258 StringBuilder sb = new StringBuilder(128); 13259 sb.append("Wake for "); 13260 app.toShortString(sb); 13261 sb.append(": over "); 13262 TimeUtils.formatDuration(realtimeSince, sb); 13263 sb.append(" used "); 13264 TimeUtils.formatDuration(wtimeUsed, sb); 13265 sb.append(" ("); 13266 sb.append((wtimeUsed*100)/realtimeSince); 13267 sb.append("%)"); 13268 Slog.i(TAG, sb.toString()); 13269 sb.setLength(0); 13270 sb.append("CPU for "); 13271 app.toShortString(sb); 13272 sb.append(": over "); 13273 TimeUtils.formatDuration(uptimeSince, sb); 13274 sb.append(" used "); 13275 TimeUtils.formatDuration(cputimeUsed, sb); 13276 sb.append(" ("); 13277 sb.append((cputimeUsed*100)/uptimeSince); 13278 sb.append("%)"); 13279 Slog.i(TAG, sb.toString()); 13280 } 13281 // If a process has held a wake lock for more 13282 // than 50% of the time during this period, 13283 // that sounds bad. Kill! 13284 if (doWakeKills && realtimeSince > 0 13285 && ((wtimeUsed*100)/realtimeSince) >= 50) { 13286 synchronized (stats) { 13287 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 13288 realtimeSince, wtimeUsed); 13289 } 13290 Slog.w(TAG, "Excessive wake lock in " + app.processName 13291 + " (pid " + app.pid + "): held " + wtimeUsed 13292 + " during " + realtimeSince); 13293 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13294 app.processName, app.setAdj, "excessive wake lock"); 13295 Process.killProcessQuiet(app.pid); 13296 } else if (doCpuKills && uptimeSince > 0 13297 && ((cputimeUsed*100)/uptimeSince) >= 50) { 13298 synchronized (stats) { 13299 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 13300 uptimeSince, cputimeUsed); 13301 } 13302 Slog.w(TAG, "Excessive CPU in " + app.processName 13303 + " (pid " + app.pid + "): used " + cputimeUsed 13304 + " during " + uptimeSince); 13305 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13306 app.processName, app.setAdj, "excessive cpu"); 13307 Process.killProcessQuiet(app.pid); 13308 } else { 13309 app.lastWakeTime = wtime; 13310 app.lastCpuTime = app.curCpuTime; 13311 } 13312 } 13313 } 13314 } 13315 13316 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, 13317 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) { 13318 app.hiddenAdj = hiddenAdj; 13319 app.emptyAdj = emptyAdj; 13320 13321 if (app.thread == null) { 13322 return false; 13323 } 13324 13325 final boolean wasKeeping = app.keeping; 13326 13327 boolean success = true; 13328 13329 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll); 13330 13331 if (app.curRawAdj != app.setRawAdj) { 13332 if (wasKeeping && !app.keeping) { 13333 // This app is no longer something we want to keep. Note 13334 // its current wake lock time to later know to kill it if 13335 // it is not behaving well. 13336 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13337 synchronized (stats) { 13338 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 13339 app.pid, SystemClock.elapsedRealtime()); 13340 } 13341 app.lastCpuTime = app.curCpuTime; 13342 } 13343 13344 app.setRawAdj = app.curRawAdj; 13345 } 13346 13347 if (app.curAdj != app.setAdj) { 13348 if (Process.setOomAdj(app.pid, app.curAdj)) { 13349 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 13350 TAG, "Set " + app.pid + " " + app.processName + 13351 " adj " + app.curAdj + ": " + app.adjType); 13352 app.setAdj = app.curAdj; 13353 } else { 13354 success = false; 13355 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 13356 } 13357 } 13358 if (app.setSchedGroup != app.curSchedGroup) { 13359 app.setSchedGroup = app.curSchedGroup; 13360 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 13361 "Setting process group of " + app.processName 13362 + " to " + app.curSchedGroup); 13363 if (app.waitingToKill != null && 13364 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 13365 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 13366 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13367 app.processName, app.setAdj, app.waitingToKill); 13368 app.killedBackground = true; 13369 Process.killProcessQuiet(app.pid); 13370 success = false; 13371 } else { 13372 if (true) { 13373 long oldId = Binder.clearCallingIdentity(); 13374 try { 13375 Process.setProcessGroup(app.pid, app.curSchedGroup); 13376 } catch (Exception e) { 13377 Slog.w(TAG, "Failed setting process group of " + app.pid 13378 + " to " + app.curSchedGroup); 13379 e.printStackTrace(); 13380 } finally { 13381 Binder.restoreCallingIdentity(oldId); 13382 } 13383 } else { 13384 if (app.thread != null) { 13385 try { 13386 app.thread.setSchedulingGroup(app.curSchedGroup); 13387 } catch (RemoteException e) { 13388 } 13389 } 13390 } 13391 } 13392 } 13393 return success; 13394 } 13395 13396 private final ActivityRecord resumedAppLocked() { 13397 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 13398 if (resumedActivity == null || resumedActivity.app == null) { 13399 resumedActivity = mMainStack.mPausingActivity; 13400 if (resumedActivity == null || resumedActivity.app == null) { 13401 resumedActivity = mMainStack.topRunningActivityLocked(null); 13402 } 13403 } 13404 return resumedActivity; 13405 } 13406 13407 final boolean updateOomAdjLocked(ProcessRecord app) { 13408 final ActivityRecord TOP_ACT = resumedAppLocked(); 13409 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13410 int curAdj = app.curAdj; 13411 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13412 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13413 13414 mAdjSeq++; 13415 13416 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj, 13417 TOP_APP, false); 13418 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 13419 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 13420 if (nowHidden != wasHidden) { 13421 // Changed to/from hidden state, so apps after it in the LRU 13422 // list may also be changed. 13423 updateOomAdjLocked(); 13424 } 13425 return success; 13426 } 13427 13428 final void updateOomAdjLocked() { 13429 final ActivityRecord TOP_ACT = resumedAppLocked(); 13430 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13431 13432 if (false) { 13433 RuntimeException e = new RuntimeException(); 13434 e.fillInStackTrace(); 13435 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13436 } 13437 13438 mAdjSeq++; 13439 mNewNumServiceProcs = 0; 13440 13441 // Let's determine how many processes we have running vs. 13442 // how many slots we have for background processes; we may want 13443 // to put multiple processes in a slot of there are enough of 13444 // them. 13445 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ 13446 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2; 13447 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots; 13448 if (emptyFactor < 1) emptyFactor = 1; 13449 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots; 13450 if (hiddenFactor < 1) hiddenFactor = 1; 13451 int stepHidden = 0; 13452 int stepEmpty = 0; 13453 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13454 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit; 13455 int numHidden = 0; 13456 int numEmpty = 0; 13457 int numTrimming = 0; 13458 13459 mNumNonHiddenProcs = 0; 13460 mNumHiddenProcs = 0; 13461 13462 // First update the OOM adjustment for each of the 13463 // application processes based on their current state. 13464 int i = mLruProcesses.size(); 13465 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13466 int nextHiddenAdj = curHiddenAdj+1; 13467 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 13468 int nextEmptyAdj = curEmptyAdj+2; 13469 while (i > 0) { 13470 i--; 13471 ProcessRecord app = mLruProcesses.get(i); 13472 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13473 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true); 13474 if (!app.killedBackground) { 13475 if (app.curRawAdj == curHiddenAdj && app.hasActivities) { 13476 // This process was assigned as a hidden process... step the 13477 // hidden level. 13478 mNumHiddenProcs++; 13479 if (curHiddenAdj != nextHiddenAdj) { 13480 stepHidden++; 13481 if (stepHidden >= hiddenFactor) { 13482 stepHidden = 0; 13483 curHiddenAdj = nextHiddenAdj; 13484 nextHiddenAdj += 2; 13485 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13486 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13487 } 13488 } 13489 } 13490 numHidden++; 13491 if (numHidden > hiddenProcessLimit) { 13492 Slog.i(TAG, "No longer want " + app.processName 13493 + " (pid " + app.pid + "): hidden #" + numHidden); 13494 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13495 app.processName, app.setAdj, "too many background"); 13496 app.killedBackground = true; 13497 Process.killProcessQuiet(app.pid); 13498 } 13499 } else { 13500 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) { 13501 // This process was assigned as an empty process... step the 13502 // empty level. 13503 if (curEmptyAdj != nextEmptyAdj) { 13504 stepEmpty++; 13505 if (stepEmpty >= emptyFactor) { 13506 stepEmpty = 0; 13507 curEmptyAdj = nextEmptyAdj; 13508 nextEmptyAdj += 2; 13509 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) { 13510 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ; 13511 } 13512 } 13513 } 13514 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { 13515 mNumNonHiddenProcs++; 13516 } 13517 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 13518 numEmpty++; 13519 if (numEmpty > emptyProcessLimit) { 13520 Slog.i(TAG, "No longer want " + app.processName 13521 + " (pid " + app.pid + "): empty #" + numEmpty); 13522 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13523 app.processName, app.setAdj, "too many background"); 13524 app.killedBackground = true; 13525 Process.killProcessQuiet(app.pid); 13526 } 13527 } 13528 } 13529 if (app.isolated && app.services.size() <= 0) { 13530 // If this is an isolated process, and there are no 13531 // services running in it, then the process is no longer 13532 // needed. We agressively kill these because we can by 13533 // definition not re-use the same process again, and it is 13534 // good to avoid having whatever code was running in them 13535 // left sitting around after no longer needed. 13536 Slog.i(TAG, "Isolated process " + app.processName 13537 + " (pid " + app.pid + ") no longer needed"); 13538 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13539 app.processName, app.setAdj, "isolated not needed"); 13540 app.killedBackground = true; 13541 Process.killProcessQuiet(app.pid); 13542 } 13543 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13544 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13545 && !app.killedBackground) { 13546 numTrimming++; 13547 } 13548 } 13549 } 13550 13551 mNumServiceProcs = mNewNumServiceProcs; 13552 13553 // Now determine the memory trimming level of background processes. 13554 // Unfortunately we need to start at the back of the list to do this 13555 // properly. We only do this if the number of background apps we 13556 // are managing to keep around is less than half the maximum we desire; 13557 // if we are keeping a good number around, we'll let them use whatever 13558 // memory they want. 13559 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4) 13560 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) { 13561 final int numHiddenAndEmpty = numHidden + numEmpty; 13562 final int N = mLruProcesses.size(); 13563 int factor = numTrimming/3; 13564 int minFactor = 2; 13565 if (mHomeProcess != null) minFactor++; 13566 if (mPreviousProcess != null) minFactor++; 13567 if (factor < minFactor) factor = minFactor; 13568 int step = 0; 13569 int fgTrimLevel; 13570 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) { 13571 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 13572 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) { 13573 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 13574 } else { 13575 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 13576 } 13577 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 13578 for (i=0; i<N; i++) { 13579 ProcessRecord app = mLruProcesses.get(i); 13580 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 13581 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 13582 && !app.killedBackground) { 13583 if (app.trimMemoryLevel < curLevel && app.thread != null) { 13584 try { 13585 app.thread.scheduleTrimMemory(curLevel); 13586 } catch (RemoteException e) { 13587 } 13588 if (false) { 13589 // For now we won't do this; our memory trimming seems 13590 // to be good enough at this point that destroying 13591 // activities causes more harm than good. 13592 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 13593 && app != mHomeProcess && app != mPreviousProcess) { 13594 // Need to do this on its own message because the stack may not 13595 // be in a consistent state at this point. 13596 // For these apps we will also finish their activities 13597 // to help them free memory. 13598 mMainStack.scheduleDestroyActivities(app, false, "trim"); 13599 } 13600 } 13601 } 13602 app.trimMemoryLevel = curLevel; 13603 step++; 13604 if (step >= factor) { 13605 step = 0; 13606 switch (curLevel) { 13607 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 13608 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 13609 break; 13610 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 13611 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13612 break; 13613 } 13614 } 13615 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 13616 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 13617 && app.thread != null) { 13618 try { 13619 app.thread.scheduleTrimMemory( 13620 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 13621 } catch (RemoteException e) { 13622 } 13623 } 13624 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 13625 } else { 13626 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13627 && app.pendingUiClean) { 13628 // If this application is now in the background and it 13629 // had done UI, then give it the special trim level to 13630 // have it free UI resources. 13631 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 13632 if (app.trimMemoryLevel < level && app.thread != null) { 13633 try { 13634 app.thread.scheduleTrimMemory(level); 13635 } catch (RemoteException e) { 13636 } 13637 } 13638 app.pendingUiClean = false; 13639 } 13640 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 13641 try { 13642 app.thread.scheduleTrimMemory(fgTrimLevel); 13643 } catch (RemoteException e) { 13644 } 13645 } 13646 app.trimMemoryLevel = fgTrimLevel; 13647 } 13648 } 13649 } else { 13650 final int N = mLruProcesses.size(); 13651 for (i=0; i<N; i++) { 13652 ProcessRecord app = mLruProcesses.get(i); 13653 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 13654 && app.pendingUiClean) { 13655 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 13656 && app.thread != null) { 13657 try { 13658 app.thread.scheduleTrimMemory( 13659 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 13660 } catch (RemoteException e) { 13661 } 13662 } 13663 app.pendingUiClean = false; 13664 } 13665 app.trimMemoryLevel = 0; 13666 } 13667 } 13668 13669 if (mAlwaysFinishActivities) { 13670 // Need to do this on its own message because the stack may not 13671 // be in a consistent state at this point. 13672 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 13673 } 13674 } 13675 13676 final void trimApplications() { 13677 synchronized (this) { 13678 int i; 13679 13680 // First remove any unused application processes whose package 13681 // has been removed. 13682 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13683 final ProcessRecord app = mRemovedProcesses.get(i); 13684 if (app.activities.size() == 0 13685 && app.curReceiver == null && app.services.size() == 0) { 13686 Slog.i( 13687 TAG, "Exiting empty application process " 13688 + app.processName + " (" 13689 + (app.thread != null ? app.thread.asBinder() : null) 13690 + ")\n"); 13691 if (app.pid > 0 && app.pid != MY_PID) { 13692 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 13693 app.processName, app.setAdj, "empty"); 13694 Process.killProcessQuiet(app.pid); 13695 } else { 13696 try { 13697 app.thread.scheduleExit(); 13698 } catch (Exception e) { 13699 // Ignore exceptions. 13700 } 13701 } 13702 cleanUpApplicationRecordLocked(app, false, true, -1); 13703 mRemovedProcesses.remove(i); 13704 13705 if (app.persistent) { 13706 if (app.persistent) { 13707 addAppLocked(app.info, false); 13708 } 13709 } 13710 } 13711 } 13712 13713 // Now update the oom adj for all processes. 13714 updateOomAdjLocked(); 13715 } 13716 } 13717 13718 /** This method sends the specified signal to each of the persistent apps */ 13719 public void signalPersistentProcesses(int sig) throws RemoteException { 13720 if (sig != Process.SIGNAL_USR1) { 13721 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13722 } 13723 13724 synchronized (this) { 13725 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13726 != PackageManager.PERMISSION_GRANTED) { 13727 throw new SecurityException("Requires permission " 13728 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13729 } 13730 13731 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13732 ProcessRecord r = mLruProcesses.get(i); 13733 if (r.thread != null && r.persistent) { 13734 Process.sendSignal(r.pid, sig); 13735 } 13736 } 13737 } 13738 } 13739 13740 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 13741 if (proc == null || proc == mProfileProc) { 13742 proc = mProfileProc; 13743 path = mProfileFile; 13744 profileType = mProfileType; 13745 clearProfilerLocked(); 13746 } 13747 if (proc == null) { 13748 return; 13749 } 13750 try { 13751 proc.thread.profilerControl(false, path, null, profileType); 13752 } catch (RemoteException e) { 13753 throw new IllegalStateException("Process disappeared"); 13754 } 13755 } 13756 13757 private void clearProfilerLocked() { 13758 if (mProfileFd != null) { 13759 try { 13760 mProfileFd.close(); 13761 } catch (IOException e) { 13762 } 13763 } 13764 mProfileApp = null; 13765 mProfileProc = null; 13766 mProfileFile = null; 13767 mProfileType = 0; 13768 mAutoStopProfiler = false; 13769 } 13770 13771 public boolean profileControl(String process, int userId, boolean start, 13772 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 13773 13774 try { 13775 synchronized (this) { 13776 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13777 // its own permission. 13778 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13779 != PackageManager.PERMISSION_GRANTED) { 13780 throw new SecurityException("Requires permission " 13781 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13782 } 13783 13784 if (start && fd == null) { 13785 throw new IllegalArgumentException("null fd"); 13786 } 13787 13788 ProcessRecord proc = null; 13789 if (process != null) { 13790 proc = findProcessLocked(process, userId, "profileControl"); 13791 } 13792 13793 if (start && (proc == null || proc.thread == null)) { 13794 throw new IllegalArgumentException("Unknown process: " + process); 13795 } 13796 13797 if (start) { 13798 stopProfilerLocked(null, null, 0); 13799 setProfileApp(proc.info, proc.processName, path, fd, false); 13800 mProfileProc = proc; 13801 mProfileType = profileType; 13802 try { 13803 fd = fd.dup(); 13804 } catch (IOException e) { 13805 fd = null; 13806 } 13807 proc.thread.profilerControl(start, path, fd, profileType); 13808 fd = null; 13809 mProfileFd = null; 13810 } else { 13811 stopProfilerLocked(proc, path, profileType); 13812 if (fd != null) { 13813 try { 13814 fd.close(); 13815 } catch (IOException e) { 13816 } 13817 } 13818 } 13819 13820 return true; 13821 } 13822 } catch (RemoteException e) { 13823 throw new IllegalStateException("Process disappeared"); 13824 } finally { 13825 if (fd != null) { 13826 try { 13827 fd.close(); 13828 } catch (IOException e) { 13829 } 13830 } 13831 } 13832 } 13833 13834 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 13835 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), 13836 userId, true, true, callName, null); 13837 ProcessRecord proc = null; 13838 try { 13839 int pid = Integer.parseInt(process); 13840 synchronized (mPidsSelfLocked) { 13841 proc = mPidsSelfLocked.get(pid); 13842 } 13843 } catch (NumberFormatException e) { 13844 } 13845 13846 if (proc == null) { 13847 HashMap<String, SparseArray<ProcessRecord>> all 13848 = mProcessNames.getMap(); 13849 SparseArray<ProcessRecord> procs = all.get(process); 13850 if (procs != null && procs.size() > 0) { 13851 proc = procs.valueAt(0); 13852 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 13853 for (int i=1; i<procs.size(); i++) { 13854 ProcessRecord thisProc = procs.valueAt(i); 13855 if (thisProc.userId == userId) { 13856 proc = thisProc; 13857 break; 13858 } 13859 } 13860 } 13861 } 13862 } 13863 13864 return proc; 13865 } 13866 13867 public boolean dumpHeap(String process, int userId, boolean managed, 13868 String path, ParcelFileDescriptor fd) throws RemoteException { 13869 13870 try { 13871 synchronized (this) { 13872 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13873 // its own permission (same as profileControl). 13874 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13875 != PackageManager.PERMISSION_GRANTED) { 13876 throw new SecurityException("Requires permission " 13877 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13878 } 13879 13880 if (fd == null) { 13881 throw new IllegalArgumentException("null fd"); 13882 } 13883 13884 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 13885 if (proc == null || proc.thread == null) { 13886 throw new IllegalArgumentException("Unknown process: " + process); 13887 } 13888 13889 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13890 if (!isDebuggable) { 13891 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13892 throw new SecurityException("Process not debuggable: " + proc); 13893 } 13894 } 13895 13896 proc.thread.dumpHeap(managed, path, fd); 13897 fd = null; 13898 return true; 13899 } 13900 } catch (RemoteException e) { 13901 throw new IllegalStateException("Process disappeared"); 13902 } finally { 13903 if (fd != null) { 13904 try { 13905 fd.close(); 13906 } catch (IOException e) { 13907 } 13908 } 13909 } 13910 } 13911 13912 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13913 public void monitor() { 13914 synchronized (this) { } 13915 } 13916 13917 void onCoreSettingsChange(Bundle settings) { 13918 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 13919 ProcessRecord processRecord = mLruProcesses.get(i); 13920 try { 13921 if (processRecord.thread != null) { 13922 processRecord.thread.setCoreSettings(settings); 13923 } 13924 } catch (RemoteException re) { 13925 /* ignore */ 13926 } 13927 } 13928 } 13929 13930 // Multi-user methods 13931 13932 @Override 13933 public boolean switchUser(int userId) { 13934 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 13935 != PackageManager.PERMISSION_GRANTED) { 13936 String msg = "Permission Denial: switchUser() from pid=" 13937 + Binder.getCallingPid() 13938 + ", uid=" + Binder.getCallingUid() 13939 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 13940 Slog.w(TAG, msg); 13941 throw new SecurityException(msg); 13942 } 13943 13944 final long ident = Binder.clearCallingIdentity(); 13945 try { 13946 synchronized (this) { 13947 final int oldUserId = mCurrentUserId; 13948 if (oldUserId == userId) { 13949 return true; 13950 } 13951 13952 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 13953 if (userInfo == null) { 13954 Slog.w(TAG, "No user info for user #" + userId); 13955 return false; 13956 } 13957 13958 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 13959 R.anim.screen_user_enter); 13960 13961 // If the user we are switching to is not currently started, then 13962 // we need to start it now. 13963 if (mStartedUsers.get(userId) == null) { 13964 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 13965 } 13966 13967 mCurrentUserId = userId; 13968 final Integer userIdInt = Integer.valueOf(userId); 13969 mUserLru.remove(userIdInt); 13970 mUserLru.add(userIdInt); 13971 13972 mWindowManager.setCurrentUser(userId); 13973 13974 final UserStartedState uss = mStartedUsers.get(userId); 13975 13976 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 13977 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 13978 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 13979 oldUserId, userId, uss)); 13980 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 13981 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 13982 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 13983 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13984 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 13985 broadcastIntentLocked(null, null, intent, 13986 null, null, 0, null, null, null, 13987 false, false, MY_PID, Process.SYSTEM_UID, userId); 13988 13989 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 13990 if (userId != 0) { 13991 intent = new Intent(Intent.ACTION_USER_INITIALIZE); 13992 broadcastIntentLocked(null, null, intent, null, 13993 new IIntentReceiver.Stub() { 13994 public void performReceive(Intent intent, int resultCode, 13995 String data, Bundle extras, boolean ordered, 13996 boolean sticky, int sendingUser) { 13997 synchronized (ActivityManagerService.this) { 13998 getUserManagerLocked().makeInitialized(userInfo.id); 13999 } 14000 } 14001 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 14002 userId); 14003 } else { 14004 getUserManagerLocked().makeInitialized(userInfo.id); 14005 } 14006 } 14007 14008 boolean haveActivities = mMainStack.switchUserLocked(userId, uss); 14009 if (!haveActivities) { 14010 startHomeActivityLocked(userId); 14011 } 14012 14013 sendUserSwitchBroadcastsLocked(oldUserId, userId); 14014 } 14015 } finally { 14016 Binder.restoreCallingIdentity(ident); 14017 } 14018 14019 return true; 14020 } 14021 14022 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 14023 long ident = Binder.clearCallingIdentity(); 14024 try { 14025 Intent intent; 14026 if (oldUserId >= 0) { 14027 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 14028 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14029 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 14030 broadcastIntentLocked(null, null, intent, 14031 null, null, 0, null, null, null, 14032 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 14033 } 14034 if (newUserId >= 0) { 14035 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 14036 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14037 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14038 broadcastIntentLocked(null, null, intent, 14039 null, null, 0, null, null, null, 14040 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 14041 intent = new Intent(Intent.ACTION_USER_SWITCHED); 14042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14043 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 14044 broadcastIntentLocked(null, null, intent, 14045 null, null, 0, null, null, 14046 android.Manifest.permission.MANAGE_USERS, 14047 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14048 } 14049 } finally { 14050 Binder.restoreCallingIdentity(ident); 14051 } 14052 } 14053 14054 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 14055 final int newUserId) { 14056 final int N = mUserSwitchObservers.beginBroadcast(); 14057 if (N > 0) { 14058 final IRemoteCallback callback = new IRemoteCallback.Stub() { 14059 int mCount = 0; 14060 @Override 14061 public void sendResult(Bundle data) throws RemoteException { 14062 synchronized (ActivityManagerService.this) { 14063 if (mCurUserSwitchCallback == this) { 14064 mCount++; 14065 if (mCount == N) { 14066 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14067 } 14068 } 14069 } 14070 } 14071 }; 14072 synchronized (this) { 14073 mCurUserSwitchCallback = callback; 14074 } 14075 for (int i=0; i<N; i++) { 14076 try { 14077 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 14078 newUserId, callback); 14079 } catch (RemoteException e) { 14080 } 14081 } 14082 } else { 14083 synchronized (this) { 14084 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14085 } 14086 } 14087 mUserSwitchObservers.finishBroadcast(); 14088 } 14089 14090 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14091 synchronized (this) { 14092 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 14093 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 14094 } 14095 } 14096 14097 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 14098 mCurUserSwitchCallback = null; 14099 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 14100 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 14101 oldUserId, newUserId, uss)); 14102 } 14103 14104 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 14105 final int N = mUserSwitchObservers.beginBroadcast(); 14106 for (int i=0; i<N; i++) { 14107 try { 14108 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 14109 } catch (RemoteException e) { 14110 } 14111 } 14112 mUserSwitchObservers.finishBroadcast(); 14113 synchronized (this) { 14114 mWindowManager.stopFreezingScreen(); 14115 } 14116 } 14117 14118 void finishUserSwitch(UserStartedState uss) { 14119 synchronized (this) { 14120 if (uss.mState == UserStartedState.STATE_BOOTING 14121 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 14122 uss.mState = UserStartedState.STATE_RUNNING; 14123 final int userId = uss.mHandle.getIdentifier(); 14124 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 14125 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 14126 broadcastIntentLocked(null, null, intent, 14127 null, null, 0, null, null, 14128 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 14129 false, false, MY_PID, Process.SYSTEM_UID, userId); 14130 } 14131 int num = mUserLru.size(); 14132 int i = 0; 14133 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 14134 Integer oldUserId = mUserLru.get(i); 14135 UserStartedState oldUss = mStartedUsers.get(oldUserId); 14136 if (oldUss == null) { 14137 // Shouldn't happen, but be sane if it does. 14138 mUserLru.remove(i); 14139 num--; 14140 continue; 14141 } 14142 if (oldUss.mState == UserStartedState.STATE_STOPPING) { 14143 // This user is already stopping, doesn't count. 14144 num--; 14145 i++; 14146 continue; 14147 } 14148 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 14149 // Owner and current can't be stopped, but count as running. 14150 i++; 14151 continue; 14152 } 14153 // This is a user to be stopped. 14154 stopUserLocked(oldUserId, null); 14155 num--; 14156 i++; 14157 } 14158 } 14159 } 14160 14161 @Override 14162 public int stopUser(final int userId, final IStopUserCallback callback) { 14163 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14164 != PackageManager.PERMISSION_GRANTED) { 14165 String msg = "Permission Denial: switchUser() from pid=" 14166 + Binder.getCallingPid() 14167 + ", uid=" + Binder.getCallingUid() 14168 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14169 Slog.w(TAG, msg); 14170 throw new SecurityException(msg); 14171 } 14172 if (userId <= 0) { 14173 throw new IllegalArgumentException("Can't stop primary user " + userId); 14174 } 14175 synchronized (this) { 14176 return stopUserLocked(userId, callback); 14177 } 14178 } 14179 14180 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 14181 if (mCurrentUserId == userId) { 14182 return ActivityManager.USER_OP_IS_CURRENT; 14183 } 14184 14185 final UserStartedState uss = mStartedUsers.get(userId); 14186 if (uss == null) { 14187 // User is not started, nothing to do... but we do need to 14188 // callback if requested. 14189 if (callback != null) { 14190 mHandler.post(new Runnable() { 14191 @Override 14192 public void run() { 14193 try { 14194 callback.userStopped(userId); 14195 } catch (RemoteException e) { 14196 } 14197 } 14198 }); 14199 } 14200 return ActivityManager.USER_OP_SUCCESS; 14201 } 14202 14203 if (callback != null) { 14204 uss.mStopCallbacks.add(callback); 14205 } 14206 14207 if (uss.mState != UserStartedState.STATE_STOPPING) { 14208 uss.mState = UserStartedState.STATE_STOPPING; 14209 14210 long ident = Binder.clearCallingIdentity(); 14211 try { 14212 // Inform of user switch 14213 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 14214 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() { 14215 @Override 14216 public void performReceive(Intent intent, int resultCode, String data, 14217 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 14218 finishUserStop(uss); 14219 } 14220 }; 14221 broadcastIntentLocked(null, null, intent, 14222 null, resultReceiver, 0, null, null, null, 14223 true, false, MY_PID, Process.SYSTEM_UID, userId); 14224 } finally { 14225 Binder.restoreCallingIdentity(ident); 14226 } 14227 } 14228 14229 return ActivityManager.USER_OP_SUCCESS; 14230 } 14231 14232 void finishUserStop(UserStartedState uss) { 14233 final int userId = uss.mHandle.getIdentifier(); 14234 boolean stopped; 14235 ArrayList<IStopUserCallback> callbacks; 14236 synchronized (this) { 14237 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 14238 if (uss.mState != UserStartedState.STATE_STOPPING 14239 || mStartedUsers.get(userId) != uss) { 14240 stopped = false; 14241 } else { 14242 stopped = true; 14243 // User can no longer run. 14244 mStartedUsers.remove(userId); 14245 mUserLru.remove(Integer.valueOf(userId)); 14246 14247 // Clean up all state and processes associated with the user. 14248 // Kill all the processes for the user. 14249 forceStopUserLocked(userId); 14250 } 14251 } 14252 14253 for (int i=0; i<callbacks.size(); i++) { 14254 try { 14255 if (stopped) callbacks.get(i).userStopped(userId); 14256 else callbacks.get(i).userStopAborted(userId); 14257 } catch (RemoteException e) { 14258 } 14259 } 14260 } 14261 14262 @Override 14263 public UserInfo getCurrentUser() { 14264 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14265 != PackageManager.PERMISSION_GRANTED) && ( 14266 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14267 != PackageManager.PERMISSION_GRANTED)) { 14268 String msg = "Permission Denial: getCurrentUser() from pid=" 14269 + Binder.getCallingPid() 14270 + ", uid=" + Binder.getCallingUid() 14271 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14272 Slog.w(TAG, msg); 14273 throw new SecurityException(msg); 14274 } 14275 synchronized (this) { 14276 return getUserManagerLocked().getUserInfo(mCurrentUserId); 14277 } 14278 } 14279 14280 @Override 14281 public boolean isUserRunning(int userId) { 14282 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 14283 != PackageManager.PERMISSION_GRANTED) { 14284 String msg = "Permission Denial: isUserRunning() from pid=" 14285 + Binder.getCallingPid() 14286 + ", uid=" + Binder.getCallingUid() 14287 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 14288 Slog.w(TAG, msg); 14289 throw new SecurityException(msg); 14290 } 14291 synchronized (this) { 14292 return isUserRunningLocked(userId); 14293 } 14294 } 14295 14296 boolean isUserRunningLocked(int userId) { 14297 UserStartedState state = mStartedUsers.get(userId); 14298 return state != null && state.mState != UserStartedState.STATE_STOPPING; 14299 } 14300 14301 @Override 14302 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 14303 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 14304 != PackageManager.PERMISSION_GRANTED) { 14305 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 14306 + Binder.getCallingPid() 14307 + ", uid=" + Binder.getCallingUid() 14308 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 14309 Slog.w(TAG, msg); 14310 throw new SecurityException(msg); 14311 } 14312 14313 mUserSwitchObservers.register(observer); 14314 } 14315 14316 @Override 14317 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 14318 mUserSwitchObservers.unregister(observer); 14319 } 14320 14321 private boolean userExists(int userId) { 14322 if (userId == 0) { 14323 return true; 14324 } 14325 UserManagerService ums = getUserManagerLocked(); 14326 return ums != null ? (ums.getUserInfo(userId) != null) : false; 14327 } 14328 14329 int[] getUsersLocked() { 14330 UserManagerService ums = getUserManagerLocked(); 14331 return ums != null ? ums.getUserIds() : new int[] { 0 }; 14332 } 14333 14334 UserManagerService getUserManagerLocked() { 14335 if (mUserManager == null) { 14336 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 14337 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 14338 } 14339 return mUserManager; 14340 } 14341 14342 private void checkValidCaller(int uid, int userId) { 14343 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 14344 14345 throw new SecurityException("Caller uid=" + uid 14346 + " is not privileged to communicate with user=" + userId); 14347 } 14348 14349 private int applyUserId(int uid, int userId) { 14350 return UserHandle.getUid(userId, uid); 14351 } 14352 14353 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 14354 if (info == null) return null; 14355 ApplicationInfo newInfo = new ApplicationInfo(info); 14356 newInfo.uid = applyUserId(info.uid, userId); 14357 newInfo.dataDir = USER_DATA_DIR + userId + "/" 14358 + info.packageName; 14359 return newInfo; 14360 } 14361 14362 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 14363 if (aInfo == null 14364 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 14365 return aInfo; 14366 } 14367 14368 ActivityInfo info = new ActivityInfo(aInfo); 14369 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 14370 return info; 14371 } 14372} 14373