ActivityManagerService.java revision 4ee364982e783b4a2eac6e05f81d167c6121e110
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.wm.WindowManagerService; 31 32import dalvik.system.Zygote; 33 34import android.app.Activity; 35import android.app.ActivityManager; 36import android.app.ActivityManagerNative; 37import android.app.ActivityOptions; 38import android.app.ActivityThread; 39import android.app.AlertDialog; 40import android.app.AppGlobals; 41import android.app.ApplicationErrorReport; 42import android.app.Dialog; 43import android.app.IActivityController; 44import android.app.IApplicationThread; 45import android.app.IInstrumentationWatcher; 46import android.app.INotificationManager; 47import android.app.IProcessObserver; 48import android.app.IServiceConnection; 49import android.app.IThumbnailReceiver; 50import android.app.Instrumentation; 51import android.app.Notification; 52import android.app.NotificationManager; 53import android.app.PendingIntent; 54import android.app.Service; 55import android.app.backup.IBackupManager; 56import android.content.ActivityNotFoundException; 57import android.content.BroadcastReceiver; 58import android.content.ClipData; 59import android.content.ComponentCallbacks2; 60import android.content.ComponentName; 61import android.content.ContentProvider; 62import android.content.ContentResolver; 63import android.content.Context; 64import android.content.DialogInterface; 65import android.content.IContentProvider; 66import android.content.IIntentReceiver; 67import android.content.IIntentSender; 68import android.content.Intent; 69import android.content.IntentFilter; 70import android.content.IntentSender; 71import android.content.pm.ActivityInfo; 72import android.content.pm.ApplicationInfo; 73import android.content.pm.ConfigurationInfo; 74import android.content.pm.IPackageDataObserver; 75import android.content.pm.IPackageManager; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.PackageInfo; 78import android.content.pm.PackageManager; 79import android.content.pm.PackageManager.NameNotFoundException; 80import android.content.pm.PathPermission; 81import android.content.pm.ProviderInfo; 82import android.content.pm.ResolveInfo; 83import android.content.pm.ServiceInfo; 84import android.content.pm.UserInfo; 85import android.content.res.CompatibilityInfo; 86import android.content.res.Configuration; 87import android.graphics.Bitmap; 88import android.net.Proxy; 89import android.net.ProxyProperties; 90import android.net.Uri; 91import android.os.Binder; 92import android.os.Build; 93import android.os.Bundle; 94import android.os.Debug; 95import android.os.DropBoxManager; 96import android.os.Environment; 97import android.os.FileObserver; 98import android.os.FileUtils; 99import android.os.Handler; 100import android.os.IBinder; 101import android.os.IPermissionController; 102import android.os.Looper; 103import android.os.Message; 104import android.os.Parcel; 105import android.os.ParcelFileDescriptor; 106import android.os.Process; 107import android.os.RemoteCallbackList; 108import android.os.RemoteException; 109import android.os.ServiceManager; 110import android.os.StrictMode; 111import android.os.SystemClock; 112import android.os.SystemProperties; 113import android.os.UserId; 114import android.provider.Settings; 115import android.text.format.Time; 116import android.util.EventLog; 117import android.util.Log; 118import android.util.Pair; 119import android.util.PrintWriterPrinter; 120import android.util.Slog; 121import android.util.SparseArray; 122import android.util.SparseIntArray; 123import android.util.TimeUtils; 124import android.view.Gravity; 125import android.view.LayoutInflater; 126import android.view.View; 127import android.view.WindowManager; 128import android.view.WindowManagerPolicy; 129 130import java.io.BufferedInputStream; 131import java.io.BufferedOutputStream; 132import java.io.BufferedReader; 133import java.io.DataInputStream; 134import java.io.DataOutputStream; 135import java.io.File; 136import java.io.FileDescriptor; 137import java.io.FileInputStream; 138import java.io.FileNotFoundException; 139import java.io.FileOutputStream; 140import java.io.IOException; 141import java.io.InputStreamReader; 142import java.io.PrintWriter; 143import java.io.StringWriter; 144import java.lang.ref.WeakReference; 145import java.util.ArrayList; 146import java.util.Collection; 147import java.util.Collections; 148import java.util.Comparator; 149import java.util.HashMap; 150import java.util.HashSet; 151import java.util.Iterator; 152import java.util.List; 153import java.util.Locale; 154import java.util.Map; 155import java.util.Map.Entry; 156import java.util.Set; 157import java.util.concurrent.atomic.AtomicBoolean; 158import java.util.concurrent.atomic.AtomicLong; 159 160public final class ActivityManagerService extends ActivityManagerNative 161 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 162 private static final String USER_DATA_DIR = "/data/user/"; 163 static final String TAG = "ActivityManager"; 164 static final String TAG_MU = "ActivityManagerServiceMU"; 165 static final boolean DEBUG = false; 166 static final boolean localLOGV = DEBUG; 167 static final boolean DEBUG_SWITCH = localLOGV || false; 168 static final boolean DEBUG_TASKS = localLOGV || false; 169 static final boolean DEBUG_PAUSE = localLOGV || false; 170 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 171 static final boolean DEBUG_TRANSITION = localLOGV || false; 172 static final boolean DEBUG_BROADCAST = localLOGV || false; 173 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 174 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 175 static final boolean DEBUG_SERVICE = localLOGV || false; 176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 177 static final boolean DEBUG_VISBILITY = localLOGV || false; 178 static final boolean DEBUG_PROCESSES = localLOGV || false; 179 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 180 static final boolean DEBUG_PROVIDER = localLOGV || false; 181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 182 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 183 static final boolean DEBUG_RESULTS = localLOGV || false; 184 static final boolean DEBUG_BACKUP = localLOGV || false; 185 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 186 static final boolean DEBUG_POWER = localLOGV || false; 187 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 188 static final boolean DEBUG_MU = localLOGV || false; 189 static final boolean VALIDATE_TOKENS = false; 190 static final boolean SHOW_ACTIVITY_START_TIME = true; 191 192 // Control over CPU and battery monitoring. 193 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 194 static final boolean MONITOR_CPU_USAGE = true; 195 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 196 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 197 static final boolean MONITOR_THREAD_CPU_USAGE = false; 198 199 // The flags that are set for all calls we make to the package manager. 200 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 201 202 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 203 204 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 205 206 // Maximum number of recent tasks that we can remember. 207 static final int MAX_RECENT_TASKS = 20; 208 209 // Amount of time after a call to stopAppSwitches() during which we will 210 // prevent further untrusted switches from happening. 211 static final long APP_SWITCH_DELAY_TIME = 5*1000; 212 213 // How long we wait for a launched process to attach to the activity manager 214 // before we decide it's never going to come up for real. 215 static final int PROC_START_TIMEOUT = 10*1000; 216 217 // How long we wait for a launched process to attach to the activity manager 218 // before we decide it's never going to come up for real, when the process was 219 // started with a wrapper for instrumentation (such as Valgrind) because it 220 // could take much longer than usual. 221 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 222 223 // How long to wait after going idle before forcing apps to GC. 224 static final int GC_TIMEOUT = 5*1000; 225 226 // The minimum amount of time between successive GC requests for a process. 227 static final int GC_MIN_INTERVAL = 60*1000; 228 229 // The rate at which we check for apps using excessive power -- 15 mins. 230 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 231 232 // The minimum sample duration we will allow before deciding we have 233 // enough data on wake locks to start killing things. 234 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 235 236 // The minimum sample duration we will allow before deciding we have 237 // enough data on CPU usage to start killing things. 238 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 239 240 // How long we allow a receiver to run before giving up on it. 241 static final int BROADCAST_FG_TIMEOUT = 10*1000; 242 static final int BROADCAST_BG_TIMEOUT = 60*1000; 243 244 // How long we wait for a service to finish executing. 245 static final int SERVICE_TIMEOUT = 20*1000; 246 247 // How long a service needs to be running until restarting its process 248 // is no longer considered to be a relaunch of the service. 249 static final int SERVICE_RESTART_DURATION = 5*1000; 250 251 // How long a service needs to be running until it will start back at 252 // SERVICE_RESTART_DURATION after being killed. 253 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 254 255 // Multiplying factor to increase restart duration time by, for each time 256 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 257 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 258 259 // The minimum amount of time between restarting services that we allow. 260 // That is, when multiple services are restarting, we won't allow each 261 // to restart less than this amount of time from the last one. 262 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 263 264 // Maximum amount of time for there to be no activity on a service before 265 // we consider it non-essential and allow its process to go on the 266 // LRU background list. 267 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 268 269 // How long we wait until we timeout on key dispatching. 270 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 271 272 // How long we wait until we timeout on key dispatching during instrumentation. 273 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 274 275 static final int MY_PID = Process.myPid(); 276 277 static final String[] EMPTY_STRING_ARRAY = new String[0]; 278 279 public ActivityStack mMainStack; 280 281 private final boolean mHeadless; 282 283 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 284 // default actuion automatically. Important for devices without direct input 285 // devices. 286 private boolean mShowDialogs = true; 287 288 /** 289 * Description of a request to start a new activity, which has been held 290 * due to app switches being disabled. 291 */ 292 static class PendingActivityLaunch { 293 ActivityRecord r; 294 ActivityRecord sourceRecord; 295 int startFlags; 296 } 297 298 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 299 = new ArrayList<PendingActivityLaunch>(); 300 301 302 BroadcastQueue mFgBroadcastQueue; 303 BroadcastQueue mBgBroadcastQueue; 304 // Convenient for easy iteration over the queues. Foreground is first 305 // so that dispatch of foreground broadcasts gets precedence. 306 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 307 308 BroadcastQueue broadcastQueueForIntent(Intent intent) { 309 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 310 if (DEBUG_BACKGROUND_BROADCAST) { 311 Slog.i(TAG, "Broadcast intent " + intent + " on " 312 + (isFg ? "foreground" : "background") 313 + " queue"); 314 } 315 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 316 } 317 318 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 319 for (BroadcastQueue queue : mBroadcastQueues) { 320 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 321 if (r != null) { 322 return r; 323 } 324 } 325 return null; 326 } 327 328 /** 329 * Activity we have told the window manager to have key focus. 330 */ 331 ActivityRecord mFocusedActivity = null; 332 /** 333 * List of intents that were used to start the most recent tasks. 334 */ 335 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 336 337 /** 338 * Process management. 339 */ 340 final ProcessList mProcessList = new ProcessList(); 341 342 /** 343 * All of the applications we currently have running organized by name. 344 * The keys are strings of the application package name (as 345 * returned by the package manager), and the keys are ApplicationRecord 346 * objects. 347 */ 348 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 349 350 /** 351 * The currently running isolated processes. 352 */ 353 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 354 355 /** 356 * Counter for assigning isolated process uids, to avoid frequently reusing the 357 * same ones. 358 */ 359 int mNextIsolatedProcessUid = 0; 360 361 /** 362 * The currently running heavy-weight process, if any. 363 */ 364 ProcessRecord mHeavyWeightProcess = null; 365 366 /** 367 * The last time that various processes have crashed. 368 */ 369 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 370 371 /** 372 * Set of applications that we consider to be bad, and will reject 373 * incoming broadcasts from (which the user has no control over). 374 * Processes are added to this set when they have crashed twice within 375 * a minimum amount of time; they are removed from it when they are 376 * later restarted (hopefully due to some user action). The value is the 377 * time it was added to the list. 378 */ 379 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 380 381 /** 382 * All of the processes we currently have running organized by pid. 383 * The keys are the pid running the application. 384 * 385 * <p>NOTE: This object is protected by its own lock, NOT the global 386 * activity manager lock! 387 */ 388 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 389 390 /** 391 * All of the processes that have been forced to be foreground. The key 392 * is the pid of the caller who requested it (we hold a death 393 * link on it). 394 */ 395 abstract class ForegroundToken implements IBinder.DeathRecipient { 396 int pid; 397 IBinder token; 398 } 399 final SparseArray<ForegroundToken> mForegroundProcesses 400 = new SparseArray<ForegroundToken>(); 401 402 /** 403 * List of records for processes that someone had tried to start before the 404 * system was ready. We don't start them at that point, but ensure they 405 * are started by the time booting is complete. 406 */ 407 final ArrayList<ProcessRecord> mProcessesOnHold 408 = new ArrayList<ProcessRecord>(); 409 410 /** 411 * List of persistent applications that are in the process 412 * of being started. 413 */ 414 final ArrayList<ProcessRecord> mPersistentStartingProcesses 415 = new ArrayList<ProcessRecord>(); 416 417 /** 418 * Processes that are being forcibly torn down. 419 */ 420 final ArrayList<ProcessRecord> mRemovedProcesses 421 = new ArrayList<ProcessRecord>(); 422 423 /** 424 * List of running applications, sorted by recent usage. 425 * The first entry in the list is the least recently used. 426 * It contains ApplicationRecord objects. This list does NOT include 427 * any persistent application records (since we never want to exit them). 428 */ 429 final ArrayList<ProcessRecord> mLruProcesses 430 = new ArrayList<ProcessRecord>(); 431 432 /** 433 * List of processes that should gc as soon as things are idle. 434 */ 435 final ArrayList<ProcessRecord> mProcessesToGc 436 = new ArrayList<ProcessRecord>(); 437 438 /** 439 * This is the process holding what we currently consider to be 440 * the "home" activity. 441 */ 442 ProcessRecord mHomeProcess; 443 444 /** 445 * This is the process holding the activity the user last visited that 446 * is in a different process from the one they are currently in. 447 */ 448 ProcessRecord mPreviousProcess; 449 450 /** 451 * The time at which the previous process was last visible. 452 */ 453 long mPreviousProcessVisibleTime; 454 455 /** 456 * Packages that the user has asked to have run in screen size 457 * compatibility mode instead of filling the screen. 458 */ 459 final CompatModePackages mCompatModePackages; 460 461 /** 462 * Set of PendingResultRecord objects that are currently active. 463 */ 464 final HashSet mPendingResultRecords = new HashSet(); 465 466 /** 467 * Set of IntentSenderRecord objects that are currently active. 468 */ 469 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 470 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 471 472 /** 473 * Fingerprints (hashCode()) of stack traces that we've 474 * already logged DropBox entries for. Guarded by itself. If 475 * something (rogue user app) forces this over 476 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 477 */ 478 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 479 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 480 481 /** 482 * Strict Mode background batched logging state. 483 * 484 * The string buffer is guarded by itself, and its lock is also 485 * used to determine if another batched write is already 486 * in-flight. 487 */ 488 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 489 490 /** 491 * Keeps track of all IIntentReceivers that have been registered for 492 * broadcasts. Hash keys are the receiver IBinder, hash value is 493 * a ReceiverList. 494 */ 495 final HashMap mRegisteredReceivers = new HashMap(); 496 497 /** 498 * Resolver for broadcast intents to registered receivers. 499 * Holds BroadcastFilter (subclass of IntentFilter). 500 */ 501 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 502 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 503 @Override 504 protected boolean allowFilterResult( 505 BroadcastFilter filter, List<BroadcastFilter> dest) { 506 IBinder target = filter.receiverList.receiver.asBinder(); 507 for (int i=dest.size()-1; i>=0; i--) { 508 if (dest.get(i).receiverList.receiver.asBinder() == target) { 509 return false; 510 } 511 } 512 return true; 513 } 514 515 @Override 516 protected String packageForFilter(BroadcastFilter filter) { 517 return filter.packageName; 518 } 519 }; 520 521 /** 522 * State of all active sticky broadcasts. Keys are the action of the 523 * sticky Intent, values are an ArrayList of all broadcasted intents with 524 * that action (which should usually be one). 525 */ 526 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 527 new HashMap<String, ArrayList<Intent>>(); 528 529 final ServiceMap mServiceMap = new ServiceMap(); 530 531 /** 532 * All currently bound service connections. Keys are the IBinder of 533 * the client's IServiceConnection. 534 */ 535 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections 536 = new HashMap<IBinder, ArrayList<ConnectionRecord>>(); 537 538 /** 539 * List of services that we have been asked to start, 540 * but haven't yet been able to. It is used to hold start requests 541 * while waiting for their corresponding application thread to get 542 * going. 543 */ 544 final ArrayList<ServiceRecord> mPendingServices 545 = new ArrayList<ServiceRecord>(); 546 547 /** 548 * List of services that are scheduled to restart following a crash. 549 */ 550 final ArrayList<ServiceRecord> mRestartingServices 551 = new ArrayList<ServiceRecord>(); 552 553 /** 554 * List of services that are in the process of being stopped. 555 */ 556 final ArrayList<ServiceRecord> mStoppingServices 557 = new ArrayList<ServiceRecord>(); 558 559 /** 560 * Backup/restore process management 561 */ 562 String mBackupAppName = null; 563 BackupRecord mBackupTarget = null; 564 565 /** 566 * List of PendingThumbnailsRecord objects of clients who are still 567 * waiting to receive all of the thumbnails for a task. 568 */ 569 final ArrayList mPendingThumbnails = new ArrayList(); 570 571 /** 572 * List of HistoryRecord objects that have been finished and must 573 * still report back to a pending thumbnail receiver. 574 */ 575 final ArrayList mCancelledThumbnails = new ArrayList(); 576 577 final ProviderMap mProviderMap = new ProviderMap(); 578 579 /** 580 * List of content providers who have clients waiting for them. The 581 * application is currently being launched and the provider will be 582 * removed from this list once it is published. 583 */ 584 final ArrayList<ContentProviderRecord> mLaunchingProviders 585 = new ArrayList<ContentProviderRecord>(); 586 587 /** 588 * Global set of specific Uri permissions that have been granted. 589 */ 590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 591 = new SparseArray<HashMap<Uri, UriPermission>>(); 592 593 CoreSettingsObserver mCoreSettingsObserver; 594 595 /** 596 * Thread-local storage used to carry caller permissions over through 597 * indirect content-provider access. 598 * @see #ActivityManagerService.openContentUri() 599 */ 600 private class Identity { 601 public int pid; 602 public int uid; 603 604 Identity(int _pid, int _uid) { 605 pid = _pid; 606 uid = _uid; 607 } 608 } 609 610 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 611 612 /** 613 * All information we have collected about the runtime performance of 614 * any user id that can impact battery performance. 615 */ 616 final BatteryStatsService mBatteryStatsService; 617 618 /** 619 * information about component usage 620 */ 621 final UsageStatsService mUsageStatsService; 622 623 /** 624 * Current configuration information. HistoryRecord objects are given 625 * a reference to this object to indicate which configuration they are 626 * currently running in, so this object must be kept immutable. 627 */ 628 Configuration mConfiguration = new Configuration(); 629 630 /** 631 * Current sequencing integer of the configuration, for skipping old 632 * configurations. 633 */ 634 int mConfigurationSeq = 0; 635 636 /** 637 * Hardware-reported OpenGLES version. 638 */ 639 final int GL_ES_VERSION; 640 641 /** 642 * List of initialization arguments to pass to all processes when binding applications to them. 643 * For example, references to the commonly used services. 644 */ 645 HashMap<String, IBinder> mAppBindArgs; 646 647 /** 648 * Temporary to avoid allocations. Protected by main lock. 649 */ 650 final StringBuilder mStringBuilder = new StringBuilder(256); 651 652 /** 653 * Used to control how we initialize the service. 654 */ 655 boolean mStartRunning = false; 656 ComponentName mTopComponent; 657 String mTopAction; 658 String mTopData; 659 boolean mProcessesReady = false; 660 boolean mSystemReady = false; 661 boolean mBooting = false; 662 boolean mWaitingUpdate = false; 663 boolean mDidUpdate = false; 664 boolean mOnBattery = false; 665 boolean mLaunchWarningShown = false; 666 667 Context mContext; 668 669 int mFactoryTest; 670 671 boolean mCheckedForSetup; 672 673 /** 674 * The time at which we will allow normal application switches again, 675 * after a call to {@link #stopAppSwitches()}. 676 */ 677 long mAppSwitchesAllowedTime; 678 679 /** 680 * This is set to true after the first switch after mAppSwitchesAllowedTime 681 * is set; any switches after that will clear the time. 682 */ 683 boolean mDidAppSwitch; 684 685 /** 686 * Last time (in realtime) at which we checked for power usage. 687 */ 688 long mLastPowerCheckRealtime; 689 690 /** 691 * Last time (in uptime) at which we checked for power usage. 692 */ 693 long mLastPowerCheckUptime; 694 695 /** 696 * Set while we are wanting to sleep, to prevent any 697 * activities from being started/resumed. 698 */ 699 boolean mSleeping = false; 700 701 /** 702 * State of external calls telling us if the device is asleep. 703 */ 704 boolean mWentToSleep = false; 705 706 /** 707 * State of external call telling us if the lock screen is shown. 708 */ 709 boolean mLockScreenShown = false; 710 711 /** 712 * Set if we are shutting down the system, similar to sleeping. 713 */ 714 boolean mShuttingDown = false; 715 716 /** 717 * Task identifier that activities are currently being started 718 * in. Incremented each time a new task is created. 719 * todo: Replace this with a TokenSpace class that generates non-repeating 720 * integers that won't wrap. 721 */ 722 int mCurTask = 1; 723 724 /** 725 * Current sequence id for oom_adj computation traversal. 726 */ 727 int mAdjSeq = 0; 728 729 /** 730 * Current sequence id for process LRU updating. 731 */ 732 int mLruSeq = 0; 733 734 /** 735 * Keep track of the number of service processes we last found, to 736 * determine on the next iteration which should be B services. 737 */ 738 int mNumServiceProcs = 0; 739 int mNewNumServiceProcs = 0; 740 741 /** 742 * System monitoring: number of processes that died since the last 743 * N procs were started. 744 */ 745 int[] mProcDeaths = new int[20]; 746 747 /** 748 * This is set if we had to do a delayed dexopt of an app before launching 749 * it, to increasing the ANR timeouts in that case. 750 */ 751 boolean mDidDexOpt; 752 753 String mDebugApp = null; 754 boolean mWaitForDebugger = false; 755 boolean mDebugTransient = false; 756 String mOrigDebugApp = null; 757 boolean mOrigWaitForDebugger = false; 758 boolean mAlwaysFinishActivities = false; 759 IActivityController mController = null; 760 String mProfileApp = null; 761 ProcessRecord mProfileProc = null; 762 String mProfileFile; 763 ParcelFileDescriptor mProfileFd; 764 int mProfileType = 0; 765 boolean mAutoStopProfiler = false; 766 String mOpenGlTraceApp = null; 767 768 static class ProcessChangeItem { 769 static final int CHANGE_ACTIVITIES = 1<<0; 770 static final int CHANGE_IMPORTANCE= 1<<1; 771 int changes; 772 int uid; 773 int pid; 774 int importance; 775 boolean foregroundActivities; 776 } 777 778 final RemoteCallbackList<IProcessObserver> mProcessObservers 779 = new RemoteCallbackList<IProcessObserver>(); 780 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 781 782 final ArrayList<ProcessChangeItem> mPendingProcessChanges 783 = new ArrayList<ProcessChangeItem>(); 784 final ArrayList<ProcessChangeItem> mAvailProcessChanges 785 = new ArrayList<ProcessChangeItem>(); 786 787 /** 788 * Callback of last caller to {@link #requestPss}. 789 */ 790 Runnable mRequestPssCallback; 791 792 /** 793 * Remaining processes for which we are waiting results from the last 794 * call to {@link #requestPss}. 795 */ 796 final ArrayList<ProcessRecord> mRequestPssList 797 = new ArrayList<ProcessRecord>(); 798 799 /** 800 * Runtime statistics collection thread. This object's lock is used to 801 * protect all related state. 802 */ 803 final Thread mProcessStatsThread; 804 805 /** 806 * Used to collect process stats when showing not responding dialog. 807 * Protected by mProcessStatsThread. 808 */ 809 final ProcessStats mProcessStats = new ProcessStats( 810 MONITOR_THREAD_CPU_USAGE); 811 final AtomicLong mLastCpuTime = new AtomicLong(0); 812 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 813 814 long mLastWriteTime = 0; 815 816 /** 817 * Set to true after the system has finished booting. 818 */ 819 boolean mBooted = false; 820 821 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS; 822 int mProcessLimitOverride = -1; 823 824 WindowManagerService mWindowManager; 825 826 static ActivityManagerService mSelf; 827 static ActivityThread mSystemThread; 828 829 private final class AppDeathRecipient implements IBinder.DeathRecipient { 830 final ProcessRecord mApp; 831 final int mPid; 832 final IApplicationThread mAppThread; 833 834 AppDeathRecipient(ProcessRecord app, int pid, 835 IApplicationThread thread) { 836 if (localLOGV) Slog.v( 837 TAG, "New death recipient " + this 838 + " for thread " + thread.asBinder()); 839 mApp = app; 840 mPid = pid; 841 mAppThread = thread; 842 } 843 844 public void binderDied() { 845 if (localLOGV) Slog.v( 846 TAG, "Death received in " + this 847 + " for thread " + mAppThread.asBinder()); 848 synchronized(ActivityManagerService.this) { 849 appDiedLocked(mApp, mPid, mAppThread); 850 } 851 } 852 } 853 854 static final int SHOW_ERROR_MSG = 1; 855 static final int SHOW_NOT_RESPONDING_MSG = 2; 856 static final int SHOW_FACTORY_ERROR_MSG = 3; 857 static final int UPDATE_CONFIGURATION_MSG = 4; 858 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 859 static final int WAIT_FOR_DEBUGGER_MSG = 6; 860 static final int SERVICE_TIMEOUT_MSG = 12; 861 static final int UPDATE_TIME_ZONE = 13; 862 static final int SHOW_UID_ERROR_MSG = 14; 863 static final int IM_FEELING_LUCKY_MSG = 15; 864 static final int PROC_START_TIMEOUT_MSG = 20; 865 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 866 static final int KILL_APPLICATION_MSG = 22; 867 static final int FINALIZE_PENDING_INTENT_MSG = 23; 868 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 869 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 870 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 871 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 872 static final int CLEAR_DNS_CACHE = 28; 873 static final int UPDATE_HTTP_PROXY = 29; 874 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 875 static final int DISPATCH_PROCESSES_CHANGED = 31; 876 static final int DISPATCH_PROCESS_DIED = 32; 877 static final int REPORT_MEM_USAGE = 33; 878 879 static final int FIRST_ACTIVITY_STACK_MSG = 100; 880 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 881 static final int FIRST_COMPAT_MODE_MSG = 300; 882 883 AlertDialog mUidAlert; 884 CompatModeDialog mCompatModeDialog; 885 long mLastMemUsageReportTime = 0; 886 887 final Handler mHandler = new Handler() { 888 //public Handler() { 889 // if (localLOGV) Slog.v(TAG, "Handler started!"); 890 //} 891 892 public void handleMessage(Message msg) { 893 switch (msg.what) { 894 case SHOW_ERROR_MSG: { 895 HashMap data = (HashMap) msg.obj; 896 synchronized (ActivityManagerService.this) { 897 ProcessRecord proc = (ProcessRecord)data.get("app"); 898 if (proc != null && proc.crashDialog != null) { 899 Slog.e(TAG, "App already has crash dialog: " + proc); 900 return; 901 } 902 AppErrorResult res = (AppErrorResult) data.get("result"); 903 if (mShowDialogs && !mSleeping && !mShuttingDown) { 904 Dialog d = new AppErrorDialog(mContext, res, proc); 905 d.show(); 906 proc.crashDialog = d; 907 } else { 908 // The device is asleep, so just pretend that the user 909 // saw a crash dialog and hit "force quit". 910 res.set(0); 911 } 912 } 913 914 ensureBootCompleted(); 915 } break; 916 case SHOW_NOT_RESPONDING_MSG: { 917 synchronized (ActivityManagerService.this) { 918 HashMap data = (HashMap) msg.obj; 919 ProcessRecord proc = (ProcessRecord)data.get("app"); 920 if (proc != null && proc.anrDialog != null) { 921 Slog.e(TAG, "App already has anr dialog: " + proc); 922 return; 923 } 924 925 Intent intent = new Intent("android.intent.action.ANR"); 926 if (!mProcessesReady) { 927 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 928 | Intent.FLAG_RECEIVER_FOREGROUND); 929 } 930 broadcastIntentLocked(null, null, intent, 931 null, null, 0, null, null, null, 932 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 933 934 if (mShowDialogs) { 935 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 936 mContext, proc, (ActivityRecord)data.get("activity")); 937 d.show(); 938 proc.anrDialog = d; 939 } else { 940 // Just kill the app if there is no dialog to be shown. 941 killAppAtUsersRequest(proc, null); 942 } 943 } 944 945 ensureBootCompleted(); 946 } break; 947 case SHOW_STRICT_MODE_VIOLATION_MSG: { 948 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 949 synchronized (ActivityManagerService.this) { 950 ProcessRecord proc = (ProcessRecord) data.get("app"); 951 if (proc == null) { 952 Slog.e(TAG, "App not found when showing strict mode dialog."); 953 break; 954 } 955 if (proc.crashDialog != null) { 956 Slog.e(TAG, "App already has strict mode dialog: " + proc); 957 return; 958 } 959 AppErrorResult res = (AppErrorResult) data.get("result"); 960 if (mShowDialogs && !mSleeping && !mShuttingDown) { 961 Dialog d = new StrictModeViolationDialog(mContext, res, proc); 962 d.show(); 963 proc.crashDialog = d; 964 } else { 965 // The device is asleep, so just pretend that the user 966 // saw a crash dialog and hit "force quit". 967 res.set(0); 968 } 969 } 970 ensureBootCompleted(); 971 } break; 972 case SHOW_FACTORY_ERROR_MSG: { 973 Dialog d = new FactoryErrorDialog( 974 mContext, msg.getData().getCharSequence("msg")); 975 d.show(); 976 ensureBootCompleted(); 977 } break; 978 case UPDATE_CONFIGURATION_MSG: { 979 final ContentResolver resolver = mContext.getContentResolver(); 980 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 981 } break; 982 case GC_BACKGROUND_PROCESSES_MSG: { 983 synchronized (ActivityManagerService.this) { 984 performAppGcsIfAppropriateLocked(); 985 } 986 } break; 987 case WAIT_FOR_DEBUGGER_MSG: { 988 synchronized (ActivityManagerService.this) { 989 ProcessRecord app = (ProcessRecord)msg.obj; 990 if (msg.arg1 != 0) { 991 if (!app.waitedForDebugger) { 992 Dialog d = new AppWaitingForDebuggerDialog( 993 ActivityManagerService.this, 994 mContext, app); 995 app.waitDialog = d; 996 app.waitedForDebugger = true; 997 d.show(); 998 } 999 } else { 1000 if (app.waitDialog != null) { 1001 app.waitDialog.dismiss(); 1002 app.waitDialog = null; 1003 } 1004 } 1005 } 1006 } break; 1007 case SERVICE_TIMEOUT_MSG: { 1008 if (mDidDexOpt) { 1009 mDidDexOpt = false; 1010 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1011 nmsg.obj = msg.obj; 1012 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1013 return; 1014 } 1015 serviceTimeout((ProcessRecord)msg.obj); 1016 } break; 1017 case UPDATE_TIME_ZONE: { 1018 synchronized (ActivityManagerService.this) { 1019 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1020 ProcessRecord r = mLruProcesses.get(i); 1021 if (r.thread != null) { 1022 try { 1023 r.thread.updateTimeZone(); 1024 } catch (RemoteException ex) { 1025 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1026 } 1027 } 1028 } 1029 } 1030 } break; 1031 case CLEAR_DNS_CACHE: { 1032 synchronized (ActivityManagerService.this) { 1033 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1034 ProcessRecord r = mLruProcesses.get(i); 1035 if (r.thread != null) { 1036 try { 1037 r.thread.clearDnsCache(); 1038 } catch (RemoteException ex) { 1039 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1040 } 1041 } 1042 } 1043 } 1044 } break; 1045 case UPDATE_HTTP_PROXY: { 1046 ProxyProperties proxy = (ProxyProperties)msg.obj; 1047 String host = ""; 1048 String port = ""; 1049 String exclList = ""; 1050 if (proxy != null) { 1051 host = proxy.getHost(); 1052 port = Integer.toString(proxy.getPort()); 1053 exclList = proxy.getExclusionList(); 1054 } 1055 synchronized (ActivityManagerService.this) { 1056 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1057 ProcessRecord r = mLruProcesses.get(i); 1058 if (r.thread != null) { 1059 try { 1060 r.thread.setHttpProxy(host, port, exclList); 1061 } catch (RemoteException ex) { 1062 Slog.w(TAG, "Failed to update http proxy for: " + 1063 r.info.processName); 1064 } 1065 } 1066 } 1067 } 1068 } break; 1069 case SHOW_UID_ERROR_MSG: { 1070 String title = "System UIDs Inconsistent"; 1071 String text = "UIDs on the system are inconsistent, you need to wipe your" 1072 + " data partition or your device will be unstable."; 1073 Log.e(TAG, title + ": " + text); 1074 if (mShowDialogs) { 1075 // XXX This is a temporary dialog, no need to localize. 1076 AlertDialog d = new BaseErrorDialog(mContext); 1077 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1078 d.setCancelable(false); 1079 d.setTitle(title); 1080 d.setMessage(text); 1081 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1082 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1083 mUidAlert = d; 1084 d.show(); 1085 } 1086 } break; 1087 case IM_FEELING_LUCKY_MSG: { 1088 if (mUidAlert != null) { 1089 mUidAlert.dismiss(); 1090 mUidAlert = null; 1091 } 1092 } break; 1093 case PROC_START_TIMEOUT_MSG: { 1094 if (mDidDexOpt) { 1095 mDidDexOpt = false; 1096 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1097 nmsg.obj = msg.obj; 1098 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1099 return; 1100 } 1101 ProcessRecord app = (ProcessRecord)msg.obj; 1102 synchronized (ActivityManagerService.this) { 1103 processStartTimedOutLocked(app); 1104 } 1105 } break; 1106 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1107 synchronized (ActivityManagerService.this) { 1108 doPendingActivityLaunchesLocked(true); 1109 } 1110 } break; 1111 case KILL_APPLICATION_MSG: { 1112 synchronized (ActivityManagerService.this) { 1113 int uid = msg.arg1; 1114 boolean restart = (msg.arg2 == 1); 1115 String pkg = (String) msg.obj; 1116 forceStopPackageLocked(pkg, uid, restart, false, true, false, 1117 UserId.getUserId(uid)); 1118 } 1119 } break; 1120 case FINALIZE_PENDING_INTENT_MSG: { 1121 ((PendingIntentRecord)msg.obj).completeFinalize(); 1122 } break; 1123 case POST_HEAVY_NOTIFICATION_MSG: { 1124 INotificationManager inm = NotificationManager.getService(); 1125 if (inm == null) { 1126 return; 1127 } 1128 1129 ActivityRecord root = (ActivityRecord)msg.obj; 1130 ProcessRecord process = root.app; 1131 if (process == null) { 1132 return; 1133 } 1134 1135 try { 1136 Context context = mContext.createPackageContext(process.info.packageName, 0); 1137 String text = mContext.getString(R.string.heavy_weight_notification, 1138 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1139 Notification notification = new Notification(); 1140 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1141 notification.when = 0; 1142 notification.flags = Notification.FLAG_ONGOING_EVENT; 1143 notification.tickerText = text; 1144 notification.defaults = 0; // please be quiet 1145 notification.sound = null; 1146 notification.vibrate = null; 1147 notification.setLatestEventInfo(context, text, 1148 mContext.getText(R.string.heavy_weight_notification_detail), 1149 PendingIntent.getActivity(mContext, 0, root.intent, 1150 PendingIntent.FLAG_CANCEL_CURRENT)); 1151 1152 try { 1153 int[] outId = new int[1]; 1154 inm.enqueueNotification("android", R.string.heavy_weight_notification, 1155 notification, outId); 1156 } catch (RuntimeException e) { 1157 Slog.w(ActivityManagerService.TAG, 1158 "Error showing notification for heavy-weight app", e); 1159 } catch (RemoteException e) { 1160 } 1161 } catch (NameNotFoundException e) { 1162 Slog.w(TAG, "Unable to create context for heavy notification", e); 1163 } 1164 } break; 1165 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1166 INotificationManager inm = NotificationManager.getService(); 1167 if (inm == null) { 1168 return; 1169 } 1170 try { 1171 inm.cancelNotification("android", 1172 R.string.heavy_weight_notification); 1173 } catch (RuntimeException e) { 1174 Slog.w(ActivityManagerService.TAG, 1175 "Error canceling notification for service", e); 1176 } catch (RemoteException e) { 1177 } 1178 } break; 1179 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1180 synchronized (ActivityManagerService.this) { 1181 checkExcessivePowerUsageLocked(true); 1182 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1183 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1184 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1185 } 1186 } break; 1187 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1188 synchronized (ActivityManagerService.this) { 1189 ActivityRecord ar = (ActivityRecord)msg.obj; 1190 if (mCompatModeDialog != null) { 1191 if (mCompatModeDialog.mAppInfo.packageName.equals( 1192 ar.info.applicationInfo.packageName)) { 1193 return; 1194 } 1195 mCompatModeDialog.dismiss(); 1196 mCompatModeDialog = null; 1197 } 1198 if (ar != null && false) { 1199 if (mCompatModePackages.getPackageAskCompatModeLocked( 1200 ar.packageName)) { 1201 int mode = mCompatModePackages.computeCompatModeLocked( 1202 ar.info.applicationInfo); 1203 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1204 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1205 mCompatModeDialog = new CompatModeDialog( 1206 ActivityManagerService.this, mContext, 1207 ar.info.applicationInfo); 1208 mCompatModeDialog.show(); 1209 } 1210 } 1211 } 1212 } 1213 break; 1214 } 1215 case DISPATCH_PROCESSES_CHANGED: { 1216 dispatchProcessesChanged(); 1217 break; 1218 } 1219 case DISPATCH_PROCESS_DIED: { 1220 final int pid = msg.arg1; 1221 final int uid = msg.arg2; 1222 dispatchProcessDied(pid, uid); 1223 break; 1224 } 1225 case REPORT_MEM_USAGE: { 1226 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 1227 if (!isDebuggable) { 1228 return; 1229 } 1230 synchronized (ActivityManagerService.this) { 1231 long now = SystemClock.uptimeMillis(); 1232 if (now < (mLastMemUsageReportTime+5*60*1000)) { 1233 // Don't report more than every 5 minutes to somewhat 1234 // avoid spamming. 1235 return; 1236 } 1237 mLastMemUsageReportTime = now; 1238 } 1239 Thread thread = new Thread() { 1240 @Override public void run() { 1241 StringBuilder dropBuilder = new StringBuilder(1024); 1242 StringBuilder logBuilder = new StringBuilder(1024); 1243 StringWriter oomSw = new StringWriter(); 1244 PrintWriter oomPw = new PrintWriter(oomSw); 1245 StringWriter catSw = new StringWriter(); 1246 PrintWriter catPw = new PrintWriter(catSw); 1247 String[] emptyArgs = new String[] { }; 1248 StringBuilder tag = new StringBuilder(128); 1249 StringBuilder stack = new StringBuilder(128); 1250 tag.append("Low on memory -- "); 1251 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw, 1252 tag, stack); 1253 dropBuilder.append(stack); 1254 dropBuilder.append('\n'); 1255 dropBuilder.append('\n'); 1256 String oomString = oomSw.toString(); 1257 dropBuilder.append(oomString); 1258 dropBuilder.append('\n'); 1259 logBuilder.append(oomString); 1260 try { 1261 java.lang.Process proc = Runtime.getRuntime().exec(new String[] { 1262 "procrank", }); 1263 final InputStreamReader converter = new InputStreamReader( 1264 proc.getInputStream()); 1265 BufferedReader in = new BufferedReader(converter); 1266 String line; 1267 while (true) { 1268 line = in.readLine(); 1269 if (line == null) { 1270 break; 1271 } 1272 if (line.length() > 0) { 1273 logBuilder.append(line); 1274 logBuilder.append('\n'); 1275 } 1276 dropBuilder.append(line); 1277 dropBuilder.append('\n'); 1278 } 1279 converter.close(); 1280 } catch (IOException e) { 1281 } 1282 synchronized (ActivityManagerService.this) { 1283 catPw.println(); 1284 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1285 catPw.println(); 1286 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null); 1287 catPw.println(); 1288 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1289 } 1290 dropBuilder.append(catSw.toString()); 1291 addErrorToDropBox("lowmem", null, "system_server", null, 1292 null, tag.toString(), dropBuilder.toString(), null, null); 1293 Slog.i(TAG, logBuilder.toString()); 1294 synchronized (ActivityManagerService.this) { 1295 long now = SystemClock.uptimeMillis(); 1296 if (mLastMemUsageReportTime < now) { 1297 mLastMemUsageReportTime = now; 1298 } 1299 } 1300 } 1301 }; 1302 thread.start(); 1303 break; 1304 } 1305 } 1306 } 1307 }; 1308 1309 public static void setSystemProcess() { 1310 try { 1311 ActivityManagerService m = mSelf; 1312 1313 ServiceManager.addService("activity", m, true); 1314 ServiceManager.addService("meminfo", new MemBinder(m)); 1315 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1316 ServiceManager.addService("dbinfo", new DbBinder(m)); 1317 if (MONITOR_CPU_USAGE) { 1318 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1319 } 1320 ServiceManager.addService("permission", new PermissionController(m)); 1321 1322 ApplicationInfo info = 1323 mSelf.mContext.getPackageManager().getApplicationInfo( 1324 "android", STOCK_PM_FLAGS); 1325 mSystemThread.installSystemApplicationInfo(info); 1326 1327 synchronized (mSelf) { 1328 ProcessRecord app = mSelf.newProcessRecordLocked( 1329 mSystemThread.getApplicationThread(), info, 1330 info.processName, false); 1331 app.persistent = true; 1332 app.pid = MY_PID; 1333 app.maxAdj = ProcessList.SYSTEM_ADJ; 1334 mSelf.mProcessNames.put(app.processName, app.uid, app); 1335 synchronized (mSelf.mPidsSelfLocked) { 1336 mSelf.mPidsSelfLocked.put(app.pid, app); 1337 } 1338 mSelf.updateLruProcessLocked(app, true, true); 1339 } 1340 } catch (PackageManager.NameNotFoundException e) { 1341 throw new RuntimeException( 1342 "Unable to find android system package", e); 1343 } 1344 } 1345 1346 public void setWindowManager(WindowManagerService wm) { 1347 mWindowManager = wm; 1348 } 1349 1350 public static final Context main(int factoryTest) { 1351 AThread thr = new AThread(); 1352 thr.start(); 1353 1354 synchronized (thr) { 1355 while (thr.mService == null) { 1356 try { 1357 thr.wait(); 1358 } catch (InterruptedException e) { 1359 } 1360 } 1361 } 1362 1363 ActivityManagerService m = thr.mService; 1364 mSelf = m; 1365 ActivityThread at = ActivityThread.systemMain(); 1366 mSystemThread = at; 1367 Context context = at.getSystemContext(); 1368 context.setTheme(android.R.style.Theme_Holo); 1369 m.mContext = context; 1370 m.mFactoryTest = factoryTest; 1371 m.mMainStack = new ActivityStack(m, context, true); 1372 1373 m.mBatteryStatsService.publish(context); 1374 m.mUsageStatsService.publish(context); 1375 1376 synchronized (thr) { 1377 thr.mReady = true; 1378 thr.notifyAll(); 1379 } 1380 1381 m.startRunning(null, null, null, null); 1382 1383 return context; 1384 } 1385 1386 public static ActivityManagerService self() { 1387 return mSelf; 1388 } 1389 1390 static class AThread extends Thread { 1391 ActivityManagerService mService; 1392 boolean mReady = false; 1393 1394 public AThread() { 1395 super("ActivityManager"); 1396 } 1397 1398 public void run() { 1399 Looper.prepare(); 1400 1401 android.os.Process.setThreadPriority( 1402 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1403 android.os.Process.setCanSelfBackground(false); 1404 1405 ActivityManagerService m = new ActivityManagerService(); 1406 1407 synchronized (this) { 1408 mService = m; 1409 notifyAll(); 1410 } 1411 1412 synchronized (this) { 1413 while (!mReady) { 1414 try { 1415 wait(); 1416 } catch (InterruptedException e) { 1417 } 1418 } 1419 } 1420 1421 // For debug builds, log event loop stalls to dropbox for analysis. 1422 if (StrictMode.conditionallyEnableDebugLogging()) { 1423 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1424 } 1425 1426 Looper.loop(); 1427 } 1428 } 1429 1430 static class MemBinder extends Binder { 1431 ActivityManagerService mActivityManagerService; 1432 MemBinder(ActivityManagerService activityManagerService) { 1433 mActivityManagerService = activityManagerService; 1434 } 1435 1436 @Override 1437 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1438 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1439 != PackageManager.PERMISSION_GRANTED) { 1440 pw.println("Permission Denial: can't dump meminfo from from pid=" 1441 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1442 + " without permission " + android.Manifest.permission.DUMP); 1443 return; 1444 } 1445 1446 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, 1447 false, null, null, null); 1448 } 1449 } 1450 1451 static class GraphicsBinder extends Binder { 1452 ActivityManagerService mActivityManagerService; 1453 GraphicsBinder(ActivityManagerService activityManagerService) { 1454 mActivityManagerService = activityManagerService; 1455 } 1456 1457 @Override 1458 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1459 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1460 != PackageManager.PERMISSION_GRANTED) { 1461 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1462 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1463 + " without permission " + android.Manifest.permission.DUMP); 1464 return; 1465 } 1466 1467 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1468 } 1469 } 1470 1471 static class DbBinder extends Binder { 1472 ActivityManagerService mActivityManagerService; 1473 DbBinder(ActivityManagerService activityManagerService) { 1474 mActivityManagerService = activityManagerService; 1475 } 1476 1477 @Override 1478 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1479 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1480 != PackageManager.PERMISSION_GRANTED) { 1481 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1482 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1483 + " without permission " + android.Manifest.permission.DUMP); 1484 return; 1485 } 1486 1487 mActivityManagerService.dumpDbInfo(fd, pw, args); 1488 } 1489 } 1490 1491 static class CpuBinder extends Binder { 1492 ActivityManagerService mActivityManagerService; 1493 CpuBinder(ActivityManagerService activityManagerService) { 1494 mActivityManagerService = activityManagerService; 1495 } 1496 1497 @Override 1498 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1499 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1500 != PackageManager.PERMISSION_GRANTED) { 1501 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1502 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1503 + " without permission " + android.Manifest.permission.DUMP); 1504 return; 1505 } 1506 1507 synchronized (mActivityManagerService.mProcessStatsThread) { 1508 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad()); 1509 pw.print(mActivityManagerService.mProcessStats.printCurrentState( 1510 SystemClock.uptimeMillis())); 1511 } 1512 } 1513 } 1514 1515 private ActivityManagerService() { 1516 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1517 1518 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT); 1519 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT); 1520 mBroadcastQueues[0] = mFgBroadcastQueue; 1521 mBroadcastQueues[1] = mBgBroadcastQueue; 1522 1523 File dataDir = Environment.getDataDirectory(); 1524 File systemDir = new File(dataDir, "system"); 1525 systemDir.mkdirs(); 1526 mBatteryStatsService = new BatteryStatsService(new File( 1527 systemDir, "batterystats.bin").toString()); 1528 mBatteryStatsService.getActiveStatistics().readLocked(); 1529 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1530 mOnBattery = DEBUG_POWER ? true 1531 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1532 mBatteryStatsService.getActiveStatistics().setCallback(this); 1533 1534 mUsageStatsService = new UsageStatsService(new File( 1535 systemDir, "usagestats").toString()); 1536 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1537 1538 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1539 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1540 1541 mConfiguration.setToDefaults(); 1542 mConfiguration.locale = Locale.getDefault(); 1543 mConfigurationSeq = mConfiguration.seq = 1; 1544 mProcessStats.init(); 1545 1546 mCompatModePackages = new CompatModePackages(this, systemDir); 1547 1548 // Add ourself to the Watchdog monitors. 1549 Watchdog.getInstance().addMonitor(this); 1550 1551 mProcessStatsThread = new Thread("ProcessStats") { 1552 public void run() { 1553 while (true) { 1554 try { 1555 try { 1556 synchronized(this) { 1557 final long now = SystemClock.uptimeMillis(); 1558 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1559 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1560 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1561 // + ", write delay=" + nextWriteDelay); 1562 if (nextWriteDelay < nextCpuDelay) { 1563 nextCpuDelay = nextWriteDelay; 1564 } 1565 if (nextCpuDelay > 0) { 1566 mProcessStatsMutexFree.set(true); 1567 this.wait(nextCpuDelay); 1568 } 1569 } 1570 } catch (InterruptedException e) { 1571 } 1572 updateCpuStatsNow(); 1573 } catch (Exception e) { 1574 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1575 } 1576 } 1577 } 1578 }; 1579 mProcessStatsThread.start(); 1580 } 1581 1582 @Override 1583 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1584 throws RemoteException { 1585 if (code == SYSPROPS_TRANSACTION) { 1586 // We need to tell all apps about the system property change. 1587 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 1588 synchronized(this) { 1589 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 1590 final int NA = apps.size(); 1591 for (int ia=0; ia<NA; ia++) { 1592 ProcessRecord app = apps.valueAt(ia); 1593 if (app.thread != null) { 1594 procs.add(app.thread.asBinder()); 1595 } 1596 } 1597 } 1598 } 1599 1600 int N = procs.size(); 1601 for (int i=0; i<N; i++) { 1602 Parcel data2 = Parcel.obtain(); 1603 try { 1604 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 1605 } catch (RemoteException e) { 1606 } 1607 data2.recycle(); 1608 } 1609 } 1610 try { 1611 return super.onTransact(code, data, reply, flags); 1612 } catch (RuntimeException e) { 1613 // The activity manager only throws security exceptions, so let's 1614 // log all others. 1615 if (!(e instanceof SecurityException)) { 1616 Slog.e(TAG, "Activity Manager Crash", e); 1617 } 1618 throw e; 1619 } 1620 } 1621 1622 void updateCpuStats() { 1623 final long now = SystemClock.uptimeMillis(); 1624 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1625 return; 1626 } 1627 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1628 synchronized (mProcessStatsThread) { 1629 mProcessStatsThread.notify(); 1630 } 1631 } 1632 } 1633 1634 void updateCpuStatsNow() { 1635 synchronized (mProcessStatsThread) { 1636 mProcessStatsMutexFree.set(false); 1637 final long now = SystemClock.uptimeMillis(); 1638 boolean haveNewCpuStats = false; 1639 1640 if (MONITOR_CPU_USAGE && 1641 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1642 mLastCpuTime.set(now); 1643 haveNewCpuStats = true; 1644 mProcessStats.update(); 1645 //Slog.i(TAG, mProcessStats.printCurrentState()); 1646 //Slog.i(TAG, "Total CPU usage: " 1647 // + mProcessStats.getTotalCpuPercent() + "%"); 1648 1649 // Slog the cpu usage if the property is set. 1650 if ("true".equals(SystemProperties.get("events.cpu"))) { 1651 int user = mProcessStats.getLastUserTime(); 1652 int system = mProcessStats.getLastSystemTime(); 1653 int iowait = mProcessStats.getLastIoWaitTime(); 1654 int irq = mProcessStats.getLastIrqTime(); 1655 int softIrq = mProcessStats.getLastSoftIrqTime(); 1656 int idle = mProcessStats.getLastIdleTime(); 1657 1658 int total = user + system + iowait + irq + softIrq + idle; 1659 if (total == 0) total = 1; 1660 1661 EventLog.writeEvent(EventLogTags.CPU, 1662 ((user+system+iowait+irq+softIrq) * 100) / total, 1663 (user * 100) / total, 1664 (system * 100) / total, 1665 (iowait * 100) / total, 1666 (irq * 100) / total, 1667 (softIrq * 100) / total); 1668 } 1669 } 1670 1671 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1672 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1673 synchronized(bstats) { 1674 synchronized(mPidsSelfLocked) { 1675 if (haveNewCpuStats) { 1676 if (mOnBattery) { 1677 int perc = bstats.startAddingCpuLocked(); 1678 int totalUTime = 0; 1679 int totalSTime = 0; 1680 final int N = mProcessStats.countStats(); 1681 for (int i=0; i<N; i++) { 1682 ProcessStats.Stats st = mProcessStats.getStats(i); 1683 if (!st.working) { 1684 continue; 1685 } 1686 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1687 int otherUTime = (st.rel_utime*perc)/100; 1688 int otherSTime = (st.rel_stime*perc)/100; 1689 totalUTime += otherUTime; 1690 totalSTime += otherSTime; 1691 if (pr != null) { 1692 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1693 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1694 st.rel_stime-otherSTime); 1695 ps.addSpeedStepTimes(cpuSpeedTimes); 1696 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 1697 } else { 1698 BatteryStatsImpl.Uid.Proc ps = 1699 bstats.getProcessStatsLocked(st.name, st.pid); 1700 if (ps != null) { 1701 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 1702 st.rel_stime-otherSTime); 1703 ps.addSpeedStepTimes(cpuSpeedTimes); 1704 } 1705 } 1706 } 1707 bstats.finishAddingCpuLocked(perc, totalUTime, 1708 totalSTime, cpuSpeedTimes); 1709 } 1710 } 1711 } 1712 1713 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1714 mLastWriteTime = now; 1715 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1716 } 1717 } 1718 } 1719 } 1720 1721 @Override 1722 public void batteryNeedsCpuUpdate() { 1723 updateCpuStatsNow(); 1724 } 1725 1726 @Override 1727 public void batteryPowerChanged(boolean onBattery) { 1728 // When plugging in, update the CPU stats first before changing 1729 // the plug state. 1730 updateCpuStatsNow(); 1731 synchronized (this) { 1732 synchronized(mPidsSelfLocked) { 1733 mOnBattery = DEBUG_POWER ? true : onBattery; 1734 } 1735 } 1736 } 1737 1738 /** 1739 * Initialize the application bind args. These are passed to each 1740 * process when the bindApplication() IPC is sent to the process. They're 1741 * lazily setup to make sure the services are running when they're asked for. 1742 */ 1743 private HashMap<String, IBinder> getCommonServicesLocked() { 1744 if (mAppBindArgs == null) { 1745 mAppBindArgs = new HashMap<String, IBinder>(); 1746 1747 // Setup the application init args 1748 mAppBindArgs.put("package", ServiceManager.getService("package")); 1749 mAppBindArgs.put("window", ServiceManager.getService("window")); 1750 mAppBindArgs.put(Context.ALARM_SERVICE, 1751 ServiceManager.getService(Context.ALARM_SERVICE)); 1752 } 1753 return mAppBindArgs; 1754 } 1755 1756 final void setFocusedActivityLocked(ActivityRecord r) { 1757 if (mFocusedActivity != r) { 1758 mFocusedActivity = r; 1759 if (r != null) { 1760 mWindowManager.setFocusedApp(r.appToken, true); 1761 } 1762 } 1763 } 1764 1765 private final void updateLruProcessInternalLocked(ProcessRecord app, 1766 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1767 // put it on the LRU to keep track of when it should be exited. 1768 int lrui = mLruProcesses.indexOf(app); 1769 if (lrui >= 0) mLruProcesses.remove(lrui); 1770 1771 int i = mLruProcesses.size()-1; 1772 int skipTop = 0; 1773 1774 app.lruSeq = mLruSeq; 1775 1776 // compute the new weight for this process. 1777 if (updateActivityTime) { 1778 app.lastActivityTime = SystemClock.uptimeMillis(); 1779 } 1780 if (app.activities.size() > 0) { 1781 // If this process has activities, we more strongly want to keep 1782 // it around. 1783 app.lruWeight = app.lastActivityTime; 1784 } else if (app.pubProviders.size() > 0) { 1785 // If this process contains content providers, we want to keep 1786 // it a little more strongly. 1787 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET; 1788 // Also don't let it kick out the first few "real" hidden processes. 1789 skipTop = ProcessList.MIN_HIDDEN_APPS; 1790 } else { 1791 // If this process doesn't have activities, we less strongly 1792 // want to keep it around, and generally want to avoid getting 1793 // in front of any very recently used activities. 1794 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET; 1795 // Also don't let it kick out the first few "real" hidden processes. 1796 skipTop = ProcessList.MIN_HIDDEN_APPS; 1797 } 1798 1799 while (i >= 0) { 1800 ProcessRecord p = mLruProcesses.get(i); 1801 // If this app shouldn't be in front of the first N background 1802 // apps, then skip over that many that are currently hidden. 1803 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 1804 skipTop--; 1805 } 1806 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1807 mLruProcesses.add(i+1, app); 1808 break; 1809 } 1810 i--; 1811 } 1812 if (i < 0) { 1813 mLruProcesses.add(0, app); 1814 } 1815 1816 // If the app is currently using a content provider or service, 1817 // bump those processes as well. 1818 if (app.connections.size() > 0) { 1819 for (ConnectionRecord cr : app.connections) { 1820 if (cr.binding != null && cr.binding.service != null 1821 && cr.binding.service.app != null 1822 && cr.binding.service.app.lruSeq != mLruSeq) { 1823 updateLruProcessInternalLocked(cr.binding.service.app, false, 1824 updateActivityTime, i+1); 1825 } 1826 } 1827 } 1828 for (int j=app.conProviders.size()-1; j>=0; j--) { 1829 ContentProviderRecord cpr = app.conProviders.get(j).provider; 1830 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 1831 updateLruProcessInternalLocked(cpr.proc, false, 1832 updateActivityTime, i+1); 1833 } 1834 } 1835 1836 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1837 if (oomAdj) { 1838 updateOomAdjLocked(); 1839 } 1840 } 1841 1842 final void updateLruProcessLocked(ProcessRecord app, 1843 boolean oomAdj, boolean updateActivityTime) { 1844 mLruSeq++; 1845 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1846 } 1847 1848 final ProcessRecord getProcessRecordLocked( 1849 String processName, int uid) { 1850 if (uid == Process.SYSTEM_UID) { 1851 // The system gets to run in any process. If there are multiple 1852 // processes with the same uid, just pick the first (this 1853 // should never happen). 1854 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1855 processName); 1856 if (procs == null) return null; 1857 final int N = procs.size(); 1858 for (int i = 0; i < N; i++) { 1859 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 1860 } 1861 } 1862 ProcessRecord proc = mProcessNames.get(processName, uid); 1863 return proc; 1864 } 1865 1866 void ensurePackageDexOpt(String packageName) { 1867 IPackageManager pm = AppGlobals.getPackageManager(); 1868 try { 1869 if (pm.performDexOpt(packageName)) { 1870 mDidDexOpt = true; 1871 } 1872 } catch (RemoteException e) { 1873 } 1874 } 1875 1876 boolean isNextTransitionForward() { 1877 int transit = mWindowManager.getPendingAppTransition(); 1878 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1879 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1880 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1881 } 1882 1883 final ProcessRecord startProcessLocked(String processName, 1884 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1885 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 1886 boolean isolated) { 1887 ProcessRecord app; 1888 if (!isolated) { 1889 app = getProcessRecordLocked(processName, info.uid); 1890 } else { 1891 // If this is an isolated process, it can't re-use an existing process. 1892 app = null; 1893 } 1894 // We don't have to do anything more if: 1895 // (1) There is an existing application record; and 1896 // (2) The caller doesn't think it is dead, OR there is no thread 1897 // object attached to it so we know it couldn't have crashed; and 1898 // (3) There is a pid assigned to it, so it is either starting or 1899 // already running. 1900 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1901 + " app=" + app + " knownToBeDead=" + knownToBeDead 1902 + " thread=" + (app != null ? app.thread : null) 1903 + " pid=" + (app != null ? app.pid : -1)); 1904 if (app != null && app.pid > 0) { 1905 if (!knownToBeDead || app.thread == null) { 1906 // We already have the app running, or are waiting for it to 1907 // come up (we have a pid but not yet its thread), so keep it. 1908 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 1909 // If this is a new package in the process, add the package to the list 1910 app.addPackage(info.packageName); 1911 return app; 1912 } else { 1913 // An application record is attached to a previous process, 1914 // clean it up now. 1915 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app); 1916 handleAppDiedLocked(app, true, true); 1917 } 1918 } 1919 1920 String hostingNameStr = hostingName != null 1921 ? hostingName.flattenToShortString() : null; 1922 1923 if (!isolated) { 1924 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1925 // If we are in the background, then check to see if this process 1926 // is bad. If so, we will just silently fail. 1927 if (mBadProcesses.get(info.processName, info.uid) != null) { 1928 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1929 + "/" + info.processName); 1930 return null; 1931 } 1932 } else { 1933 // When the user is explicitly starting a process, then clear its 1934 // crash count so that we won't make it bad until they see at 1935 // least one crash dialog again, and make the process good again 1936 // if it had been bad. 1937 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1938 + "/" + info.processName); 1939 mProcessCrashTimes.remove(info.processName, info.uid); 1940 if (mBadProcesses.get(info.processName, info.uid) != null) { 1941 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1942 info.processName); 1943 mBadProcesses.remove(info.processName, info.uid); 1944 if (app != null) { 1945 app.bad = false; 1946 } 1947 } 1948 } 1949 } 1950 1951 if (app == null) { 1952 app = newProcessRecordLocked(null, info, processName, isolated); 1953 if (app == null) { 1954 Slog.w(TAG, "Failed making new process record for " 1955 + processName + "/" + info.uid + " isolated=" + isolated); 1956 return null; 1957 } 1958 mProcessNames.put(processName, app.uid, app); 1959 if (isolated) { 1960 mIsolatedProcesses.put(app.uid, app); 1961 } 1962 } else { 1963 // If this is a new package in the process, add the package to the list 1964 app.addPackage(info.packageName); 1965 } 1966 1967 // If the system is not ready yet, then hold off on starting this 1968 // process until it is. 1969 if (!mProcessesReady 1970 && !isAllowedWhileBooting(info) 1971 && !allowWhileBooting) { 1972 if (!mProcessesOnHold.contains(app)) { 1973 mProcessesOnHold.add(app); 1974 } 1975 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 1976 return app; 1977 } 1978 1979 startProcessLocked(app, hostingType, hostingNameStr); 1980 return (app.pid != 0) ? app : null; 1981 } 1982 1983 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1984 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1985 } 1986 1987 private final void startProcessLocked(ProcessRecord app, 1988 String hostingType, String hostingNameStr) { 1989 if (app.pid > 0 && app.pid != MY_PID) { 1990 synchronized (mPidsSelfLocked) { 1991 mPidsSelfLocked.remove(app.pid); 1992 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1993 } 1994 app.pid = 0; 1995 } 1996 1997 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 1998 "startProcessLocked removing on hold: " + app); 1999 mProcessesOnHold.remove(app); 2000 2001 updateCpuStats(); 2002 2003 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2004 mProcDeaths[0] = 0; 2005 2006 try { 2007 int uid = app.uid; 2008 2009 int[] gids = null; 2010 if (!app.isolated) { 2011 try { 2012 gids = mContext.getPackageManager().getPackageGids( 2013 app.info.packageName); 2014 } catch (PackageManager.NameNotFoundException e) { 2015 Slog.w(TAG, "Unable to retrieve gids", e); 2016 } 2017 } 2018 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2019 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2020 && mTopComponent != null 2021 && app.processName.equals(mTopComponent.getPackageName())) { 2022 uid = 0; 2023 } 2024 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2025 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2026 uid = 0; 2027 } 2028 } 2029 int debugFlags = 0; 2030 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2031 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2032 // Also turn on CheckJNI for debuggable apps. It's quite 2033 // awkward to turn on otherwise. 2034 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2035 } 2036 // Run the app in safe mode if its manifest requests so or the 2037 // system is booted in safe mode. 2038 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2039 Zygote.systemInSafeMode == true) { 2040 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2041 } 2042 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2043 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2044 } 2045 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2046 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2047 } 2048 if ("1".equals(SystemProperties.get("debug.assert"))) { 2049 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2050 } 2051 2052 // Start the process. It will either succeed and return a result containing 2053 // the PID of the new process, or else throw a RuntimeException. 2054 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2055 app.processName, uid, uid, gids, debugFlags, 2056 app.info.targetSdkVersion, null, null); 2057 2058 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2059 synchronized (bs) { 2060 if (bs.isOnBattery()) { 2061 app.batteryStats.incStartsLocked(); 2062 } 2063 } 2064 2065 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, 2066 app.processName, hostingType, 2067 hostingNameStr != null ? hostingNameStr : ""); 2068 2069 if (app.persistent) { 2070 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2071 } 2072 2073 StringBuilder buf = mStringBuilder; 2074 buf.setLength(0); 2075 buf.append("Start proc "); 2076 buf.append(app.processName); 2077 buf.append(" for "); 2078 buf.append(hostingType); 2079 if (hostingNameStr != null) { 2080 buf.append(" "); 2081 buf.append(hostingNameStr); 2082 } 2083 buf.append(": pid="); 2084 buf.append(startResult.pid); 2085 buf.append(" uid="); 2086 buf.append(uid); 2087 buf.append(" gids={"); 2088 if (gids != null) { 2089 for (int gi=0; gi<gids.length; gi++) { 2090 if (gi != 0) buf.append(", "); 2091 buf.append(gids[gi]); 2092 2093 } 2094 } 2095 buf.append("}"); 2096 Slog.i(TAG, buf.toString()); 2097 app.pid = startResult.pid; 2098 app.usingWrapper = startResult.usingWrapper; 2099 app.removed = false; 2100 synchronized (mPidsSelfLocked) { 2101 this.mPidsSelfLocked.put(startResult.pid, app); 2102 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2103 msg.obj = app; 2104 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2105 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2106 } 2107 } catch (RuntimeException e) { 2108 // XXX do better error recovery. 2109 app.pid = 0; 2110 Slog.e(TAG, "Failure starting process " + app.processName, e); 2111 } 2112 } 2113 2114 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) { 2115 if (resumed) { 2116 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2117 } else { 2118 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2119 } 2120 } 2121 2122 boolean startHomeActivityLocked(int userId) { 2123 if (mHeadless) { 2124 // Added because none of the other calls to ensureBootCompleted seem to fire 2125 // when running headless. 2126 ensureBootCompleted(); 2127 return false; 2128 } 2129 2130 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2131 && mTopAction == null) { 2132 // We are running in factory test mode, but unable to find 2133 // the factory test app, so just sit around displaying the 2134 // error message and don't try to start anything. 2135 return false; 2136 } 2137 Intent intent = new Intent( 2138 mTopAction, 2139 mTopData != null ? Uri.parse(mTopData) : null); 2140 intent.setComponent(mTopComponent); 2141 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2142 intent.addCategory(Intent.CATEGORY_HOME); 2143 } 2144 ActivityInfo aInfo = 2145 intent.resolveActivityInfo(mContext.getPackageManager(), 2146 STOCK_PM_FLAGS); 2147 if (aInfo != null) { 2148 intent.setComponent(new ComponentName( 2149 aInfo.applicationInfo.packageName, aInfo.name)); 2150 // Don't do this if the home app is currently being 2151 // instrumented. 2152 aInfo = new ActivityInfo(aInfo); 2153 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2154 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2155 aInfo.applicationInfo.uid); 2156 if (app == null || app.instrumentationClass == null) { 2157 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2158 mMainStack.startActivityLocked(null, intent, null, aInfo, 2159 null, null, 0, 0, 0, 0, null, false, null); 2160 } 2161 } 2162 2163 return true; 2164 } 2165 2166 /** 2167 * Starts the "new version setup screen" if appropriate. 2168 */ 2169 void startSetupActivityLocked() { 2170 // Only do this once per boot. 2171 if (mCheckedForSetup) { 2172 return; 2173 } 2174 2175 // We will show this screen if the current one is a different 2176 // version than the last one shown, and we are not running in 2177 // low-level factory test mode. 2178 final ContentResolver resolver = mContext.getContentResolver(); 2179 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2180 Settings.Secure.getInt(resolver, 2181 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2182 mCheckedForSetup = true; 2183 2184 // See if we should be showing the platform update setup UI. 2185 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2186 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2187 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2188 2189 // We don't allow third party apps to replace this. 2190 ResolveInfo ri = null; 2191 for (int i=0; ris != null && i<ris.size(); i++) { 2192 if ((ris.get(i).activityInfo.applicationInfo.flags 2193 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2194 ri = ris.get(i); 2195 break; 2196 } 2197 } 2198 2199 if (ri != null) { 2200 String vers = ri.activityInfo.metaData != null 2201 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2202 : null; 2203 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2204 vers = ri.activityInfo.applicationInfo.metaData.getString( 2205 Intent.METADATA_SETUP_VERSION); 2206 } 2207 String lastVers = Settings.Secure.getString( 2208 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2209 if (vers != null && !vers.equals(lastVers)) { 2210 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2211 intent.setComponent(new ComponentName( 2212 ri.activityInfo.packageName, ri.activityInfo.name)); 2213 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo, 2214 null, null, 0, 0, 0, 0, null, false, null); 2215 } 2216 } 2217 } 2218 } 2219 2220 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2221 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2222 } 2223 2224 void enforceNotIsolatedCaller(String caller) { 2225 if (UserId.isIsolated(Binder.getCallingUid())) { 2226 throw new SecurityException("Isolated process not allowed to call " + caller); 2227 } 2228 } 2229 2230 public int getFrontActivityScreenCompatMode() { 2231 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2232 synchronized (this) { 2233 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2234 } 2235 } 2236 2237 public void setFrontActivityScreenCompatMode(int mode) { 2238 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2239 "setFrontActivityScreenCompatMode"); 2240 synchronized (this) { 2241 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2242 } 2243 } 2244 2245 public int getPackageScreenCompatMode(String packageName) { 2246 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2247 synchronized (this) { 2248 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2249 } 2250 } 2251 2252 public void setPackageScreenCompatMode(String packageName, int mode) { 2253 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2254 "setPackageScreenCompatMode"); 2255 synchronized (this) { 2256 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2257 } 2258 } 2259 2260 public boolean getPackageAskScreenCompat(String packageName) { 2261 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2262 synchronized (this) { 2263 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2264 } 2265 } 2266 2267 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2268 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2269 "setPackageAskScreenCompat"); 2270 synchronized (this) { 2271 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2272 } 2273 } 2274 2275 void reportResumedActivityLocked(ActivityRecord r) { 2276 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2277 updateUsageStats(r, true); 2278 } 2279 2280 private void dispatchProcessesChanged() { 2281 int N; 2282 synchronized (this) { 2283 N = mPendingProcessChanges.size(); 2284 if (mActiveProcessChanges.length < N) { 2285 mActiveProcessChanges = new ProcessChangeItem[N]; 2286 } 2287 mPendingProcessChanges.toArray(mActiveProcessChanges); 2288 mAvailProcessChanges.addAll(mPendingProcessChanges); 2289 mPendingProcessChanges.clear(); 2290 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2291 } 2292 int i = mProcessObservers.beginBroadcast(); 2293 while (i > 0) { 2294 i--; 2295 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2296 if (observer != null) { 2297 try { 2298 for (int j=0; j<N; j++) { 2299 ProcessChangeItem item = mActiveProcessChanges[j]; 2300 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2301 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2302 + item.pid + " uid=" + item.uid + ": " 2303 + item.foregroundActivities); 2304 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2305 item.foregroundActivities); 2306 } 2307 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2308 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2309 + item.pid + " uid=" + item.uid + ": " + item.importance); 2310 observer.onImportanceChanged(item.pid, item.uid, 2311 item.importance); 2312 } 2313 } 2314 } catch (RemoteException e) { 2315 } 2316 } 2317 } 2318 mProcessObservers.finishBroadcast(); 2319 } 2320 2321 private void dispatchProcessDied(int pid, int uid) { 2322 int i = mProcessObservers.beginBroadcast(); 2323 while (i > 0) { 2324 i--; 2325 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2326 if (observer != null) { 2327 try { 2328 observer.onProcessDied(pid, uid); 2329 } catch (RemoteException e) { 2330 } 2331 } 2332 } 2333 mProcessObservers.finishBroadcast(); 2334 } 2335 2336 final void doPendingActivityLaunchesLocked(boolean doResume) { 2337 final int N = mPendingActivityLaunches.size(); 2338 if (N <= 0) { 2339 return; 2340 } 2341 for (int i=0; i<N; i++) { 2342 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2343 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord, 2344 pal.startFlags, doResume && i == (N-1), null); 2345 } 2346 mPendingActivityLaunches.clear(); 2347 } 2348 2349 public final int startActivity(IApplicationThread caller, 2350 Intent intent, String resolvedType, IBinder resultTo, 2351 String resultWho, int requestCode, int startFlags, 2352 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2353 enforceNotIsolatedCaller("startActivity"); 2354 int userId = 0; 2355 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) { 2356 // Requesting home, set the identity to the current user 2357 // HACK! 2358 userId = mCurrentUserId; 2359 } else { 2360 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry 2361 // the current user's userId 2362 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) { 2363 userId = 0; 2364 } else { 2365 userId = Binder.getOrigCallingUser(); 2366 } 2367 } 2368 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2369 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2370 null, null, options, userId); 2371 } 2372 2373 public final WaitResult startActivityAndWait(IApplicationThread caller, 2374 Intent intent, String resolvedType, IBinder resultTo, 2375 String resultWho, int requestCode, int startFlags, String profileFile, 2376 ParcelFileDescriptor profileFd, Bundle options) { 2377 enforceNotIsolatedCaller("startActivityAndWait"); 2378 WaitResult res = new WaitResult(); 2379 int userId = Binder.getOrigCallingUser(); 2380 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2381 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2382 res, null, options, userId); 2383 return res; 2384 } 2385 2386 public final int startActivityWithConfig(IApplicationThread caller, 2387 Intent intent, String resolvedType, IBinder resultTo, 2388 String resultWho, int requestCode, int startFlags, Configuration config, 2389 Bundle options) { 2390 enforceNotIsolatedCaller("startActivityWithConfig"); 2391 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, 2392 resultTo, resultWho, requestCode, startFlags, 2393 null, null, null, config, options, Binder.getOrigCallingUser()); 2394 return ret; 2395 } 2396 2397 public int startActivityIntentSender(IApplicationThread caller, 2398 IntentSender intent, Intent fillInIntent, String resolvedType, 2399 IBinder resultTo, String resultWho, int requestCode, 2400 int flagsMask, int flagsValues, Bundle options) { 2401 enforceNotIsolatedCaller("startActivityIntentSender"); 2402 // Refuse possible leaked file descriptors 2403 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 2404 throw new IllegalArgumentException("File descriptors passed in Intent"); 2405 } 2406 2407 IIntentSender sender = intent.getTarget(); 2408 if (!(sender instanceof PendingIntentRecord)) { 2409 throw new IllegalArgumentException("Bad PendingIntent object"); 2410 } 2411 2412 PendingIntentRecord pir = (PendingIntentRecord)sender; 2413 2414 synchronized (this) { 2415 // If this is coming from the currently resumed activity, it is 2416 // effectively saying that app switches are allowed at this point. 2417 if (mMainStack.mResumedActivity != null 2418 && mMainStack.mResumedActivity.info.applicationInfo.uid == 2419 Binder.getCallingUid()) { 2420 mAppSwitchesAllowedTime = 0; 2421 } 2422 } 2423 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 2424 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 2425 return ret; 2426 } 2427 2428 public boolean startNextMatchingActivity(IBinder callingActivity, 2429 Intent intent, Bundle options) { 2430 // Refuse possible leaked file descriptors 2431 if (intent != null && intent.hasFileDescriptors() == true) { 2432 throw new IllegalArgumentException("File descriptors passed in Intent"); 2433 } 2434 2435 synchronized (this) { 2436 ActivityRecord r = mMainStack.isInStackLocked(callingActivity); 2437 if (r == null) { 2438 ActivityOptions.abort(options); 2439 return false; 2440 } 2441 if (r.app == null || r.app.thread == null) { 2442 // The caller is not running... d'oh! 2443 ActivityOptions.abort(options); 2444 return false; 2445 } 2446 intent = new Intent(intent); 2447 // The caller is not allowed to change the data. 2448 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 2449 // And we are resetting to find the next component... 2450 intent.setComponent(null); 2451 2452 ActivityInfo aInfo = null; 2453 try { 2454 List<ResolveInfo> resolves = 2455 AppGlobals.getPackageManager().queryIntentActivities( 2456 intent, r.resolvedType, 2457 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 2458 UserId.getCallingUserId()); 2459 2460 // Look for the original activity in the list... 2461 final int N = resolves != null ? resolves.size() : 0; 2462 for (int i=0; i<N; i++) { 2463 ResolveInfo rInfo = resolves.get(i); 2464 if (rInfo.activityInfo.packageName.equals(r.packageName) 2465 && rInfo.activityInfo.name.equals(r.info.name)) { 2466 // We found the current one... the next matching is 2467 // after it. 2468 i++; 2469 if (i<N) { 2470 aInfo = resolves.get(i).activityInfo; 2471 } 2472 break; 2473 } 2474 } 2475 } catch (RemoteException e) { 2476 } 2477 2478 if (aInfo == null) { 2479 // Nobody who is next! 2480 ActivityOptions.abort(options); 2481 return false; 2482 } 2483 2484 intent.setComponent(new ComponentName( 2485 aInfo.applicationInfo.packageName, aInfo.name)); 2486 intent.setFlags(intent.getFlags()&~( 2487 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 2488 Intent.FLAG_ACTIVITY_CLEAR_TOP| 2489 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 2490 Intent.FLAG_ACTIVITY_NEW_TASK)); 2491 2492 // Okay now we need to start the new activity, replacing the 2493 // currently running activity. This is a little tricky because 2494 // we want to start the new one as if the current one is finished, 2495 // but not finish the current one first so that there is no flicker. 2496 // And thus... 2497 final boolean wasFinishing = r.finishing; 2498 r.finishing = true; 2499 2500 // Propagate reply information over to the new activity. 2501 final ActivityRecord resultTo = r.resultTo; 2502 final String resultWho = r.resultWho; 2503 final int requestCode = r.requestCode; 2504 r.resultTo = null; 2505 if (resultTo != null) { 2506 resultTo.removeResultsLocked(r, resultWho, requestCode); 2507 } 2508 2509 final long origId = Binder.clearCallingIdentity(); 2510 int res = mMainStack.startActivityLocked(r.app.thread, intent, 2511 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 2512 resultWho, requestCode, -1, r.launchedFromUid, 0, 2513 options, false, null); 2514 Binder.restoreCallingIdentity(origId); 2515 2516 r.finishing = wasFinishing; 2517 if (res != ActivityManager.START_SUCCESS) { 2518 return false; 2519 } 2520 return true; 2521 } 2522 } 2523 2524 public final int startActivityInPackage(int uid, 2525 Intent intent, String resolvedType, IBinder resultTo, 2526 String resultWho, int requestCode, int startFlags, Bundle options) { 2527 2528 // This is so super not safe, that only the system (or okay root) 2529 // can do it. 2530 int userId = Binder.getOrigCallingUser(); 2531 final int callingUid = Binder.getCallingUid(); 2532 if (callingUid != 0 && callingUid != Process.myUid()) { 2533 throw new SecurityException( 2534 "startActivityInPackage only available to the system"); 2535 } 2536 2537 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType, 2538 resultTo, resultWho, requestCode, startFlags, 2539 null, null, null, null, options, userId); 2540 return ret; 2541 } 2542 2543 public final int startActivities(IApplicationThread caller, 2544 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) { 2545 enforceNotIsolatedCaller("startActivities"); 2546 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo, 2547 options, Binder.getOrigCallingUser()); 2548 return ret; 2549 } 2550 2551 public final int startActivitiesInPackage(int uid, 2552 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 2553 Bundle options) { 2554 2555 // This is so super not safe, that only the system (or okay root) 2556 // can do it. 2557 final int callingUid = Binder.getCallingUid(); 2558 if (callingUid != 0 && callingUid != Process.myUid()) { 2559 throw new SecurityException( 2560 "startActivityInPackage only available to the system"); 2561 } 2562 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo, 2563 options, UserId.getUserId(uid)); 2564 return ret; 2565 } 2566 2567 final void addRecentTaskLocked(TaskRecord task) { 2568 int N = mRecentTasks.size(); 2569 // Quick case: check if the top-most recent task is the same. 2570 if (N > 0 && mRecentTasks.get(0) == task) { 2571 return; 2572 } 2573 // Remove any existing entries that are the same kind of task. 2574 for (int i=0; i<N; i++) { 2575 TaskRecord tr = mRecentTasks.get(i); 2576 if (task.userId == tr.userId 2577 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 2578 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 2579 mRecentTasks.remove(i); 2580 i--; 2581 N--; 2582 if (task.intent == null) { 2583 // If the new recent task we are adding is not fully 2584 // specified, then replace it with the existing recent task. 2585 task = tr; 2586 } 2587 } 2588 } 2589 if (N >= MAX_RECENT_TASKS) { 2590 mRecentTasks.remove(N-1); 2591 } 2592 mRecentTasks.add(0, task); 2593 } 2594 2595 public void setRequestedOrientation(IBinder token, 2596 int requestedOrientation) { 2597 synchronized (this) { 2598 ActivityRecord r = mMainStack.isInStackLocked(token); 2599 if (r == null) { 2600 return; 2601 } 2602 final long origId = Binder.clearCallingIdentity(); 2603 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 2604 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2605 mConfiguration, 2606 r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 2607 if (config != null) { 2608 r.frozenBeforeDestroy = true; 2609 if (!updateConfigurationLocked(config, r, false, false)) { 2610 mMainStack.resumeTopActivityLocked(null); 2611 } 2612 } 2613 Binder.restoreCallingIdentity(origId); 2614 } 2615 } 2616 2617 public int getRequestedOrientation(IBinder token) { 2618 synchronized (this) { 2619 ActivityRecord r = mMainStack.isInStackLocked(token); 2620 if (r == null) { 2621 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 2622 } 2623 return mWindowManager.getAppOrientation(r.appToken); 2624 } 2625 } 2626 2627 /** 2628 * This is the internal entry point for handling Activity.finish(). 2629 * 2630 * @param token The Binder token referencing the Activity we want to finish. 2631 * @param resultCode Result code, if any, from this Activity. 2632 * @param resultData Result data (Intent), if any, from this Activity. 2633 * 2634 * @return Returns true if the activity successfully finished, or false if it is still running. 2635 */ 2636 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 2637 // Refuse possible leaked file descriptors 2638 if (resultData != null && resultData.hasFileDescriptors() == true) { 2639 throw new IllegalArgumentException("File descriptors passed in Intent"); 2640 } 2641 2642 synchronized(this) { 2643 if (mController != null) { 2644 // Find the first activity that is not finishing. 2645 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 2646 if (next != null) { 2647 // ask watcher if this is allowed 2648 boolean resumeOK = true; 2649 try { 2650 resumeOK = mController.activityResuming(next.packageName); 2651 } catch (RemoteException e) { 2652 mController = null; 2653 } 2654 2655 if (!resumeOK) { 2656 return false; 2657 } 2658 } 2659 } 2660 final long origId = Binder.clearCallingIdentity(); 2661 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode, 2662 resultData, "app-request"); 2663 Binder.restoreCallingIdentity(origId); 2664 return res; 2665 } 2666 } 2667 2668 public final void finishHeavyWeightApp() { 2669 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2670 != PackageManager.PERMISSION_GRANTED) { 2671 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 2672 + Binder.getCallingPid() 2673 + ", uid=" + Binder.getCallingUid() 2674 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2675 Slog.w(TAG, msg); 2676 throw new SecurityException(msg); 2677 } 2678 2679 synchronized(this) { 2680 if (mHeavyWeightProcess == null) { 2681 return; 2682 } 2683 2684 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 2685 mHeavyWeightProcess.activities); 2686 for (int i=0; i<activities.size(); i++) { 2687 ActivityRecord r = activities.get(i); 2688 if (!r.finishing) { 2689 int index = mMainStack.indexOfTokenLocked(r.appToken); 2690 if (index >= 0) { 2691 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, 2692 null, "finish-heavy"); 2693 } 2694 } 2695 } 2696 2697 mHeavyWeightProcess = null; 2698 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 2699 } 2700 } 2701 2702 public void crashApplication(int uid, int initialPid, String packageName, 2703 String message) { 2704 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2705 != PackageManager.PERMISSION_GRANTED) { 2706 String msg = "Permission Denial: crashApplication() from pid=" 2707 + Binder.getCallingPid() 2708 + ", uid=" + Binder.getCallingUid() 2709 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2710 Slog.w(TAG, msg); 2711 throw new SecurityException(msg); 2712 } 2713 2714 synchronized(this) { 2715 ProcessRecord proc = null; 2716 2717 // Figure out which process to kill. We don't trust that initialPid 2718 // still has any relation to current pids, so must scan through the 2719 // list. 2720 synchronized (mPidsSelfLocked) { 2721 for (int i=0; i<mPidsSelfLocked.size(); i++) { 2722 ProcessRecord p = mPidsSelfLocked.valueAt(i); 2723 if (p.uid != uid) { 2724 continue; 2725 } 2726 if (p.pid == initialPid) { 2727 proc = p; 2728 break; 2729 } 2730 for (String str : p.pkgList) { 2731 if (str.equals(packageName)) { 2732 proc = p; 2733 } 2734 } 2735 } 2736 } 2737 2738 if (proc == null) { 2739 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 2740 + " initialPid=" + initialPid 2741 + " packageName=" + packageName); 2742 return; 2743 } 2744 2745 if (proc.thread != null) { 2746 if (proc.pid == Process.myPid()) { 2747 Log.w(TAG, "crashApplication: trying to crash self!"); 2748 return; 2749 } 2750 long ident = Binder.clearCallingIdentity(); 2751 try { 2752 proc.thread.scheduleCrash(message); 2753 } catch (RemoteException e) { 2754 } 2755 Binder.restoreCallingIdentity(ident); 2756 } 2757 } 2758 } 2759 2760 public final void finishSubActivity(IBinder token, String resultWho, 2761 int requestCode) { 2762 synchronized(this) { 2763 final long origId = Binder.clearCallingIdentity(); 2764 mMainStack.finishSubActivityLocked(token, resultWho, requestCode); 2765 Binder.restoreCallingIdentity(origId); 2766 } 2767 } 2768 2769 public boolean finishActivityAffinity(IBinder token) { 2770 synchronized(this) { 2771 final long origId = Binder.clearCallingIdentity(); 2772 boolean res = mMainStack.finishActivityAffinityLocked(token); 2773 Binder.restoreCallingIdentity(origId); 2774 return res; 2775 } 2776 } 2777 2778 public boolean willActivityBeVisible(IBinder token) { 2779 synchronized(this) { 2780 int i; 2781 for (i=mMainStack.mHistory.size()-1; i>=0; i--) { 2782 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2783 if (r.appToken == token) { 2784 return true; 2785 } 2786 if (r.fullscreen && !r.finishing) { 2787 return false; 2788 } 2789 } 2790 return true; 2791 } 2792 } 2793 2794 public void overridePendingTransition(IBinder token, String packageName, 2795 int enterAnim, int exitAnim) { 2796 synchronized(this) { 2797 ActivityRecord self = mMainStack.isInStackLocked(token); 2798 if (self == null) { 2799 return; 2800 } 2801 2802 final long origId = Binder.clearCallingIdentity(); 2803 2804 if (self.state == ActivityState.RESUMED 2805 || self.state == ActivityState.PAUSING) { 2806 mWindowManager.overridePendingAppTransition(packageName, 2807 enterAnim, exitAnim, null); 2808 } 2809 2810 Binder.restoreCallingIdentity(origId); 2811 } 2812 } 2813 2814 /** 2815 * Main function for removing an existing process from the activity manager 2816 * as a result of that process going away. Clears out all connections 2817 * to the process. 2818 */ 2819 private final void handleAppDiedLocked(ProcessRecord app, 2820 boolean restarting, boolean allowRestart) { 2821 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 2822 if (!restarting) { 2823 mLruProcesses.remove(app); 2824 } 2825 2826 if (mProfileProc == app) { 2827 clearProfilerLocked(); 2828 } 2829 2830 // Just in case... 2831 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { 2832 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); 2833 mMainStack.mPausingActivity = null; 2834 } 2835 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { 2836 mMainStack.mLastPausedActivity = null; 2837 } 2838 2839 // Remove this application's activities from active lists. 2840 mMainStack.removeHistoryRecordsForAppLocked(app); 2841 2842 boolean atTop = true; 2843 boolean hasVisibleActivities = false; 2844 2845 // Clean out the history list. 2846 int i = mMainStack.mHistory.size(); 2847 if (localLOGV) Slog.v( 2848 TAG, "Removing app " + app + " from history with " + i + " entries"); 2849 while (i > 0) { 2850 i--; 2851 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 2852 if (localLOGV) Slog.v( 2853 TAG, "Record #" + i + " " + r + ": app=" + r.app); 2854 if (r.app == app) { 2855 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 2856 if (ActivityStack.DEBUG_ADD_REMOVE) { 2857 RuntimeException here = new RuntimeException("here"); 2858 here.fillInStackTrace(); 2859 Slog.i(TAG, "Removing activity " + r + " from stack at " + i 2860 + ": haveState=" + r.haveState 2861 + " stateNotNeeded=" + r.stateNotNeeded 2862 + " finishing=" + r.finishing 2863 + " state=" + r.state, here); 2864 } 2865 if (!r.finishing) { 2866 Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); 2867 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 2868 System.identityHashCode(r), 2869 r.task.taskId, r.shortComponentName, 2870 "proc died without state saved"); 2871 } 2872 mMainStack.removeActivityFromHistoryLocked(r); 2873 2874 } else { 2875 // We have the current state for this activity, so 2876 // it can be restarted later when needed. 2877 if (localLOGV) Slog.v( 2878 TAG, "Keeping entry, setting app to null"); 2879 if (r.visible) { 2880 hasVisibleActivities = true; 2881 } 2882 r.app = null; 2883 r.nowVisible = false; 2884 if (!r.haveState) { 2885 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG, 2886 "App died, clearing saved state of " + r); 2887 r.icicle = null; 2888 } 2889 } 2890 2891 r.stack.cleanUpActivityLocked(r, true, true); 2892 } 2893 atTop = false; 2894 } 2895 2896 app.activities.clear(); 2897 2898 if (app.instrumentationClass != null) { 2899 Slog.w(TAG, "Crash of app " + app.processName 2900 + " running instrumentation " + app.instrumentationClass); 2901 Bundle info = new Bundle(); 2902 info.putString("shortMsg", "Process crashed."); 2903 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 2904 } 2905 2906 if (!restarting) { 2907 if (!mMainStack.resumeTopActivityLocked(null)) { 2908 // If there was nothing to resume, and we are not already 2909 // restarting this process, but there is a visible activity that 2910 // is hosted by the process... then make sure all visible 2911 // activities are running, taking care of restarting this 2912 // process. 2913 if (hasVisibleActivities) { 2914 mMainStack.ensureActivitiesVisibleLocked(null, 0); 2915 } 2916 } 2917 } 2918 } 2919 2920 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 2921 IBinder threadBinder = thread.asBinder(); 2922 // Find the application record. 2923 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2924 ProcessRecord rec = mLruProcesses.get(i); 2925 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2926 return i; 2927 } 2928 } 2929 return -1; 2930 } 2931 2932 final ProcessRecord getRecordForAppLocked( 2933 IApplicationThread thread) { 2934 if (thread == null) { 2935 return null; 2936 } 2937 2938 int appIndex = getLRURecordIndexForAppLocked(thread); 2939 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 2940 } 2941 2942 final void appDiedLocked(ProcessRecord app, int pid, 2943 IApplicationThread thread) { 2944 2945 mProcDeaths[0]++; 2946 2947 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2948 synchronized (stats) { 2949 stats.noteProcessDiedLocked(app.info.uid, pid); 2950 } 2951 2952 // Clean up already done if the process has been re-started. 2953 if (app.pid == pid && app.thread != null && 2954 app.thread.asBinder() == thread.asBinder()) { 2955 if (!app.killedBackground) { 2956 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 2957 + ") has died."); 2958 } 2959 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 2960 if (localLOGV) Slog.v( 2961 TAG, "Dying app: " + app + ", pid: " + pid 2962 + ", thread: " + thread.asBinder()); 2963 boolean doLowMem = app.instrumentationClass == null; 2964 handleAppDiedLocked(app, false, true); 2965 2966 if (doLowMem) { 2967 // If there are no longer any background processes running, 2968 // and the app that died was not running instrumentation, 2969 // then tell everyone we are now low on memory. 2970 boolean haveBg = false; 2971 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2972 ProcessRecord rec = mLruProcesses.get(i); 2973 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 2974 haveBg = true; 2975 break; 2976 } 2977 } 2978 2979 if (!haveBg) { 2980 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 2981 long now = SystemClock.uptimeMillis(); 2982 for (int i=mLruProcesses.size()-1; i>=0; i--) { 2983 ProcessRecord rec = mLruProcesses.get(i); 2984 if (rec != app && rec.thread != null && 2985 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 2986 // The low memory report is overriding any current 2987 // state for a GC request. Make sure to do 2988 // heavy/important/visible/foreground processes first. 2989 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 2990 rec.lastRequestedGc = 0; 2991 } else { 2992 rec.lastRequestedGc = rec.lastLowMemory; 2993 } 2994 rec.reportLowMemory = true; 2995 rec.lastLowMemory = now; 2996 mProcessesToGc.remove(rec); 2997 addProcessToGcListLocked(rec); 2998 } 2999 } 3000 mHandler.sendEmptyMessage(REPORT_MEM_USAGE); 3001 scheduleAppGcsLocked(); 3002 } 3003 } 3004 } else if (app.pid != pid) { 3005 // A new process has already been started. 3006 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3007 + ") has died and restarted (pid " + app.pid + ")."); 3008 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 3009 } else if (DEBUG_PROCESSES) { 3010 Slog.d(TAG, "Received spurious death notification for thread " 3011 + thread.asBinder()); 3012 } 3013 } 3014 3015 /** 3016 * If a stack trace dump file is configured, dump process stack traces. 3017 * @param clearTraces causes the dump file to be erased prior to the new 3018 * traces being written, if true; when false, the new traces will be 3019 * appended to any existing file content. 3020 * @param firstPids of dalvik VM processes to dump stack traces for first 3021 * @param lastPids of dalvik VM processes to dump stack traces for last 3022 * @param nativeProcs optional list of native process names to dump stack crawls 3023 * @return file containing stack traces, or null if no dump file is configured 3024 */ 3025 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3026 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3027 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3028 if (tracesPath == null || tracesPath.length() == 0) { 3029 return null; 3030 } 3031 3032 File tracesFile = new File(tracesPath); 3033 try { 3034 File tracesDir = tracesFile.getParentFile(); 3035 if (!tracesDir.exists()) tracesFile.mkdirs(); 3036 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3037 3038 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3039 tracesFile.createNewFile(); 3040 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3041 } catch (IOException e) { 3042 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3043 return null; 3044 } 3045 3046 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs); 3047 return tracesFile; 3048 } 3049 3050 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3051 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3052 // Use a FileObserver to detect when traces finish writing. 3053 // The order of traces is considered important to maintain for legibility. 3054 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3055 public synchronized void onEvent(int event, String path) { notify(); } 3056 }; 3057 3058 try { 3059 observer.startWatching(); 3060 3061 // First collect all of the stacks of the most important pids. 3062 if (firstPids != null) { 3063 try { 3064 int num = firstPids.size(); 3065 for (int i = 0; i < num; i++) { 3066 synchronized (observer) { 3067 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3068 observer.wait(200); // Wait for write-close, give up after 200msec 3069 } 3070 } 3071 } catch (InterruptedException e) { 3072 Log.wtf(TAG, e); 3073 } 3074 } 3075 3076 // Next measure CPU usage. 3077 if (processStats != null) { 3078 processStats.init(); 3079 System.gc(); 3080 processStats.update(); 3081 try { 3082 synchronized (processStats) { 3083 processStats.wait(500); // measure over 1/2 second. 3084 } 3085 } catch (InterruptedException e) { 3086 } 3087 processStats.update(); 3088 3089 // We'll take the stack crawls of just the top apps using CPU. 3090 final int N = processStats.countWorkingStats(); 3091 int numProcs = 0; 3092 for (int i=0; i<N && numProcs<5; i++) { 3093 ProcessStats.Stats stats = processStats.getWorkingStats(i); 3094 if (lastPids.indexOfKey(stats.pid) >= 0) { 3095 numProcs++; 3096 try { 3097 synchronized (observer) { 3098 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3099 observer.wait(200); // Wait for write-close, give up after 200msec 3100 } 3101 } catch (InterruptedException e) { 3102 Log.wtf(TAG, e); 3103 } 3104 3105 } 3106 } 3107 } 3108 3109 } finally { 3110 observer.stopWatching(); 3111 } 3112 3113 if (nativeProcs != null) { 3114 int[] pids = Process.getPidsForCommands(nativeProcs); 3115 if (pids != null) { 3116 for (int pid : pids) { 3117 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3118 } 3119 } 3120 } 3121 } 3122 3123 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3124 if (true || IS_USER_BUILD) { 3125 return; 3126 } 3127 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3128 if (tracesPath == null || tracesPath.length() == 0) { 3129 return; 3130 } 3131 3132 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3133 StrictMode.allowThreadDiskWrites(); 3134 try { 3135 final File tracesFile = new File(tracesPath); 3136 final File tracesDir = tracesFile.getParentFile(); 3137 final File tracesTmp = new File(tracesDir, "__tmp__"); 3138 try { 3139 if (!tracesDir.exists()) tracesFile.mkdirs(); 3140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3141 3142 if (tracesFile.exists()) { 3143 tracesTmp.delete(); 3144 tracesFile.renameTo(tracesTmp); 3145 } 3146 StringBuilder sb = new StringBuilder(); 3147 Time tobj = new Time(); 3148 tobj.set(System.currentTimeMillis()); 3149 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3150 sb.append(": "); 3151 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3152 sb.append(" since "); 3153 sb.append(msg); 3154 FileOutputStream fos = new FileOutputStream(tracesFile); 3155 fos.write(sb.toString().getBytes()); 3156 if (app == null) { 3157 fos.write("\n*** No application process!".getBytes()); 3158 } 3159 fos.close(); 3160 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3161 } catch (IOException e) { 3162 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3163 return; 3164 } 3165 3166 if (app != null) { 3167 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3168 firstPids.add(app.pid); 3169 dumpStackTraces(tracesPath, firstPids, null, null, null); 3170 } 3171 3172 File lastTracesFile = null; 3173 File curTracesFile = null; 3174 for (int i=9; i>=0; i--) { 3175 String name = String.format("slow%02d.txt", i); 3176 curTracesFile = new File(tracesDir, name); 3177 if (curTracesFile.exists()) { 3178 if (lastTracesFile != null) { 3179 curTracesFile.renameTo(lastTracesFile); 3180 } else { 3181 curTracesFile.delete(); 3182 } 3183 } 3184 lastTracesFile = curTracesFile; 3185 } 3186 tracesFile.renameTo(curTracesFile); 3187 if (tracesTmp.exists()) { 3188 tracesTmp.renameTo(tracesFile); 3189 } 3190 } finally { 3191 StrictMode.setThreadPolicy(oldPolicy); 3192 } 3193 } 3194 3195 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3196 ActivityRecord parent, final String annotation) { 3197 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3198 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3199 3200 if (mController != null) { 3201 try { 3202 // 0 == continue, -1 = kill process immediately 3203 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3204 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3205 } catch (RemoteException e) { 3206 mController = null; 3207 } 3208 } 3209 3210 long anrTime = SystemClock.uptimeMillis(); 3211 if (MONITOR_CPU_USAGE) { 3212 updateCpuStatsNow(); 3213 } 3214 3215 synchronized (this) { 3216 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3217 if (mShuttingDown) { 3218 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3219 return; 3220 } else if (app.notResponding) { 3221 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3222 return; 3223 } else if (app.crashing) { 3224 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3225 return; 3226 } 3227 3228 // In case we come through here for the same app before completing 3229 // this one, mark as anring now so we will bail out. 3230 app.notResponding = true; 3231 3232 // Log the ANR to the event log. 3233 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 3234 annotation); 3235 3236 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3237 firstPids.add(app.pid); 3238 3239 int parentPid = app.pid; 3240 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3241 if (parentPid != app.pid) firstPids.add(parentPid); 3242 3243 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3244 3245 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3246 ProcessRecord r = mLruProcesses.get(i); 3247 if (r != null && r.thread != null) { 3248 int pid = r.pid; 3249 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3250 if (r.persistent) { 3251 firstPids.add(pid); 3252 } else { 3253 lastPids.put(pid, Boolean.TRUE); 3254 } 3255 } 3256 } 3257 } 3258 } 3259 3260 // Log the ANR to the main log. 3261 StringBuilder info = new StringBuilder(); 3262 info.setLength(0); 3263 info.append("ANR in ").append(app.processName); 3264 if (activity != null && activity.shortComponentName != null) { 3265 info.append(" (").append(activity.shortComponentName).append(")"); 3266 } 3267 info.append("\n"); 3268 if (annotation != null) { 3269 info.append("Reason: ").append(annotation).append("\n"); 3270 } 3271 if (parent != null && parent != activity) { 3272 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3273 } 3274 3275 final ProcessStats processStats = new ProcessStats(true); 3276 3277 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null); 3278 3279 String cpuInfo = null; 3280 if (MONITOR_CPU_USAGE) { 3281 updateCpuStatsNow(); 3282 synchronized (mProcessStatsThread) { 3283 cpuInfo = mProcessStats.printCurrentState(anrTime); 3284 } 3285 info.append(processStats.printCurrentLoad()); 3286 info.append(cpuInfo); 3287 } 3288 3289 info.append(processStats.printCurrentState(anrTime)); 3290 3291 Slog.e(TAG, info.toString()); 3292 if (tracesFile == null) { 3293 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3294 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3295 } 3296 3297 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3298 cpuInfo, tracesFile, null); 3299 3300 if (mController != null) { 3301 try { 3302 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3303 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3304 if (res != 0) { 3305 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3306 return; 3307 } 3308 } catch (RemoteException e) { 3309 mController = null; 3310 } 3311 } 3312 3313 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3314 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3315 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3316 3317 synchronized (this) { 3318 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3319 Slog.w(TAG, "Killing " + app + ": background ANR"); 3320 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 3321 app.processName, app.setAdj, "background ANR"); 3322 Process.killProcessQuiet(app.pid); 3323 return; 3324 } 3325 3326 // Set the app's notResponding state, and look up the errorReportReceiver 3327 makeAppNotRespondingLocked(app, 3328 activity != null ? activity.shortComponentName : null, 3329 annotation != null ? "ANR " + annotation : "ANR", 3330 info.toString()); 3331 3332 // Bring up the infamous App Not Responding dialog 3333 Message msg = Message.obtain(); 3334 HashMap map = new HashMap(); 3335 msg.what = SHOW_NOT_RESPONDING_MSG; 3336 msg.obj = map; 3337 map.put("app", app); 3338 if (activity != null) { 3339 map.put("activity", activity); 3340 } 3341 3342 mHandler.sendMessage(msg); 3343 } 3344 } 3345 3346 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3347 if (!mLaunchWarningShown) { 3348 mLaunchWarningShown = true; 3349 mHandler.post(new Runnable() { 3350 @Override 3351 public void run() { 3352 synchronized (ActivityManagerService.this) { 3353 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3354 d.show(); 3355 mHandler.postDelayed(new Runnable() { 3356 @Override 3357 public void run() { 3358 synchronized (ActivityManagerService.this) { 3359 d.dismiss(); 3360 mLaunchWarningShown = false; 3361 } 3362 } 3363 }, 4000); 3364 } 3365 } 3366 }); 3367 } 3368 } 3369 3370 public boolean clearApplicationUserData(final String packageName, 3371 final IPackageDataObserver observer, final int userId) { 3372 enforceNotIsolatedCaller("clearApplicationUserData"); 3373 int uid = Binder.getCallingUid(); 3374 int pid = Binder.getCallingPid(); 3375 long callingId = Binder.clearCallingIdentity(); 3376 try { 3377 IPackageManager pm = AppGlobals.getPackageManager(); 3378 int pkgUid = -1; 3379 synchronized(this) { 3380 try { 3381 pkgUid = pm.getPackageUid(packageName, userId); 3382 } catch (RemoteException e) { 3383 } 3384 if (pkgUid == -1) { 3385 Slog.w(TAG, "Invalid packageName:" + packageName); 3386 return false; 3387 } 3388 if (uid == pkgUid || checkComponentPermission( 3389 android.Manifest.permission.CLEAR_APP_USER_DATA, 3390 pid, uid, -1, true) 3391 == PackageManager.PERMISSION_GRANTED) { 3392 forceStopPackageLocked(packageName, pkgUid); 3393 } else { 3394 throw new SecurityException(pid+" does not have permission:"+ 3395 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 3396 "for process:"+packageName); 3397 } 3398 } 3399 3400 try { 3401 //clear application user data 3402 pm.clearApplicationUserData(packageName, observer, userId); 3403 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 3404 Uri.fromParts("package", packageName, null)); 3405 intent.putExtra(Intent.EXTRA_UID, pkgUid); 3406 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 3407 null, null, 0, null, null, null, false, false, userId); 3408 } catch (RemoteException e) { 3409 } 3410 } finally { 3411 Binder.restoreCallingIdentity(callingId); 3412 } 3413 return true; 3414 } 3415 3416 public void killBackgroundProcesses(final String packageName) { 3417 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3418 != PackageManager.PERMISSION_GRANTED && 3419 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 3420 != PackageManager.PERMISSION_GRANTED) { 3421 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 3422 + Binder.getCallingPid() 3423 + ", uid=" + Binder.getCallingUid() 3424 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3425 Slog.w(TAG, msg); 3426 throw new SecurityException(msg); 3427 } 3428 3429 int userId = UserId.getCallingUserId(); 3430 long callingId = Binder.clearCallingIdentity(); 3431 try { 3432 IPackageManager pm = AppGlobals.getPackageManager(); 3433 int pkgUid = -1; 3434 synchronized(this) { 3435 try { 3436 pkgUid = pm.getPackageUid(packageName, userId); 3437 } catch (RemoteException e) { 3438 } 3439 if (pkgUid == -1) { 3440 Slog.w(TAG, "Invalid packageName: " + packageName); 3441 return; 3442 } 3443 killPackageProcessesLocked(packageName, pkgUid, 3444 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 3445 } 3446 } finally { 3447 Binder.restoreCallingIdentity(callingId); 3448 } 3449 } 3450 3451 public void killAllBackgroundProcesses() { 3452 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 long callingId = Binder.clearCallingIdentity(); 3463 try { 3464 synchronized(this) { 3465 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3466 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3467 final int NA = apps.size(); 3468 for (int ia=0; ia<NA; ia++) { 3469 ProcessRecord app = apps.valueAt(ia); 3470 if (app.persistent) { 3471 // we don't kill persistent processes 3472 continue; 3473 } 3474 if (app.removed) { 3475 procs.add(app); 3476 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 3477 app.removed = true; 3478 procs.add(app); 3479 } 3480 } 3481 } 3482 3483 int N = procs.size(); 3484 for (int i=0; i<N; i++) { 3485 removeProcessLocked(procs.get(i), false, true, "kill all background"); 3486 } 3487 } 3488 } finally { 3489 Binder.restoreCallingIdentity(callingId); 3490 } 3491 } 3492 3493 public void forceStopPackage(final String packageName) { 3494 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3495 != PackageManager.PERMISSION_GRANTED) { 3496 String msg = "Permission Denial: forceStopPackage() from pid=" 3497 + Binder.getCallingPid() 3498 + ", uid=" + Binder.getCallingUid() 3499 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3500 Slog.w(TAG, msg); 3501 throw new SecurityException(msg); 3502 } 3503 final int userId = UserId.getCallingUserId(); 3504 long callingId = Binder.clearCallingIdentity(); 3505 try { 3506 IPackageManager pm = AppGlobals.getPackageManager(); 3507 int pkgUid = -1; 3508 synchronized(this) { 3509 try { 3510 pkgUid = pm.getPackageUid(packageName, userId); 3511 } catch (RemoteException e) { 3512 } 3513 if (pkgUid == -1) { 3514 Slog.w(TAG, "Invalid packageName: " + packageName); 3515 return; 3516 } 3517 forceStopPackageLocked(packageName, pkgUid); 3518 try { 3519 pm.setPackageStoppedState(packageName, true, userId); 3520 } catch (RemoteException e) { 3521 } catch (IllegalArgumentException e) { 3522 Slog.w(TAG, "Failed trying to unstop package " 3523 + packageName + ": " + e); 3524 } 3525 } 3526 } finally { 3527 Binder.restoreCallingIdentity(callingId); 3528 } 3529 } 3530 3531 /* 3532 * The pkg name and uid have to be specified. 3533 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 3534 */ 3535 public void killApplicationWithUid(String pkg, int uid) { 3536 if (pkg == null) { 3537 return; 3538 } 3539 // Make sure the uid is valid. 3540 if (uid < 0) { 3541 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 3542 return; 3543 } 3544 int callerUid = Binder.getCallingUid(); 3545 // Only the system server can kill an application 3546 if (callerUid == Process.SYSTEM_UID) { 3547 // Post an aysnc message to kill the application 3548 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 3549 msg.arg1 = uid; 3550 msg.arg2 = 0; 3551 msg.obj = pkg; 3552 mHandler.sendMessage(msg); 3553 } else { 3554 throw new SecurityException(callerUid + " cannot kill pkg: " + 3555 pkg); 3556 } 3557 } 3558 3559 public void closeSystemDialogs(String reason) { 3560 enforceNotIsolatedCaller("closeSystemDialogs"); 3561 3562 final int uid = Binder.getCallingUid(); 3563 final long origId = Binder.clearCallingIdentity(); 3564 synchronized (this) { 3565 closeSystemDialogsLocked(uid, reason); 3566 } 3567 Binder.restoreCallingIdentity(origId); 3568 } 3569 3570 void closeSystemDialogsLocked(int callingUid, String reason) { 3571 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 3572 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3573 if (reason != null) { 3574 intent.putExtra("reason", reason); 3575 } 3576 mWindowManager.closeSystemDialogs(reason); 3577 3578 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 3579 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3580 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 3581 r.stack.finishActivityLocked(r, i, 3582 Activity.RESULT_CANCELED, null, "close-sys"); 3583 } 3584 } 3585 3586 broadcastIntentLocked(null, null, intent, null, 3587 null, 0, null, null, null, false, false, -1, 3588 callingUid, 0 /* TODO: Verify */); 3589 } 3590 3591 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 3592 throws RemoteException { 3593 enforceNotIsolatedCaller("getProcessMemoryInfo"); 3594 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 3595 for (int i=pids.length-1; i>=0; i--) { 3596 infos[i] = new Debug.MemoryInfo(); 3597 Debug.getMemoryInfo(pids[i], infos[i]); 3598 } 3599 return infos; 3600 } 3601 3602 public long[] getProcessPss(int[] pids) throws RemoteException { 3603 enforceNotIsolatedCaller("getProcessPss"); 3604 long[] pss = new long[pids.length]; 3605 for (int i=pids.length-1; i>=0; i--) { 3606 pss[i] = Debug.getPss(pids[i]); 3607 } 3608 return pss; 3609 } 3610 3611 public void killApplicationProcess(String processName, int uid) { 3612 if (processName == null) { 3613 return; 3614 } 3615 3616 int callerUid = Binder.getCallingUid(); 3617 // Only the system server can kill an application 3618 if (callerUid == Process.SYSTEM_UID) { 3619 synchronized (this) { 3620 ProcessRecord app = getProcessRecordLocked(processName, uid); 3621 if (app != null && app.thread != null) { 3622 try { 3623 app.thread.scheduleSuicide(); 3624 } catch (RemoteException e) { 3625 // If the other end already died, then our work here is done. 3626 } 3627 } else { 3628 Slog.w(TAG, "Process/uid not found attempting kill of " 3629 + processName + " / " + uid); 3630 } 3631 } 3632 } else { 3633 throw new SecurityException(callerUid + " cannot kill app process: " + 3634 processName); 3635 } 3636 } 3637 3638 private void forceStopPackageLocked(final String packageName, int uid) { 3639 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid)); 3640 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 3641 Uri.fromParts("package", packageName, null)); 3642 if (!mProcessesReady) { 3643 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3644 } 3645 intent.putExtra(Intent.EXTRA_UID, uid); 3646 broadcastIntentLocked(null, null, intent, 3647 null, null, 0, null, null, null, 3648 false, false, 3649 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid)); 3650 } 3651 3652 private final boolean killPackageProcessesLocked(String packageName, int uid, 3653 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, 3654 boolean evenPersistent, String reason) { 3655 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 3656 3657 // Remove all processes this package may have touched: all with the 3658 // same UID (except for the system or root user), and all whose name 3659 // matches the package name. 3660 final String procNamePrefix = packageName + ":"; 3661 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 3662 final int NA = apps.size(); 3663 for (int ia=0; ia<NA; ia++) { 3664 ProcessRecord app = apps.valueAt(ia); 3665 if (app.persistent && !evenPersistent) { 3666 // we don't kill persistent processes 3667 continue; 3668 } 3669 if (app.removed) { 3670 if (doit) { 3671 procs.add(app); 3672 } 3673 // If uid is specified and the uid and process name match 3674 // Or, the uid is not specified and the process name matches 3675 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 3676 || ((app.processName.equals(packageName) 3677 || app.processName.startsWith(procNamePrefix)) 3678 && uid < 0))) { 3679 if (app.setAdj >= minOomAdj) { 3680 if (!doit) { 3681 return true; 3682 } 3683 app.removed = true; 3684 procs.add(app); 3685 } 3686 } 3687 } 3688 } 3689 3690 int N = procs.size(); 3691 for (int i=0; i<N; i++) { 3692 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 3693 } 3694 return N > 0; 3695 } 3696 3697 private final boolean forceStopPackageLocked(String name, int uid, 3698 boolean callerWillRestart, boolean purgeCache, boolean doit, 3699 boolean evenPersistent, int userId) { 3700 int i; 3701 int N; 3702 3703 if (uid < 0) { 3704 try { 3705 uid = AppGlobals.getPackageManager().getPackageUid(name, userId); 3706 } catch (RemoteException e) { 3707 } 3708 } 3709 3710 if (doit) { 3711 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 3712 3713 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 3714 while (badApps.hasNext()) { 3715 SparseArray<Long> ba = badApps.next(); 3716 if (ba.get(uid) != null) { 3717 badApps.remove(); 3718 } 3719 } 3720 } 3721 3722 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 3723 callerWillRestart, false, doit, evenPersistent, "force stop"); 3724 3725 TaskRecord lastTask = null; 3726 for (i=0; i<mMainStack.mHistory.size(); i++) { 3727 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 3728 final boolean samePackage = r.packageName.equals(name); 3729 if (r.userId == userId 3730 && (samePackage || r.task == lastTask) 3731 && (r.app == null || evenPersistent || !r.app.persistent)) { 3732 if (!doit) { 3733 if (r.finishing) { 3734 // If this activity is just finishing, then it is not 3735 // interesting as far as something to stop. 3736 continue; 3737 } 3738 return true; 3739 } 3740 didSomething = true; 3741 Slog.i(TAG, " Force finishing activity " + r); 3742 if (samePackage) { 3743 if (r.app != null) { 3744 r.app.removed = true; 3745 } 3746 r.app = null; 3747 } 3748 lastTask = r.task; 3749 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3750 null, "force-stop", true)) { 3751 i--; 3752 } 3753 } 3754 } 3755 3756 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 3757 for (ServiceRecord service : mServiceMap.getAllServices(userId)) { 3758 if (service.packageName.equals(name) 3759 && (service.app == null || evenPersistent || !service.app.persistent)) { 3760 if (!doit) { 3761 return true; 3762 } 3763 didSomething = true; 3764 Slog.i(TAG, " Force stopping service " + service); 3765 if (service.app != null) { 3766 service.app.removed = true; 3767 } 3768 service.app = null; 3769 service.isolatedProc = null; 3770 services.add(service); 3771 } 3772 } 3773 3774 N = services.size(); 3775 for (i=0; i<N; i++) { 3776 bringDownServiceLocked(services.get(i), true); 3777 } 3778 3779 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 3780 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) { 3781 if (provider.info.packageName.equals(name) 3782 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { 3783 if (!doit) { 3784 return true; 3785 } 3786 didSomething = true; 3787 providers.add(provider); 3788 } 3789 } 3790 3791 N = providers.size(); 3792 for (i=0; i<N; i++) { 3793 removeDyingProviderLocked(null, providers.get(i), true); 3794 } 3795 3796 if (doit) { 3797 if (purgeCache) { 3798 AttributeCache ac = AttributeCache.instance(); 3799 if (ac != null) { 3800 ac.removePackage(name); 3801 } 3802 } 3803 if (mBooted) { 3804 mMainStack.resumeTopActivityLocked(null); 3805 mMainStack.scheduleIdleLocked(); 3806 } 3807 } 3808 3809 return didSomething; 3810 } 3811 3812 private final boolean removeProcessLocked(ProcessRecord app, 3813 boolean callerWillRestart, boolean allowRestart, String reason) { 3814 final String name = app.processName; 3815 final int uid = app.uid; 3816 if (DEBUG_PROCESSES) Slog.d( 3817 TAG, "Force removing proc " + app.toShortString() + " (" + name 3818 + "/" + uid + ")"); 3819 3820 mProcessNames.remove(name, uid); 3821 mIsolatedProcesses.remove(app.uid); 3822 if (mHeavyWeightProcess == app) { 3823 mHeavyWeightProcess = null; 3824 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3825 } 3826 boolean needRestart = false; 3827 if (app.pid > 0 && app.pid != MY_PID) { 3828 int pid = app.pid; 3829 synchronized (mPidsSelfLocked) { 3830 mPidsSelfLocked.remove(pid); 3831 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3832 } 3833 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason); 3834 handleAppDiedLocked(app, true, allowRestart); 3835 mLruProcesses.remove(app); 3836 Process.killProcessQuiet(pid); 3837 3838 if (app.persistent && !app.isolated) { 3839 if (!callerWillRestart) { 3840 addAppLocked(app.info, false); 3841 } else { 3842 needRestart = true; 3843 } 3844 } 3845 } else { 3846 mRemovedProcesses.add(app); 3847 } 3848 3849 return needRestart; 3850 } 3851 3852 private final void processStartTimedOutLocked(ProcessRecord app) { 3853 final int pid = app.pid; 3854 boolean gone = false; 3855 synchronized (mPidsSelfLocked) { 3856 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 3857 if (knownApp != null && knownApp.thread == null) { 3858 mPidsSelfLocked.remove(pid); 3859 gone = true; 3860 } 3861 } 3862 3863 if (gone) { 3864 Slog.w(TAG, "Process " + app + " failed to attach"); 3865 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid, 3866 app.processName); 3867 mProcessNames.remove(app.processName, app.uid); 3868 mIsolatedProcesses.remove(app.uid); 3869 if (mHeavyWeightProcess == app) { 3870 mHeavyWeightProcess = null; 3871 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 3872 } 3873 // Take care of any launching providers waiting for this process. 3874 checkAppInLaunchingProvidersLocked(app, true); 3875 // Take care of any services that are waiting for the process. 3876 for (int i=0; i<mPendingServices.size(); i++) { 3877 ServiceRecord sr = mPendingServices.get(i); 3878 if ((app.uid == sr.appInfo.uid 3879 && app.processName.equals(sr.processName)) 3880 || sr.isolatedProc == app) { 3881 Slog.w(TAG, "Forcing bringing down service: " + sr); 3882 sr.isolatedProc = null; 3883 mPendingServices.remove(i); 3884 i--; 3885 bringDownServiceLocked(sr, true); 3886 } 3887 } 3888 EventLog.writeEvent(EventLogTags.AM_KILL, pid, 3889 app.processName, app.setAdj, "start timeout"); 3890 Process.killProcessQuiet(pid); 3891 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 3892 Slog.w(TAG, "Unattached app died before backup, skipping"); 3893 try { 3894 IBackupManager bm = IBackupManager.Stub.asInterface( 3895 ServiceManager.getService(Context.BACKUP_SERVICE)); 3896 bm.agentDisconnected(app.info.packageName); 3897 } catch (RemoteException e) { 3898 // Can't happen; the backup manager is local 3899 } 3900 } 3901 if (isPendingBroadcastProcessLocked(pid)) { 3902 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 3903 skipPendingBroadcastLocked(pid); 3904 } 3905 } else { 3906 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 3907 } 3908 } 3909 3910 private final boolean attachApplicationLocked(IApplicationThread thread, 3911 int pid) { 3912 3913 // Find the application record that is being attached... either via 3914 // the pid if we are running in multiple processes, or just pull the 3915 // next app record if we are emulating process with anonymous threads. 3916 ProcessRecord app; 3917 if (pid != MY_PID && pid >= 0) { 3918 synchronized (mPidsSelfLocked) { 3919 app = mPidsSelfLocked.get(pid); 3920 } 3921 } else { 3922 app = null; 3923 } 3924 3925 if (app == null) { 3926 Slog.w(TAG, "No pending application record for pid " + pid 3927 + " (IApplicationThread " + thread + "); dropping process"); 3928 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 3929 if (pid > 0 && pid != MY_PID) { 3930 Process.killProcessQuiet(pid); 3931 } else { 3932 try { 3933 thread.scheduleExit(); 3934 } catch (Exception e) { 3935 // Ignore exceptions. 3936 } 3937 } 3938 return false; 3939 } 3940 3941 // If this application record is still attached to a previous 3942 // process, clean it up now. 3943 if (app.thread != null) { 3944 handleAppDiedLocked(app, true, true); 3945 } 3946 3947 // Tell the process all about itself. 3948 3949 if (localLOGV) Slog.v( 3950 TAG, "Binding process pid " + pid + " to record " + app); 3951 3952 String processName = app.processName; 3953 try { 3954 AppDeathRecipient adr = new AppDeathRecipient( 3955 app, pid, thread); 3956 thread.asBinder().linkToDeath(adr, 0); 3957 app.deathRecipient = adr; 3958 } catch (RemoteException e) { 3959 app.resetPackageList(); 3960 startProcessLocked(app, "link fail", processName); 3961 return false; 3962 } 3963 3964 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 3965 3966 app.thread = thread; 3967 app.curAdj = app.setAdj = -100; 3968 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 3969 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 3970 app.forcingToForeground = null; 3971 app.foregroundServices = false; 3972 app.hasShownUi = false; 3973 app.debugging = false; 3974 3975 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3976 3977 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 3978 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 3979 3980 if (!normalMode) { 3981 Slog.i(TAG, "Launching preboot mode app: " + app); 3982 } 3983 3984 if (localLOGV) Slog.v( 3985 TAG, "New app record " + app 3986 + " thread=" + thread.asBinder() + " pid=" + pid); 3987 try { 3988 int testMode = IApplicationThread.DEBUG_OFF; 3989 if (mDebugApp != null && mDebugApp.equals(processName)) { 3990 testMode = mWaitForDebugger 3991 ? IApplicationThread.DEBUG_WAIT 3992 : IApplicationThread.DEBUG_ON; 3993 app.debugging = true; 3994 if (mDebugTransient) { 3995 mDebugApp = mOrigDebugApp; 3996 mWaitForDebugger = mOrigWaitForDebugger; 3997 } 3998 } 3999 String profileFile = app.instrumentationProfileFile; 4000 ParcelFileDescriptor profileFd = null; 4001 boolean profileAutoStop = false; 4002 if (mProfileApp != null && mProfileApp.equals(processName)) { 4003 mProfileProc = app; 4004 profileFile = mProfileFile; 4005 profileFd = mProfileFd; 4006 profileAutoStop = mAutoStopProfiler; 4007 } 4008 boolean enableOpenGlTrace = false; 4009 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4010 enableOpenGlTrace = true; 4011 mOpenGlTraceApp = null; 4012 } 4013 4014 // If the app is being launched for restore or full backup, set it up specially 4015 boolean isRestrictedBackupMode = false; 4016 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4017 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4018 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4019 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4020 } 4021 4022 ensurePackageDexOpt(app.instrumentationInfo != null 4023 ? app.instrumentationInfo.packageName 4024 : app.info.packageName); 4025 if (app.instrumentationClass != null) { 4026 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4027 } 4028 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4029 + processName + " with config " + mConfiguration); 4030 ApplicationInfo appInfo = app.instrumentationInfo != null 4031 ? app.instrumentationInfo : app.info; 4032 app.compat = compatibilityInfoForPackageLocked(appInfo); 4033 if (profileFd != null) { 4034 profileFd = profileFd.dup(); 4035 } 4036 thread.bindApplication(processName, appInfo, providers, 4037 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4038 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4039 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, 4040 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4041 mCoreSettingsObserver.getCoreSettingsLocked()); 4042 updateLruProcessLocked(app, false, true); 4043 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4044 } catch (Exception e) { 4045 // todo: Yikes! What should we do? For now we will try to 4046 // start another process, but that could easily get us in 4047 // an infinite loop of restarting processes... 4048 Slog.w(TAG, "Exception thrown during bind!", e); 4049 4050 app.resetPackageList(); 4051 app.unlinkDeathRecipient(); 4052 startProcessLocked(app, "bind fail", processName); 4053 return false; 4054 } 4055 4056 // Remove this record from the list of starting applications. 4057 mPersistentStartingProcesses.remove(app); 4058 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4059 "Attach application locked removing on hold: " + app); 4060 mProcessesOnHold.remove(app); 4061 4062 boolean badApp = false; 4063 boolean didSomething = false; 4064 4065 // See if the top visible activity is waiting to run in this process... 4066 ActivityRecord hr = mMainStack.topRunningActivityLocked(null); 4067 if (hr != null && normalMode) { 4068 if (hr.app == null && app.uid == hr.info.applicationInfo.uid 4069 && processName.equals(hr.processName)) { 4070 try { 4071 if (mHeadless) { 4072 Slog.e(TAG, "Starting activities not supported on headless device: " + hr); 4073 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) { 4074 didSomething = true; 4075 } 4076 } catch (Exception e) { 4077 Slog.w(TAG, "Exception in new application when starting activity " 4078 + hr.intent.getComponent().flattenToShortString(), e); 4079 badApp = true; 4080 } 4081 } else { 4082 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0); 4083 } 4084 } 4085 4086 // Find any services that should be running in this process... 4087 if (!badApp && mPendingServices.size() > 0) { 4088 ServiceRecord sr = null; 4089 try { 4090 for (int i=0; i<mPendingServices.size(); i++) { 4091 sr = mPendingServices.get(i); 4092 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid 4093 || !processName.equals(sr.processName))) { 4094 continue; 4095 } 4096 4097 mPendingServices.remove(i); 4098 i--; 4099 realStartServiceLocked(sr, app); 4100 didSomething = true; 4101 } 4102 } catch (Exception e) { 4103 Slog.w(TAG, "Exception in new application when starting service " 4104 + sr.shortName, e); 4105 badApp = true; 4106 } 4107 } 4108 4109 // Check if a next-broadcast receiver is in this process... 4110 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4111 try { 4112 didSomething = sendPendingBroadcastsLocked(app); 4113 } catch (Exception e) { 4114 // If the app died trying to launch the receiver we declare it 'bad' 4115 badApp = true; 4116 } 4117 } 4118 4119 // Check whether the next backup agent is in this process... 4120 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4121 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4122 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4123 try { 4124 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4125 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4126 mBackupTarget.backupMode); 4127 } catch (Exception e) { 4128 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4129 e.printStackTrace(); 4130 } 4131 } 4132 4133 if (badApp) { 4134 // todo: Also need to kill application to deal with all 4135 // kinds of exceptions. 4136 handleAppDiedLocked(app, false, true); 4137 return false; 4138 } 4139 4140 if (!didSomething) { 4141 updateOomAdjLocked(); 4142 } 4143 4144 return true; 4145 } 4146 4147 public final void attachApplication(IApplicationThread thread) { 4148 synchronized (this) { 4149 int callingPid = Binder.getCallingPid(); 4150 final long origId = Binder.clearCallingIdentity(); 4151 attachApplicationLocked(thread, callingPid); 4152 Binder.restoreCallingIdentity(origId); 4153 } 4154 } 4155 4156 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4157 final long origId = Binder.clearCallingIdentity(); 4158 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config); 4159 if (stopProfiling) { 4160 synchronized (this) { 4161 if (mProfileProc == r.app) { 4162 if (mProfileFd != null) { 4163 try { 4164 mProfileFd.close(); 4165 } catch (IOException e) { 4166 } 4167 clearProfilerLocked(); 4168 } 4169 } 4170 } 4171 } 4172 Binder.restoreCallingIdentity(origId); 4173 } 4174 4175 void enableScreenAfterBoot() { 4176 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4177 SystemClock.uptimeMillis()); 4178 mWindowManager.enableScreenAfterBoot(); 4179 4180 synchronized (this) { 4181 updateEventDispatchingLocked(); 4182 } 4183 } 4184 4185 public void showBootMessage(final CharSequence msg, final boolean always) { 4186 enforceNotIsolatedCaller("showBootMessage"); 4187 mWindowManager.showBootMessage(msg, always); 4188 } 4189 4190 public void dismissKeyguardOnNextActivity() { 4191 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4192 final long token = Binder.clearCallingIdentity(); 4193 try { 4194 synchronized (this) { 4195 if (mLockScreenShown) { 4196 mLockScreenShown = false; 4197 comeOutOfSleepIfNeededLocked(); 4198 } 4199 mMainStack.dismissKeyguardOnNextActivityLocked(); 4200 } 4201 } finally { 4202 Binder.restoreCallingIdentity(token); 4203 } 4204 } 4205 4206 final void finishBooting() { 4207 IntentFilter pkgFilter = new IntentFilter(); 4208 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4209 pkgFilter.addDataScheme("package"); 4210 mContext.registerReceiver(new BroadcastReceiver() { 4211 @Override 4212 public void onReceive(Context context, Intent intent) { 4213 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4214 if (pkgs != null) { 4215 for (String pkg : pkgs) { 4216 synchronized (ActivityManagerService.this) { 4217 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) { 4218 setResultCode(Activity.RESULT_OK); 4219 return; 4220 } 4221 } 4222 } 4223 } 4224 } 4225 }, pkgFilter); 4226 4227 IntentFilter userFilter = new IntentFilter(); 4228 userFilter.addAction(Intent.ACTION_USER_REMOVED); 4229 mContext.registerReceiver(new BroadcastReceiver() { 4230 @Override 4231 public void onReceive(Context context, Intent intent) { 4232 onUserRemoved(intent); 4233 } 4234 }, userFilter); 4235 4236 synchronized (this) { 4237 // Ensure that any processes we had put on hold are now started 4238 // up. 4239 final int NP = mProcessesOnHold.size(); 4240 if (NP > 0) { 4241 ArrayList<ProcessRecord> procs = 4242 new ArrayList<ProcessRecord>(mProcessesOnHold); 4243 for (int ip=0; ip<NP; ip++) { 4244 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 4245 + procs.get(ip)); 4246 startProcessLocked(procs.get(ip), "on-hold", null); 4247 } 4248 } 4249 4250 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 4251 // Start looking for apps that are abusing wake locks. 4252 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 4253 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 4254 // Tell anyone interested that we are done booting! 4255 SystemProperties.set("sys.boot_completed", "1"); 4256 SystemProperties.set("dev.bootcomplete", "1"); 4257 /* TODO: Send this to all users that are to be logged in on startup */ 4258 broadcastIntentLocked(null, null, 4259 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 4260 null, null, 0, null, null, 4261 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 4262 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser()); 4263 } 4264 } 4265 } 4266 4267 final void ensureBootCompleted() { 4268 boolean booting; 4269 boolean enableScreen; 4270 synchronized (this) { 4271 booting = mBooting; 4272 mBooting = false; 4273 enableScreen = !mBooted; 4274 mBooted = true; 4275 } 4276 4277 if (booting) { 4278 finishBooting(); 4279 } 4280 4281 if (enableScreen) { 4282 enableScreenAfterBoot(); 4283 } 4284 } 4285 4286 public final void activityPaused(IBinder token) { 4287 final long origId = Binder.clearCallingIdentity(); 4288 mMainStack.activityPaused(token, false); 4289 Binder.restoreCallingIdentity(origId); 4290 } 4291 4292 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 4293 CharSequence description) { 4294 if (localLOGV) Slog.v( 4295 TAG, "Activity stopped: token=" + token); 4296 4297 // Refuse possible leaked file descriptors 4298 if (icicle != null && icicle.hasFileDescriptors()) { 4299 throw new IllegalArgumentException("File descriptors passed in Bundle"); 4300 } 4301 4302 ActivityRecord r = null; 4303 4304 final long origId = Binder.clearCallingIdentity(); 4305 4306 synchronized (this) { 4307 r = mMainStack.isInStackLocked(token); 4308 if (r != null) { 4309 r.stack.activityStoppedLocked(r, icicle, thumbnail, description); 4310 } 4311 } 4312 4313 if (r != null) { 4314 sendPendingThumbnail(r, null, null, null, false); 4315 } 4316 4317 trimApplications(); 4318 4319 Binder.restoreCallingIdentity(origId); 4320 } 4321 4322 public final void activityDestroyed(IBinder token) { 4323 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 4324 mMainStack.activityDestroyed(token); 4325 } 4326 4327 public String getCallingPackage(IBinder token) { 4328 synchronized (this) { 4329 ActivityRecord r = getCallingRecordLocked(token); 4330 return r != null && r.app != null ? r.info.packageName : null; 4331 } 4332 } 4333 4334 public ComponentName getCallingActivity(IBinder token) { 4335 synchronized (this) { 4336 ActivityRecord r = getCallingRecordLocked(token); 4337 return r != null ? r.intent.getComponent() : null; 4338 } 4339 } 4340 4341 private ActivityRecord getCallingRecordLocked(IBinder token) { 4342 ActivityRecord r = mMainStack.isInStackLocked(token); 4343 if (r == null) { 4344 return null; 4345 } 4346 return r.resultTo; 4347 } 4348 4349 public ComponentName getActivityClassForToken(IBinder token) { 4350 synchronized(this) { 4351 ActivityRecord r = mMainStack.isInStackLocked(token); 4352 if (r == null) { 4353 return null; 4354 } 4355 return r.intent.getComponent(); 4356 } 4357 } 4358 4359 public String getPackageForToken(IBinder token) { 4360 synchronized(this) { 4361 ActivityRecord r = mMainStack.isInStackLocked(token); 4362 if (r == null) { 4363 return null; 4364 } 4365 return r.packageName; 4366 } 4367 } 4368 4369 public IIntentSender getIntentSender(int type, 4370 String packageName, IBinder token, String resultWho, 4371 int requestCode, Intent[] intents, String[] resolvedTypes, 4372 int flags, Bundle options) { 4373 enforceNotIsolatedCaller("getIntentSender"); 4374 // Refuse possible leaked file descriptors 4375 if (intents != null) { 4376 if (intents.length < 1) { 4377 throw new IllegalArgumentException("Intents array length must be >= 1"); 4378 } 4379 for (int i=0; i<intents.length; i++) { 4380 Intent intent = intents[i]; 4381 if (intent != null) { 4382 if (intent.hasFileDescriptors()) { 4383 throw new IllegalArgumentException("File descriptors passed in Intent"); 4384 } 4385 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 4386 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 4387 throw new IllegalArgumentException( 4388 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 4389 } 4390 intents[i] = new Intent(intent); 4391 } 4392 } 4393 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 4394 throw new IllegalArgumentException( 4395 "Intent array length does not match resolvedTypes length"); 4396 } 4397 } 4398 if (options != null) { 4399 if (options.hasFileDescriptors()) { 4400 throw new IllegalArgumentException("File descriptors passed in options"); 4401 } 4402 } 4403 4404 synchronized(this) { 4405 int callingUid = Binder.getCallingUid(); 4406 try { 4407 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 4408 int uid = AppGlobals.getPackageManager() 4409 .getPackageUid(packageName, UserId.getUserId(callingUid)); 4410 if (!UserId.isSameApp(callingUid, uid)) { 4411 String msg = "Permission Denial: getIntentSender() from pid=" 4412 + Binder.getCallingPid() 4413 + ", uid=" + Binder.getCallingUid() 4414 + ", (need uid=" + uid + ")" 4415 + " is not allowed to send as package " + packageName; 4416 Slog.w(TAG, msg); 4417 throw new SecurityException(msg); 4418 } 4419 } 4420 4421 if (DEBUG_MU) 4422 Slog.i(TAG_MU, "Getting intent sender for origCallingUid=" 4423 + Binder.getOrigCallingUid()); 4424 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(), 4425 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 4426 4427 } catch (RemoteException e) { 4428 throw new SecurityException(e); 4429 } 4430 } 4431 } 4432 4433 IIntentSender getIntentSenderLocked(int type, 4434 String packageName, int callingUid, IBinder token, String resultWho, 4435 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 4436 Bundle options) { 4437 if (DEBUG_MU) 4438 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 4439 ActivityRecord activity = null; 4440 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4441 activity = mMainStack.isInStackLocked(token); 4442 if (activity == null) { 4443 return null; 4444 } 4445 if (activity.finishing) { 4446 return null; 4447 } 4448 } 4449 4450 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 4451 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 4452 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 4453 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 4454 |PendingIntent.FLAG_UPDATE_CURRENT); 4455 4456 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 4457 type, packageName, activity, resultWho, 4458 requestCode, intents, resolvedTypes, flags, options); 4459 WeakReference<PendingIntentRecord> ref; 4460 ref = mIntentSenderRecords.get(key); 4461 PendingIntentRecord rec = ref != null ? ref.get() : null; 4462 if (rec != null) { 4463 if (!cancelCurrent) { 4464 if (updateCurrent) { 4465 if (rec.key.requestIntent != null) { 4466 rec.key.requestIntent.replaceExtras(intents != null ? 4467 intents[intents.length - 1] : null); 4468 } 4469 if (intents != null) { 4470 intents[intents.length-1] = rec.key.requestIntent; 4471 rec.key.allIntents = intents; 4472 rec.key.allResolvedTypes = resolvedTypes; 4473 } else { 4474 rec.key.allIntents = null; 4475 rec.key.allResolvedTypes = null; 4476 } 4477 } 4478 return rec; 4479 } 4480 rec.canceled = true; 4481 mIntentSenderRecords.remove(key); 4482 } 4483 if (noCreate) { 4484 return rec; 4485 } 4486 rec = new PendingIntentRecord(this, key, callingUid); 4487 mIntentSenderRecords.put(key, rec.ref); 4488 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 4489 if (activity.pendingResults == null) { 4490 activity.pendingResults 4491 = new HashSet<WeakReference<PendingIntentRecord>>(); 4492 } 4493 activity.pendingResults.add(rec.ref); 4494 } 4495 return rec; 4496 } 4497 4498 public void cancelIntentSender(IIntentSender sender) { 4499 if (!(sender instanceof PendingIntentRecord)) { 4500 return; 4501 } 4502 synchronized(this) { 4503 PendingIntentRecord rec = (PendingIntentRecord)sender; 4504 try { 4505 int uid = AppGlobals.getPackageManager() 4506 .getPackageUid(rec.key.packageName, UserId.getCallingUserId()); 4507 if (!UserId.isSameApp(uid, Binder.getCallingUid())) { 4508 String msg = "Permission Denial: cancelIntentSender() from pid=" 4509 + Binder.getCallingPid() 4510 + ", uid=" + Binder.getCallingUid() 4511 + " is not allowed to cancel packges " 4512 + rec.key.packageName; 4513 Slog.w(TAG, msg); 4514 throw new SecurityException(msg); 4515 } 4516 } catch (RemoteException e) { 4517 throw new SecurityException(e); 4518 } 4519 cancelIntentSenderLocked(rec, true); 4520 } 4521 } 4522 4523 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 4524 rec.canceled = true; 4525 mIntentSenderRecords.remove(rec.key); 4526 if (cleanActivity && rec.key.activity != null) { 4527 rec.key.activity.pendingResults.remove(rec.ref); 4528 } 4529 } 4530 4531 public String getPackageForIntentSender(IIntentSender pendingResult) { 4532 if (!(pendingResult instanceof PendingIntentRecord)) { 4533 return null; 4534 } 4535 try { 4536 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4537 return res.key.packageName; 4538 } catch (ClassCastException e) { 4539 } 4540 return null; 4541 } 4542 4543 public int getUidForIntentSender(IIntentSender sender) { 4544 if (sender instanceof PendingIntentRecord) { 4545 try { 4546 PendingIntentRecord res = (PendingIntentRecord)sender; 4547 return res.uid; 4548 } catch (ClassCastException e) { 4549 } 4550 } 4551 return -1; 4552 } 4553 4554 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 4555 if (!(pendingResult instanceof PendingIntentRecord)) { 4556 return false; 4557 } 4558 try { 4559 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4560 if (res.key.allIntents == null) { 4561 return false; 4562 } 4563 for (int i=0; i<res.key.allIntents.length; i++) { 4564 Intent intent = res.key.allIntents[i]; 4565 if (intent.getPackage() != null && intent.getComponent() != null) { 4566 return false; 4567 } 4568 } 4569 return true; 4570 } catch (ClassCastException e) { 4571 } 4572 return false; 4573 } 4574 4575 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 4576 if (!(pendingResult instanceof PendingIntentRecord)) { 4577 return false; 4578 } 4579 try { 4580 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 4581 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 4582 return true; 4583 } 4584 return false; 4585 } catch (ClassCastException e) { 4586 } 4587 return false; 4588 } 4589 4590 public void setProcessLimit(int max) { 4591 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4592 "setProcessLimit()"); 4593 synchronized (this) { 4594 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max; 4595 mProcessLimitOverride = max; 4596 } 4597 trimApplications(); 4598 } 4599 4600 public int getProcessLimit() { 4601 synchronized (this) { 4602 return mProcessLimitOverride; 4603 } 4604 } 4605 4606 void foregroundTokenDied(ForegroundToken token) { 4607 synchronized (ActivityManagerService.this) { 4608 synchronized (mPidsSelfLocked) { 4609 ForegroundToken cur 4610 = mForegroundProcesses.get(token.pid); 4611 if (cur != token) { 4612 return; 4613 } 4614 mForegroundProcesses.remove(token.pid); 4615 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 4616 if (pr == null) { 4617 return; 4618 } 4619 pr.forcingToForeground = null; 4620 pr.foregroundServices = false; 4621 } 4622 updateOomAdjLocked(); 4623 } 4624 } 4625 4626 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 4627 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4628 "setProcessForeground()"); 4629 synchronized(this) { 4630 boolean changed = false; 4631 4632 synchronized (mPidsSelfLocked) { 4633 ProcessRecord pr = mPidsSelfLocked.get(pid); 4634 if (pr == null && isForeground) { 4635 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 4636 return; 4637 } 4638 ForegroundToken oldToken = mForegroundProcesses.get(pid); 4639 if (oldToken != null) { 4640 oldToken.token.unlinkToDeath(oldToken, 0); 4641 mForegroundProcesses.remove(pid); 4642 if (pr != null) { 4643 pr.forcingToForeground = null; 4644 } 4645 changed = true; 4646 } 4647 if (isForeground && token != null) { 4648 ForegroundToken newToken = new ForegroundToken() { 4649 public void binderDied() { 4650 foregroundTokenDied(this); 4651 } 4652 }; 4653 newToken.pid = pid; 4654 newToken.token = token; 4655 try { 4656 token.linkToDeath(newToken, 0); 4657 mForegroundProcesses.put(pid, newToken); 4658 pr.forcingToForeground = token; 4659 changed = true; 4660 } catch (RemoteException e) { 4661 // If the process died while doing this, we will later 4662 // do the cleanup with the process death link. 4663 } 4664 } 4665 } 4666 4667 if (changed) { 4668 updateOomAdjLocked(); 4669 } 4670 } 4671 } 4672 4673 // ========================================================= 4674 // PERMISSIONS 4675 // ========================================================= 4676 4677 static class PermissionController extends IPermissionController.Stub { 4678 ActivityManagerService mActivityManagerService; 4679 PermissionController(ActivityManagerService activityManagerService) { 4680 mActivityManagerService = activityManagerService; 4681 } 4682 4683 public boolean checkPermission(String permission, int pid, int uid) { 4684 return mActivityManagerService.checkPermission(permission, pid, 4685 uid) == PackageManager.PERMISSION_GRANTED; 4686 } 4687 } 4688 4689 /** 4690 * This can be called with or without the global lock held. 4691 */ 4692 int checkComponentPermission(String permission, int pid, int uid, 4693 int owningUid, boolean exported) { 4694 // We might be performing an operation on behalf of an indirect binder 4695 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 4696 // client identity accordingly before proceeding. 4697 Identity tlsIdentity = sCallerIdentity.get(); 4698 if (tlsIdentity != null) { 4699 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 4700 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 4701 uid = tlsIdentity.uid; 4702 pid = tlsIdentity.pid; 4703 } 4704 4705 if (pid == MY_PID) { 4706 return PackageManager.PERMISSION_GRANTED; 4707 } 4708 4709 return ActivityManager.checkComponentPermission(permission, uid, 4710 owningUid, exported); 4711 } 4712 4713 /** 4714 * As the only public entry point for permissions checking, this method 4715 * can enforce the semantic that requesting a check on a null global 4716 * permission is automatically denied. (Internally a null permission 4717 * string is used when calling {@link #checkComponentPermission} in cases 4718 * when only uid-based security is needed.) 4719 * 4720 * This can be called with or without the global lock held. 4721 */ 4722 public int checkPermission(String permission, int pid, int uid) { 4723 if (permission == null) { 4724 return PackageManager.PERMISSION_DENIED; 4725 } 4726 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true); 4727 } 4728 4729 /** 4730 * Binder IPC calls go through the public entry point. 4731 * This can be called with or without the global lock held. 4732 */ 4733 int checkCallingPermission(String permission) { 4734 return checkPermission(permission, 4735 Binder.getCallingPid(), 4736 UserId.getAppId(Binder.getCallingUid())); 4737 } 4738 4739 /** 4740 * This can be called with or without the global lock held. 4741 */ 4742 void enforceCallingPermission(String permission, String func) { 4743 if (checkCallingPermission(permission) 4744 == PackageManager.PERMISSION_GRANTED) { 4745 return; 4746 } 4747 4748 String msg = "Permission Denial: " + func + " from pid=" 4749 + Binder.getCallingPid() 4750 + ", uid=" + Binder.getCallingUid() 4751 + " requires " + permission; 4752 Slog.w(TAG, msg); 4753 throw new SecurityException(msg); 4754 } 4755 4756 /** 4757 * Determine if UID is holding permissions required to access {@link Uri} in 4758 * the given {@link ProviderInfo}. Final permission checking is always done 4759 * in {@link ContentProvider}. 4760 */ 4761 private final boolean checkHoldingPermissionsLocked( 4762 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 4763 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4764 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 4765 4766 if (pi.applicationInfo.uid == uid) { 4767 return true; 4768 } else if (!pi.exported) { 4769 return false; 4770 } 4771 4772 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 4773 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 4774 try { 4775 // check if target holds top-level <provider> permissions 4776 if (!readMet && pi.readPermission != null 4777 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 4778 readMet = true; 4779 } 4780 if (!writeMet && pi.writePermission != null 4781 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 4782 writeMet = true; 4783 } 4784 4785 // track if unprotected read/write is allowed; any denied 4786 // <path-permission> below removes this ability 4787 boolean allowDefaultRead = pi.readPermission == null; 4788 boolean allowDefaultWrite = pi.writePermission == null; 4789 4790 // check if target holds any <path-permission> that match uri 4791 final PathPermission[] pps = pi.pathPermissions; 4792 if (pps != null) { 4793 final String path = uri.getPath(); 4794 int i = pps.length; 4795 while (i > 0 && (!readMet || !writeMet)) { 4796 i--; 4797 PathPermission pp = pps[i]; 4798 if (pp.match(path)) { 4799 if (!readMet) { 4800 final String pprperm = pp.getReadPermission(); 4801 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 4802 + pprperm + " for " + pp.getPath() 4803 + ": match=" + pp.match(path) 4804 + " check=" + pm.checkUidPermission(pprperm, uid)); 4805 if (pprperm != null) { 4806 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 4807 readMet = true; 4808 } else { 4809 allowDefaultRead = false; 4810 } 4811 } 4812 } 4813 if (!writeMet) { 4814 final String ppwperm = pp.getWritePermission(); 4815 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 4816 + ppwperm + " for " + pp.getPath() 4817 + ": match=" + pp.match(path) 4818 + " check=" + pm.checkUidPermission(ppwperm, uid)); 4819 if (ppwperm != null) { 4820 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 4821 writeMet = true; 4822 } else { 4823 allowDefaultWrite = false; 4824 } 4825 } 4826 } 4827 } 4828 } 4829 } 4830 4831 // grant unprotected <provider> read/write, if not blocked by 4832 // <path-permission> above 4833 if (allowDefaultRead) readMet = true; 4834 if (allowDefaultWrite) writeMet = true; 4835 4836 } catch (RemoteException e) { 4837 return false; 4838 } 4839 4840 return readMet && writeMet; 4841 } 4842 4843 private final boolean checkUriPermissionLocked(Uri uri, int uid, 4844 int modeFlags) { 4845 // Root gets to do everything. 4846 if (uid == 0) { 4847 return true; 4848 } 4849 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 4850 if (perms == null) return false; 4851 UriPermission perm = perms.get(uri); 4852 if (perm == null) return false; 4853 return (modeFlags&perm.modeFlags) == modeFlags; 4854 } 4855 4856 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 4857 enforceNotIsolatedCaller("checkUriPermission"); 4858 4859 // Another redirected-binder-call permissions check as in 4860 // {@link checkComponentPermission}. 4861 Identity tlsIdentity = sCallerIdentity.get(); 4862 if (tlsIdentity != null) { 4863 uid = tlsIdentity.uid; 4864 pid = tlsIdentity.pid; 4865 } 4866 4867 uid = UserId.getAppId(uid); 4868 // Our own process gets to do everything. 4869 if (pid == MY_PID) { 4870 return PackageManager.PERMISSION_GRANTED; 4871 } 4872 synchronized(this) { 4873 return checkUriPermissionLocked(uri, uid, modeFlags) 4874 ? PackageManager.PERMISSION_GRANTED 4875 : PackageManager.PERMISSION_DENIED; 4876 } 4877 } 4878 4879 /** 4880 * Check if the targetPkg can be granted permission to access uri by 4881 * the callingUid using the given modeFlags. Throws a security exception 4882 * if callingUid is not allowed to do this. Returns the uid of the target 4883 * if the URI permission grant should be performed; returns -1 if it is not 4884 * needed (for example targetPkg already has permission to access the URI). 4885 * If you already know the uid of the target, you can supply it in 4886 * lastTargetUid else set that to -1. 4887 */ 4888 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 4889 Uri uri, int modeFlags, int lastTargetUid) { 4890 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 4891 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 4892 if (modeFlags == 0) { 4893 return -1; 4894 } 4895 4896 if (targetPkg != null) { 4897 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4898 "Checking grant " + targetPkg + " permission to " + uri); 4899 } 4900 4901 final IPackageManager pm = AppGlobals.getPackageManager(); 4902 4903 // If this is not a content: uri, we can't do anything with it. 4904 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 4905 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4906 "Can't grant URI permission for non-content URI: " + uri); 4907 return -1; 4908 } 4909 4910 String name = uri.getAuthority(); 4911 ProviderInfo pi = null; 4912 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 4913 UserId.getUserId(callingUid)); 4914 if (cpr != null) { 4915 pi = cpr.info; 4916 } else { 4917 try { 4918 pi = pm.resolveContentProvider(name, 4919 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid)); 4920 } catch (RemoteException ex) { 4921 } 4922 } 4923 if (pi == null) { 4924 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 4925 return -1; 4926 } 4927 4928 int targetUid = lastTargetUid; 4929 if (targetUid < 0 && targetPkg != null) { 4930 try { 4931 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid)); 4932 if (targetUid < 0) { 4933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4934 "Can't grant URI permission no uid for: " + targetPkg); 4935 return -1; 4936 } 4937 } catch (RemoteException ex) { 4938 return -1; 4939 } 4940 } 4941 4942 if (targetUid >= 0) { 4943 // First... does the target actually need this permission? 4944 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 4945 // No need to grant the target this permission. 4946 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 4947 "Target " + targetPkg + " already has full permission to " + uri); 4948 return -1; 4949 } 4950 } else { 4951 // First... there is no target package, so can anyone access it? 4952 boolean allowed = pi.exported; 4953 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 4954 if (pi.readPermission != null) { 4955 allowed = false; 4956 } 4957 } 4958 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 4959 if (pi.writePermission != null) { 4960 allowed = false; 4961 } 4962 } 4963 if (allowed) { 4964 return -1; 4965 } 4966 } 4967 4968 // Second... is the provider allowing granting of URI permissions? 4969 if (!pi.grantUriPermissions) { 4970 throw new SecurityException("Provider " + pi.packageName 4971 + "/" + pi.name 4972 + " does not allow granting of Uri permissions (uri " 4973 + uri + ")"); 4974 } 4975 if (pi.uriPermissionPatterns != null) { 4976 final int N = pi.uriPermissionPatterns.length; 4977 boolean allowed = false; 4978 for (int i=0; i<N; i++) { 4979 if (pi.uriPermissionPatterns[i] != null 4980 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 4981 allowed = true; 4982 break; 4983 } 4984 } 4985 if (!allowed) { 4986 throw new SecurityException("Provider " + pi.packageName 4987 + "/" + pi.name 4988 + " does not allow granting of permission to path of Uri " 4989 + uri); 4990 } 4991 } 4992 4993 // Third... does the caller itself have permission to access 4994 // this uri? 4995 if (callingUid != Process.myUid()) { 4996 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 4997 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 4998 throw new SecurityException("Uid " + callingUid 4999 + " does not have permission to uri " + uri); 5000 } 5001 } 5002 } 5003 5004 return targetUid; 5005 } 5006 5007 public int checkGrantUriPermission(int callingUid, String targetPkg, 5008 Uri uri, int modeFlags) { 5009 enforceNotIsolatedCaller("checkGrantUriPermission"); 5010 synchronized(this) { 5011 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5012 } 5013 } 5014 5015 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, 5016 Uri uri, int modeFlags, UriPermissionOwner owner) { 5017 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5018 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5019 if (modeFlags == 0) { 5020 return; 5021 } 5022 5023 // So here we are: the caller has the assumed permission 5024 // to the uri, and the target doesn't. Let's now give this to 5025 // the target. 5026 5027 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5028 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5029 5030 HashMap<Uri, UriPermission> targetUris 5031 = mGrantedUriPermissions.get(targetUid); 5032 if (targetUris == null) { 5033 targetUris = new HashMap<Uri, UriPermission>(); 5034 mGrantedUriPermissions.put(targetUid, targetUris); 5035 } 5036 5037 UriPermission perm = targetUris.get(uri); 5038 if (perm == null) { 5039 perm = new UriPermission(targetUid, uri); 5040 targetUris.put(uri, perm); 5041 } 5042 5043 perm.modeFlags |= modeFlags; 5044 if (owner == null) { 5045 perm.globalModeFlags |= modeFlags; 5046 } else { 5047 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5048 perm.readOwners.add(owner); 5049 owner.addReadPermission(perm); 5050 } 5051 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5052 perm.writeOwners.add(owner); 5053 owner.addWritePermission(perm); 5054 } 5055 } 5056 } 5057 5058 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5059 int modeFlags, UriPermissionOwner owner) { 5060 if (targetPkg == null) { 5061 throw new NullPointerException("targetPkg"); 5062 } 5063 5064 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5065 if (targetUid < 0) { 5066 return; 5067 } 5068 5069 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5070 } 5071 5072 static class NeededUriGrants extends ArrayList<Uri> { 5073 final String targetPkg; 5074 final int targetUid; 5075 final int flags; 5076 5077 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) { 5078 targetPkg = _targetPkg; 5079 targetUid = _targetUid; 5080 flags = _flags; 5081 } 5082 } 5083 5084 /** 5085 * Like checkGrantUriPermissionLocked, but takes an Intent. 5086 */ 5087 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5088 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5090 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5091 + " clip=" + (intent != null ? intent.getClipData() : null) 5092 + " from " + intent + "; flags=0x" 5093 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5094 5095 if (targetPkg == null) { 5096 throw new NullPointerException("targetPkg"); 5097 } 5098 5099 if (intent == null) { 5100 return null; 5101 } 5102 Uri data = intent.getData(); 5103 ClipData clip = intent.getClipData(); 5104 if (data == null && clip == null) { 5105 return null; 5106 } 5107 if (data != null) { 5108 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5109 mode, needed != null ? needed.targetUid : -1); 5110 if (target > 0) { 5111 if (needed == null) { 5112 needed = new NeededUriGrants(targetPkg, target, mode); 5113 } 5114 needed.add(data); 5115 } 5116 } 5117 if (clip != null) { 5118 for (int i=0; i<clip.getItemCount(); i++) { 5119 Uri uri = clip.getItemAt(i).getUri(); 5120 if (uri != null) { 5121 int target = -1; 5122 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 5123 mode, needed != null ? needed.targetUid : -1); 5124 if (target > 0) { 5125 if (needed == null) { 5126 needed = new NeededUriGrants(targetPkg, target, mode); 5127 } 5128 needed.add(uri); 5129 } 5130 } else { 5131 Intent clipIntent = clip.getItemAt(i).getIntent(); 5132 if (clipIntent != null) { 5133 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 5134 callingUid, targetPkg, clipIntent, mode, needed); 5135 if (newNeeded != null) { 5136 needed = newNeeded; 5137 } 5138 } 5139 } 5140 } 5141 } 5142 5143 return needed; 5144 } 5145 5146 /** 5147 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 5148 */ 5149 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 5150 UriPermissionOwner owner) { 5151 if (needed != null) { 5152 for (int i=0; i<needed.size(); i++) { 5153 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 5154 needed.get(i), needed.flags, owner); 5155 } 5156 } 5157 } 5158 5159 void grantUriPermissionFromIntentLocked(int callingUid, 5160 String targetPkg, Intent intent, UriPermissionOwner owner) { 5161 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 5162 intent, intent != null ? intent.getFlags() : 0, null); 5163 if (needed == null) { 5164 return; 5165 } 5166 5167 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 5168 } 5169 5170 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5171 Uri uri, int modeFlags) { 5172 enforceNotIsolatedCaller("grantUriPermission"); 5173 synchronized(this) { 5174 final ProcessRecord r = getRecordForAppLocked(caller); 5175 if (r == null) { 5176 throw new SecurityException("Unable to find app for caller " 5177 + caller 5178 + " when granting permission to uri " + uri); 5179 } 5180 if (targetPkg == null) { 5181 throw new IllegalArgumentException("null target"); 5182 } 5183 if (uri == null) { 5184 throw new IllegalArgumentException("null uri"); 5185 } 5186 5187 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 5188 null); 5189 } 5190 } 5191 5192 void removeUriPermissionIfNeededLocked(UriPermission perm) { 5193 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5194 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5195 HashMap<Uri, UriPermission> perms 5196 = mGrantedUriPermissions.get(perm.uid); 5197 if (perms != null) { 5198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5199 "Removing " + perm.uid + " permission to " + perm.uri); 5200 perms.remove(perm.uri); 5201 if (perms.size() == 0) { 5202 mGrantedUriPermissions.remove(perm.uid); 5203 } 5204 } 5205 } 5206 } 5207 5208 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5209 int modeFlags) { 5210 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5211 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5212 if (modeFlags == 0) { 5213 return; 5214 } 5215 5216 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5217 "Revoking all granted permissions to " + uri); 5218 5219 final IPackageManager pm = AppGlobals.getPackageManager(); 5220 5221 final String authority = uri.getAuthority(); 5222 ProviderInfo pi = null; 5223 int userId = UserId.getUserId(callingUid); 5224 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId); 5225 if (cpr != null) { 5226 pi = cpr.info; 5227 } else { 5228 try { 5229 pi = pm.resolveContentProvider(authority, 5230 PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 5231 } catch (RemoteException ex) { 5232 } 5233 } 5234 if (pi == null) { 5235 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 5236 return; 5237 } 5238 5239 // Does the caller have this permission on the URI? 5240 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5241 // Right now, if you are not the original owner of the permission, 5242 // you are not allowed to revoke it. 5243 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5244 throw new SecurityException("Uid " + callingUid 5245 + " does not have permission to uri " + uri); 5246 //} 5247 } 5248 5249 // Go through all of the permissions and remove any that match. 5250 final List<String> SEGMENTS = uri.getPathSegments(); 5251 if (SEGMENTS != null) { 5252 final int NS = SEGMENTS.size(); 5253 int N = mGrantedUriPermissions.size(); 5254 for (int i=0; i<N; i++) { 5255 HashMap<Uri, UriPermission> perms 5256 = mGrantedUriPermissions.valueAt(i); 5257 Iterator<UriPermission> it = perms.values().iterator(); 5258 toploop: 5259 while (it.hasNext()) { 5260 UriPermission perm = it.next(); 5261 Uri targetUri = perm.uri; 5262 if (!authority.equals(targetUri.getAuthority())) { 5263 continue; 5264 } 5265 List<String> targetSegments = targetUri.getPathSegments(); 5266 if (targetSegments == null) { 5267 continue; 5268 } 5269 if (targetSegments.size() < NS) { 5270 continue; 5271 } 5272 for (int j=0; j<NS; j++) { 5273 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5274 continue toploop; 5275 } 5276 } 5277 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5278 "Revoking " + perm.uid + " permission to " + perm.uri); 5279 perm.clearModes(modeFlags); 5280 if (perm.modeFlags == 0) { 5281 it.remove(); 5282 } 5283 } 5284 if (perms.size() == 0) { 5285 mGrantedUriPermissions.remove( 5286 mGrantedUriPermissions.keyAt(i)); 5287 N--; 5288 i--; 5289 } 5290 } 5291 } 5292 } 5293 5294 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5295 int modeFlags) { 5296 enforceNotIsolatedCaller("revokeUriPermission"); 5297 synchronized(this) { 5298 final ProcessRecord r = getRecordForAppLocked(caller); 5299 if (r == null) { 5300 throw new SecurityException("Unable to find app for caller " 5301 + caller 5302 + " when revoking permission to uri " + uri); 5303 } 5304 if (uri == null) { 5305 Slog.w(TAG, "revokeUriPermission: null uri"); 5306 return; 5307 } 5308 5309 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5310 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5311 if (modeFlags == 0) { 5312 return; 5313 } 5314 5315 final IPackageManager pm = AppGlobals.getPackageManager(); 5316 5317 final String authority = uri.getAuthority(); 5318 ProviderInfo pi = null; 5319 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId); 5320 if (cpr != null) { 5321 pi = cpr.info; 5322 } else { 5323 try { 5324 pi = pm.resolveContentProvider(authority, 5325 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId); 5326 } catch (RemoteException ex) { 5327 } 5328 } 5329 if (pi == null) { 5330 Slog.w(TAG, "No content provider found for permission revoke: " 5331 + uri.toSafeString()); 5332 return; 5333 } 5334 5335 revokeUriPermissionLocked(r.uid, uri, modeFlags); 5336 } 5337 } 5338 5339 @Override 5340 public IBinder newUriPermissionOwner(String name) { 5341 enforceNotIsolatedCaller("newUriPermissionOwner"); 5342 synchronized(this) { 5343 UriPermissionOwner owner = new UriPermissionOwner(this, name); 5344 return owner.getExternalTokenLocked(); 5345 } 5346 } 5347 5348 @Override 5349 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 5350 Uri uri, int modeFlags) { 5351 synchronized(this) { 5352 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5353 if (owner == null) { 5354 throw new IllegalArgumentException("Unknown owner: " + token); 5355 } 5356 if (fromUid != Binder.getCallingUid()) { 5357 if (Binder.getCallingUid() != Process.myUid()) { 5358 // Only system code can grant URI permissions on behalf 5359 // of other users. 5360 throw new SecurityException("nice try"); 5361 } 5362 } 5363 if (targetPkg == null) { 5364 throw new IllegalArgumentException("null target"); 5365 } 5366 if (uri == null) { 5367 throw new IllegalArgumentException("null uri"); 5368 } 5369 5370 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 5371 } 5372 } 5373 5374 @Override 5375 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 5376 synchronized(this) { 5377 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 5378 if (owner == null) { 5379 throw new IllegalArgumentException("Unknown owner: " + token); 5380 } 5381 5382 if (uri == null) { 5383 owner.removeUriPermissionsLocked(mode); 5384 } else { 5385 owner.removeUriPermissionLocked(uri, mode); 5386 } 5387 } 5388 } 5389 5390 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5391 synchronized (this) { 5392 ProcessRecord app = 5393 who != null ? getRecordForAppLocked(who) : null; 5394 if (app == null) return; 5395 5396 Message msg = Message.obtain(); 5397 msg.what = WAIT_FOR_DEBUGGER_MSG; 5398 msg.obj = app; 5399 msg.arg1 = waiting ? 1 : 0; 5400 mHandler.sendMessage(msg); 5401 } 5402 } 5403 5404 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5405 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 5406 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ); 5407 outInfo.availMem = Process.getFreeMemory(); 5408 outInfo.totalMem = Process.getTotalMemory(); 5409 outInfo.threshold = homeAppMem; 5410 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2)); 5411 outInfo.hiddenAppThreshold = hiddenAppMem; 5412 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 5413 ProcessList.SERVICE_ADJ); 5414 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 5415 ProcessList.VISIBLE_APP_ADJ); 5416 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 5417 ProcessList.FOREGROUND_APP_ADJ); 5418 } 5419 5420 // ========================================================= 5421 // TASK MANAGEMENT 5422 // ========================================================= 5423 5424 public List getTasks(int maxNum, int flags, 5425 IThumbnailReceiver receiver) { 5426 ArrayList list = new ArrayList(); 5427 5428 PendingThumbnailsRecord pending = null; 5429 IApplicationThread topThumbnail = null; 5430 ActivityRecord topRecord = null; 5431 5432 synchronized(this) { 5433 if (localLOGV) Slog.v( 5434 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 5435 + ", receiver=" + receiver); 5436 5437 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 5438 != PackageManager.PERMISSION_GRANTED) { 5439 if (receiver != null) { 5440 // If the caller wants to wait for pending thumbnails, 5441 // it ain't gonna get them. 5442 try { 5443 receiver.finished(); 5444 } catch (RemoteException ex) { 5445 } 5446 } 5447 String msg = "Permission Denial: getTasks() from pid=" 5448 + Binder.getCallingPid() 5449 + ", uid=" + Binder.getCallingUid() 5450 + " requires " + android.Manifest.permission.GET_TASKS; 5451 Slog.w(TAG, msg); 5452 throw new SecurityException(msg); 5453 } 5454 5455 int pos = mMainStack.mHistory.size()-1; 5456 ActivityRecord next = 5457 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5458 ActivityRecord top = null; 5459 TaskRecord curTask = null; 5460 int numActivities = 0; 5461 int numRunning = 0; 5462 while (pos >= 0 && maxNum > 0) { 5463 final ActivityRecord r = next; 5464 pos--; 5465 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; 5466 5467 // Initialize state for next task if needed. 5468 if (top == null || 5469 (top.state == ActivityState.INITIALIZING 5470 && top.task == r.task)) { 5471 top = r; 5472 curTask = r.task; 5473 numActivities = numRunning = 0; 5474 } 5475 5476 // Add 'r' into the current task. 5477 numActivities++; 5478 if (r.app != null && r.app.thread != null) { 5479 numRunning++; 5480 } 5481 5482 if (localLOGV) Slog.v( 5483 TAG, r.intent.getComponent().flattenToShortString() 5484 + ": task=" + r.task); 5485 5486 // If the next one is a different task, generate a new 5487 // TaskInfo entry for what we have. 5488 if (next == null || next.task != curTask) { 5489 ActivityManager.RunningTaskInfo ci 5490 = new ActivityManager.RunningTaskInfo(); 5491 ci.id = curTask.taskId; 5492 ci.baseActivity = r.intent.getComponent(); 5493 ci.topActivity = top.intent.getComponent(); 5494 if (top.thumbHolder != null) { 5495 ci.description = top.thumbHolder.lastDescription; 5496 } 5497 ci.numActivities = numActivities; 5498 ci.numRunning = numRunning; 5499 //System.out.println( 5500 // "#" + maxNum + ": " + " descr=" + ci.description); 5501 if (ci.thumbnail == null && receiver != null) { 5502 if (localLOGV) Slog.v( 5503 TAG, "State=" + top.state + "Idle=" + top.idle 5504 + " app=" + top.app 5505 + " thr=" + (top.app != null ? top.app.thread : null)); 5506 if (top.state == ActivityState.RESUMED 5507 || top.state == ActivityState.PAUSING) { 5508 if (top.idle && top.app != null 5509 && top.app.thread != null) { 5510 topRecord = top; 5511 topThumbnail = top.app.thread; 5512 } else { 5513 top.thumbnailNeeded = true; 5514 } 5515 } 5516 if (pending == null) { 5517 pending = new PendingThumbnailsRecord(receiver); 5518 } 5519 pending.pendingRecords.add(top); 5520 } 5521 list.add(ci); 5522 maxNum--; 5523 top = null; 5524 } 5525 } 5526 5527 if (pending != null) { 5528 mPendingThumbnails.add(pending); 5529 } 5530 } 5531 5532 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 5533 5534 if (topThumbnail != null) { 5535 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 5536 try { 5537 topThumbnail.requestThumbnail(topRecord.appToken); 5538 } catch (Exception e) { 5539 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5540 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 5541 } 5542 } 5543 5544 if (pending == null && receiver != null) { 5545 // In this case all thumbnails were available and the client 5546 // is being asked to be told when the remaining ones come in... 5547 // which is unusually, since the top-most currently running 5548 // activity should never have a canned thumbnail! Oh well. 5549 try { 5550 receiver.finished(); 5551 } catch (RemoteException ex) { 5552 } 5553 } 5554 5555 return list; 5556 } 5557 5558 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 5559 int flags) { 5560 final int callingUid = Binder.getCallingUid(); 5561 // If it's the system uid asking, then use the current user id. 5562 // TODO: Make sure that there aren't any other legitimate calls from the system uid that 5563 // require the entire list. 5564 final int callingUserId = callingUid == Process.SYSTEM_UID 5565 ? mCurrentUserId : UserId.getUserId(callingUid); 5566 synchronized (this) { 5567 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 5568 "getRecentTasks()"); 5569 final boolean detailed = checkCallingPermission( 5570 android.Manifest.permission.GET_DETAILED_TASKS) 5571 == PackageManager.PERMISSION_GRANTED; 5572 5573 IPackageManager pm = AppGlobals.getPackageManager(); 5574 5575 final int N = mRecentTasks.size(); 5576 ArrayList<ActivityManager.RecentTaskInfo> res 5577 = new ArrayList<ActivityManager.RecentTaskInfo>( 5578 maxNum < N ? maxNum : N); 5579 for (int i=0; i<N && maxNum > 0; i++) { 5580 TaskRecord tr = mRecentTasks.get(i); 5581 // Only add calling user's recent tasks 5582 if (tr.userId != callingUserId) continue; 5583 // Return the entry if desired by the caller. We always return 5584 // the first entry, because callers always expect this to be the 5585 // foreground app. We may filter others if the caller has 5586 // not supplied RECENT_WITH_EXCLUDED and there is some reason 5587 // we should exclude the entry. 5588 5589 if (i == 0 5590 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 5591 || (tr.intent == null) 5592 || ((tr.intent.getFlags() 5593 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 5594 ActivityManager.RecentTaskInfo rti 5595 = new ActivityManager.RecentTaskInfo(); 5596 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 5597 rti.persistentId = tr.taskId; 5598 rti.baseIntent = new Intent( 5599 tr.intent != null ? tr.intent : tr.affinityIntent); 5600 if (!detailed) { 5601 rti.baseIntent.replaceExtras((Bundle)null); 5602 } 5603 rti.origActivity = tr.origActivity; 5604 rti.description = tr.lastDescription; 5605 5606 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 5607 // Check whether this activity is currently available. 5608 try { 5609 if (rti.origActivity != null) { 5610 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId) 5611 == null) { 5612 continue; 5613 } 5614 } else if (rti.baseIntent != null) { 5615 if (pm.queryIntentActivities(rti.baseIntent, 5616 null, 0, callingUserId) == null) { 5617 continue; 5618 } 5619 } 5620 } catch (RemoteException e) { 5621 // Will never happen. 5622 } 5623 } 5624 5625 res.add(rti); 5626 maxNum--; 5627 } 5628 } 5629 return res; 5630 } 5631 } 5632 5633 private TaskRecord taskForIdLocked(int id) { 5634 final int N = mRecentTasks.size(); 5635 for (int i=0; i<N; i++) { 5636 TaskRecord tr = mRecentTasks.get(i); 5637 if (tr.taskId == id) { 5638 return tr; 5639 } 5640 } 5641 return null; 5642 } 5643 5644 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 5645 synchronized (this) { 5646 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5647 "getTaskThumbnails()"); 5648 TaskRecord tr = taskForIdLocked(id); 5649 if (tr != null) { 5650 return mMainStack.getTaskThumbnailsLocked(tr); 5651 } 5652 } 5653 return null; 5654 } 5655 5656 public boolean removeSubTask(int taskId, int subTaskIndex) { 5657 synchronized (this) { 5658 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5659 "removeSubTask()"); 5660 long ident = Binder.clearCallingIdentity(); 5661 try { 5662 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex, 5663 true) != null; 5664 } finally { 5665 Binder.restoreCallingIdentity(ident); 5666 } 5667 } 5668 } 5669 5670 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 5671 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 5672 Intent baseIntent = new Intent( 5673 tr.intent != null ? tr.intent : tr.affinityIntent); 5674 ComponentName component = baseIntent.getComponent(); 5675 if (component == null) { 5676 Slog.w(TAG, "Now component for base intent of task: " + tr); 5677 return; 5678 } 5679 5680 // Find any running services associated with this app. 5681 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5682 for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) { 5683 if (sr.packageName.equals(component.getPackageName())) { 5684 services.add(sr); 5685 } 5686 } 5687 5688 // Take care of any running services associated with the app. 5689 for (int i=0; i<services.size(); i++) { 5690 ServiceRecord sr = services.get(i); 5691 if (sr.startRequested) { 5692 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { 5693 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); 5694 stopServiceLocked(sr); 5695 } else { 5696 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, 5697 sr.makeNextStartId(), baseIntent, null)); 5698 if (sr.app != null && sr.app.thread != null) { 5699 sendServiceArgsLocked(sr, false); 5700 } 5701 } 5702 } 5703 } 5704 5705 if (killProcesses) { 5706 // Find any running processes associated with this app. 5707 final String pkg = component.getPackageName(); 5708 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5709 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5710 for (SparseArray<ProcessRecord> uids : pmap.values()) { 5711 for (int i=0; i<uids.size(); i++) { 5712 ProcessRecord proc = uids.valueAt(i); 5713 if (proc.userId != tr.userId) { 5714 continue; 5715 } 5716 if (!proc.pkgList.contains(pkg)) { 5717 continue; 5718 } 5719 procs.add(proc); 5720 } 5721 } 5722 5723 // Kill the running processes. 5724 for (int i=0; i<procs.size(); i++) { 5725 ProcessRecord pr = procs.get(i); 5726 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5727 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5728 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5729 pr.processName, pr.setAdj, "remove task"); 5730 pr.killedBackground = true; 5731 Process.killProcessQuiet(pr.pid); 5732 } else { 5733 pr.waitingToKill = "remove task"; 5734 } 5735 } 5736 } 5737 } 5738 5739 public boolean removeTask(int taskId, int flags) { 5740 synchronized (this) { 5741 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5742 "removeTask()"); 5743 long ident = Binder.clearCallingIdentity(); 5744 try { 5745 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5746 false); 5747 if (r != null) { 5748 mRecentTasks.remove(r.task); 5749 cleanUpRemovedTaskLocked(r.task, flags); 5750 return true; 5751 } else { 5752 TaskRecord tr = null; 5753 int i=0; 5754 while (i < mRecentTasks.size()) { 5755 TaskRecord t = mRecentTasks.get(i); 5756 if (t.taskId == taskId) { 5757 tr = t; 5758 break; 5759 } 5760 i++; 5761 } 5762 if (tr != null) { 5763 if (tr.numActivities <= 0) { 5764 // Caller is just removing a recent task that is 5765 // not actively running. That is easy! 5766 mRecentTasks.remove(i); 5767 cleanUpRemovedTaskLocked(tr, flags); 5768 return true; 5769 } else { 5770 Slog.w(TAG, "removeTask: task " + taskId 5771 + " does not have activities to remove, " 5772 + " but numActivities=" + tr.numActivities 5773 + ": " + tr); 5774 } 5775 } 5776 } 5777 } finally { 5778 Binder.restoreCallingIdentity(ident); 5779 } 5780 } 5781 return false; 5782 } 5783 5784 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5785 int j; 5786 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5787 TaskRecord jt = startTask; 5788 5789 // First look backwards 5790 for (j=startIndex-1; j>=0; j--) { 5791 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5792 if (r.task != jt) { 5793 jt = r.task; 5794 if (affinity.equals(jt.affinity)) { 5795 return j; 5796 } 5797 } 5798 } 5799 5800 // Now look forwards 5801 final int N = mMainStack.mHistory.size(); 5802 jt = startTask; 5803 for (j=startIndex+1; j<N; j++) { 5804 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5805 if (r.task != jt) { 5806 if (affinity.equals(jt.affinity)) { 5807 return j; 5808 } 5809 jt = r.task; 5810 } 5811 } 5812 5813 // Might it be at the top? 5814 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5815 return N-1; 5816 } 5817 5818 return -1; 5819 } 5820 5821 /** 5822 * TODO: Add mController hook 5823 */ 5824 public void moveTaskToFront(int task, int flags, Bundle options) { 5825 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5826 "moveTaskToFront()"); 5827 5828 synchronized(this) { 5829 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5830 Binder.getCallingUid(), "Task to front")) { 5831 ActivityOptions.abort(options); 5832 return; 5833 } 5834 final long origId = Binder.clearCallingIdentity(); 5835 try { 5836 TaskRecord tr = taskForIdLocked(task); 5837 if (tr != null) { 5838 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5839 mMainStack.mUserLeaving = true; 5840 } 5841 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5842 // Caller wants the home activity moved with it. To accomplish this, 5843 // we'll just move the home task to the top first. 5844 mMainStack.moveHomeToFrontLocked(); 5845 } 5846 mMainStack.moveTaskToFrontLocked(tr, null, options); 5847 return; 5848 } 5849 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5850 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5851 if (hr.task.taskId == task) { 5852 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5853 mMainStack.mUserLeaving = true; 5854 } 5855 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5856 // Caller wants the home activity moved with it. To accomplish this, 5857 // we'll just move the home task to the top first. 5858 mMainStack.moveHomeToFrontLocked(); 5859 } 5860 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5861 return; 5862 } 5863 } 5864 } finally { 5865 Binder.restoreCallingIdentity(origId); 5866 } 5867 ActivityOptions.abort(options); 5868 } 5869 } 5870 5871 public void moveTaskToBack(int task) { 5872 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5873 "moveTaskToBack()"); 5874 5875 synchronized(this) { 5876 if (mMainStack.mResumedActivity != null 5877 && mMainStack.mResumedActivity.task.taskId == task) { 5878 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5879 Binder.getCallingUid(), "Task to back")) { 5880 return; 5881 } 5882 } 5883 final long origId = Binder.clearCallingIdentity(); 5884 mMainStack.moveTaskToBackLocked(task, null); 5885 Binder.restoreCallingIdentity(origId); 5886 } 5887 } 5888 5889 /** 5890 * Moves an activity, and all of the other activities within the same task, to the bottom 5891 * of the history stack. The activity's order within the task is unchanged. 5892 * 5893 * @param token A reference to the activity we wish to move 5894 * @param nonRoot If false then this only works if the activity is the root 5895 * of a task; if true it will work for any activity in a task. 5896 * @return Returns true if the move completed, false if not. 5897 */ 5898 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5899 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5900 synchronized(this) { 5901 final long origId = Binder.clearCallingIdentity(); 5902 int taskId = getTaskForActivityLocked(token, !nonRoot); 5903 if (taskId >= 0) { 5904 return mMainStack.moveTaskToBackLocked(taskId, null); 5905 } 5906 Binder.restoreCallingIdentity(origId); 5907 } 5908 return false; 5909 } 5910 5911 public void moveTaskBackwards(int task) { 5912 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5913 "moveTaskBackwards()"); 5914 5915 synchronized(this) { 5916 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5917 Binder.getCallingUid(), "Task backwards")) { 5918 return; 5919 } 5920 final long origId = Binder.clearCallingIdentity(); 5921 moveTaskBackwardsLocked(task); 5922 Binder.restoreCallingIdentity(origId); 5923 } 5924 } 5925 5926 private final void moveTaskBackwardsLocked(int task) { 5927 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5928 } 5929 5930 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5931 synchronized(this) { 5932 return getTaskForActivityLocked(token, onlyRoot); 5933 } 5934 } 5935 5936 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5937 final int N = mMainStack.mHistory.size(); 5938 TaskRecord lastTask = null; 5939 for (int i=0; i<N; i++) { 5940 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5941 if (r.appToken == token) { 5942 if (!onlyRoot || lastTask != r.task) { 5943 return r.task.taskId; 5944 } 5945 return -1; 5946 } 5947 lastTask = r.task; 5948 } 5949 5950 return -1; 5951 } 5952 5953 // ========================================================= 5954 // THUMBNAILS 5955 // ========================================================= 5956 5957 public void reportThumbnail(IBinder token, 5958 Bitmap thumbnail, CharSequence description) { 5959 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5960 final long origId = Binder.clearCallingIdentity(); 5961 sendPendingThumbnail(null, token, thumbnail, description, true); 5962 Binder.restoreCallingIdentity(origId); 5963 } 5964 5965 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5966 Bitmap thumbnail, CharSequence description, boolean always) { 5967 TaskRecord task = null; 5968 ArrayList receivers = null; 5969 5970 //System.out.println("Send pending thumbnail: " + r); 5971 5972 synchronized(this) { 5973 if (r == null) { 5974 r = mMainStack.isInStackLocked(token); 5975 if (r == null) { 5976 return; 5977 } 5978 } 5979 if (thumbnail == null && r.thumbHolder != null) { 5980 thumbnail = r.thumbHolder.lastThumbnail; 5981 description = r.thumbHolder.lastDescription; 5982 } 5983 if (thumbnail == null && !always) { 5984 // If there is no thumbnail, and this entry is not actually 5985 // going away, then abort for now and pick up the next 5986 // thumbnail we get. 5987 return; 5988 } 5989 task = r.task; 5990 5991 int N = mPendingThumbnails.size(); 5992 int i=0; 5993 while (i<N) { 5994 PendingThumbnailsRecord pr = 5995 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5996 //System.out.println("Looking in " + pr.pendingRecords); 5997 if (pr.pendingRecords.remove(r)) { 5998 if (receivers == null) { 5999 receivers = new ArrayList(); 6000 } 6001 receivers.add(pr); 6002 if (pr.pendingRecords.size() == 0) { 6003 pr.finished = true; 6004 mPendingThumbnails.remove(i); 6005 N--; 6006 continue; 6007 } 6008 } 6009 i++; 6010 } 6011 } 6012 6013 if (receivers != null) { 6014 final int N = receivers.size(); 6015 for (int i=0; i<N; i++) { 6016 try { 6017 PendingThumbnailsRecord pr = 6018 (PendingThumbnailsRecord)receivers.get(i); 6019 pr.receiver.newThumbnail( 6020 task != null ? task.taskId : -1, thumbnail, description); 6021 if (pr.finished) { 6022 pr.receiver.finished(); 6023 } 6024 } catch (Exception e) { 6025 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6026 } 6027 } 6028 } 6029 } 6030 6031 // ========================================================= 6032 // CONTENT PROVIDERS 6033 // ========================================================= 6034 6035 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6036 List<ProviderInfo> providers = null; 6037 try { 6038 providers = AppGlobals.getPackageManager(). 6039 queryContentProviders(app.processName, app.uid, 6040 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6041 } catch (RemoteException ex) { 6042 } 6043 if (DEBUG_MU) 6044 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6045 int userId = app.userId; 6046 if (providers != null) { 6047 final int N = providers.size(); 6048 for (int i=0; i<N; i++) { 6049 ProviderInfo cpi = 6050 (ProviderInfo)providers.get(i); 6051 6052 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6053 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6054 if (cpr == null) { 6055 cpr = new ContentProviderRecord(this, cpi, app.info, comp); 6056 mProviderMap.putProviderByClass(comp, cpr); 6057 } 6058 if (DEBUG_MU) 6059 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6060 app.pubProviders.put(cpi.name, cpr); 6061 app.addPackage(cpi.applicationInfo.packageName); 6062 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6063 } 6064 } 6065 return providers; 6066 } 6067 6068 /** 6069 * Check if {@link ProcessRecord} has a possible chance at accessing the 6070 * given {@link ProviderInfo}. Final permission checking is always done 6071 * in {@link ContentProvider}. 6072 */ 6073 private final String checkContentProviderPermissionLocked( 6074 ProviderInfo cpi, ProcessRecord r) { 6075 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6076 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6077 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6078 cpi.applicationInfo.uid, cpi.exported) 6079 == PackageManager.PERMISSION_GRANTED) { 6080 return null; 6081 } 6082 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6083 cpi.applicationInfo.uid, cpi.exported) 6084 == PackageManager.PERMISSION_GRANTED) { 6085 return null; 6086 } 6087 6088 PathPermission[] pps = cpi.pathPermissions; 6089 if (pps != null) { 6090 int i = pps.length; 6091 while (i > 0) { 6092 i--; 6093 PathPermission pp = pps[i]; 6094 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6095 cpi.applicationInfo.uid, cpi.exported) 6096 == PackageManager.PERMISSION_GRANTED) { 6097 return null; 6098 } 6099 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6100 cpi.applicationInfo.uid, cpi.exported) 6101 == PackageManager.PERMISSION_GRANTED) { 6102 return null; 6103 } 6104 } 6105 } 6106 6107 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6108 if (perms != null) { 6109 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6110 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6111 return null; 6112 } 6113 } 6114 } 6115 6116 String msg; 6117 if (!cpi.exported) { 6118 msg = "Permission Denial: opening provider " + cpi.name 6119 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6120 + ", uid=" + callingUid + ") that is not exported from uid " 6121 + cpi.applicationInfo.uid; 6122 } else { 6123 msg = "Permission Denial: opening provider " + cpi.name 6124 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6125 + ", uid=" + callingUid + ") requires " 6126 + cpi.readPermission + " or " + cpi.writePermission; 6127 } 6128 Slog.w(TAG, msg); 6129 return msg; 6130 } 6131 6132 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6133 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6134 if (r != null) { 6135 for (int i=0; i<r.conProviders.size(); i++) { 6136 ContentProviderConnection conn = r.conProviders.get(i); 6137 if (conn.provider == cpr) { 6138 if (DEBUG_PROVIDER) Slog.v(TAG, 6139 "Adding provider requested by " 6140 + r.processName + " from process " 6141 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6142 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6143 if (stable) { 6144 conn.stableCount++; 6145 conn.numStableIncs++; 6146 } else { 6147 conn.unstableCount++; 6148 conn.numUnstableIncs++; 6149 } 6150 return conn; 6151 } 6152 } 6153 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6154 if (stable) { 6155 conn.stableCount = 1; 6156 conn.numStableIncs = 1; 6157 } else { 6158 conn.unstableCount = 1; 6159 conn.numUnstableIncs = 1; 6160 } 6161 cpr.connections.add(conn); 6162 r.conProviders.add(conn); 6163 return conn; 6164 } 6165 cpr.addExternalProcessHandleLocked(externalProcessToken); 6166 return null; 6167 } 6168 6169 boolean decProviderCountLocked(ContentProviderConnection conn, 6170 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6171 if (conn != null) { 6172 cpr = conn.provider; 6173 if (DEBUG_PROVIDER) Slog.v(TAG, 6174 "Removing provider requested by " 6175 + conn.client.processName + " from process " 6176 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6177 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6178 if (stable) { 6179 conn.stableCount--; 6180 } else { 6181 conn.unstableCount--; 6182 } 6183 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6184 cpr.connections.remove(conn); 6185 conn.client.conProviders.remove(conn); 6186 return true; 6187 } 6188 return false; 6189 } 6190 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6191 return false; 6192 } 6193 6194 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6195 String name, IBinder token, boolean stable) { 6196 ContentProviderRecord cpr; 6197 ContentProviderConnection conn = null; 6198 ProviderInfo cpi = null; 6199 6200 synchronized(this) { 6201 ProcessRecord r = null; 6202 if (caller != null) { 6203 r = getRecordForAppLocked(caller); 6204 if (r == null) { 6205 throw new SecurityException( 6206 "Unable to find app for caller " + caller 6207 + " (pid=" + Binder.getCallingPid() 6208 + ") when getting content provider " + name); 6209 } 6210 } 6211 6212 // First check if this content provider has been published... 6213 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6214 cpr = mProviderMap.getProviderByName(name, userId); 6215 boolean providerRunning = cpr != null; 6216 if (providerRunning) { 6217 cpi = cpr.info; 6218 String msg; 6219 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6220 throw new SecurityException(msg); 6221 } 6222 6223 if (r != null && cpr.canRunHere(r)) { 6224 // This provider has been published or is in the process 6225 // of being published... but it is also allowed to run 6226 // in the caller's process, so don't make a connection 6227 // and just let the caller instantiate its own instance. 6228 ContentProviderHolder holder = cpr.newHolder(null); 6229 // don't give caller the provider object, it needs 6230 // to make its own. 6231 holder.provider = null; 6232 return holder; 6233 } 6234 6235 final long origId = Binder.clearCallingIdentity(); 6236 6237 // In this case the provider instance already exists, so we can 6238 // return it right away. 6239 conn = incProviderCountLocked(r, cpr, token, stable); 6240 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6241 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6242 // If this is a perceptible app accessing the provider, 6243 // make sure to count it as being accessed and thus 6244 // back up on the LRU list. This is good because 6245 // content providers are often expensive to start. 6246 updateLruProcessLocked(cpr.proc, false, true); 6247 } 6248 } 6249 6250 if (cpr.proc != null) { 6251 if (false) { 6252 if (cpr.name.flattenToShortString().equals( 6253 "com.android.providers.calendar/.CalendarProvider2")) { 6254 Slog.v(TAG, "****************** KILLING " 6255 + cpr.name.flattenToShortString()); 6256 Process.killProcess(cpr.proc.pid); 6257 } 6258 } 6259 boolean success = updateOomAdjLocked(cpr.proc); 6260 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6261 // NOTE: there is still a race here where a signal could be 6262 // pending on the process even though we managed to update its 6263 // adj level. Not sure what to do about this, but at least 6264 // the race is now smaller. 6265 if (!success) { 6266 // Uh oh... it looks like the provider's process 6267 // has been killed on us. We need to wait for a new 6268 // process to be started, and make sure its death 6269 // doesn't kill our process. 6270 Slog.i(TAG, 6271 "Existing provider " + cpr.name.flattenToShortString() 6272 + " is crashing; detaching " + r); 6273 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6274 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6275 if (!lastRef) { 6276 // This wasn't the last ref our process had on 6277 // the provider... we have now been killed, bail. 6278 return null; 6279 } 6280 providerRunning = false; 6281 conn = null; 6282 } 6283 } 6284 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 if (!providerRunning) { 6289 try { 6290 cpi = AppGlobals.getPackageManager(). 6291 resolveContentProvider(name, 6292 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6293 } catch (RemoteException ex) { 6294 } 6295 if (cpi == null) { 6296 return null; 6297 } 6298 if (isSingleton(cpi.processName, cpi.applicationInfo)) { 6299 userId = 0; 6300 } 6301 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6302 6303 String msg; 6304 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6305 throw new SecurityException(msg); 6306 } 6307 6308 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6309 && !cpi.processName.equals("system")) { 6310 // If this content provider does not run in the system 6311 // process, and the system is not yet ready to run other 6312 // processes, then fail fast instead of hanging. 6313 throw new IllegalArgumentException( 6314 "Attempt to launch content provider before system ready"); 6315 } 6316 6317 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6318 cpr = mProviderMap.getProviderByClass(comp, userId); 6319 final boolean firstClass = cpr == null; 6320 if (firstClass) { 6321 try { 6322 ApplicationInfo ai = 6323 AppGlobals.getPackageManager(). 6324 getApplicationInfo( 6325 cpi.applicationInfo.packageName, 6326 STOCK_PM_FLAGS, userId); 6327 if (ai == null) { 6328 Slog.w(TAG, "No package info for content provider " 6329 + cpi.name); 6330 return null; 6331 } 6332 ai = getAppInfoForUser(ai, userId); 6333 cpr = new ContentProviderRecord(this, cpi, ai, comp); 6334 } catch (RemoteException ex) { 6335 // pm is in same process, this will never happen. 6336 } 6337 } 6338 6339 if (r != null && cpr.canRunHere(r)) { 6340 // If this is a multiprocess provider, then just return its 6341 // info and allow the caller to instantiate it. Only do 6342 // this if the provider is the same user as the caller's 6343 // process, or can run as root (so can be in any process). 6344 return cpr.newHolder(null); 6345 } 6346 6347 if (DEBUG_PROVIDER) { 6348 RuntimeException e = new RuntimeException("here"); 6349 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6350 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6351 } 6352 6353 // This is single process, and our app is now connecting to it. 6354 // See if we are already in the process of launching this 6355 // provider. 6356 final int N = mLaunchingProviders.size(); 6357 int i; 6358 for (i=0; i<N; i++) { 6359 if (mLaunchingProviders.get(i) == cpr) { 6360 break; 6361 } 6362 } 6363 6364 // If the provider is not already being launched, then get it 6365 // started. 6366 if (i >= N) { 6367 final long origId = Binder.clearCallingIdentity(); 6368 6369 try { 6370 // Content provider is now in use, its package can't be stopped. 6371 try { 6372 AppGlobals.getPackageManager().setPackageStoppedState( 6373 cpr.appInfo.packageName, false, userId); 6374 } catch (RemoteException e) { 6375 } catch (IllegalArgumentException e) { 6376 Slog.w(TAG, "Failed trying to unstop package " 6377 + cpr.appInfo.packageName + ": " + e); 6378 } 6379 6380 ProcessRecord proc = startProcessLocked(cpi.processName, 6381 cpr.appInfo, false, 0, "content provider", 6382 new ComponentName(cpi.applicationInfo.packageName, 6383 cpi.name), false, false); 6384 if (proc == null) { 6385 Slog.w(TAG, "Unable to launch app " 6386 + cpi.applicationInfo.packageName + "/" 6387 + cpi.applicationInfo.uid + " for provider " 6388 + name + ": process is bad"); 6389 return null; 6390 } 6391 cpr.launchingApp = proc; 6392 mLaunchingProviders.add(cpr); 6393 } finally { 6394 Binder.restoreCallingIdentity(origId); 6395 } 6396 } 6397 6398 // Make sure the provider is published (the same provider class 6399 // may be published under multiple names). 6400 if (firstClass) { 6401 mProviderMap.putProviderByClass(comp, cpr); 6402 } 6403 6404 mProviderMap.putProviderByName(name, cpr); 6405 conn = incProviderCountLocked(r, cpr, token, stable); 6406 if (conn != null) { 6407 conn.waiting = true; 6408 } 6409 } 6410 } 6411 6412 // Wait for the provider to be published... 6413 synchronized (cpr) { 6414 while (cpr.provider == null) { 6415 if (cpr.launchingApp == null) { 6416 Slog.w(TAG, "Unable to launch app " 6417 + cpi.applicationInfo.packageName + "/" 6418 + cpi.applicationInfo.uid + " for provider " 6419 + name + ": launching app became null"); 6420 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6421 cpi.applicationInfo.packageName, 6422 cpi.applicationInfo.uid, name); 6423 return null; 6424 } 6425 try { 6426 if (DEBUG_MU) { 6427 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6428 + cpr.launchingApp); 6429 } 6430 if (conn != null) { 6431 conn.waiting = true; 6432 } 6433 cpr.wait(); 6434 } catch (InterruptedException ex) { 6435 } finally { 6436 if (conn != null) { 6437 conn.waiting = false; 6438 } 6439 } 6440 } 6441 } 6442 return cpr != null ? cpr.newHolder(conn) : null; 6443 } 6444 6445 public final ContentProviderHolder getContentProvider( 6446 IApplicationThread caller, String name, boolean stable) { 6447 enforceNotIsolatedCaller("getContentProvider"); 6448 if (caller == null) { 6449 String msg = "null IApplicationThread when getting content provider " 6450 + name; 6451 Slog.w(TAG, msg); 6452 throw new SecurityException(msg); 6453 } 6454 6455 return getContentProviderImpl(caller, name, null, stable); 6456 } 6457 6458 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6459 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6460 "Do not have permission in call getContentProviderExternal()"); 6461 return getContentProviderExternalUnchecked(name, token); 6462 } 6463 6464 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6465 return getContentProviderImpl(null, name, token, true); 6466 } 6467 6468 /** 6469 * Drop a content provider from a ProcessRecord's bookkeeping 6470 * @param cpr 6471 */ 6472 public void removeContentProvider(IBinder connection, boolean stable) { 6473 enforceNotIsolatedCaller("removeContentProvider"); 6474 synchronized (this) { 6475 ContentProviderConnection conn; 6476 try { 6477 conn = (ContentProviderConnection)connection; 6478 } catch (ClassCastException e) { 6479 String msg ="removeContentProvider: " + connection 6480 + " not a ContentProviderConnection"; 6481 Slog.w(TAG, msg); 6482 throw new IllegalArgumentException(msg); 6483 } 6484 if (conn == null) { 6485 throw new NullPointerException("connection is null"); 6486 } 6487 if (decProviderCountLocked(conn, null, null, stable)) { 6488 updateOomAdjLocked(); 6489 } 6490 } 6491 } 6492 6493 public void removeContentProviderExternal(String name, IBinder token) { 6494 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6495 "Do not have permission in call removeContentProviderExternal()"); 6496 removeContentProviderExternalUnchecked(name, token); 6497 } 6498 6499 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6500 synchronized (this) { 6501 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6502 Binder.getOrigCallingUser()); 6503 if(cpr == null) { 6504 //remove from mProvidersByClass 6505 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6506 return; 6507 } 6508 6509 //update content provider record entry info 6510 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6511 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6512 Binder.getOrigCallingUser()); 6513 if (localCpr.hasExternalProcessHandles()) { 6514 if (localCpr.removeExternalProcessHandleLocked(token)) { 6515 updateOomAdjLocked(); 6516 } else { 6517 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6518 + " with no external reference for token: " 6519 + token + "."); 6520 } 6521 } else { 6522 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6523 + " with no external references."); 6524 } 6525 } 6526 } 6527 6528 public final void publishContentProviders(IApplicationThread caller, 6529 List<ContentProviderHolder> providers) { 6530 if (providers == null) { 6531 return; 6532 } 6533 6534 enforceNotIsolatedCaller("publishContentProviders"); 6535 synchronized (this) { 6536 final ProcessRecord r = getRecordForAppLocked(caller); 6537 if (DEBUG_MU) 6538 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6539 if (r == null) { 6540 throw new SecurityException( 6541 "Unable to find app for caller " + caller 6542 + " (pid=" + Binder.getCallingPid() 6543 + ") when publishing content providers"); 6544 } 6545 6546 final long origId = Binder.clearCallingIdentity(); 6547 6548 final int N = providers.size(); 6549 for (int i=0; i<N; i++) { 6550 ContentProviderHolder src = providers.get(i); 6551 if (src == null || src.info == null || src.provider == null) { 6552 continue; 6553 } 6554 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6555 if (DEBUG_MU) 6556 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6557 if (dst != null) { 6558 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6559 mProviderMap.putProviderByClass(comp, dst); 6560 String names[] = dst.info.authority.split(";"); 6561 for (int j = 0; j < names.length; j++) { 6562 mProviderMap.putProviderByName(names[j], dst); 6563 } 6564 6565 int NL = mLaunchingProviders.size(); 6566 int j; 6567 for (j=0; j<NL; j++) { 6568 if (mLaunchingProviders.get(j) == dst) { 6569 mLaunchingProviders.remove(j); 6570 j--; 6571 NL--; 6572 } 6573 } 6574 synchronized (dst) { 6575 dst.provider = src.provider; 6576 dst.proc = r; 6577 dst.notifyAll(); 6578 } 6579 updateOomAdjLocked(r); 6580 } 6581 } 6582 6583 Binder.restoreCallingIdentity(origId); 6584 } 6585 } 6586 6587 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6588 ContentProviderConnection conn; 6589 try { 6590 conn = (ContentProviderConnection)connection; 6591 } catch (ClassCastException e) { 6592 String msg ="refContentProvider: " + connection 6593 + " not a ContentProviderConnection"; 6594 Slog.w(TAG, msg); 6595 throw new IllegalArgumentException(msg); 6596 } 6597 if (conn == null) { 6598 throw new NullPointerException("connection is null"); 6599 } 6600 6601 synchronized (this) { 6602 if (stable > 0) { 6603 conn.numStableIncs += stable; 6604 } 6605 stable = conn.stableCount + stable; 6606 if (stable < 0) { 6607 throw new IllegalStateException("stableCount < 0: " + stable); 6608 } 6609 6610 if (unstable > 0) { 6611 conn.numUnstableIncs += unstable; 6612 } 6613 unstable = conn.unstableCount + unstable; 6614 if (unstable < 0) { 6615 throw new IllegalStateException("unstableCount < 0: " + unstable); 6616 } 6617 6618 if ((stable+unstable) <= 0) { 6619 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6620 + stable + " unstable=" + unstable); 6621 } 6622 conn.stableCount = stable; 6623 conn.unstableCount = unstable; 6624 return !conn.dead; 6625 } 6626 } 6627 6628 public void unstableProviderDied(IBinder connection) { 6629 ContentProviderConnection conn; 6630 try { 6631 conn = (ContentProviderConnection)connection; 6632 } catch (ClassCastException e) { 6633 String msg ="refContentProvider: " + connection 6634 + " not a ContentProviderConnection"; 6635 Slog.w(TAG, msg); 6636 throw new IllegalArgumentException(msg); 6637 } 6638 if (conn == null) { 6639 throw new NullPointerException("connection is null"); 6640 } 6641 6642 // Safely retrieve the content provider associated with the connection. 6643 IContentProvider provider; 6644 synchronized (this) { 6645 provider = conn.provider.provider; 6646 } 6647 6648 if (provider == null) { 6649 // Um, yeah, we're way ahead of you. 6650 return; 6651 } 6652 6653 // Make sure the caller is being honest with us. 6654 if (provider.asBinder().pingBinder()) { 6655 // Er, no, still looks good to us. 6656 synchronized (this) { 6657 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6658 + " says " + conn + " died, but we don't agree"); 6659 return; 6660 } 6661 } 6662 6663 // Well look at that! It's dead! 6664 synchronized (this) { 6665 if (conn.provider.provider != provider) { 6666 // But something changed... good enough. 6667 return; 6668 } 6669 6670 ProcessRecord proc = conn.provider.proc; 6671 if (proc == null || proc.thread == null) { 6672 // Seems like the process is already cleaned up. 6673 return; 6674 } 6675 6676 // As far as we're concerned, this is just like receiving a 6677 // death notification... just a bit prematurely. 6678 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6679 + ") early provider death"); 6680 final long ident = Binder.clearCallingIdentity(); 6681 try { 6682 appDiedLocked(proc, proc.pid, proc.thread); 6683 } finally { 6684 Binder.restoreCallingIdentity(ident); 6685 } 6686 } 6687 } 6688 6689 public static final void installSystemProviders() { 6690 List<ProviderInfo> providers; 6691 synchronized (mSelf) { 6692 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6693 providers = mSelf.generateApplicationProvidersLocked(app); 6694 if (providers != null) { 6695 for (int i=providers.size()-1; i>=0; i--) { 6696 ProviderInfo pi = (ProviderInfo)providers.get(i); 6697 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6698 Slog.w(TAG, "Not installing system proc provider " + pi.name 6699 + ": not system .apk"); 6700 providers.remove(i); 6701 } 6702 } 6703 } 6704 } 6705 if (providers != null) { 6706 mSystemThread.installSystemProviders(providers); 6707 } 6708 6709 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6710 6711 mSelf.mUsageStatsService.monitorPackages(); 6712 } 6713 6714 /** 6715 * Allows app to retrieve the MIME type of a URI without having permission 6716 * to access its content provider. 6717 * 6718 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6719 * 6720 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6721 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6722 */ 6723 public String getProviderMimeType(Uri uri) { 6724 enforceNotIsolatedCaller("getProviderMimeType"); 6725 final String name = uri.getAuthority(); 6726 final long ident = Binder.clearCallingIdentity(); 6727 ContentProviderHolder holder = null; 6728 6729 try { 6730 holder = getContentProviderExternalUnchecked(name, null); 6731 if (holder != null) { 6732 return holder.provider.getType(uri); 6733 } 6734 } catch (RemoteException e) { 6735 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6736 return null; 6737 } finally { 6738 if (holder != null) { 6739 removeContentProviderExternalUnchecked(name, null); 6740 } 6741 Binder.restoreCallingIdentity(ident); 6742 } 6743 6744 return null; 6745 } 6746 6747 // ========================================================= 6748 // GLOBAL MANAGEMENT 6749 // ========================================================= 6750 6751 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6752 ApplicationInfo info, String customProcess, boolean isolated) { 6753 String proc = customProcess != null ? customProcess : info.processName; 6754 BatteryStatsImpl.Uid.Proc ps = null; 6755 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6756 int uid = info.uid; 6757 if (isolated) { 6758 int userId = UserId.getUserId(uid); 6759 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6760 uid = 0; 6761 while (true) { 6762 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6763 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6764 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6765 } 6766 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6767 mNextIsolatedProcessUid++; 6768 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6769 // No process for this uid, use it. 6770 break; 6771 } 6772 stepsLeft--; 6773 if (stepsLeft <= 0) { 6774 return null; 6775 } 6776 } 6777 } 6778 synchronized (stats) { 6779 ps = stats.getProcessStatsLocked(info.uid, proc); 6780 } 6781 return new ProcessRecord(ps, thread, info, proc, uid); 6782 } 6783 6784 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6785 ProcessRecord app; 6786 if (!isolated) { 6787 app = getProcessRecordLocked(info.processName, info.uid); 6788 } else { 6789 app = null; 6790 } 6791 6792 if (app == null) { 6793 app = newProcessRecordLocked(null, info, null, isolated); 6794 mProcessNames.put(info.processName, app.uid, app); 6795 if (isolated) { 6796 mIsolatedProcesses.put(app.uid, app); 6797 } 6798 updateLruProcessLocked(app, true, true); 6799 } 6800 6801 // This package really, really can not be stopped. 6802 try { 6803 AppGlobals.getPackageManager().setPackageStoppedState( 6804 info.packageName, false, UserId.getUserId(app.uid)); 6805 } catch (RemoteException e) { 6806 } catch (IllegalArgumentException e) { 6807 Slog.w(TAG, "Failed trying to unstop package " 6808 + info.packageName + ": " + e); 6809 } 6810 6811 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6812 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6813 app.persistent = true; 6814 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6815 } 6816 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6817 mPersistentStartingProcesses.add(app); 6818 startProcessLocked(app, "added application", app.processName); 6819 } 6820 6821 return app; 6822 } 6823 6824 public void unhandledBack() { 6825 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6826 "unhandledBack()"); 6827 6828 synchronized(this) { 6829 int count = mMainStack.mHistory.size(); 6830 if (DEBUG_SWITCH) Slog.d( 6831 TAG, "Performing unhandledBack(): stack size = " + count); 6832 if (count > 1) { 6833 final long origId = Binder.clearCallingIdentity(); 6834 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6835 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6836 Binder.restoreCallingIdentity(origId); 6837 } 6838 } 6839 } 6840 6841 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6842 enforceNotIsolatedCaller("openContentUri"); 6843 String name = uri.getAuthority(); 6844 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6845 ParcelFileDescriptor pfd = null; 6846 if (cph != null) { 6847 // We record the binder invoker's uid in thread-local storage before 6848 // going to the content provider to open the file. Later, in the code 6849 // that handles all permissions checks, we look for this uid and use 6850 // that rather than the Activity Manager's own uid. The effect is that 6851 // we do the check against the caller's permissions even though it looks 6852 // to the content provider like the Activity Manager itself is making 6853 // the request. 6854 sCallerIdentity.set(new Identity( 6855 Binder.getCallingPid(), Binder.getCallingUid())); 6856 try { 6857 pfd = cph.provider.openFile(uri, "r"); 6858 } catch (FileNotFoundException e) { 6859 // do nothing; pfd will be returned null 6860 } finally { 6861 // Ensure that whatever happens, we clean up the identity state 6862 sCallerIdentity.remove(); 6863 } 6864 6865 // We've got the fd now, so we're done with the provider. 6866 removeContentProviderExternalUnchecked(name, null); 6867 } else { 6868 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6869 } 6870 return pfd; 6871 } 6872 6873 // Actually is sleeping or shutting down or whatever else in the future 6874 // is an inactive state. 6875 public boolean isSleeping() { 6876 return mSleeping || mShuttingDown; 6877 } 6878 6879 public void goingToSleep() { 6880 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6881 != PackageManager.PERMISSION_GRANTED) { 6882 throw new SecurityException("Requires permission " 6883 + android.Manifest.permission.DEVICE_POWER); 6884 } 6885 6886 synchronized(this) { 6887 mWentToSleep = true; 6888 updateEventDispatchingLocked(); 6889 6890 if (!mSleeping) { 6891 mSleeping = true; 6892 mMainStack.stopIfSleepingLocked(); 6893 6894 // Initialize the wake times of all processes. 6895 checkExcessivePowerUsageLocked(false); 6896 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6897 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6898 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6899 } 6900 } 6901 } 6902 6903 public boolean shutdown(int timeout) { 6904 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6905 != PackageManager.PERMISSION_GRANTED) { 6906 throw new SecurityException("Requires permission " 6907 + android.Manifest.permission.SHUTDOWN); 6908 } 6909 6910 boolean timedout = false; 6911 6912 synchronized(this) { 6913 mShuttingDown = true; 6914 updateEventDispatchingLocked(); 6915 6916 if (mMainStack.mResumedActivity != null) { 6917 mMainStack.stopIfSleepingLocked(); 6918 final long endTime = System.currentTimeMillis() + timeout; 6919 while (mMainStack.mResumedActivity != null 6920 || mMainStack.mPausingActivity != null) { 6921 long delay = endTime - System.currentTimeMillis(); 6922 if (delay <= 0) { 6923 Slog.w(TAG, "Activity manager shutdown timed out"); 6924 timedout = true; 6925 break; 6926 } 6927 try { 6928 this.wait(); 6929 } catch (InterruptedException e) { 6930 } 6931 } 6932 } 6933 } 6934 6935 mUsageStatsService.shutdown(); 6936 mBatteryStatsService.shutdown(); 6937 6938 return timedout; 6939 } 6940 6941 public final void activitySlept(IBinder token) { 6942 if (localLOGV) Slog.v( 6943 TAG, "Activity slept: token=" + token); 6944 6945 ActivityRecord r = null; 6946 6947 final long origId = Binder.clearCallingIdentity(); 6948 6949 synchronized (this) { 6950 r = mMainStack.isInStackLocked(token); 6951 if (r != null) { 6952 mMainStack.activitySleptLocked(r); 6953 } 6954 } 6955 6956 Binder.restoreCallingIdentity(origId); 6957 } 6958 6959 private void comeOutOfSleepIfNeededLocked() { 6960 if (!mWentToSleep && !mLockScreenShown) { 6961 if (mSleeping) { 6962 mSleeping = false; 6963 mMainStack.awakeFromSleepingLocked(); 6964 mMainStack.resumeTopActivityLocked(null); 6965 } 6966 } 6967 } 6968 6969 public void wakingUp() { 6970 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6971 != PackageManager.PERMISSION_GRANTED) { 6972 throw new SecurityException("Requires permission " 6973 + android.Manifest.permission.DEVICE_POWER); 6974 } 6975 6976 synchronized(this) { 6977 mWentToSleep = false; 6978 updateEventDispatchingLocked(); 6979 comeOutOfSleepIfNeededLocked(); 6980 } 6981 } 6982 6983 private void updateEventDispatchingLocked() { 6984 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6985 } 6986 6987 public void setLockScreenShown(boolean shown) { 6988 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6989 != PackageManager.PERMISSION_GRANTED) { 6990 throw new SecurityException("Requires permission " 6991 + android.Manifest.permission.DEVICE_POWER); 6992 } 6993 6994 synchronized(this) { 6995 mLockScreenShown = shown; 6996 comeOutOfSleepIfNeededLocked(); 6997 } 6998 } 6999 7000 public void stopAppSwitches() { 7001 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7002 != PackageManager.PERMISSION_GRANTED) { 7003 throw new SecurityException("Requires permission " 7004 + android.Manifest.permission.STOP_APP_SWITCHES); 7005 } 7006 7007 synchronized(this) { 7008 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7009 + APP_SWITCH_DELAY_TIME; 7010 mDidAppSwitch = false; 7011 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7012 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7013 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7014 } 7015 } 7016 7017 public void resumeAppSwitches() { 7018 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7019 != PackageManager.PERMISSION_GRANTED) { 7020 throw new SecurityException("Requires permission " 7021 + android.Manifest.permission.STOP_APP_SWITCHES); 7022 } 7023 7024 synchronized(this) { 7025 // Note that we don't execute any pending app switches... we will 7026 // let those wait until either the timeout, or the next start 7027 // activity request. 7028 mAppSwitchesAllowedTime = 0; 7029 } 7030 } 7031 7032 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7033 String name) { 7034 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7035 return true; 7036 } 7037 7038 final int perm = checkComponentPermission( 7039 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7040 callingUid, -1, true); 7041 if (perm == PackageManager.PERMISSION_GRANTED) { 7042 return true; 7043 } 7044 7045 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7046 return false; 7047 } 7048 7049 public void setDebugApp(String packageName, boolean waitForDebugger, 7050 boolean persistent) { 7051 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7052 "setDebugApp()"); 7053 7054 // Note that this is not really thread safe if there are multiple 7055 // callers into it at the same time, but that's not a situation we 7056 // care about. 7057 if (persistent) { 7058 final ContentResolver resolver = mContext.getContentResolver(); 7059 Settings.System.putString( 7060 resolver, Settings.System.DEBUG_APP, 7061 packageName); 7062 Settings.System.putInt( 7063 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7064 waitForDebugger ? 1 : 0); 7065 } 7066 7067 synchronized (this) { 7068 if (!persistent) { 7069 mOrigDebugApp = mDebugApp; 7070 mOrigWaitForDebugger = mWaitForDebugger; 7071 } 7072 mDebugApp = packageName; 7073 mWaitForDebugger = waitForDebugger; 7074 mDebugTransient = !persistent; 7075 if (packageName != null) { 7076 final long origId = Binder.clearCallingIdentity(); 7077 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7078 Binder.restoreCallingIdentity(origId); 7079 } 7080 } 7081 } 7082 7083 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7084 synchronized (this) { 7085 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7086 if (!isDebuggable) { 7087 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7088 throw new SecurityException("Process not debuggable: " + app.packageName); 7089 } 7090 } 7091 7092 mOpenGlTraceApp = processName; 7093 } 7094 } 7095 7096 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7097 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7098 synchronized (this) { 7099 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7100 if (!isDebuggable) { 7101 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7102 throw new SecurityException("Process not debuggable: " + app.packageName); 7103 } 7104 } 7105 mProfileApp = processName; 7106 mProfileFile = profileFile; 7107 if (mProfileFd != null) { 7108 try { 7109 mProfileFd.close(); 7110 } catch (IOException e) { 7111 } 7112 mProfileFd = null; 7113 } 7114 mProfileFd = profileFd; 7115 mProfileType = 0; 7116 mAutoStopProfiler = autoStopProfiler; 7117 } 7118 } 7119 7120 public void setAlwaysFinish(boolean enabled) { 7121 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7122 "setAlwaysFinish()"); 7123 7124 Settings.System.putInt( 7125 mContext.getContentResolver(), 7126 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7127 7128 synchronized (this) { 7129 mAlwaysFinishActivities = enabled; 7130 } 7131 } 7132 7133 public void setActivityController(IActivityController controller) { 7134 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7135 "setActivityController()"); 7136 synchronized (this) { 7137 mController = controller; 7138 } 7139 } 7140 7141 public boolean isUserAMonkey() { 7142 // For now the fact that there is a controller implies 7143 // we have a monkey. 7144 synchronized (this) { 7145 return mController != null; 7146 } 7147 } 7148 7149 public void registerProcessObserver(IProcessObserver observer) { 7150 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7151 "registerProcessObserver()"); 7152 synchronized (this) { 7153 mProcessObservers.register(observer); 7154 } 7155 } 7156 7157 public void unregisterProcessObserver(IProcessObserver observer) { 7158 synchronized (this) { 7159 mProcessObservers.unregister(observer); 7160 } 7161 } 7162 7163 public void setImmersive(IBinder token, boolean immersive) { 7164 synchronized(this) { 7165 ActivityRecord r = mMainStack.isInStackLocked(token); 7166 if (r == null) { 7167 throw new IllegalArgumentException(); 7168 } 7169 r.immersive = immersive; 7170 } 7171 } 7172 7173 public boolean isImmersive(IBinder token) { 7174 synchronized (this) { 7175 ActivityRecord r = mMainStack.isInStackLocked(token); 7176 if (r == null) { 7177 throw new IllegalArgumentException(); 7178 } 7179 return r.immersive; 7180 } 7181 } 7182 7183 public boolean isTopActivityImmersive() { 7184 enforceNotIsolatedCaller("startActivity"); 7185 synchronized (this) { 7186 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7187 return (r != null) ? r.immersive : false; 7188 } 7189 } 7190 7191 public final void enterSafeMode() { 7192 synchronized(this) { 7193 // It only makes sense to do this before the system is ready 7194 // and started launching other packages. 7195 if (!mSystemReady) { 7196 try { 7197 AppGlobals.getPackageManager().enterSafeMode(); 7198 } catch (RemoteException e) { 7199 } 7200 } 7201 } 7202 } 7203 7204 public final void showSafeModeOverlay() { 7205 View v = LayoutInflater.from(mContext).inflate( 7206 com.android.internal.R.layout.safe_mode, null); 7207 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7208 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7209 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7210 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7211 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 7212 lp.format = v.getBackground().getOpacity(); 7213 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7214 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7215 ((WindowManager)mContext.getSystemService( 7216 Context.WINDOW_SERVICE)).addView(v, lp); 7217 } 7218 7219 public void noteWakeupAlarm(IIntentSender sender) { 7220 if (!(sender instanceof PendingIntentRecord)) { 7221 return; 7222 } 7223 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7224 synchronized (stats) { 7225 if (mBatteryStatsService.isOnBattery()) { 7226 mBatteryStatsService.enforceCallingPermission(); 7227 PendingIntentRecord rec = (PendingIntentRecord)sender; 7228 int MY_UID = Binder.getCallingUid(); 7229 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7230 BatteryStatsImpl.Uid.Pkg pkg = 7231 stats.getPackageStatsLocked(uid, rec.key.packageName); 7232 pkg.incWakeupsLocked(); 7233 } 7234 } 7235 } 7236 7237 public boolean killPids(int[] pids, String pReason, boolean secure) { 7238 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7239 throw new SecurityException("killPids only available to the system"); 7240 } 7241 String reason = (pReason == null) ? "Unknown" : pReason; 7242 // XXX Note: don't acquire main activity lock here, because the window 7243 // manager calls in with its locks held. 7244 7245 boolean killed = false; 7246 synchronized (mPidsSelfLocked) { 7247 int[] types = new int[pids.length]; 7248 int worstType = 0; 7249 for (int i=0; i<pids.length; i++) { 7250 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7251 if (proc != null) { 7252 int type = proc.setAdj; 7253 types[i] = type; 7254 if (type > worstType) { 7255 worstType = type; 7256 } 7257 } 7258 } 7259 7260 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7261 // then constrain it so we will kill all hidden procs. 7262 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7263 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7264 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7265 } 7266 7267 // If this is not a secure call, don't let it kill processes that 7268 // are important. 7269 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7270 worstType = ProcessList.SERVICE_ADJ; 7271 } 7272 7273 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7274 for (int i=0; i<pids.length; i++) { 7275 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7276 if (proc == null) { 7277 continue; 7278 } 7279 int adj = proc.setAdj; 7280 if (adj >= worstType && !proc.killedBackground) { 7281 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7282 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7283 proc.processName, adj, reason); 7284 killed = true; 7285 proc.killedBackground = true; 7286 Process.killProcessQuiet(pids[i]); 7287 } 7288 } 7289 } 7290 return killed; 7291 } 7292 7293 @Override 7294 public boolean killProcessesBelowForeground(String reason) { 7295 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7296 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7297 } 7298 7299 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7300 } 7301 7302 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7303 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7304 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7305 } 7306 7307 boolean killed = false; 7308 synchronized (mPidsSelfLocked) { 7309 final int size = mPidsSelfLocked.size(); 7310 for (int i = 0; i < size; i++) { 7311 final int pid = mPidsSelfLocked.keyAt(i); 7312 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7313 if (proc == null) continue; 7314 7315 final int adj = proc.setAdj; 7316 if (adj > belowAdj && !proc.killedBackground) { 7317 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7318 EventLog.writeEvent( 7319 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7320 killed = true; 7321 proc.killedBackground = true; 7322 Process.killProcessQuiet(pid); 7323 } 7324 } 7325 } 7326 return killed; 7327 } 7328 7329 public final void startRunning(String pkg, String cls, String action, 7330 String data) { 7331 synchronized(this) { 7332 if (mStartRunning) { 7333 return; 7334 } 7335 mStartRunning = true; 7336 mTopComponent = pkg != null && cls != null 7337 ? new ComponentName(pkg, cls) : null; 7338 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7339 mTopData = data; 7340 if (!mSystemReady) { 7341 return; 7342 } 7343 } 7344 7345 systemReady(null); 7346 } 7347 7348 private void retrieveSettings() { 7349 final ContentResolver resolver = mContext.getContentResolver(); 7350 String debugApp = Settings.System.getString( 7351 resolver, Settings.System.DEBUG_APP); 7352 boolean waitForDebugger = Settings.System.getInt( 7353 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7354 boolean alwaysFinishActivities = Settings.System.getInt( 7355 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7356 7357 Configuration configuration = new Configuration(); 7358 Settings.System.getConfiguration(resolver, configuration); 7359 7360 synchronized (this) { 7361 mDebugApp = mOrigDebugApp = debugApp; 7362 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7363 mAlwaysFinishActivities = alwaysFinishActivities; 7364 // This happens before any activities are started, so we can 7365 // change mConfiguration in-place. 7366 updateConfigurationLocked(configuration, null, false, true); 7367 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7368 } 7369 } 7370 7371 public boolean testIsSystemReady() { 7372 // no need to synchronize(this) just to read & return the value 7373 return mSystemReady; 7374 } 7375 7376 private static File getCalledPreBootReceiversFile() { 7377 File dataDir = Environment.getDataDirectory(); 7378 File systemDir = new File(dataDir, "system"); 7379 File fname = new File(systemDir, "called_pre_boots.dat"); 7380 return fname; 7381 } 7382 7383 static final int LAST_DONE_VERSION = 10000; 7384 7385 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7386 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7387 File file = getCalledPreBootReceiversFile(); 7388 FileInputStream fis = null; 7389 try { 7390 fis = new FileInputStream(file); 7391 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7392 int fvers = dis.readInt(); 7393 if (fvers == LAST_DONE_VERSION) { 7394 String vers = dis.readUTF(); 7395 String codename = dis.readUTF(); 7396 String build = dis.readUTF(); 7397 if (android.os.Build.VERSION.RELEASE.equals(vers) 7398 && android.os.Build.VERSION.CODENAME.equals(codename) 7399 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7400 int num = dis.readInt(); 7401 while (num > 0) { 7402 num--; 7403 String pkg = dis.readUTF(); 7404 String cls = dis.readUTF(); 7405 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7406 } 7407 } 7408 } 7409 } catch (FileNotFoundException e) { 7410 } catch (IOException e) { 7411 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7412 } finally { 7413 if (fis != null) { 7414 try { 7415 fis.close(); 7416 } catch (IOException e) { 7417 } 7418 } 7419 } 7420 return lastDoneReceivers; 7421 } 7422 7423 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7424 File file = getCalledPreBootReceiversFile(); 7425 FileOutputStream fos = null; 7426 DataOutputStream dos = null; 7427 try { 7428 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7429 fos = new FileOutputStream(file); 7430 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7431 dos.writeInt(LAST_DONE_VERSION); 7432 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7433 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7434 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7435 dos.writeInt(list.size()); 7436 for (int i=0; i<list.size(); i++) { 7437 dos.writeUTF(list.get(i).getPackageName()); 7438 dos.writeUTF(list.get(i).getClassName()); 7439 } 7440 } catch (IOException e) { 7441 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7442 file.delete(); 7443 } finally { 7444 FileUtils.sync(fos); 7445 if (dos != null) { 7446 try { 7447 dos.close(); 7448 } catch (IOException e) { 7449 // TODO Auto-generated catch block 7450 e.printStackTrace(); 7451 } 7452 } 7453 } 7454 } 7455 7456 public void systemReady(final Runnable goingCallback) { 7457 synchronized(this) { 7458 if (mSystemReady) { 7459 if (goingCallback != null) goingCallback.run(); 7460 return; 7461 } 7462 7463 // Check to see if there are any update receivers to run. 7464 if (!mDidUpdate) { 7465 if (mWaitingUpdate) { 7466 return; 7467 } 7468 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7469 List<ResolveInfo> ris = null; 7470 try { 7471 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7472 intent, null, 0, 0); 7473 } catch (RemoteException e) { 7474 } 7475 if (ris != null) { 7476 for (int i=ris.size()-1; i>=0; i--) { 7477 if ((ris.get(i).activityInfo.applicationInfo.flags 7478 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7479 ris.remove(i); 7480 } 7481 } 7482 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7483 7484 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7485 7486 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7487 for (int i=0; i<ris.size(); i++) { 7488 ActivityInfo ai = ris.get(i).activityInfo; 7489 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7490 if (lastDoneReceivers.contains(comp)) { 7491 ris.remove(i); 7492 i--; 7493 } 7494 } 7495 7496 for (int i=0; i<ris.size(); i++) { 7497 ActivityInfo ai = ris.get(i).activityInfo; 7498 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7499 doneReceivers.add(comp); 7500 intent.setComponent(comp); 7501 IIntentReceiver finisher = null; 7502 if (i == ris.size()-1) { 7503 finisher = new IIntentReceiver.Stub() { 7504 public void performReceive(Intent intent, int resultCode, 7505 String data, Bundle extras, boolean ordered, 7506 boolean sticky) { 7507 // The raw IIntentReceiver interface is called 7508 // with the AM lock held, so redispatch to 7509 // execute our code without the lock. 7510 mHandler.post(new Runnable() { 7511 public void run() { 7512 synchronized (ActivityManagerService.this) { 7513 mDidUpdate = true; 7514 } 7515 writeLastDonePreBootReceivers(doneReceivers); 7516 showBootMessage(mContext.getText( 7517 R.string.android_upgrading_complete), 7518 false); 7519 systemReady(goingCallback); 7520 } 7521 }); 7522 } 7523 }; 7524 } 7525 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7526 /* TODO: Send this to all users */ 7527 broadcastIntentLocked(null, null, intent, null, finisher, 7528 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7529 0 /* UserId zero */); 7530 if (finisher != null) { 7531 mWaitingUpdate = true; 7532 } 7533 } 7534 } 7535 if (mWaitingUpdate) { 7536 return; 7537 } 7538 mDidUpdate = true; 7539 } 7540 7541 mSystemReady = true; 7542 if (!mStartRunning) { 7543 return; 7544 } 7545 } 7546 7547 ArrayList<ProcessRecord> procsToKill = null; 7548 synchronized(mPidsSelfLocked) { 7549 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7550 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7551 if (!isAllowedWhileBooting(proc.info)){ 7552 if (procsToKill == null) { 7553 procsToKill = new ArrayList<ProcessRecord>(); 7554 } 7555 procsToKill.add(proc); 7556 } 7557 } 7558 } 7559 7560 synchronized(this) { 7561 if (procsToKill != null) { 7562 for (int i=procsToKill.size()-1; i>=0; i--) { 7563 ProcessRecord proc = procsToKill.get(i); 7564 Slog.i(TAG, "Removing system update proc: " + proc); 7565 removeProcessLocked(proc, true, false, "system update done"); 7566 } 7567 } 7568 7569 // Now that we have cleaned up any update processes, we 7570 // are ready to start launching real processes and know that 7571 // we won't trample on them any more. 7572 mProcessesReady = true; 7573 } 7574 7575 Slog.i(TAG, "System now ready"); 7576 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7577 SystemClock.uptimeMillis()); 7578 7579 synchronized(this) { 7580 // Make sure we have no pre-ready processes sitting around. 7581 7582 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7583 ResolveInfo ri = mContext.getPackageManager() 7584 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7585 STOCK_PM_FLAGS); 7586 CharSequence errorMsg = null; 7587 if (ri != null) { 7588 ActivityInfo ai = ri.activityInfo; 7589 ApplicationInfo app = ai.applicationInfo; 7590 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7591 mTopAction = Intent.ACTION_FACTORY_TEST; 7592 mTopData = null; 7593 mTopComponent = new ComponentName(app.packageName, 7594 ai.name); 7595 } else { 7596 errorMsg = mContext.getResources().getText( 7597 com.android.internal.R.string.factorytest_not_system); 7598 } 7599 } else { 7600 errorMsg = mContext.getResources().getText( 7601 com.android.internal.R.string.factorytest_no_action); 7602 } 7603 if (errorMsg != null) { 7604 mTopAction = null; 7605 mTopData = null; 7606 mTopComponent = null; 7607 Message msg = Message.obtain(); 7608 msg.what = SHOW_FACTORY_ERROR_MSG; 7609 msg.getData().putCharSequence("msg", errorMsg); 7610 mHandler.sendMessage(msg); 7611 } 7612 } 7613 } 7614 7615 retrieveSettings(); 7616 7617 if (goingCallback != null) goingCallback.run(); 7618 7619 synchronized (this) { 7620 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7621 try { 7622 List apps = AppGlobals.getPackageManager(). 7623 getPersistentApplications(STOCK_PM_FLAGS); 7624 if (apps != null) { 7625 int N = apps.size(); 7626 int i; 7627 for (i=0; i<N; i++) { 7628 ApplicationInfo info 7629 = (ApplicationInfo)apps.get(i); 7630 if (info != null && 7631 !info.packageName.equals("android")) { 7632 addAppLocked(info, false); 7633 } 7634 } 7635 } 7636 } catch (RemoteException ex) { 7637 // pm is in same process, this will never happen. 7638 } 7639 } 7640 7641 // Start up initial activity. 7642 mBooting = true; 7643 7644 try { 7645 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7646 Message msg = Message.obtain(); 7647 msg.what = SHOW_UID_ERROR_MSG; 7648 mHandler.sendMessage(msg); 7649 } 7650 } catch (RemoteException e) { 7651 } 7652 7653 mMainStack.resumeTopActivityLocked(null); 7654 } 7655 } 7656 7657 private boolean makeAppCrashingLocked(ProcessRecord app, 7658 String shortMsg, String longMsg, String stackTrace) { 7659 app.crashing = true; 7660 app.crashingReport = generateProcessError(app, 7661 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7662 startAppProblemLocked(app); 7663 app.stopFreezingAllLocked(); 7664 return handleAppCrashLocked(app); 7665 } 7666 7667 private void makeAppNotRespondingLocked(ProcessRecord app, 7668 String activity, String shortMsg, String longMsg) { 7669 app.notResponding = true; 7670 app.notRespondingReport = generateProcessError(app, 7671 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7672 activity, shortMsg, longMsg, null); 7673 startAppProblemLocked(app); 7674 app.stopFreezingAllLocked(); 7675 } 7676 7677 /** 7678 * Generate a process error record, suitable for attachment to a ProcessRecord. 7679 * 7680 * @param app The ProcessRecord in which the error occurred. 7681 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7682 * ActivityManager.AppErrorStateInfo 7683 * @param activity The activity associated with the crash, if known. 7684 * @param shortMsg Short message describing the crash. 7685 * @param longMsg Long message describing the crash. 7686 * @param stackTrace Full crash stack trace, may be null. 7687 * 7688 * @return Returns a fully-formed AppErrorStateInfo record. 7689 */ 7690 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7691 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7692 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7693 7694 report.condition = condition; 7695 report.processName = app.processName; 7696 report.pid = app.pid; 7697 report.uid = app.info.uid; 7698 report.tag = activity; 7699 report.shortMsg = shortMsg; 7700 report.longMsg = longMsg; 7701 report.stackTrace = stackTrace; 7702 7703 return report; 7704 } 7705 7706 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7707 synchronized (this) { 7708 app.crashing = false; 7709 app.crashingReport = null; 7710 app.notResponding = false; 7711 app.notRespondingReport = null; 7712 if (app.anrDialog == fromDialog) { 7713 app.anrDialog = null; 7714 } 7715 if (app.waitDialog == fromDialog) { 7716 app.waitDialog = null; 7717 } 7718 if (app.pid > 0 && app.pid != MY_PID) { 7719 handleAppCrashLocked(app); 7720 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7721 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7722 app.processName, app.setAdj, "user's request after error"); 7723 Process.killProcessQuiet(app.pid); 7724 } 7725 } 7726 } 7727 7728 private boolean handleAppCrashLocked(ProcessRecord app) { 7729 if (mHeadless) { 7730 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7731 return false; 7732 } 7733 long now = SystemClock.uptimeMillis(); 7734 7735 Long crashTime; 7736 if (!app.isolated) { 7737 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7738 } else { 7739 crashTime = null; 7740 } 7741 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7742 // This process loses! 7743 Slog.w(TAG, "Process " + app.info.processName 7744 + " has crashed too many times: killing!"); 7745 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7746 app.info.processName, app.uid); 7747 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7748 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7749 if (r.app == app) { 7750 Slog.w(TAG, " Force finishing activity " 7751 + r.intent.getComponent().flattenToShortString()); 7752 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7753 } 7754 } 7755 if (!app.persistent) { 7756 // We don't want to start this process again until the user 7757 // explicitly does so... but for persistent process, we really 7758 // need to keep it running. If a persistent process is actually 7759 // repeatedly crashing, then badness for everyone. 7760 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7761 app.info.processName); 7762 if (!app.isolated) { 7763 // XXX We don't have a way to mark isolated processes 7764 // as bad, since they don't have a peristent identity. 7765 mBadProcesses.put(app.info.processName, app.uid, now); 7766 mProcessCrashTimes.remove(app.info.processName, app.uid); 7767 } 7768 app.bad = true; 7769 app.removed = true; 7770 // Don't let services in this process be restarted and potentially 7771 // annoy the user repeatedly. Unless it is persistent, since those 7772 // processes run critical code. 7773 removeProcessLocked(app, false, false, "crash"); 7774 mMainStack.resumeTopActivityLocked(null); 7775 return false; 7776 } 7777 mMainStack.resumeTopActivityLocked(null); 7778 } else { 7779 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7780 if (r != null && r.app == app) { 7781 // If the top running activity is from this crashing 7782 // process, then terminate it to avoid getting in a loop. 7783 Slog.w(TAG, " Force finishing activity " 7784 + r.intent.getComponent().flattenToShortString()); 7785 int index = mMainStack.indexOfActivityLocked(r); 7786 r.stack.finishActivityLocked(r, index, 7787 Activity.RESULT_CANCELED, null, "crashed"); 7788 // Also terminate any activities below it that aren't yet 7789 // stopped, to avoid a situation where one will get 7790 // re-start our crashing activity once it gets resumed again. 7791 index--; 7792 if (index >= 0) { 7793 r = (ActivityRecord)mMainStack.mHistory.get(index); 7794 if (r.state == ActivityState.RESUMED 7795 || r.state == ActivityState.PAUSING 7796 || r.state == ActivityState.PAUSED) { 7797 if (!r.isHomeActivity || mHomeProcess != r.app) { 7798 Slog.w(TAG, " Force finishing activity " 7799 + r.intent.getComponent().flattenToShortString()); 7800 r.stack.finishActivityLocked(r, index, 7801 Activity.RESULT_CANCELED, null, "crashed"); 7802 } 7803 } 7804 } 7805 } 7806 } 7807 7808 // Bump up the crash count of any services currently running in the proc. 7809 if (app.services.size() != 0) { 7810 // Any services running in the application need to be placed 7811 // back in the pending list. 7812 Iterator<ServiceRecord> it = app.services.iterator(); 7813 while (it.hasNext()) { 7814 ServiceRecord sr = it.next(); 7815 sr.crashCount++; 7816 } 7817 } 7818 7819 // If the crashing process is what we consider to be the "home process" and it has been 7820 // replaced by a third-party app, clear the package preferred activities from packages 7821 // with a home activity running in the process to prevent a repeatedly crashing app 7822 // from blocking the user to manually clear the list. 7823 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7824 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7825 Iterator it = mHomeProcess.activities.iterator(); 7826 while (it.hasNext()) { 7827 ActivityRecord r = (ActivityRecord)it.next(); 7828 if (r.isHomeActivity) { 7829 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7830 try { 7831 ActivityThread.getPackageManager() 7832 .clearPackagePreferredActivities(r.packageName); 7833 } catch (RemoteException c) { 7834 // pm is in same process, this will never happen. 7835 } 7836 } 7837 } 7838 } 7839 7840 if (!app.isolated) { 7841 // XXX Can't keep track of crash times for isolated processes, 7842 // because they don't have a perisistent identity. 7843 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7844 } 7845 7846 return true; 7847 } 7848 7849 void startAppProblemLocked(ProcessRecord app) { 7850 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7851 mContext, app.info.packageName, app.info.flags); 7852 skipCurrentReceiverLocked(app); 7853 } 7854 7855 void skipCurrentReceiverLocked(ProcessRecord app) { 7856 for (BroadcastQueue queue : mBroadcastQueues) { 7857 queue.skipCurrentReceiverLocked(app); 7858 } 7859 } 7860 7861 /** 7862 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7863 * The application process will exit immediately after this call returns. 7864 * @param app object of the crashing app, null for the system server 7865 * @param crashInfo describing the exception 7866 */ 7867 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7868 ProcessRecord r = findAppProcess(app, "Crash"); 7869 final String processName = app == null ? "system_server" 7870 : (r == null ? "unknown" : r.processName); 7871 7872 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7873 processName, 7874 r == null ? -1 : r.info.flags, 7875 crashInfo.exceptionClassName, 7876 crashInfo.exceptionMessage, 7877 crashInfo.throwFileName, 7878 crashInfo.throwLineNumber); 7879 7880 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7881 7882 crashApplication(r, crashInfo); 7883 } 7884 7885 public void handleApplicationStrictModeViolation( 7886 IBinder app, 7887 int violationMask, 7888 StrictMode.ViolationInfo info) { 7889 ProcessRecord r = findAppProcess(app, "StrictMode"); 7890 if (r == null) { 7891 return; 7892 } 7893 7894 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7895 Integer stackFingerprint = info.hashCode(); 7896 boolean logIt = true; 7897 synchronized (mAlreadyLoggedViolatedStacks) { 7898 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7899 logIt = false; 7900 // TODO: sub-sample into EventLog for these, with 7901 // the info.durationMillis? Then we'd get 7902 // the relative pain numbers, without logging all 7903 // the stack traces repeatedly. We'd want to do 7904 // likewise in the client code, which also does 7905 // dup suppression, before the Binder call. 7906 } else { 7907 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7908 mAlreadyLoggedViolatedStacks.clear(); 7909 } 7910 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7911 } 7912 } 7913 if (logIt) { 7914 logStrictModeViolationToDropBox(r, info); 7915 } 7916 } 7917 7918 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7919 AppErrorResult result = new AppErrorResult(); 7920 synchronized (this) { 7921 final long origId = Binder.clearCallingIdentity(); 7922 7923 Message msg = Message.obtain(); 7924 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7925 HashMap<String, Object> data = new HashMap<String, Object>(); 7926 data.put("result", result); 7927 data.put("app", r); 7928 data.put("violationMask", violationMask); 7929 data.put("info", info); 7930 msg.obj = data; 7931 mHandler.sendMessage(msg); 7932 7933 Binder.restoreCallingIdentity(origId); 7934 } 7935 int res = result.get(); 7936 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7937 } 7938 } 7939 7940 // Depending on the policy in effect, there could be a bunch of 7941 // these in quick succession so we try to batch these together to 7942 // minimize disk writes, number of dropbox entries, and maximize 7943 // compression, by having more fewer, larger records. 7944 private void logStrictModeViolationToDropBox( 7945 ProcessRecord process, 7946 StrictMode.ViolationInfo info) { 7947 if (info == null) { 7948 return; 7949 } 7950 final boolean isSystemApp = process == null || 7951 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7952 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7953 final String processName = process == null ? "unknown" : process.processName; 7954 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7955 final DropBoxManager dbox = (DropBoxManager) 7956 mContext.getSystemService(Context.DROPBOX_SERVICE); 7957 7958 // Exit early if the dropbox isn't configured to accept this report type. 7959 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7960 7961 boolean bufferWasEmpty; 7962 boolean needsFlush; 7963 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7964 synchronized (sb) { 7965 bufferWasEmpty = sb.length() == 0; 7966 appendDropBoxProcessHeaders(process, processName, sb); 7967 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7968 sb.append("System-App: ").append(isSystemApp).append("\n"); 7969 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7970 if (info.violationNumThisLoop != 0) { 7971 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7972 } 7973 if (info.numAnimationsRunning != 0) { 7974 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7975 } 7976 if (info.broadcastIntentAction != null) { 7977 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7978 } 7979 if (info.durationMillis != -1) { 7980 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7981 } 7982 if (info.numInstances != -1) { 7983 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7984 } 7985 if (info.tags != null) { 7986 for (String tag : info.tags) { 7987 sb.append("Span-Tag: ").append(tag).append("\n"); 7988 } 7989 } 7990 sb.append("\n"); 7991 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7992 sb.append(info.crashInfo.stackTrace); 7993 } 7994 sb.append("\n"); 7995 7996 // Only buffer up to ~64k. Various logging bits truncate 7997 // things at 128k. 7998 needsFlush = (sb.length() > 64 * 1024); 7999 } 8000 8001 // Flush immediately if the buffer's grown too large, or this 8002 // is a non-system app. Non-system apps are isolated with a 8003 // different tag & policy and not batched. 8004 // 8005 // Batching is useful during internal testing with 8006 // StrictMode settings turned up high. Without batching, 8007 // thousands of separate files could be created on boot. 8008 if (!isSystemApp || needsFlush) { 8009 new Thread("Error dump: " + dropboxTag) { 8010 @Override 8011 public void run() { 8012 String report; 8013 synchronized (sb) { 8014 report = sb.toString(); 8015 sb.delete(0, sb.length()); 8016 sb.trimToSize(); 8017 } 8018 if (report.length() != 0) { 8019 dbox.addText(dropboxTag, report); 8020 } 8021 } 8022 }.start(); 8023 return; 8024 } 8025 8026 // System app batching: 8027 if (!bufferWasEmpty) { 8028 // An existing dropbox-writing thread is outstanding, so 8029 // we don't need to start it up. The existing thread will 8030 // catch the buffer appends we just did. 8031 return; 8032 } 8033 8034 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8035 // (After this point, we shouldn't access AMS internal data structures.) 8036 new Thread("Error dump: " + dropboxTag) { 8037 @Override 8038 public void run() { 8039 // 5 second sleep to let stacks arrive and be batched together 8040 try { 8041 Thread.sleep(5000); // 5 seconds 8042 } catch (InterruptedException e) {} 8043 8044 String errorReport; 8045 synchronized (mStrictModeBuffer) { 8046 errorReport = mStrictModeBuffer.toString(); 8047 if (errorReport.length() == 0) { 8048 return; 8049 } 8050 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8051 mStrictModeBuffer.trimToSize(); 8052 } 8053 dbox.addText(dropboxTag, errorReport); 8054 } 8055 }.start(); 8056 } 8057 8058 /** 8059 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8060 * @param app object of the crashing app, null for the system server 8061 * @param tag reported by the caller 8062 * @param crashInfo describing the context of the error 8063 * @return true if the process should exit immediately (WTF is fatal) 8064 */ 8065 public boolean handleApplicationWtf(IBinder app, String tag, 8066 ApplicationErrorReport.CrashInfo crashInfo) { 8067 ProcessRecord r = findAppProcess(app, "WTF"); 8068 final String processName = app == null ? "system_server" 8069 : (r == null ? "unknown" : r.processName); 8070 8071 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8072 processName, 8073 r == null ? -1 : r.info.flags, 8074 tag, crashInfo.exceptionMessage); 8075 8076 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8077 8078 if (r != null && r.pid != Process.myPid() && 8079 Settings.Secure.getInt(mContext.getContentResolver(), 8080 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8081 crashApplication(r, crashInfo); 8082 return true; 8083 } else { 8084 return false; 8085 } 8086 } 8087 8088 /** 8089 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8090 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8091 */ 8092 private ProcessRecord findAppProcess(IBinder app, String reason) { 8093 if (app == null) { 8094 return null; 8095 } 8096 8097 synchronized (this) { 8098 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8099 final int NA = apps.size(); 8100 for (int ia=0; ia<NA; ia++) { 8101 ProcessRecord p = apps.valueAt(ia); 8102 if (p.thread != null && p.thread.asBinder() == app) { 8103 return p; 8104 } 8105 } 8106 } 8107 8108 Slog.w(TAG, "Can't find mystery application for " + reason 8109 + " from pid=" + Binder.getCallingPid() 8110 + " uid=" + Binder.getCallingUid() + ": " + app); 8111 return null; 8112 } 8113 } 8114 8115 /** 8116 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8117 * to append various headers to the dropbox log text. 8118 */ 8119 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8120 StringBuilder sb) { 8121 // Watchdog thread ends up invoking this function (with 8122 // a null ProcessRecord) to add the stack file to dropbox. 8123 // Do not acquire a lock on this (am) in such cases, as it 8124 // could cause a potential deadlock, if and when watchdog 8125 // is invoked due to unavailability of lock on am and it 8126 // would prevent watchdog from killing system_server. 8127 if (process == null) { 8128 sb.append("Process: ").append(processName).append("\n"); 8129 return; 8130 } 8131 // Note: ProcessRecord 'process' is guarded by the service 8132 // instance. (notably process.pkgList, which could otherwise change 8133 // concurrently during execution of this method) 8134 synchronized (this) { 8135 sb.append("Process: ").append(processName).append("\n"); 8136 int flags = process.info.flags; 8137 IPackageManager pm = AppGlobals.getPackageManager(); 8138 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8139 for (String pkg : process.pkgList) { 8140 sb.append("Package: ").append(pkg); 8141 try { 8142 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8143 if (pi != null) { 8144 sb.append(" v").append(pi.versionCode); 8145 if (pi.versionName != null) { 8146 sb.append(" (").append(pi.versionName).append(")"); 8147 } 8148 } 8149 } catch (RemoteException e) { 8150 Slog.e(TAG, "Error getting package info: " + pkg, e); 8151 } 8152 sb.append("\n"); 8153 } 8154 } 8155 } 8156 8157 private static String processClass(ProcessRecord process) { 8158 if (process == null || process.pid == MY_PID) { 8159 return "system_server"; 8160 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8161 return "system_app"; 8162 } else { 8163 return "data_app"; 8164 } 8165 } 8166 8167 /** 8168 * Write a description of an error (crash, WTF, ANR) to the drop box. 8169 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8170 * @param process which caused the error, null means the system server 8171 * @param activity which triggered the error, null if unknown 8172 * @param parent activity related to the error, null if unknown 8173 * @param subject line related to the error, null if absent 8174 * @param report in long form describing the error, null if absent 8175 * @param logFile to include in the report, null if none 8176 * @param crashInfo giving an application stack trace, null if absent 8177 */ 8178 public void addErrorToDropBox(String eventType, 8179 ProcessRecord process, String processName, ActivityRecord activity, 8180 ActivityRecord parent, String subject, 8181 final String report, final File logFile, 8182 final ApplicationErrorReport.CrashInfo crashInfo) { 8183 // NOTE -- this must never acquire the ActivityManagerService lock, 8184 // otherwise the watchdog may be prevented from resetting the system. 8185 8186 final String dropboxTag = processClass(process) + "_" + eventType; 8187 final DropBoxManager dbox = (DropBoxManager) 8188 mContext.getSystemService(Context.DROPBOX_SERVICE); 8189 8190 // Exit early if the dropbox isn't configured to accept this report type. 8191 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8192 8193 final StringBuilder sb = new StringBuilder(1024); 8194 appendDropBoxProcessHeaders(process, processName, sb); 8195 if (activity != null) { 8196 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8197 } 8198 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8199 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8200 } 8201 if (parent != null && parent != activity) { 8202 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8203 } 8204 if (subject != null) { 8205 sb.append("Subject: ").append(subject).append("\n"); 8206 } 8207 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8208 if (Debug.isDebuggerConnected()) { 8209 sb.append("Debugger: Connected\n"); 8210 } 8211 sb.append("\n"); 8212 8213 // Do the rest in a worker thread to avoid blocking the caller on I/O 8214 // (After this point, we shouldn't access AMS internal data structures.) 8215 Thread worker = new Thread("Error dump: " + dropboxTag) { 8216 @Override 8217 public void run() { 8218 if (report != null) { 8219 sb.append(report); 8220 } 8221 if (logFile != null) { 8222 try { 8223 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8224 } catch (IOException e) { 8225 Slog.e(TAG, "Error reading " + logFile, e); 8226 } 8227 } 8228 if (crashInfo != null && crashInfo.stackTrace != null) { 8229 sb.append(crashInfo.stackTrace); 8230 } 8231 8232 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8233 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8234 if (lines > 0) { 8235 sb.append("\n"); 8236 8237 // Merge several logcat streams, and take the last N lines 8238 InputStreamReader input = null; 8239 try { 8240 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8241 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8242 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8243 8244 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8245 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8246 input = new InputStreamReader(logcat.getInputStream()); 8247 8248 int num; 8249 char[] buf = new char[8192]; 8250 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8251 } catch (IOException e) { 8252 Slog.e(TAG, "Error running logcat", e); 8253 } finally { 8254 if (input != null) try { input.close(); } catch (IOException e) {} 8255 } 8256 } 8257 8258 dbox.addText(dropboxTag, sb.toString()); 8259 } 8260 }; 8261 8262 if (process == null) { 8263 // If process is null, we are being called from some internal code 8264 // and may be about to die -- run this synchronously. 8265 worker.run(); 8266 } else { 8267 worker.start(); 8268 } 8269 } 8270 8271 /** 8272 * Bring up the "unexpected error" dialog box for a crashing app. 8273 * Deal with edge cases (intercepts from instrumented applications, 8274 * ActivityController, error intent receivers, that sort of thing). 8275 * @param r the application crashing 8276 * @param crashInfo describing the failure 8277 */ 8278 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8279 long timeMillis = System.currentTimeMillis(); 8280 String shortMsg = crashInfo.exceptionClassName; 8281 String longMsg = crashInfo.exceptionMessage; 8282 String stackTrace = crashInfo.stackTrace; 8283 if (shortMsg != null && longMsg != null) { 8284 longMsg = shortMsg + ": " + longMsg; 8285 } else if (shortMsg != null) { 8286 longMsg = shortMsg; 8287 } 8288 8289 AppErrorResult result = new AppErrorResult(); 8290 synchronized (this) { 8291 if (mController != null) { 8292 try { 8293 String name = r != null ? r.processName : null; 8294 int pid = r != null ? r.pid : Binder.getCallingPid(); 8295 if (!mController.appCrashed(name, pid, 8296 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8297 Slog.w(TAG, "Force-killing crashed app " + name 8298 + " at watcher's request"); 8299 Process.killProcess(pid); 8300 return; 8301 } 8302 } catch (RemoteException e) { 8303 mController = null; 8304 } 8305 } 8306 8307 final long origId = Binder.clearCallingIdentity(); 8308 8309 // If this process is running instrumentation, finish it. 8310 if (r != null && r.instrumentationClass != null) { 8311 Slog.w(TAG, "Error in app " + r.processName 8312 + " running instrumentation " + r.instrumentationClass + ":"); 8313 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8314 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8315 Bundle info = new Bundle(); 8316 info.putString("shortMsg", shortMsg); 8317 info.putString("longMsg", longMsg); 8318 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8319 Binder.restoreCallingIdentity(origId); 8320 return; 8321 } 8322 8323 // If we can't identify the process or it's already exceeded its crash quota, 8324 // quit right away without showing a crash dialog. 8325 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8326 Binder.restoreCallingIdentity(origId); 8327 return; 8328 } 8329 8330 Message msg = Message.obtain(); 8331 msg.what = SHOW_ERROR_MSG; 8332 HashMap data = new HashMap(); 8333 data.put("result", result); 8334 data.put("app", r); 8335 msg.obj = data; 8336 mHandler.sendMessage(msg); 8337 8338 Binder.restoreCallingIdentity(origId); 8339 } 8340 8341 int res = result.get(); 8342 8343 Intent appErrorIntent = null; 8344 synchronized (this) { 8345 if (r != null && !r.isolated) { 8346 // XXX Can't keep track of crash time for isolated processes, 8347 // since they don't have a persistent identity. 8348 mProcessCrashTimes.put(r.info.processName, r.uid, 8349 SystemClock.uptimeMillis()); 8350 } 8351 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8352 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8353 } 8354 } 8355 8356 if (appErrorIntent != null) { 8357 try { 8358 mContext.startActivity(appErrorIntent); 8359 } catch (ActivityNotFoundException e) { 8360 Slog.w(TAG, "bug report receiver dissappeared", e); 8361 } 8362 } 8363 } 8364 8365 Intent createAppErrorIntentLocked(ProcessRecord r, 8366 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8367 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8368 if (report == null) { 8369 return null; 8370 } 8371 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8372 result.setComponent(r.errorReportReceiver); 8373 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8374 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8375 return result; 8376 } 8377 8378 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8379 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8380 if (r.errorReportReceiver == null) { 8381 return null; 8382 } 8383 8384 if (!r.crashing && !r.notResponding) { 8385 return null; 8386 } 8387 8388 ApplicationErrorReport report = new ApplicationErrorReport(); 8389 report.packageName = r.info.packageName; 8390 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8391 report.processName = r.processName; 8392 report.time = timeMillis; 8393 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8394 8395 if (r.crashing) { 8396 report.type = ApplicationErrorReport.TYPE_CRASH; 8397 report.crashInfo = crashInfo; 8398 } else if (r.notResponding) { 8399 report.type = ApplicationErrorReport.TYPE_ANR; 8400 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8401 8402 report.anrInfo.activity = r.notRespondingReport.tag; 8403 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8404 report.anrInfo.info = r.notRespondingReport.longMsg; 8405 } 8406 8407 return report; 8408 } 8409 8410 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8411 enforceNotIsolatedCaller("getProcessesInErrorState"); 8412 // assume our apps are happy - lazy create the list 8413 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8414 8415 synchronized (this) { 8416 8417 // iterate across all processes 8418 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8419 ProcessRecord app = mLruProcesses.get(i); 8420 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8421 // This one's in trouble, so we'll generate a report for it 8422 // crashes are higher priority (in case there's a crash *and* an anr) 8423 ActivityManager.ProcessErrorStateInfo report = null; 8424 if (app.crashing) { 8425 report = app.crashingReport; 8426 } else if (app.notResponding) { 8427 report = app.notRespondingReport; 8428 } 8429 8430 if (report != null) { 8431 if (errList == null) { 8432 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8433 } 8434 errList.add(report); 8435 } else { 8436 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8437 " crashing = " + app.crashing + 8438 " notResponding = " + app.notResponding); 8439 } 8440 } 8441 } 8442 } 8443 8444 return errList; 8445 } 8446 8447 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8448 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8449 if (currApp != null) { 8450 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8451 } 8452 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8453 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8454 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8455 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8456 if (currApp != null) { 8457 currApp.lru = 0; 8458 } 8459 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8460 } else if (adj >= ProcessList.SERVICE_ADJ) { 8461 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8462 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8463 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8464 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8465 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8466 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8467 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8468 } else { 8469 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8470 } 8471 } 8472 8473 private void fillInProcMemInfo(ProcessRecord app, 8474 ActivityManager.RunningAppProcessInfo outInfo) { 8475 outInfo.pid = app.pid; 8476 outInfo.uid = app.info.uid; 8477 if (mHeavyWeightProcess == app) { 8478 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8479 } 8480 if (app.persistent) { 8481 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8482 } 8483 outInfo.lastTrimLevel = app.trimMemoryLevel; 8484 int adj = app.curAdj; 8485 outInfo.importance = oomAdjToImportance(adj, outInfo); 8486 outInfo.importanceReasonCode = app.adjTypeCode; 8487 } 8488 8489 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8490 enforceNotIsolatedCaller("getRunningAppProcesses"); 8491 // Lazy instantiation of list 8492 List<ActivityManager.RunningAppProcessInfo> runList = null; 8493 synchronized (this) { 8494 // Iterate across all processes 8495 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8496 ProcessRecord app = mLruProcesses.get(i); 8497 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8498 // Generate process state info for running application 8499 ActivityManager.RunningAppProcessInfo currApp = 8500 new ActivityManager.RunningAppProcessInfo(app.processName, 8501 app.pid, app.getPackageList()); 8502 fillInProcMemInfo(app, currApp); 8503 if (app.adjSource instanceof ProcessRecord) { 8504 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8505 currApp.importanceReasonImportance = oomAdjToImportance( 8506 app.adjSourceOom, null); 8507 } else if (app.adjSource instanceof ActivityRecord) { 8508 ActivityRecord r = (ActivityRecord)app.adjSource; 8509 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8510 } 8511 if (app.adjTarget instanceof ComponentName) { 8512 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8513 } 8514 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8515 // + " lru=" + currApp.lru); 8516 if (runList == null) { 8517 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8518 } 8519 runList.add(currApp); 8520 } 8521 } 8522 } 8523 return runList; 8524 } 8525 8526 public List<ApplicationInfo> getRunningExternalApplications() { 8527 enforceNotIsolatedCaller("getRunningExternalApplications"); 8528 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8529 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8530 if (runningApps != null && runningApps.size() > 0) { 8531 Set<String> extList = new HashSet<String>(); 8532 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8533 if (app.pkgList != null) { 8534 for (String pkg : app.pkgList) { 8535 extList.add(pkg); 8536 } 8537 } 8538 } 8539 IPackageManager pm = AppGlobals.getPackageManager(); 8540 for (String pkg : extList) { 8541 try { 8542 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8543 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8544 retList.add(info); 8545 } 8546 } catch (RemoteException e) { 8547 } 8548 } 8549 } 8550 return retList; 8551 } 8552 8553 @Override 8554 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8555 enforceNotIsolatedCaller("getMyMemoryState"); 8556 synchronized (this) { 8557 ProcessRecord proc; 8558 synchronized (mPidsSelfLocked) { 8559 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8560 } 8561 fillInProcMemInfo(proc, outInfo); 8562 } 8563 } 8564 8565 @Override 8566 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8567 if (checkCallingPermission(android.Manifest.permission.DUMP) 8568 != PackageManager.PERMISSION_GRANTED) { 8569 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8570 + Binder.getCallingPid() 8571 + ", uid=" + Binder.getCallingUid() 8572 + " without permission " 8573 + android.Manifest.permission.DUMP); 8574 return; 8575 } 8576 8577 boolean dumpAll = false; 8578 boolean dumpClient = false; 8579 String dumpPackage = null; 8580 8581 int opti = 0; 8582 while (opti < args.length) { 8583 String opt = args[opti]; 8584 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8585 break; 8586 } 8587 opti++; 8588 if ("-a".equals(opt)) { 8589 dumpAll = true; 8590 } else if ("-c".equals(opt)) { 8591 dumpClient = true; 8592 } else if ("-h".equals(opt)) { 8593 pw.println("Activity manager dump options:"); 8594 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8595 pw.println(" cmd may be one of:"); 8596 pw.println(" a[ctivities]: activity stack state"); 8597 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8598 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8599 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8600 pw.println(" o[om]: out of memory management"); 8601 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8602 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8603 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8604 pw.println(" service [COMP_SPEC]: service client-side state"); 8605 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8606 pw.println(" all: dump all activities"); 8607 pw.println(" top: dump the top activity"); 8608 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8609 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8610 pw.println(" a partial substring in a component name, a"); 8611 pw.println(" hex object identifier."); 8612 pw.println(" -a: include all available server state."); 8613 pw.println(" -c: include client state."); 8614 return; 8615 } else { 8616 pw.println("Unknown argument: " + opt + "; use -h for help"); 8617 } 8618 } 8619 8620 long origId = Binder.clearCallingIdentity(); 8621 boolean more = false; 8622 // Is the caller requesting to dump a particular piece of data? 8623 if (opti < args.length) { 8624 String cmd = args[opti]; 8625 opti++; 8626 if ("activities".equals(cmd) || "a".equals(cmd)) { 8627 synchronized (this) { 8628 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8629 } 8630 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8631 String[] newArgs; 8632 String name; 8633 if (opti >= args.length) { 8634 name = null; 8635 newArgs = EMPTY_STRING_ARRAY; 8636 } else { 8637 name = args[opti]; 8638 opti++; 8639 newArgs = new String[args.length - opti]; 8640 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8641 args.length - opti); 8642 } 8643 synchronized (this) { 8644 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8645 } 8646 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8647 String[] newArgs; 8648 String name; 8649 if (opti >= args.length) { 8650 name = null; 8651 newArgs = EMPTY_STRING_ARRAY; 8652 } else { 8653 name = args[opti]; 8654 opti++; 8655 newArgs = new String[args.length - opti]; 8656 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8657 args.length - opti); 8658 } 8659 synchronized (this) { 8660 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8661 } 8662 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8663 String[] newArgs; 8664 String name; 8665 if (opti >= args.length) { 8666 name = null; 8667 newArgs = EMPTY_STRING_ARRAY; 8668 } else { 8669 name = args[opti]; 8670 opti++; 8671 newArgs = new String[args.length - opti]; 8672 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8673 args.length - opti); 8674 } 8675 synchronized (this) { 8676 dumpProcessesLocked(fd, pw, args, opti, true, name); 8677 } 8678 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8679 synchronized (this) { 8680 dumpOomLocked(fd, pw, args, opti, true); 8681 } 8682 } else if ("provider".equals(cmd)) { 8683 String[] newArgs; 8684 String name; 8685 if (opti >= args.length) { 8686 name = null; 8687 newArgs = EMPTY_STRING_ARRAY; 8688 } else { 8689 name = args[opti]; 8690 opti++; 8691 newArgs = new String[args.length - opti]; 8692 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8693 } 8694 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8695 pw.println("No providers match: " + name); 8696 pw.println("Use -h for help."); 8697 } 8698 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8699 synchronized (this) { 8700 dumpProvidersLocked(fd, pw, args, opti, true, null); 8701 } 8702 } else if ("service".equals(cmd)) { 8703 String[] newArgs; 8704 String name; 8705 if (opti >= args.length) { 8706 name = null; 8707 newArgs = EMPTY_STRING_ARRAY; 8708 } else { 8709 name = args[opti]; 8710 opti++; 8711 newArgs = new String[args.length - opti]; 8712 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8713 args.length - opti); 8714 } 8715 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8716 pw.println("No services match: " + name); 8717 pw.println("Use -h for help."); 8718 } 8719 } else if ("package".equals(cmd)) { 8720 String[] newArgs; 8721 if (opti >= args.length) { 8722 pw.println("package: no package name specified"); 8723 pw.println("Use -h for help."); 8724 } else { 8725 dumpPackage = args[opti]; 8726 opti++; 8727 newArgs = new String[args.length - opti]; 8728 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8729 args.length - opti); 8730 args = newArgs; 8731 opti = 0; 8732 more = true; 8733 } 8734 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8735 synchronized (this) { 8736 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8737 } 8738 } else { 8739 // Dumping a single activity? 8740 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8741 pw.println("Bad activity command, or no activities match: " + cmd); 8742 pw.println("Use -h for help."); 8743 } 8744 } 8745 if (!more) { 8746 Binder.restoreCallingIdentity(origId); 8747 return; 8748 } 8749 } 8750 8751 // No piece of data specified, dump everything. 8752 synchronized (this) { 8753 boolean needSep; 8754 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8755 if (needSep) { 8756 pw.println(" "); 8757 } 8758 if (dumpAll) { 8759 pw.println("-------------------------------------------------------------------------------"); 8760 } 8761 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8762 if (needSep) { 8763 pw.println(" "); 8764 } 8765 if (dumpAll) { 8766 pw.println("-------------------------------------------------------------------------------"); 8767 } 8768 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8769 if (needSep) { 8770 pw.println(" "); 8771 } 8772 if (dumpAll) { 8773 pw.println("-------------------------------------------------------------------------------"); 8774 } 8775 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8776 if (needSep) { 8777 pw.println(" "); 8778 } 8779 if (dumpAll) { 8780 pw.println("-------------------------------------------------------------------------------"); 8781 } 8782 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8783 if (needSep) { 8784 pw.println(" "); 8785 } 8786 if (dumpAll) { 8787 pw.println("-------------------------------------------------------------------------------"); 8788 } 8789 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8790 } 8791 Binder.restoreCallingIdentity(origId); 8792 } 8793 8794 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8795 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8796 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8797 pw.println(" Main stack:"); 8798 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8799 dumpPackage); 8800 pw.println(" "); 8801 pw.println(" Running activities (most recent first):"); 8802 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8803 dumpPackage); 8804 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8805 pw.println(" "); 8806 pw.println(" Activities waiting for another to become visible:"); 8807 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8808 !dumpAll, false, dumpPackage); 8809 } 8810 if (mMainStack.mStoppingActivities.size() > 0) { 8811 pw.println(" "); 8812 pw.println(" Activities waiting to stop:"); 8813 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8814 !dumpAll, false, dumpPackage); 8815 } 8816 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8817 pw.println(" "); 8818 pw.println(" Activities waiting to sleep:"); 8819 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8820 !dumpAll, false, dumpPackage); 8821 } 8822 if (mMainStack.mFinishingActivities.size() > 0) { 8823 pw.println(" "); 8824 pw.println(" Activities waiting to finish:"); 8825 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8826 !dumpAll, false, dumpPackage); 8827 } 8828 8829 pw.println(" "); 8830 if (mMainStack.mPausingActivity != null) { 8831 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8832 } 8833 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8834 pw.println(" mFocusedActivity: " + mFocusedActivity); 8835 if (dumpAll) { 8836 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8837 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8838 pw.println(" mDismissKeyguardOnNextActivity: " 8839 + mMainStack.mDismissKeyguardOnNextActivity); 8840 } 8841 8842 if (mRecentTasks.size() > 0) { 8843 pw.println(); 8844 pw.println(" Recent tasks:"); 8845 8846 final int N = mRecentTasks.size(); 8847 for (int i=0; i<N; i++) { 8848 TaskRecord tr = mRecentTasks.get(i); 8849 if (dumpPackage != null) { 8850 if (tr.realActivity == null || 8851 !dumpPackage.equals(tr.realActivity)) { 8852 continue; 8853 } 8854 } 8855 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8856 pw.println(tr); 8857 if (dumpAll) { 8858 mRecentTasks.get(i).dump(pw, " "); 8859 } 8860 } 8861 } 8862 8863 if (dumpAll) { 8864 pw.println(" "); 8865 pw.println(" mCurTask: " + mCurTask); 8866 } 8867 8868 return true; 8869 } 8870 8871 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8872 int opti, boolean dumpAll, String dumpPackage) { 8873 boolean needSep = false; 8874 int numPers = 0; 8875 8876 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8877 8878 if (dumpAll) { 8879 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8880 final int NA = procs.size(); 8881 for (int ia=0; ia<NA; ia++) { 8882 ProcessRecord r = procs.valueAt(ia); 8883 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8884 continue; 8885 } 8886 if (!needSep) { 8887 pw.println(" All known processes:"); 8888 needSep = true; 8889 } 8890 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8891 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8892 pw.print(" "); pw.println(r); 8893 r.dump(pw, " "); 8894 if (r.persistent) { 8895 numPers++; 8896 } 8897 } 8898 } 8899 } 8900 8901 if (mIsolatedProcesses.size() > 0) { 8902 if (needSep) pw.println(" "); 8903 needSep = true; 8904 pw.println(" Isolated process list (sorted by uid):"); 8905 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8906 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8907 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8908 continue; 8909 } 8910 pw.println(String.format("%sIsolated #%2d: %s", 8911 " ", i, r.toString())); 8912 } 8913 } 8914 8915 if (mLruProcesses.size() > 0) { 8916 if (needSep) pw.println(" "); 8917 needSep = true; 8918 pw.println(" Process LRU list (sorted by oom_adj):"); 8919 dumpProcessOomList(pw, this, mLruProcesses, " ", 8920 "Proc", "PERS", false, dumpPackage); 8921 needSep = true; 8922 } 8923 8924 if (dumpAll) { 8925 synchronized (mPidsSelfLocked) { 8926 boolean printed = false; 8927 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8928 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8929 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8930 continue; 8931 } 8932 if (!printed) { 8933 if (needSep) pw.println(" "); 8934 needSep = true; 8935 pw.println(" PID mappings:"); 8936 printed = true; 8937 } 8938 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8939 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8940 } 8941 } 8942 } 8943 8944 if (mForegroundProcesses.size() > 0) { 8945 synchronized (mPidsSelfLocked) { 8946 boolean printed = false; 8947 for (int i=0; i<mForegroundProcesses.size(); i++) { 8948 ProcessRecord r = mPidsSelfLocked.get( 8949 mForegroundProcesses.valueAt(i).pid); 8950 if (dumpPackage != null && (r == null 8951 || !dumpPackage.equals(r.info.packageName))) { 8952 continue; 8953 } 8954 if (!printed) { 8955 if (needSep) pw.println(" "); 8956 needSep = true; 8957 pw.println(" Foreground Processes:"); 8958 printed = true; 8959 } 8960 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8961 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8962 } 8963 } 8964 } 8965 8966 if (mPersistentStartingProcesses.size() > 0) { 8967 if (needSep) pw.println(" "); 8968 needSep = true; 8969 pw.println(" Persisent processes that are starting:"); 8970 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8971 "Starting Norm", "Restarting PERS", dumpPackage); 8972 } 8973 8974 if (mRemovedProcesses.size() > 0) { 8975 if (needSep) pw.println(" "); 8976 needSep = true; 8977 pw.println(" Processes that are being removed:"); 8978 dumpProcessList(pw, this, mRemovedProcesses, " ", 8979 "Removed Norm", "Removed PERS", dumpPackage); 8980 } 8981 8982 if (mProcessesOnHold.size() > 0) { 8983 if (needSep) pw.println(" "); 8984 needSep = true; 8985 pw.println(" Processes that are on old until the system is ready:"); 8986 dumpProcessList(pw, this, mProcessesOnHold, " ", 8987 "OnHold Norm", "OnHold PERS", dumpPackage); 8988 } 8989 8990 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8991 8992 if (mProcessCrashTimes.getMap().size() > 0) { 8993 boolean printed = false; 8994 long now = SystemClock.uptimeMillis(); 8995 for (Map.Entry<String, SparseArray<Long>> procs 8996 : mProcessCrashTimes.getMap().entrySet()) { 8997 String pname = procs.getKey(); 8998 SparseArray<Long> uids = procs.getValue(); 8999 final int N = uids.size(); 9000 for (int i=0; i<N; i++) { 9001 int puid = uids.keyAt(i); 9002 ProcessRecord r = mProcessNames.get(pname, puid); 9003 if (dumpPackage != null && (r == null 9004 || !dumpPackage.equals(r.info.packageName))) { 9005 continue; 9006 } 9007 if (!printed) { 9008 if (needSep) pw.println(" "); 9009 needSep = true; 9010 pw.println(" Time since processes crashed:"); 9011 printed = true; 9012 } 9013 pw.print(" Process "); pw.print(pname); 9014 pw.print(" uid "); pw.print(puid); 9015 pw.print(": last crashed "); 9016 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9017 pw.println(" ago"); 9018 } 9019 } 9020 } 9021 9022 if (mBadProcesses.getMap().size() > 0) { 9023 boolean printed = false; 9024 for (Map.Entry<String, SparseArray<Long>> procs 9025 : mBadProcesses.getMap().entrySet()) { 9026 String pname = procs.getKey(); 9027 SparseArray<Long> uids = procs.getValue(); 9028 final int N = uids.size(); 9029 for (int i=0; i<N; i++) { 9030 int puid = uids.keyAt(i); 9031 ProcessRecord r = mProcessNames.get(pname, puid); 9032 if (dumpPackage != null && (r == null 9033 || !dumpPackage.equals(r.info.packageName))) { 9034 continue; 9035 } 9036 if (!printed) { 9037 if (needSep) pw.println(" "); 9038 needSep = true; 9039 pw.println(" Bad processes:"); 9040 } 9041 pw.print(" Bad process "); pw.print(pname); 9042 pw.print(" uid "); pw.print(puid); 9043 pw.print(": crashed at time "); 9044 pw.println(uids.valueAt(i)); 9045 } 9046 } 9047 } 9048 9049 pw.println(); 9050 pw.println(" mHomeProcess: " + mHomeProcess); 9051 pw.println(" mPreviousProcess: " + mPreviousProcess); 9052 if (dumpAll) { 9053 StringBuilder sb = new StringBuilder(128); 9054 sb.append(" mPreviousProcessVisibleTime: "); 9055 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9056 pw.println(sb); 9057 } 9058 if (mHeavyWeightProcess != null) { 9059 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9060 } 9061 pw.println(" mConfiguration: " + mConfiguration); 9062 if (dumpAll) { 9063 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9064 if (mCompatModePackages.getPackages().size() > 0) { 9065 boolean printed = false; 9066 for (Map.Entry<String, Integer> entry 9067 : mCompatModePackages.getPackages().entrySet()) { 9068 String pkg = entry.getKey(); 9069 int mode = entry.getValue(); 9070 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9071 continue; 9072 } 9073 if (!printed) { 9074 pw.println(" mScreenCompatPackages:"); 9075 printed = true; 9076 } 9077 pw.print(" "); pw.print(pkg); pw.print(": "); 9078 pw.print(mode); pw.println(); 9079 } 9080 } 9081 } 9082 if (mSleeping || mWentToSleep || mLockScreenShown) { 9083 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9084 + " mLockScreenShown " + mLockScreenShown); 9085 } 9086 if (mShuttingDown) { 9087 pw.println(" mShuttingDown=" + mShuttingDown); 9088 } 9089 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9090 || mOrigWaitForDebugger) { 9091 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9092 + " mDebugTransient=" + mDebugTransient 9093 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9094 } 9095 if (mOpenGlTraceApp != null) { 9096 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9097 } 9098 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9099 || mProfileFd != null) { 9100 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9101 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9102 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9103 + mAutoStopProfiler); 9104 } 9105 if (mAlwaysFinishActivities || mController != null) { 9106 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9107 + " mController=" + mController); 9108 } 9109 if (dumpAll) { 9110 pw.println(" Total persistent processes: " + numPers); 9111 pw.println(" mStartRunning=" + mStartRunning 9112 + " mProcessesReady=" + mProcessesReady 9113 + " mSystemReady=" + mSystemReady); 9114 pw.println(" mBooting=" + mBooting 9115 + " mBooted=" + mBooted 9116 + " mFactoryTest=" + mFactoryTest); 9117 pw.print(" mLastPowerCheckRealtime="); 9118 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9119 pw.println(""); 9120 pw.print(" mLastPowerCheckUptime="); 9121 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9122 pw.println(""); 9123 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9124 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9125 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9126 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9127 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9128 } 9129 9130 return true; 9131 } 9132 9133 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9134 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9135 if (mProcessesToGc.size() > 0) { 9136 boolean printed = false; 9137 long now = SystemClock.uptimeMillis(); 9138 for (int i=0; i<mProcessesToGc.size(); i++) { 9139 ProcessRecord proc = mProcessesToGc.get(i); 9140 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9141 continue; 9142 } 9143 if (!printed) { 9144 if (needSep) pw.println(" "); 9145 needSep = true; 9146 pw.println(" Processes that are waiting to GC:"); 9147 printed = true; 9148 } 9149 pw.print(" Process "); pw.println(proc); 9150 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9151 pw.print(", last gced="); 9152 pw.print(now-proc.lastRequestedGc); 9153 pw.print(" ms ago, last lowMem="); 9154 pw.print(now-proc.lastLowMemory); 9155 pw.println(" ms ago"); 9156 9157 } 9158 } 9159 return needSep; 9160 } 9161 9162 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9163 int opti, boolean dumpAll) { 9164 boolean needSep = false; 9165 9166 if (mLruProcesses.size() > 0) { 9167 if (needSep) pw.println(" "); 9168 needSep = true; 9169 pw.println(" OOM levels:"); 9170 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9171 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9172 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9173 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9174 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9175 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9176 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9177 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9178 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9179 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9180 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9181 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9182 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9183 9184 if (needSep) pw.println(" "); 9185 needSep = true; 9186 pw.println(" Process OOM control:"); 9187 dumpProcessOomList(pw, this, mLruProcesses, " ", 9188 "Proc", "PERS", true, null); 9189 needSep = true; 9190 } 9191 9192 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9193 9194 pw.println(); 9195 pw.println(" mHomeProcess: " + mHomeProcess); 9196 pw.println(" mPreviousProcess: " + mPreviousProcess); 9197 if (mHeavyWeightProcess != null) { 9198 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9199 } 9200 9201 return true; 9202 } 9203 9204 /** 9205 * There are three ways to call this: 9206 * - no service specified: dump all the services 9207 * - a flattened component name that matched an existing service was specified as the 9208 * first arg: dump that one service 9209 * - the first arg isn't the flattened component name of an existing service: 9210 * dump all services whose component contains the first arg as a substring 9211 */ 9212 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9213 int opti, boolean dumpAll) { 9214 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 9215 9216 if ("all".equals(name)) { 9217 synchronized (this) { 9218 try { 9219 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9220 for (UserInfo user : users) { 9221 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9222 services.add(r1); 9223 } 9224 } 9225 } catch (RemoteException re) { 9226 } 9227 } 9228 } else { 9229 ComponentName componentName = name != null 9230 ? ComponentName.unflattenFromString(name) : null; 9231 int objectId = 0; 9232 if (componentName == null) { 9233 // Not a '/' separated full component name; maybe an object ID? 9234 try { 9235 objectId = Integer.parseInt(name, 16); 9236 name = null; 9237 componentName = null; 9238 } catch (RuntimeException e) { 9239 } 9240 } 9241 9242 synchronized (this) { 9243 try { 9244 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9245 for (UserInfo user : users) { 9246 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9247 if (componentName != null) { 9248 if (r1.name.equals(componentName)) { 9249 services.add(r1); 9250 } 9251 } else if (name != null) { 9252 if (r1.name.flattenToString().contains(name)) { 9253 services.add(r1); 9254 } 9255 } else if (System.identityHashCode(r1) == objectId) { 9256 services.add(r1); 9257 } 9258 } 9259 } 9260 } catch (RemoteException re) { 9261 } 9262 } 9263 } 9264 9265 if (services.size() <= 0) { 9266 return false; 9267 } 9268 9269 boolean needSep = false; 9270 for (int i=0; i<services.size(); i++) { 9271 if (needSep) { 9272 pw.println(); 9273 } 9274 needSep = true; 9275 dumpService("", fd, pw, services.get(i), args, dumpAll); 9276 } 9277 return true; 9278 } 9279 9280 /** 9281 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9282 * there is a thread associated with the service. 9283 */ 9284 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 9285 final ServiceRecord r, String[] args, boolean dumpAll) { 9286 String innerPrefix = prefix + " "; 9287 synchronized (this) { 9288 pw.print(prefix); pw.print("SERVICE "); 9289 pw.print(r.shortName); pw.print(" "); 9290 pw.print(Integer.toHexString(System.identityHashCode(r))); 9291 pw.print(" pid="); 9292 if (r.app != null) pw.println(r.app.pid); 9293 else pw.println("(not running)"); 9294 if (dumpAll) { 9295 r.dump(pw, innerPrefix); 9296 } 9297 } 9298 if (r.app != null && r.app.thread != null) { 9299 pw.print(prefix); pw.println(" Client:"); 9300 pw.flush(); 9301 try { 9302 TransferPipe tp = new TransferPipe(); 9303 try { 9304 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 9305 tp.setBufferPrefix(prefix + " "); 9306 tp.go(fd); 9307 } finally { 9308 tp.kill(); 9309 } 9310 } catch (IOException e) { 9311 pw.println(prefix + " Failure while dumping the service: " + e); 9312 } catch (RemoteException e) { 9313 pw.println(prefix + " Got a RemoteException while dumping the service"); 9314 } 9315 } 9316 } 9317 9318 /** 9319 * There are three ways to call this: 9320 * - no provider specified: dump all the providers 9321 * - a flattened component name that matched an existing provider was specified as the 9322 * first arg: dump that one provider 9323 * - the first arg isn't the flattened component name of an existing provider: 9324 * dump all providers whose component contains the first arg as a substring 9325 */ 9326 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9327 int opti, boolean dumpAll) { 9328 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9329 } 9330 9331 static class ItemMatcher { 9332 ArrayList<ComponentName> components; 9333 ArrayList<String> strings; 9334 ArrayList<Integer> objects; 9335 boolean all; 9336 9337 ItemMatcher() { 9338 all = true; 9339 } 9340 9341 void build(String name) { 9342 ComponentName componentName = ComponentName.unflattenFromString(name); 9343 if (componentName != null) { 9344 if (components == null) { 9345 components = new ArrayList<ComponentName>(); 9346 } 9347 components.add(componentName); 9348 all = false; 9349 } else { 9350 int objectId = 0; 9351 // Not a '/' separated full component name; maybe an object ID? 9352 try { 9353 objectId = Integer.parseInt(name, 16); 9354 if (objects == null) { 9355 objects = new ArrayList<Integer>(); 9356 } 9357 objects.add(objectId); 9358 all = false; 9359 } catch (RuntimeException e) { 9360 // Not an integer; just do string match. 9361 if (strings == null) { 9362 strings = new ArrayList<String>(); 9363 } 9364 strings.add(name); 9365 all = false; 9366 } 9367 } 9368 } 9369 9370 int build(String[] args, int opti) { 9371 for (; opti<args.length; opti++) { 9372 String name = args[opti]; 9373 if ("--".equals(name)) { 9374 return opti+1; 9375 } 9376 build(name); 9377 } 9378 return opti; 9379 } 9380 9381 boolean match(Object object, ComponentName comp) { 9382 if (all) { 9383 return true; 9384 } 9385 if (components != null) { 9386 for (int i=0; i<components.size(); i++) { 9387 if (components.get(i).equals(comp)) { 9388 return true; 9389 } 9390 } 9391 } 9392 if (objects != null) { 9393 for (int i=0; i<objects.size(); i++) { 9394 if (System.identityHashCode(object) == objects.get(i)) { 9395 return true; 9396 } 9397 } 9398 } 9399 if (strings != null) { 9400 String flat = comp.flattenToString(); 9401 for (int i=0; i<strings.size(); i++) { 9402 if (flat.contains(strings.get(i))) { 9403 return true; 9404 } 9405 } 9406 } 9407 return false; 9408 } 9409 } 9410 9411 /** 9412 * There are three things that cmd can be: 9413 * - a flattened component name that matches an existing activity 9414 * - the cmd arg isn't the flattened component name of an existing activity: 9415 * dump all activity whose component contains the cmd as a substring 9416 * - A hex number of the ActivityRecord object instance. 9417 */ 9418 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9419 int opti, boolean dumpAll) { 9420 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9421 9422 if ("all".equals(name)) { 9423 synchronized (this) { 9424 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9425 activities.add(r1); 9426 } 9427 } 9428 } else if ("top".equals(name)) { 9429 synchronized (this) { 9430 final int N = mMainStack.mHistory.size(); 9431 if (N > 0) { 9432 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9433 } 9434 } 9435 } else { 9436 ItemMatcher matcher = new ItemMatcher(); 9437 matcher.build(name); 9438 9439 synchronized (this) { 9440 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9441 if (matcher.match(r1, r1.intent.getComponent())) { 9442 activities.add(r1); 9443 } 9444 } 9445 } 9446 } 9447 9448 if (activities.size() <= 0) { 9449 return false; 9450 } 9451 9452 String[] newArgs = new String[args.length - opti]; 9453 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9454 9455 TaskRecord lastTask = null; 9456 boolean needSep = false; 9457 for (int i=activities.size()-1; i>=0; i--) { 9458 ActivityRecord r = (ActivityRecord)activities.get(i); 9459 if (needSep) { 9460 pw.println(); 9461 } 9462 needSep = true; 9463 synchronized (this) { 9464 if (lastTask != r.task) { 9465 lastTask = r.task; 9466 pw.print("TASK "); pw.print(lastTask.affinity); 9467 pw.print(" id="); pw.println(lastTask.taskId); 9468 if (dumpAll) { 9469 lastTask.dump(pw, " "); 9470 } 9471 } 9472 } 9473 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9474 } 9475 return true; 9476 } 9477 9478 /** 9479 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9480 * there is a thread associated with the activity. 9481 */ 9482 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9483 final ActivityRecord r, String[] args, boolean dumpAll) { 9484 String innerPrefix = prefix + " "; 9485 synchronized (this) { 9486 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9487 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9488 pw.print(" pid="); 9489 if (r.app != null) pw.println(r.app.pid); 9490 else pw.println("(not running)"); 9491 if (dumpAll) { 9492 r.dump(pw, innerPrefix); 9493 } 9494 } 9495 if (r.app != null && r.app.thread != null) { 9496 // flush anything that is already in the PrintWriter since the thread is going 9497 // to write to the file descriptor directly 9498 pw.flush(); 9499 try { 9500 TransferPipe tp = new TransferPipe(); 9501 try { 9502 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9503 r.appToken, innerPrefix, args); 9504 tp.go(fd); 9505 } finally { 9506 tp.kill(); 9507 } 9508 } catch (IOException e) { 9509 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9510 } catch (RemoteException e) { 9511 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9512 } 9513 } 9514 } 9515 9516 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9517 int opti, boolean dumpAll, String dumpPackage) { 9518 boolean needSep = false; 9519 9520 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9521 if (dumpAll) { 9522 if (mRegisteredReceivers.size() > 0) { 9523 boolean printed = false; 9524 Iterator it = mRegisteredReceivers.values().iterator(); 9525 while (it.hasNext()) { 9526 ReceiverList r = (ReceiverList)it.next(); 9527 if (dumpPackage != null && (r.app == null || 9528 !dumpPackage.equals(r.app.info.packageName))) { 9529 continue; 9530 } 9531 if (!printed) { 9532 pw.println(" Registered Receivers:"); 9533 needSep = true; 9534 printed = true; 9535 } 9536 pw.print(" * "); pw.println(r); 9537 r.dump(pw, " "); 9538 } 9539 } 9540 9541 if (mReceiverResolver.dump(pw, needSep ? 9542 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9543 " ", dumpPackage, false)) { 9544 needSep = true; 9545 } 9546 } 9547 9548 for (BroadcastQueue q : mBroadcastQueues) { 9549 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9550 } 9551 9552 needSep = true; 9553 9554 if (mStickyBroadcasts != null && dumpPackage == null) { 9555 if (needSep) { 9556 pw.println(); 9557 } 9558 needSep = true; 9559 pw.println(" Sticky broadcasts:"); 9560 StringBuilder sb = new StringBuilder(128); 9561 for (Map.Entry<String, ArrayList<Intent>> ent 9562 : mStickyBroadcasts.entrySet()) { 9563 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9564 if (dumpAll) { 9565 pw.println(":"); 9566 ArrayList<Intent> intents = ent.getValue(); 9567 final int N = intents.size(); 9568 for (int i=0; i<N; i++) { 9569 sb.setLength(0); 9570 sb.append(" Intent: "); 9571 intents.get(i).toShortString(sb, false, true, false, false); 9572 pw.println(sb.toString()); 9573 Bundle bundle = intents.get(i).getExtras(); 9574 if (bundle != null) { 9575 pw.print(" "); 9576 pw.println(bundle.toString()); 9577 } 9578 } 9579 } else { 9580 pw.println(""); 9581 } 9582 } 9583 needSep = true; 9584 } 9585 9586 if (dumpAll) { 9587 pw.println(); 9588 for (BroadcastQueue queue : mBroadcastQueues) { 9589 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9590 + queue.mBroadcastsScheduled); 9591 } 9592 pw.println(" mHandler:"); 9593 mHandler.dump(new PrintWriterPrinter(pw), " "); 9594 needSep = true; 9595 } 9596 9597 return needSep; 9598 } 9599 9600 /** 9601 * Prints a list of ServiceRecords (dumpsys activity services) 9602 */ 9603 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9604 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9605 boolean needSep = false; 9606 9607 ItemMatcher matcher = new ItemMatcher(); 9608 matcher.build(args, opti); 9609 9610 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 9611 try { 9612 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9613 for (UserInfo user : users) { 9614 if (mServiceMap.getAllServices(user.id).size() > 0) { 9615 boolean printed = false; 9616 long nowReal = SystemClock.elapsedRealtime(); 9617 Iterator<ServiceRecord> it = mServiceMap.getAllServices( 9618 user.id).iterator(); 9619 needSep = false; 9620 while (it.hasNext()) { 9621 ServiceRecord r = it.next(); 9622 if (!matcher.match(r, r.name)) { 9623 continue; 9624 } 9625 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9626 continue; 9627 } 9628 if (!printed) { 9629 pw.println(" Active services:"); 9630 printed = true; 9631 } 9632 if (needSep) { 9633 pw.println(); 9634 } 9635 pw.print(" * "); 9636 pw.println(r); 9637 if (dumpAll) { 9638 r.dump(pw, " "); 9639 needSep = true; 9640 } else { 9641 pw.print(" app="); 9642 pw.println(r.app); 9643 pw.print(" created="); 9644 TimeUtils.formatDuration(r.createTime, nowReal, pw); 9645 pw.print(" started="); 9646 pw.print(r.startRequested); 9647 pw.print(" connections="); 9648 pw.println(r.connections.size()); 9649 if (r.connections.size() > 0) { 9650 pw.println(" Connections:"); 9651 for (ArrayList<ConnectionRecord> clist : r.connections.values()) { 9652 for (int i = 0; i < clist.size(); i++) { 9653 ConnectionRecord conn = clist.get(i); 9654 pw.print(" "); 9655 pw.print(conn.binding.intent.intent.getIntent() 9656 .toShortString(false, false, false, false)); 9657 pw.print(" -> "); 9658 ProcessRecord proc = conn.binding.client; 9659 pw.println(proc != null ? proc.toShortString() : "null"); 9660 } 9661 } 9662 } 9663 } 9664 if (dumpClient && r.app != null && r.app.thread != null) { 9665 pw.println(" Client:"); 9666 pw.flush(); 9667 try { 9668 TransferPipe tp = new TransferPipe(); 9669 try { 9670 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), 9671 r, args); 9672 tp.setBufferPrefix(" "); 9673 // Short timeout, since blocking here can 9674 // deadlock with the application. 9675 tp.go(fd, 2000); 9676 } finally { 9677 tp.kill(); 9678 } 9679 } catch (IOException e) { 9680 pw.println(" Failure while dumping the service: " + e); 9681 } catch (RemoteException e) { 9682 pw.println(" Got a RemoteException while dumping the service"); 9683 } 9684 needSep = true; 9685 } 9686 } 9687 needSep = printed; 9688 } 9689 } 9690 } catch (RemoteException re) { 9691 9692 } 9693 9694 if (mPendingServices.size() > 0) { 9695 boolean printed = false; 9696 for (int i=0; i<mPendingServices.size(); i++) { 9697 ServiceRecord r = mPendingServices.get(i); 9698 if (!matcher.match(r, r.name)) { 9699 continue; 9700 } 9701 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9702 continue; 9703 } 9704 if (!printed) { 9705 if (needSep) pw.println(" "); 9706 needSep = true; 9707 pw.println(" Pending services:"); 9708 printed = true; 9709 } 9710 pw.print(" * Pending "); pw.println(r); 9711 r.dump(pw, " "); 9712 } 9713 needSep = true; 9714 } 9715 9716 if (mRestartingServices.size() > 0) { 9717 boolean printed = false; 9718 for (int i=0; i<mRestartingServices.size(); i++) { 9719 ServiceRecord r = mRestartingServices.get(i); 9720 if (!matcher.match(r, r.name)) { 9721 continue; 9722 } 9723 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9724 continue; 9725 } 9726 if (!printed) { 9727 if (needSep) pw.println(" "); 9728 needSep = true; 9729 pw.println(" Restarting services:"); 9730 printed = true; 9731 } 9732 pw.print(" * Restarting "); pw.println(r); 9733 r.dump(pw, " "); 9734 } 9735 needSep = true; 9736 } 9737 9738 if (mStoppingServices.size() > 0) { 9739 boolean printed = false; 9740 for (int i=0; i<mStoppingServices.size(); i++) { 9741 ServiceRecord r = mStoppingServices.get(i); 9742 if (!matcher.match(r, r.name)) { 9743 continue; 9744 } 9745 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9746 continue; 9747 } 9748 if (!printed) { 9749 if (needSep) pw.println(" "); 9750 needSep = true; 9751 pw.println(" Stopping services:"); 9752 printed = true; 9753 } 9754 pw.print(" * Stopping "); pw.println(r); 9755 r.dump(pw, " "); 9756 } 9757 needSep = true; 9758 } 9759 9760 if (dumpAll) { 9761 if (mServiceConnections.size() > 0) { 9762 boolean printed = false; 9763 Iterator<ArrayList<ConnectionRecord>> it 9764 = mServiceConnections.values().iterator(); 9765 while (it.hasNext()) { 9766 ArrayList<ConnectionRecord> r = it.next(); 9767 for (int i=0; i<r.size(); i++) { 9768 ConnectionRecord cr = r.get(i); 9769 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 9770 continue; 9771 } 9772 if (dumpPackage != null && (cr.binding.client == null 9773 || !dumpPackage.equals(cr.binding.client.info.packageName))) { 9774 continue; 9775 } 9776 if (!printed) { 9777 if (needSep) pw.println(" "); 9778 needSep = true; 9779 pw.println(" Connection bindings to services:"); 9780 printed = true; 9781 } 9782 pw.print(" * "); pw.println(cr); 9783 cr.dump(pw, " "); 9784 } 9785 } 9786 needSep = true; 9787 } 9788 } 9789 9790 return needSep; 9791 } 9792 9793 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9794 int opti, boolean dumpAll, String dumpPackage) { 9795 boolean needSep = true; 9796 9797 ItemMatcher matcher = new ItemMatcher(); 9798 matcher.build(args, opti); 9799 9800 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9801 9802 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9803 9804 if (mLaunchingProviders.size() > 0) { 9805 boolean printed = false; 9806 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9807 ContentProviderRecord r = mLaunchingProviders.get(i); 9808 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9809 continue; 9810 } 9811 if (!printed) { 9812 if (needSep) pw.println(" "); 9813 needSep = true; 9814 pw.println(" Launching content providers:"); 9815 printed = true; 9816 } 9817 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9818 pw.println(r); 9819 } 9820 } 9821 9822 if (mGrantedUriPermissions.size() > 0) { 9823 if (needSep) pw.println(); 9824 needSep = true; 9825 pw.println("Granted Uri Permissions:"); 9826 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9827 int uid = mGrantedUriPermissions.keyAt(i); 9828 HashMap<Uri, UriPermission> perms 9829 = mGrantedUriPermissions.valueAt(i); 9830 pw.print(" * UID "); pw.print(uid); 9831 pw.println(" holds:"); 9832 for (UriPermission perm : perms.values()) { 9833 pw.print(" "); pw.println(perm); 9834 if (dumpAll) { 9835 perm.dump(pw, " "); 9836 } 9837 } 9838 } 9839 needSep = true; 9840 } 9841 9842 return needSep; 9843 } 9844 9845 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9846 int opti, boolean dumpAll, String dumpPackage) { 9847 boolean needSep = false; 9848 9849 if (mIntentSenderRecords.size() > 0) { 9850 boolean printed = false; 9851 Iterator<WeakReference<PendingIntentRecord>> it 9852 = mIntentSenderRecords.values().iterator(); 9853 while (it.hasNext()) { 9854 WeakReference<PendingIntentRecord> ref = it.next(); 9855 PendingIntentRecord rec = ref != null ? ref.get(): null; 9856 if (dumpPackage != null && (rec == null 9857 || !dumpPackage.equals(rec.key.packageName))) { 9858 continue; 9859 } 9860 if (!printed) { 9861 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9862 printed = true; 9863 } 9864 needSep = true; 9865 if (rec != null) { 9866 pw.print(" * "); pw.println(rec); 9867 if (dumpAll) { 9868 rec.dump(pw, " "); 9869 } 9870 } else { 9871 pw.print(" * "); pw.println(ref); 9872 } 9873 } 9874 } 9875 9876 return needSep; 9877 } 9878 9879 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9880 String prefix, String label, boolean complete, boolean brief, boolean client, 9881 String dumpPackage) { 9882 TaskRecord lastTask = null; 9883 boolean needNL = false; 9884 final String innerPrefix = prefix + " "; 9885 final String[] args = new String[0]; 9886 for (int i=list.size()-1; i>=0; i--) { 9887 final ActivityRecord r = (ActivityRecord)list.get(i); 9888 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9889 continue; 9890 } 9891 final boolean full = !brief && (complete || !r.isInHistory()); 9892 if (needNL) { 9893 pw.println(" "); 9894 needNL = false; 9895 } 9896 if (lastTask != r.task) { 9897 lastTask = r.task; 9898 pw.print(prefix); 9899 pw.print(full ? "* " : " "); 9900 pw.println(lastTask); 9901 if (full) { 9902 lastTask.dump(pw, prefix + " "); 9903 } else if (complete) { 9904 // Complete + brief == give a summary. Isn't that obvious?!? 9905 if (lastTask.intent != null) { 9906 pw.print(prefix); pw.print(" "); 9907 pw.println(lastTask.intent.toInsecureStringWithClip()); 9908 } 9909 } 9910 } 9911 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9912 pw.print(" #"); pw.print(i); pw.print(": "); 9913 pw.println(r); 9914 if (full) { 9915 r.dump(pw, innerPrefix); 9916 } else if (complete) { 9917 // Complete + brief == give a summary. Isn't that obvious?!? 9918 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9919 if (r.app != null) { 9920 pw.print(innerPrefix); pw.println(r.app); 9921 } 9922 } 9923 if (client && r.app != null && r.app.thread != null) { 9924 // flush anything that is already in the PrintWriter since the thread is going 9925 // to write to the file descriptor directly 9926 pw.flush(); 9927 try { 9928 TransferPipe tp = new TransferPipe(); 9929 try { 9930 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9931 r.appToken, innerPrefix, args); 9932 // Short timeout, since blocking here can 9933 // deadlock with the application. 9934 tp.go(fd, 2000); 9935 } finally { 9936 tp.kill(); 9937 } 9938 } catch (IOException e) { 9939 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9940 } catch (RemoteException e) { 9941 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9942 } 9943 needNL = true; 9944 } 9945 } 9946 } 9947 9948 private static String buildOomTag(String prefix, String space, int val, int base) { 9949 if (val == base) { 9950 if (space == null) return prefix; 9951 return prefix + " "; 9952 } 9953 return prefix + "+" + Integer.toString(val-base); 9954 } 9955 9956 private static final int dumpProcessList(PrintWriter pw, 9957 ActivityManagerService service, List list, 9958 String prefix, String normalLabel, String persistentLabel, 9959 String dumpPackage) { 9960 int numPers = 0; 9961 final int N = list.size()-1; 9962 for (int i=N; i>=0; i--) { 9963 ProcessRecord r = (ProcessRecord)list.get(i); 9964 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9965 continue; 9966 } 9967 pw.println(String.format("%s%s #%2d: %s", 9968 prefix, (r.persistent ? persistentLabel : normalLabel), 9969 i, r.toString())); 9970 if (r.persistent) { 9971 numPers++; 9972 } 9973 } 9974 return numPers; 9975 } 9976 9977 private static final boolean dumpProcessOomList(PrintWriter pw, 9978 ActivityManagerService service, List<ProcessRecord> origList, 9979 String prefix, String normalLabel, String persistentLabel, 9980 boolean inclDetails, String dumpPackage) { 9981 9982 ArrayList<Pair<ProcessRecord, Integer>> list 9983 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9984 for (int i=0; i<origList.size(); i++) { 9985 ProcessRecord r = origList.get(i); 9986 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9987 continue; 9988 } 9989 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9990 } 9991 9992 if (list.size() <= 0) { 9993 return false; 9994 } 9995 9996 Comparator<Pair<ProcessRecord, Integer>> comparator 9997 = new Comparator<Pair<ProcessRecord, Integer>>() { 9998 @Override 9999 public int compare(Pair<ProcessRecord, Integer> object1, 10000 Pair<ProcessRecord, Integer> object2) { 10001 if (object1.first.setAdj != object2.first.setAdj) { 10002 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 10003 } 10004 if (object1.second.intValue() != object2.second.intValue()) { 10005 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 10006 } 10007 return 0; 10008 } 10009 }; 10010 10011 Collections.sort(list, comparator); 10012 10013 final long curRealtime = SystemClock.elapsedRealtime(); 10014 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10015 final long curUptime = SystemClock.uptimeMillis(); 10016 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10017 10018 for (int i=list.size()-1; i>=0; i--) { 10019 ProcessRecord r = list.get(i).first; 10020 String oomAdj; 10021 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10022 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10023 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10024 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10025 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10026 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10027 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10028 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10029 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10030 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10031 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10032 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10033 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10034 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10035 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10036 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10037 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10038 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10039 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10040 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10041 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10042 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10043 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10044 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10045 } else { 10046 oomAdj = Integer.toString(r.setAdj); 10047 } 10048 String schedGroup; 10049 switch (r.setSchedGroup) { 10050 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10051 schedGroup = "B"; 10052 break; 10053 case Process.THREAD_GROUP_DEFAULT: 10054 schedGroup = "F"; 10055 break; 10056 default: 10057 schedGroup = Integer.toString(r.setSchedGroup); 10058 break; 10059 } 10060 String foreground; 10061 if (r.foregroundActivities) { 10062 foreground = "A"; 10063 } else if (r.foregroundServices) { 10064 foreground = "S"; 10065 } else { 10066 foreground = " "; 10067 } 10068 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10069 prefix, (r.persistent ? persistentLabel : normalLabel), 10070 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10071 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10072 if (r.adjSource != null || r.adjTarget != null) { 10073 pw.print(prefix); 10074 pw.print(" "); 10075 if (r.adjTarget instanceof ComponentName) { 10076 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10077 } else if (r.adjTarget != null) { 10078 pw.print(r.adjTarget.toString()); 10079 } else { 10080 pw.print("{null}"); 10081 } 10082 pw.print("<="); 10083 if (r.adjSource instanceof ProcessRecord) { 10084 pw.print("Proc{"); 10085 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10086 pw.println("}"); 10087 } else if (r.adjSource != null) { 10088 pw.println(r.adjSource.toString()); 10089 } else { 10090 pw.println("{null}"); 10091 } 10092 } 10093 if (inclDetails) { 10094 pw.print(prefix); 10095 pw.print(" "); 10096 pw.print("oom: max="); pw.print(r.maxAdj); 10097 pw.print(" hidden="); pw.print(r.hiddenAdj); 10098 pw.print(" curRaw="); pw.print(r.curRawAdj); 10099 pw.print(" setRaw="); pw.print(r.setRawAdj); 10100 pw.print(" cur="); pw.print(r.curAdj); 10101 pw.print(" set="); pw.println(r.setAdj); 10102 pw.print(prefix); 10103 pw.print(" "); 10104 pw.print("keeping="); pw.print(r.keeping); 10105 pw.print(" hidden="); pw.print(r.hidden); 10106 pw.print(" empty="); pw.print(r.empty); 10107 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10108 10109 if (!r.keeping) { 10110 if (r.lastWakeTime != 0) { 10111 long wtime; 10112 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10113 synchronized (stats) { 10114 wtime = stats.getProcessWakeTime(r.info.uid, 10115 r.pid, curRealtime); 10116 } 10117 long timeUsed = wtime - r.lastWakeTime; 10118 pw.print(prefix); 10119 pw.print(" "); 10120 pw.print("keep awake over "); 10121 TimeUtils.formatDuration(realtimeSince, pw); 10122 pw.print(" used "); 10123 TimeUtils.formatDuration(timeUsed, pw); 10124 pw.print(" ("); 10125 pw.print((timeUsed*100)/realtimeSince); 10126 pw.println("%)"); 10127 } 10128 if (r.lastCpuTime != 0) { 10129 long timeUsed = r.curCpuTime - r.lastCpuTime; 10130 pw.print(prefix); 10131 pw.print(" "); 10132 pw.print("run cpu over "); 10133 TimeUtils.formatDuration(uptimeSince, pw); 10134 pw.print(" used "); 10135 TimeUtils.formatDuration(timeUsed, pw); 10136 pw.print(" ("); 10137 pw.print((timeUsed*100)/uptimeSince); 10138 pw.println("%)"); 10139 } 10140 } 10141 } 10142 } 10143 return true; 10144 } 10145 10146 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10147 ArrayList<ProcessRecord> procs; 10148 synchronized (this) { 10149 if (args != null && args.length > start 10150 && args[start].charAt(0) != '-') { 10151 procs = new ArrayList<ProcessRecord>(); 10152 int pid = -1; 10153 try { 10154 pid = Integer.parseInt(args[start]); 10155 } catch (NumberFormatException e) { 10156 10157 } 10158 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10159 ProcessRecord proc = mLruProcesses.get(i); 10160 if (proc.pid == pid) { 10161 procs.add(proc); 10162 } else if (proc.processName.equals(args[start])) { 10163 procs.add(proc); 10164 } 10165 } 10166 if (procs.size() <= 0) { 10167 pw.println("No process found for: " + args[start]); 10168 return null; 10169 } 10170 } else { 10171 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10172 } 10173 } 10174 return procs; 10175 } 10176 10177 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10178 PrintWriter pw, String[] args) { 10179 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10180 if (procs == null) { 10181 return; 10182 } 10183 10184 long uptime = SystemClock.uptimeMillis(); 10185 long realtime = SystemClock.elapsedRealtime(); 10186 pw.println("Applications Graphics Acceleration Info:"); 10187 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10188 10189 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10190 ProcessRecord r = procs.get(i); 10191 if (r.thread != null) { 10192 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10193 pw.flush(); 10194 try { 10195 TransferPipe tp = new TransferPipe(); 10196 try { 10197 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10198 tp.go(fd); 10199 } finally { 10200 tp.kill(); 10201 } 10202 } catch (IOException e) { 10203 pw.println("Failure while dumping the app: " + r); 10204 pw.flush(); 10205 } catch (RemoteException e) { 10206 pw.println("Got a RemoteException while dumping the app " + r); 10207 pw.flush(); 10208 } 10209 } 10210 } 10211 } 10212 10213 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10214 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10215 if (procs == null) { 10216 return; 10217 } 10218 10219 pw.println("Applications Database Info:"); 10220 10221 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10222 ProcessRecord r = procs.get(i); 10223 if (r.thread != null) { 10224 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10225 pw.flush(); 10226 try { 10227 TransferPipe tp = new TransferPipe(); 10228 try { 10229 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10230 tp.go(fd); 10231 } finally { 10232 tp.kill(); 10233 } 10234 } catch (IOException e) { 10235 pw.println("Failure while dumping the app: " + r); 10236 pw.flush(); 10237 } catch (RemoteException e) { 10238 pw.println("Got a RemoteException while dumping the app " + r); 10239 pw.flush(); 10240 } 10241 } 10242 } 10243 } 10244 10245 final static class MemItem { 10246 final String label; 10247 final String shortLabel; 10248 final long pss; 10249 final int id; 10250 ArrayList<MemItem> subitems; 10251 10252 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10253 label = _label; 10254 shortLabel = _shortLabel; 10255 pss = _pss; 10256 id = _id; 10257 } 10258 } 10259 10260 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10261 boolean sort) { 10262 if (sort) { 10263 Collections.sort(items, new Comparator<MemItem>() { 10264 @Override 10265 public int compare(MemItem lhs, MemItem rhs) { 10266 if (lhs.pss < rhs.pss) { 10267 return 1; 10268 } else if (lhs.pss > rhs.pss) { 10269 return -1; 10270 } 10271 return 0; 10272 } 10273 }); 10274 } 10275 10276 for (int i=0; i<items.size(); i++) { 10277 MemItem mi = items.get(i); 10278 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10279 if (mi.subitems != null) { 10280 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10281 } 10282 } 10283 } 10284 10285 // These are in KB. 10286 static final long[] DUMP_MEM_BUCKETS = new long[] { 10287 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10288 120*1024, 160*1024, 200*1024, 10289 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10290 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10291 }; 10292 10293 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10294 boolean stackLike) { 10295 int start = label.lastIndexOf('.'); 10296 if (start >= 0) start++; 10297 else start = 0; 10298 int end = label.length(); 10299 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10300 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10301 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10302 out.append(bucket); 10303 out.append(stackLike ? "MB." : "MB "); 10304 out.append(label, start, end); 10305 return; 10306 } 10307 } 10308 out.append(memKB/1024); 10309 out.append(stackLike ? "MB." : "MB "); 10310 out.append(label, start, end); 10311 } 10312 10313 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10314 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10315 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10316 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10317 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10318 }; 10319 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10320 "System", "Persistent", "Foreground", 10321 "Visible", "Perceptible", "Heavy Weight", 10322 "Backup", "A Services", "Home", "Previous", 10323 "B Services", "Background" 10324 }; 10325 10326 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10327 PrintWriter pw, String prefix, String[] args, boolean brief, 10328 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10329 boolean dumpAll = false; 10330 boolean oomOnly = false; 10331 10332 int opti = 0; 10333 while (opti < args.length) { 10334 String opt = args[opti]; 10335 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10336 break; 10337 } 10338 opti++; 10339 if ("-a".equals(opt)) { 10340 dumpAll = true; 10341 } else if ("--oom".equals(opt)) { 10342 oomOnly = true; 10343 } else if ("-h".equals(opt)) { 10344 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10345 pw.println(" -a: include all available information for each process."); 10346 pw.println(" --oom: only show processes organized by oom adj."); 10347 pw.println("If [process] is specified it can be the name or "); 10348 pw.println("pid of a specific process to dump."); 10349 return; 10350 } else { 10351 pw.println("Unknown argument: " + opt + "; use -h for help"); 10352 } 10353 } 10354 10355 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10356 if (procs == null) { 10357 return; 10358 } 10359 10360 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10361 long uptime = SystemClock.uptimeMillis(); 10362 long realtime = SystemClock.elapsedRealtime(); 10363 10364 if (procs.size() == 1 || isCheckinRequest) { 10365 dumpAll = true; 10366 } 10367 10368 if (isCheckinRequest) { 10369 // short checkin version 10370 pw.println(uptime + "," + realtime); 10371 pw.flush(); 10372 } else { 10373 pw.println("Applications Memory Usage (kB):"); 10374 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10375 } 10376 10377 String[] innerArgs = new String[args.length-opti]; 10378 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10379 10380 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10381 long nativePss=0, dalvikPss=0, otherPss=0; 10382 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10383 10384 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10385 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10386 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10387 10388 long totalPss = 0; 10389 10390 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10391 ProcessRecord r = procs.get(i); 10392 if (r.thread != null) { 10393 if (!isCheckinRequest && dumpAll) { 10394 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10395 pw.flush(); 10396 } 10397 Debug.MemoryInfo mi = null; 10398 if (dumpAll) { 10399 try { 10400 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10401 } catch (RemoteException e) { 10402 if (!isCheckinRequest) { 10403 pw.println("Got RemoteException!"); 10404 pw.flush(); 10405 } 10406 } 10407 } else { 10408 mi = new Debug.MemoryInfo(); 10409 Debug.getMemoryInfo(r.pid, mi); 10410 } 10411 10412 if (!isCheckinRequest && mi != null) { 10413 long myTotalPss = mi.getTotalPss(); 10414 totalPss += myTotalPss; 10415 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10416 r.processName, myTotalPss, 0); 10417 procMems.add(pssItem); 10418 10419 nativePss += mi.nativePss; 10420 dalvikPss += mi.dalvikPss; 10421 otherPss += mi.otherPss; 10422 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10423 long mem = mi.getOtherPss(j); 10424 miscPss[j] += mem; 10425 otherPss -= mem; 10426 } 10427 10428 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10429 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10430 || oomIndex == (oomPss.length-1)) { 10431 oomPss[oomIndex] += myTotalPss; 10432 if (oomProcs[oomIndex] == null) { 10433 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10434 } 10435 oomProcs[oomIndex].add(pssItem); 10436 break; 10437 } 10438 } 10439 } 10440 } 10441 } 10442 10443 if (!isCheckinRequest && procs.size() > 1) { 10444 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10445 10446 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10447 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10448 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10449 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10450 String label = Debug.MemoryInfo.getOtherLabel(j); 10451 catMems.add(new MemItem(label, label, miscPss[j], j)); 10452 } 10453 10454 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10455 for (int j=0; j<oomPss.length; j++) { 10456 if (oomPss[j] != 0) { 10457 String label = DUMP_MEM_OOM_LABEL[j]; 10458 MemItem item = new MemItem(label, label, oomPss[j], 10459 DUMP_MEM_OOM_ADJ[j]); 10460 item.subitems = oomProcs[j]; 10461 oomMems.add(item); 10462 } 10463 } 10464 10465 if (outTag != null || outStack != null) { 10466 if (outTag != null) { 10467 appendMemBucket(outTag, totalPss, "total", false); 10468 } 10469 if (outStack != null) { 10470 appendMemBucket(outStack, totalPss, "total", true); 10471 } 10472 boolean firstLine = true; 10473 for (int i=0; i<oomMems.size(); i++) { 10474 MemItem miCat = oomMems.get(i); 10475 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10476 continue; 10477 } 10478 if (miCat.id < ProcessList.SERVICE_ADJ 10479 || miCat.id == ProcessList.HOME_APP_ADJ 10480 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10481 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10482 outTag.append(" / "); 10483 } 10484 if (outStack != null) { 10485 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10486 if (firstLine) { 10487 outStack.append(":"); 10488 firstLine = false; 10489 } 10490 outStack.append("\n\t at "); 10491 } else { 10492 outStack.append("$"); 10493 } 10494 } 10495 for (int j=0; j<miCat.subitems.size(); j++) { 10496 MemItem mi = miCat.subitems.get(j); 10497 if (j > 0) { 10498 if (outTag != null) { 10499 outTag.append(" "); 10500 } 10501 if (outStack != null) { 10502 outStack.append("$"); 10503 } 10504 } 10505 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10506 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10507 } 10508 if (outStack != null) { 10509 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10510 } 10511 } 10512 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10513 outStack.append("("); 10514 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10515 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10516 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10517 outStack.append(":"); 10518 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10519 } 10520 } 10521 outStack.append(")"); 10522 } 10523 } 10524 } 10525 } 10526 10527 if (!brief && !oomOnly) { 10528 pw.println(); 10529 pw.println("Total PSS by process:"); 10530 dumpMemItems(pw, " ", procMems, true); 10531 pw.println(); 10532 } 10533 pw.println("Total PSS by OOM adjustment:"); 10534 dumpMemItems(pw, " ", oomMems, false); 10535 if (!oomOnly) { 10536 PrintWriter out = categoryPw != null ? categoryPw : pw; 10537 out.println(); 10538 out.println("Total PSS by category:"); 10539 dumpMemItems(out, " ", catMems, true); 10540 } 10541 pw.println(); 10542 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10543 final int[] SINGLE_LONG_FORMAT = new int[] { 10544 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10545 }; 10546 long[] longOut = new long[1]; 10547 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10548 SINGLE_LONG_FORMAT, null, longOut, null); 10549 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10550 longOut[0] = 0; 10551 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10552 SINGLE_LONG_FORMAT, null, longOut, null); 10553 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10554 longOut[0] = 0; 10555 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10556 SINGLE_LONG_FORMAT, null, longOut, null); 10557 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10558 longOut[0] = 0; 10559 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10560 SINGLE_LONG_FORMAT, null, longOut, null); 10561 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10562 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10563 pw.print(shared); pw.println(" kB"); 10564 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10565 pw.print(voltile); pw.println(" kB volatile"); 10566 } 10567 } 10568 10569 /** 10570 * Searches array of arguments for the specified string 10571 * @param args array of argument strings 10572 * @param value value to search for 10573 * @return true if the value is contained in the array 10574 */ 10575 private static boolean scanArgs(String[] args, String value) { 10576 if (args != null) { 10577 for (String arg : args) { 10578 if (value.equals(arg)) { 10579 return true; 10580 } 10581 } 10582 } 10583 return false; 10584 } 10585 10586 private final void killServicesLocked(ProcessRecord app, 10587 boolean allowRestart) { 10588 // Report disconnected services. 10589 if (false) { 10590 // XXX we are letting the client link to the service for 10591 // death notifications. 10592 if (app.services.size() > 0) { 10593 Iterator<ServiceRecord> it = app.services.iterator(); 10594 while (it.hasNext()) { 10595 ServiceRecord r = it.next(); 10596 if (r.connections.size() > 0) { 10597 Iterator<ArrayList<ConnectionRecord>> jt 10598 = r.connections.values().iterator(); 10599 while (jt.hasNext()) { 10600 ArrayList<ConnectionRecord> cl = jt.next(); 10601 for (int i=0; i<cl.size(); i++) { 10602 ConnectionRecord c = cl.get(i); 10603 if (c.binding.client != app) { 10604 try { 10605 //c.conn.connected(r.className, null); 10606 } catch (Exception e) { 10607 // todo: this should be asynchronous! 10608 Slog.w(TAG, "Exception thrown disconnected servce " 10609 + r.shortName 10610 + " from app " + app.processName, e); 10611 } 10612 } 10613 } 10614 } 10615 } 10616 } 10617 } 10618 } 10619 10620 // Clean up any connections this application has to other services. 10621 if (app.connections.size() > 0) { 10622 Iterator<ConnectionRecord> it = app.connections.iterator(); 10623 while (it.hasNext()) { 10624 ConnectionRecord r = it.next(); 10625 removeConnectionLocked(r, app, null); 10626 } 10627 } 10628 app.connections.clear(); 10629 10630 if (app.services.size() != 0) { 10631 // Any services running in the application need to be placed 10632 // back in the pending list. 10633 Iterator<ServiceRecord> it = app.services.iterator(); 10634 while (it.hasNext()) { 10635 ServiceRecord sr = it.next(); 10636 synchronized (sr.stats.getBatteryStats()) { 10637 sr.stats.stopLaunchedLocked(); 10638 } 10639 sr.app = null; 10640 sr.isolatedProc = null; 10641 sr.executeNesting = 0; 10642 if (mStoppingServices.remove(sr)) { 10643 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10644 } 10645 10646 boolean hasClients = sr.bindings.size() > 0; 10647 if (hasClients) { 10648 Iterator<IntentBindRecord> bindings 10649 = sr.bindings.values().iterator(); 10650 while (bindings.hasNext()) { 10651 IntentBindRecord b = bindings.next(); 10652 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10653 + ": shouldUnbind=" + b.hasBound); 10654 b.binder = null; 10655 b.requested = b.received = b.hasBound = false; 10656 } 10657 } 10658 10659 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 10660 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 10661 Slog.w(TAG, "Service crashed " + sr.crashCount 10662 + " times, stopping: " + sr); 10663 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10664 sr.crashCount, sr.shortName, app.pid); 10665 bringDownServiceLocked(sr, true); 10666 } else if (!allowRestart) { 10667 bringDownServiceLocked(sr, true); 10668 } else { 10669 boolean canceled = scheduleServiceRestartLocked(sr, true); 10670 10671 // Should the service remain running? Note that in the 10672 // extreme case of so many attempts to deliver a command 10673 // that it failed we also will stop it here. 10674 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10675 if (sr.pendingStarts.size() == 0) { 10676 sr.startRequested = false; 10677 if (!hasClients) { 10678 // Whoops, no reason to restart! 10679 bringDownServiceLocked(sr, true); 10680 } 10681 } 10682 } 10683 } 10684 } 10685 10686 if (!allowRestart) { 10687 app.services.clear(); 10688 } 10689 } 10690 10691 // Make sure we have no more records on the stopping list. 10692 int i = mStoppingServices.size(); 10693 while (i > 0) { 10694 i--; 10695 ServiceRecord sr = mStoppingServices.get(i); 10696 if (sr.app == app) { 10697 mStoppingServices.remove(i); 10698 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10699 } 10700 } 10701 10702 app.executingServices.clear(); 10703 } 10704 10705 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10706 ContentProviderRecord cpr, boolean always) { 10707 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10708 10709 if (!inLaunching || always) { 10710 synchronized (cpr) { 10711 cpr.launchingApp = null; 10712 cpr.notifyAll(); 10713 } 10714 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10715 String names[] = cpr.info.authority.split(";"); 10716 for (int j = 0; j < names.length; j++) { 10717 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10718 } 10719 } 10720 10721 for (int i=0; i<cpr.connections.size(); i++) { 10722 ContentProviderConnection conn = cpr.connections.get(i); 10723 if (conn.waiting) { 10724 // If this connection is waiting for the provider, then we don't 10725 // need to mess with its process unless we are always removing 10726 // or for some reason the provider is not currently launching. 10727 if (inLaunching && !always) { 10728 continue; 10729 } 10730 } 10731 ProcessRecord capp = conn.client; 10732 conn.dead = true; 10733 if (conn.stableCount > 0) { 10734 if (!capp.persistent && capp.thread != null 10735 && capp.pid != 0 10736 && capp.pid != MY_PID) { 10737 Slog.i(TAG, "Kill " + capp.processName 10738 + " (pid " + capp.pid + "): provider " + cpr.info.name 10739 + " in dying process " + (proc != null ? proc.processName : "??")); 10740 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10741 capp.processName, capp.setAdj, "dying provider " 10742 + cpr.name.toShortString()); 10743 Process.killProcessQuiet(capp.pid); 10744 } 10745 } else if (capp.thread != null && conn.provider.provider != null) { 10746 try { 10747 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10748 } catch (RemoteException e) { 10749 } 10750 // In the protocol here, we don't expect the client to correctly 10751 // clean up this connection, we'll just remove it. 10752 cpr.connections.remove(i); 10753 conn.client.conProviders.remove(conn); 10754 } 10755 } 10756 10757 if (inLaunching && always) { 10758 mLaunchingProviders.remove(cpr); 10759 } 10760 return inLaunching; 10761 } 10762 10763 /** 10764 * Main code for cleaning up a process when it has gone away. This is 10765 * called both as a result of the process dying, or directly when stopping 10766 * a process when running in single process mode. 10767 */ 10768 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10769 boolean restarting, boolean allowRestart, int index) { 10770 if (index >= 0) { 10771 mLruProcesses.remove(index); 10772 } 10773 10774 mProcessesToGc.remove(app); 10775 10776 // Dismiss any open dialogs. 10777 if (app.crashDialog != null) { 10778 app.crashDialog.dismiss(); 10779 app.crashDialog = null; 10780 } 10781 if (app.anrDialog != null) { 10782 app.anrDialog.dismiss(); 10783 app.anrDialog = null; 10784 } 10785 if (app.waitDialog != null) { 10786 app.waitDialog.dismiss(); 10787 app.waitDialog = null; 10788 } 10789 10790 app.crashing = false; 10791 app.notResponding = false; 10792 10793 app.resetPackageList(); 10794 app.unlinkDeathRecipient(); 10795 app.thread = null; 10796 app.forcingToForeground = null; 10797 app.foregroundServices = false; 10798 app.foregroundActivities = false; 10799 app.hasShownUi = false; 10800 app.hasAboveClient = false; 10801 10802 killServicesLocked(app, allowRestart); 10803 10804 boolean restart = false; 10805 10806 // Remove published content providers. 10807 if (!app.pubProviders.isEmpty()) { 10808 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10809 while (it.hasNext()) { 10810 ContentProviderRecord cpr = it.next(); 10811 10812 final boolean always = app.bad || !allowRestart; 10813 if (removeDyingProviderLocked(app, cpr, always) || always) { 10814 // We left the provider in the launching list, need to 10815 // restart it. 10816 restart = true; 10817 } 10818 10819 cpr.provider = null; 10820 cpr.proc = null; 10821 } 10822 app.pubProviders.clear(); 10823 } 10824 10825 // Take care of any launching providers waiting for this process. 10826 if (checkAppInLaunchingProvidersLocked(app, false)) { 10827 restart = true; 10828 } 10829 10830 // Unregister from connected content providers. 10831 if (!app.conProviders.isEmpty()) { 10832 for (int i=0; i<app.conProviders.size(); i++) { 10833 ContentProviderConnection conn = app.conProviders.get(i); 10834 conn.provider.connections.remove(conn); 10835 } 10836 app.conProviders.clear(); 10837 } 10838 10839 // At this point there may be remaining entries in mLaunchingProviders 10840 // where we were the only one waiting, so they are no longer of use. 10841 // Look for these and clean up if found. 10842 // XXX Commented out for now. Trying to figure out a way to reproduce 10843 // the actual situation to identify what is actually going on. 10844 if (false) { 10845 for (int i=0; i<mLaunchingProviders.size(); i++) { 10846 ContentProviderRecord cpr = (ContentProviderRecord) 10847 mLaunchingProviders.get(i); 10848 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10849 synchronized (cpr) { 10850 cpr.launchingApp = null; 10851 cpr.notifyAll(); 10852 } 10853 } 10854 } 10855 } 10856 10857 skipCurrentReceiverLocked(app); 10858 10859 // Unregister any receivers. 10860 if (app.receivers.size() > 0) { 10861 Iterator<ReceiverList> it = app.receivers.iterator(); 10862 while (it.hasNext()) { 10863 removeReceiverLocked(it.next()); 10864 } 10865 app.receivers.clear(); 10866 } 10867 10868 // If the app is undergoing backup, tell the backup manager about it 10869 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10870 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10871 try { 10872 IBackupManager bm = IBackupManager.Stub.asInterface( 10873 ServiceManager.getService(Context.BACKUP_SERVICE)); 10874 bm.agentDisconnected(app.info.packageName); 10875 } catch (RemoteException e) { 10876 // can't happen; backup manager is local 10877 } 10878 } 10879 10880 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10881 ProcessChangeItem item = mPendingProcessChanges.get(i); 10882 if (item.pid == app.pid) { 10883 mPendingProcessChanges.remove(i); 10884 mAvailProcessChanges.add(item); 10885 } 10886 } 10887 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10888 10889 // If the caller is restarting this app, then leave it in its 10890 // current lists and let the caller take care of it. 10891 if (restarting) { 10892 return; 10893 } 10894 10895 if (!app.persistent || app.isolated) { 10896 if (DEBUG_PROCESSES) Slog.v(TAG, 10897 "Removing non-persistent process during cleanup: " + app); 10898 mProcessNames.remove(app.processName, app.uid); 10899 mIsolatedProcesses.remove(app.uid); 10900 if (mHeavyWeightProcess == app) { 10901 mHeavyWeightProcess = null; 10902 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10903 } 10904 } else if (!app.removed) { 10905 // This app is persistent, so we need to keep its record around. 10906 // If it is not already on the pending app list, add it there 10907 // and start a new process for it. 10908 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10909 mPersistentStartingProcesses.add(app); 10910 restart = true; 10911 } 10912 } 10913 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10914 "Clean-up removing on hold: " + app); 10915 mProcessesOnHold.remove(app); 10916 10917 if (app == mHomeProcess) { 10918 mHomeProcess = null; 10919 } 10920 if (app == mPreviousProcess) { 10921 mPreviousProcess = null; 10922 } 10923 10924 if (restart && !app.isolated) { 10925 // We have components that still need to be running in the 10926 // process, so re-launch it. 10927 mProcessNames.put(app.processName, app.uid, app); 10928 startProcessLocked(app, "restart", app.processName); 10929 } else if (app.pid > 0 && app.pid != MY_PID) { 10930 // Goodbye! 10931 synchronized (mPidsSelfLocked) { 10932 mPidsSelfLocked.remove(app.pid); 10933 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10934 } 10935 app.setPid(0); 10936 } 10937 } 10938 10939 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10940 // Look through the content providers we are waiting to have launched, 10941 // and if any run in this process then either schedule a restart of 10942 // the process or kill the client waiting for it if this process has 10943 // gone bad. 10944 int NL = mLaunchingProviders.size(); 10945 boolean restart = false; 10946 for (int i=0; i<NL; i++) { 10947 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10948 if (cpr.launchingApp == app) { 10949 if (!alwaysBad && !app.bad) { 10950 restart = true; 10951 } else { 10952 removeDyingProviderLocked(app, cpr, true); 10953 // cpr should have been removed from mLaunchingProviders 10954 NL = mLaunchingProviders.size(); 10955 i--; 10956 } 10957 } 10958 } 10959 return restart; 10960 } 10961 10962 // ========================================================= 10963 // SERVICES 10964 // ========================================================= 10965 10966 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10967 ActivityManager.RunningServiceInfo info = 10968 new ActivityManager.RunningServiceInfo(); 10969 info.service = r.name; 10970 if (r.app != null) { 10971 info.pid = r.app.pid; 10972 } 10973 info.uid = r.appInfo.uid; 10974 info.process = r.processName; 10975 info.foreground = r.isForeground; 10976 info.activeSince = r.createTime; 10977 info.started = r.startRequested; 10978 info.clientCount = r.connections.size(); 10979 info.crashCount = r.crashCount; 10980 info.lastActivityTime = r.lastActivity; 10981 if (r.isForeground) { 10982 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10983 } 10984 if (r.startRequested) { 10985 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10986 } 10987 if (r.app != null && r.app.pid == MY_PID) { 10988 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10989 } 10990 if (r.app != null && r.app.persistent) { 10991 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10992 } 10993 10994 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 10995 for (int i=0; i<connl.size(); i++) { 10996 ConnectionRecord conn = connl.get(i); 10997 if (conn.clientLabel != 0) { 10998 info.clientPackage = conn.binding.client.info.packageName; 10999 info.clientLabel = conn.clientLabel; 11000 return info; 11001 } 11002 } 11003 } 11004 return info; 11005 } 11006 11007 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 11008 int flags) { 11009 enforceNotIsolatedCaller("getServices"); 11010 synchronized (this) { 11011 ArrayList<ActivityManager.RunningServiceInfo> res 11012 = new ArrayList<ActivityManager.RunningServiceInfo>(); 11013 11014 int userId = UserId.getUserId(Binder.getCallingUid()); 11015 if (mServiceMap.getAllServices(userId).size() > 0) { 11016 Iterator<ServiceRecord> it 11017 = mServiceMap.getAllServices(userId).iterator(); 11018 while (it.hasNext() && res.size() < maxNum) { 11019 res.add(makeRunningServiceInfoLocked(it.next())); 11020 } 11021 } 11022 11023 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 11024 ServiceRecord r = mRestartingServices.get(i); 11025 ActivityManager.RunningServiceInfo info = 11026 makeRunningServiceInfoLocked(r); 11027 info.restarting = r.nextRestartTime; 11028 res.add(info); 11029 } 11030 11031 return res; 11032 } 11033 } 11034 11035 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 11036 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 11037 synchronized (this) { 11038 int userId = UserId.getUserId(Binder.getCallingUid()); 11039 ServiceRecord r = mServiceMap.getServiceByName(name, userId); 11040 if (r != null) { 11041 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 11042 for (int i=0; i<conn.size(); i++) { 11043 if (conn.get(i).clientIntent != null) { 11044 return conn.get(i).clientIntent; 11045 } 11046 } 11047 } 11048 } 11049 } 11050 return null; 11051 } 11052 11053 private final ServiceRecord findServiceLocked(ComponentName name, 11054 IBinder token) { 11055 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 11056 return r == token ? r : null; 11057 } 11058 11059 private final class ServiceLookupResult { 11060 final ServiceRecord record; 11061 final String permission; 11062 11063 ServiceLookupResult(ServiceRecord _record, String _permission) { 11064 record = _record; 11065 permission = _permission; 11066 } 11067 }; 11068 11069 private ServiceLookupResult findServiceLocked(Intent service, 11070 String resolvedType, int userId) { 11071 ServiceRecord r = null; 11072 if (service.getComponent() != null) { 11073 r = mServiceMap.getServiceByName(service.getComponent(), userId); 11074 } 11075 if (r == null) { 11076 Intent.FilterComparison filter = new Intent.FilterComparison(service); 11077 r = mServiceMap.getServiceByIntent(filter, userId); 11078 } 11079 11080 if (r == null) { 11081 try { 11082 ResolveInfo rInfo = 11083 AppGlobals.getPackageManager().resolveService( 11084 service, resolvedType, 0, userId); 11085 ServiceInfo sInfo = 11086 rInfo != null ? rInfo.serviceInfo : null; 11087 if (sInfo == null) { 11088 return null; 11089 } 11090 11091 ComponentName name = new ComponentName( 11092 sInfo.applicationInfo.packageName, sInfo.name); 11093 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 11094 } catch (RemoteException ex) { 11095 // pm is in same process, this will never happen. 11096 } 11097 } 11098 if (r != null) { 11099 int callingPid = Binder.getCallingPid(); 11100 int callingUid = Binder.getCallingUid(); 11101 if (checkComponentPermission(r.permission, 11102 callingPid, callingUid, r.appInfo.uid, r.exported) 11103 != PackageManager.PERMISSION_GRANTED) { 11104 if (!r.exported) { 11105 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11106 + " from pid=" + callingPid 11107 + ", uid=" + callingUid 11108 + " that is not exported from uid " + r.appInfo.uid); 11109 return new ServiceLookupResult(null, "not exported from uid " 11110 + r.appInfo.uid); 11111 } 11112 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11113 + " from pid=" + callingPid 11114 + ", uid=" + callingUid 11115 + " requires " + r.permission); 11116 return new ServiceLookupResult(null, r.permission); 11117 } 11118 return new ServiceLookupResult(r, null); 11119 } 11120 return null; 11121 } 11122 11123 private class ServiceRestarter implements Runnable { 11124 private ServiceRecord mService; 11125 11126 void setService(ServiceRecord service) { 11127 mService = service; 11128 } 11129 11130 public void run() { 11131 synchronized(ActivityManagerService.this) { 11132 performServiceRestartLocked(mService); 11133 } 11134 } 11135 } 11136 11137 private ServiceLookupResult retrieveServiceLocked(Intent service, 11138 String resolvedType, int callingPid, int callingUid, int userId) { 11139 ServiceRecord r = null; 11140 if (DEBUG_SERVICE) 11141 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType 11142 + " callingUid=" + callingUid); 11143 11144 if (service.getComponent() != null) { 11145 r = mServiceMap.getServiceByName(service.getComponent(), userId); 11146 } 11147 if (r == null) { 11148 Intent.FilterComparison filter = new Intent.FilterComparison(service); 11149 r = mServiceMap.getServiceByIntent(filter, userId); 11150 } 11151 if (r == null) { 11152 try { 11153 ResolveInfo rInfo = 11154 AppGlobals.getPackageManager().resolveService( 11155 service, resolvedType, STOCK_PM_FLAGS, userId); 11156 ServiceInfo sInfo = 11157 rInfo != null ? rInfo.serviceInfo : null; 11158 if (sInfo == null) { 11159 Slog.w(TAG, "Unable to start service " + service + 11160 ": not found"); 11161 return null; 11162 } 11163 if (userId > 0) { 11164 if (isSingleton(sInfo.processName, sInfo.applicationInfo)) { 11165 userId = 0; 11166 } 11167 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId); 11168 } 11169 ComponentName name = new ComponentName( 11170 sInfo.applicationInfo.packageName, sInfo.name); 11171 r = mServiceMap.getServiceByName(name, userId); 11172 if (r == null) { 11173 Intent.FilterComparison filter = new Intent.FilterComparison( 11174 service.cloneFilter()); 11175 ServiceRestarter res = new ServiceRestarter(); 11176 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11177 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11178 synchronized (stats) { 11179 ss = stats.getServiceStatsLocked( 11180 sInfo.applicationInfo.uid, sInfo.packageName, 11181 sInfo.name); 11182 } 11183 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 11184 res.setService(r); 11185 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r); 11186 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r); 11187 11188 // Make sure this component isn't in the pending list. 11189 int N = mPendingServices.size(); 11190 for (int i=0; i<N; i++) { 11191 ServiceRecord pr = mPendingServices.get(i); 11192 if (pr.name.equals(name)) { 11193 mPendingServices.remove(i); 11194 i--; 11195 N--; 11196 } 11197 } 11198 } 11199 } catch (RemoteException ex) { 11200 // pm is in same process, this will never happen. 11201 } 11202 } 11203 if (r != null) { 11204 if (checkComponentPermission(r.permission, 11205 callingPid, callingUid, r.appInfo.uid, r.exported) 11206 != PackageManager.PERMISSION_GRANTED) { 11207 if (!r.exported) { 11208 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11209 + " from pid=" + callingPid 11210 + ", uid=" + callingUid 11211 + " that is not exported from uid " + r.appInfo.uid); 11212 return new ServiceLookupResult(null, "not exported from uid " 11213 + r.appInfo.uid); 11214 } 11215 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11216 + " from pid=" + callingPid 11217 + ", uid=" + callingUid 11218 + " requires " + r.permission); 11219 return new ServiceLookupResult(null, r.permission); 11220 } 11221 return new ServiceLookupResult(r, null); 11222 } 11223 return null; 11224 } 11225 11226 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 11227 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 11228 + why + " of " + r + " in app " + r.app); 11229 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 11230 + why + " of " + r.shortName); 11231 long now = SystemClock.uptimeMillis(); 11232 if (r.executeNesting == 0 && r.app != null) { 11233 if (r.app.executingServices.size() == 0) { 11234 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11235 msg.obj = r.app; 11236 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 11237 } 11238 r.app.executingServices.add(r); 11239 } 11240 r.executeNesting++; 11241 r.executingStart = now; 11242 } 11243 11244 private final void sendServiceArgsLocked(ServiceRecord r, 11245 boolean oomAdjusted) { 11246 final int N = r.pendingStarts.size(); 11247 if (N == 0) { 11248 return; 11249 } 11250 11251 while (r.pendingStarts.size() > 0) { 11252 try { 11253 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 11254 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 11255 + r + " " + r.intent + " args=" + si.intent); 11256 if (si.intent == null && N > 1) { 11257 // If somehow we got a dummy null intent in the middle, 11258 // then skip it. DO NOT skip a null intent when it is 11259 // the only one in the list -- this is to support the 11260 // onStartCommand(null) case. 11261 continue; 11262 } 11263 si.deliveredTime = SystemClock.uptimeMillis(); 11264 r.deliveredStarts.add(si); 11265 si.deliveryCount++; 11266 if (si.neededGrants != null) { 11267 grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, 11268 si.getUriPermissionsLocked()); 11269 } 11270 bumpServiceExecutingLocked(r, "start"); 11271 if (!oomAdjusted) { 11272 oomAdjusted = true; 11273 updateOomAdjLocked(r.app); 11274 } 11275 int flags = 0; 11276 if (si.deliveryCount > 1) { 11277 flags |= Service.START_FLAG_RETRY; 11278 } 11279 if (si.doneExecutingCount > 0) { 11280 flags |= Service.START_FLAG_REDELIVERY; 11281 } 11282 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 11283 } catch (RemoteException e) { 11284 // Remote process gone... we'll let the normal cleanup take 11285 // care of this. 11286 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 11287 break; 11288 } catch (Exception e) { 11289 Slog.w(TAG, "Unexpected exception", e); 11290 break; 11291 } 11292 } 11293 } 11294 11295 private final boolean requestServiceBindingLocked(ServiceRecord r, 11296 IntentBindRecord i, boolean rebind) { 11297 if (r.app == null || r.app.thread == null) { 11298 // If service is not currently running, can't yet bind. 11299 return false; 11300 } 11301 if ((!i.requested || rebind) && i.apps.size() > 0) { 11302 try { 11303 bumpServiceExecutingLocked(r, "bind"); 11304 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 11305 if (!rebind) { 11306 i.requested = true; 11307 } 11308 i.hasBound = true; 11309 i.doRebind = false; 11310 } catch (RemoteException e) { 11311 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 11312 return false; 11313 } 11314 } 11315 return true; 11316 } 11317 11318 private final void requestServiceBindingsLocked(ServiceRecord r) { 11319 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 11320 while (bindings.hasNext()) { 11321 IntentBindRecord i = bindings.next(); 11322 if (!requestServiceBindingLocked(r, i, false)) { 11323 break; 11324 } 11325 } 11326 } 11327 11328 private final void realStartServiceLocked(ServiceRecord r, 11329 ProcessRecord app) throws RemoteException { 11330 if (app.thread == null) { 11331 throw new RemoteException(); 11332 } 11333 if (DEBUG_MU) 11334 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid 11335 + ", ProcessRecord.uid = " + app.uid); 11336 r.app = app; 11337 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 11338 11339 app.services.add(r); 11340 bumpServiceExecutingLocked(r, "create"); 11341 updateLruProcessLocked(app, true, true); 11342 11343 boolean created = false; 11344 try { 11345 mStringBuilder.setLength(0); 11346 r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false); 11347 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 11348 System.identityHashCode(r), r.shortName, 11349 mStringBuilder.toString(), r.app.pid); 11350 synchronized (r.stats.getBatteryStats()) { 11351 r.stats.startLaunchedLocked(); 11352 } 11353 ensurePackageDexOpt(r.serviceInfo.packageName); 11354 app.thread.scheduleCreateService(r, r.serviceInfo, 11355 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 11356 r.postNotification(); 11357 created = true; 11358 } finally { 11359 if (!created) { 11360 app.services.remove(r); 11361 scheduleServiceRestartLocked(r, false); 11362 } 11363 } 11364 11365 requestServiceBindingsLocked(r); 11366 11367 // If the service is in the started state, and there are no 11368 // pending arguments, then fake up one so its onStartCommand() will 11369 // be called. 11370 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 11371 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11372 null, null)); 11373 } 11374 11375 sendServiceArgsLocked(r, true); 11376 } 11377 11378 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 11379 boolean allowCancel) { 11380 boolean canceled = false; 11381 11382 final long now = SystemClock.uptimeMillis(); 11383 long minDuration = SERVICE_RESTART_DURATION; 11384 long resetTime = SERVICE_RESET_RUN_DURATION; 11385 11386 if ((r.serviceInfo.applicationInfo.flags 11387 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11388 minDuration /= 4; 11389 } 11390 11391 // Any delivered but not yet finished starts should be put back 11392 // on the pending list. 11393 final int N = r.deliveredStarts.size(); 11394 if (N > 0) { 11395 for (int i=N-1; i>=0; i--) { 11396 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 11397 si.removeUriPermissionsLocked(); 11398 if (si.intent == null) { 11399 // We'll generate this again if needed. 11400 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 11401 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 11402 r.pendingStarts.add(0, si); 11403 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 11404 dur *= 2; 11405 if (minDuration < dur) minDuration = dur; 11406 if (resetTime < dur) resetTime = dur; 11407 } else { 11408 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 11409 + r.name); 11410 canceled = true; 11411 } 11412 } 11413 r.deliveredStarts.clear(); 11414 } 11415 11416 r.totalRestartCount++; 11417 if (r.restartDelay == 0) { 11418 r.restartCount++; 11419 r.restartDelay = minDuration; 11420 } else { 11421 // If it has been a "reasonably long time" since the service 11422 // was started, then reset our restart duration back to 11423 // the beginning, so we don't infinitely increase the duration 11424 // on a service that just occasionally gets killed (which is 11425 // a normal case, due to process being killed to reclaim memory). 11426 if (now > (r.restartTime+resetTime)) { 11427 r.restartCount = 1; 11428 r.restartDelay = minDuration; 11429 } else { 11430 if ((r.serviceInfo.applicationInfo.flags 11431 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11432 // Services in peristent processes will restart much more 11433 // quickly, since they are pretty important. (Think SystemUI). 11434 r.restartDelay += minDuration/2; 11435 } else { 11436 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 11437 if (r.restartDelay < minDuration) { 11438 r.restartDelay = minDuration; 11439 } 11440 } 11441 } 11442 } 11443 11444 r.nextRestartTime = now + r.restartDelay; 11445 11446 // Make sure that we don't end up restarting a bunch of services 11447 // all at the same time. 11448 boolean repeat; 11449 do { 11450 repeat = false; 11451 for (int i=mRestartingServices.size()-1; i>=0; i--) { 11452 ServiceRecord r2 = mRestartingServices.get(i); 11453 if (r2 != r && r.nextRestartTime 11454 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 11455 && r.nextRestartTime 11456 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 11457 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 11458 r.restartDelay = r.nextRestartTime - now; 11459 repeat = true; 11460 break; 11461 } 11462 } 11463 } while (repeat); 11464 11465 if (!mRestartingServices.contains(r)) { 11466 mRestartingServices.add(r); 11467 } 11468 11469 r.cancelNotification(); 11470 11471 mHandler.removeCallbacks(r.restarter); 11472 mHandler.postAtTime(r.restarter, r.nextRestartTime); 11473 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 11474 Slog.w(TAG, "Scheduling restart of crashed service " 11475 + r.shortName + " in " + r.restartDelay + "ms"); 11476 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 11477 r.shortName, r.restartDelay); 11478 11479 return canceled; 11480 } 11481 11482 final void performServiceRestartLocked(ServiceRecord r) { 11483 if (!mRestartingServices.contains(r)) { 11484 return; 11485 } 11486 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 11487 } 11488 11489 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 11490 if (r.restartDelay == 0) { 11491 return false; 11492 } 11493 r.resetRestartCounter(); 11494 mRestartingServices.remove(r); 11495 mHandler.removeCallbacks(r.restarter); 11496 return true; 11497 } 11498 11499 private final boolean bringUpServiceLocked(ServiceRecord r, 11500 int intentFlags, boolean whileRestarting) { 11501 //Slog.i(TAG, "Bring up service:"); 11502 //r.dump(" "); 11503 11504 if (r.app != null && r.app.thread != null) { 11505 sendServiceArgsLocked(r, false); 11506 return true; 11507 } 11508 11509 if (!whileRestarting && r.restartDelay > 0) { 11510 // If waiting for a restart, then do nothing. 11511 return true; 11512 } 11513 11514 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 11515 11516 // We are now bringing the service up, so no longer in the 11517 // restarting state. 11518 mRestartingServices.remove(r); 11519 11520 // Service is now being launched, its package can't be stopped. 11521 try { 11522 AppGlobals.getPackageManager().setPackageStoppedState( 11523 r.packageName, false, r.userId); 11524 } catch (RemoteException e) { 11525 } catch (IllegalArgumentException e) { 11526 Slog.w(TAG, "Failed trying to unstop package " 11527 + r.packageName + ": " + e); 11528 } 11529 11530 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; 11531 final String appName = r.processName; 11532 ProcessRecord app; 11533 11534 if (!isolated) { 11535 app = getProcessRecordLocked(appName, r.appInfo.uid); 11536 if (DEBUG_MU) 11537 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); 11538 if (app != null && app.thread != null) { 11539 try { 11540 app.addPackage(r.appInfo.packageName); 11541 realStartServiceLocked(r, app); 11542 return true; 11543 } catch (RemoteException e) { 11544 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 11545 } 11546 11547 // If a dead object exception was thrown -- fall through to 11548 // restart the application. 11549 } 11550 } else { 11551 // If this service runs in an isolated process, then each time 11552 // we call startProcessLocked() we will get a new isolated 11553 // process, starting another process if we are currently waiting 11554 // for a previous process to come up. To deal with this, we store 11555 // in the service any current isolated process it is running in or 11556 // waiting to have come up. 11557 app = r.isolatedProc; 11558 } 11559 11560 // Not running -- get it started, and enqueue this service record 11561 // to be executed when the app comes up. 11562 if (app == null) { 11563 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags, 11564 "service", r.name, false, isolated)) == null) { 11565 Slog.w(TAG, "Unable to launch app " 11566 + r.appInfo.packageName + "/" 11567 + r.appInfo.uid + " for service " 11568 + r.intent.getIntent() + ": process is bad"); 11569 bringDownServiceLocked(r, true); 11570 return false; 11571 } 11572 if (isolated) { 11573 r.isolatedProc = app; 11574 } 11575 } 11576 11577 if (!mPendingServices.contains(r)) { 11578 mPendingServices.add(r); 11579 } 11580 11581 return true; 11582 } 11583 11584 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 11585 //Slog.i(TAG, "Bring down service:"); 11586 //r.dump(" "); 11587 11588 // Does it still need to run? 11589 if (!force && r.startRequested) { 11590 return; 11591 } 11592 if (r.connections.size() > 0) { 11593 if (!force) { 11594 // XXX should probably keep a count of the number of auto-create 11595 // connections directly in the service. 11596 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11597 while (it.hasNext()) { 11598 ArrayList<ConnectionRecord> cr = it.next(); 11599 for (int i=0; i<cr.size(); i++) { 11600 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 11601 return; 11602 } 11603 } 11604 } 11605 } 11606 11607 // Report to all of the connections that the service is no longer 11608 // available. 11609 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11610 while (it.hasNext()) { 11611 ArrayList<ConnectionRecord> c = it.next(); 11612 for (int i=0; i<c.size(); i++) { 11613 ConnectionRecord cr = c.get(i); 11614 // There is still a connection to the service that is 11615 // being brought down. Mark it as dead. 11616 cr.serviceDead = true; 11617 try { 11618 cr.conn.connected(r.name, null); 11619 } catch (Exception e) { 11620 Slog.w(TAG, "Failure disconnecting service " + r.name + 11621 " to connection " + c.get(i).conn.asBinder() + 11622 " (in " + c.get(i).binding.client.processName + ")", e); 11623 } 11624 } 11625 } 11626 } 11627 11628 // Tell the service that it has been unbound. 11629 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 11630 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 11631 while (it.hasNext()) { 11632 IntentBindRecord ibr = it.next(); 11633 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 11634 + ": hasBound=" + ibr.hasBound); 11635 if (r.app != null && r.app.thread != null && ibr.hasBound) { 11636 try { 11637 bumpServiceExecutingLocked(r, "bring down unbind"); 11638 updateOomAdjLocked(r.app); 11639 ibr.hasBound = false; 11640 r.app.thread.scheduleUnbindService(r, 11641 ibr.intent.getIntent()); 11642 } catch (Exception e) { 11643 Slog.w(TAG, "Exception when unbinding service " 11644 + r.shortName, e); 11645 serviceDoneExecutingLocked(r, true); 11646 } 11647 } 11648 } 11649 } 11650 11651 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 11652 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 11653 System.identityHashCode(r), r.shortName, 11654 (r.app != null) ? r.app.pid : -1); 11655 11656 mServiceMap.removeServiceByName(r.name, r.userId); 11657 mServiceMap.removeServiceByIntent(r.intent, r.userId); 11658 r.totalRestartCount = 0; 11659 unscheduleServiceRestartLocked(r); 11660 11661 // Also make sure it is not on the pending list. 11662 int N = mPendingServices.size(); 11663 for (int i=0; i<N; i++) { 11664 if (mPendingServices.get(i) == r) { 11665 mPendingServices.remove(i); 11666 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 11667 i--; 11668 N--; 11669 } 11670 } 11671 11672 r.cancelNotification(); 11673 r.isForeground = false; 11674 r.foregroundId = 0; 11675 r.foregroundNoti = null; 11676 11677 // Clear start entries. 11678 r.clearDeliveredStartsLocked(); 11679 r.pendingStarts.clear(); 11680 11681 if (r.app != null) { 11682 synchronized (r.stats.getBatteryStats()) { 11683 r.stats.stopLaunchedLocked(); 11684 } 11685 r.app.services.remove(r); 11686 if (r.app.thread != null) { 11687 try { 11688 bumpServiceExecutingLocked(r, "stop"); 11689 mStoppingServices.add(r); 11690 updateOomAdjLocked(r.app); 11691 r.app.thread.scheduleStopService(r); 11692 } catch (Exception e) { 11693 Slog.w(TAG, "Exception when stopping service " 11694 + r.shortName, e); 11695 serviceDoneExecutingLocked(r, true); 11696 } 11697 updateServiceForegroundLocked(r.app, false); 11698 } else { 11699 if (DEBUG_SERVICE) Slog.v( 11700 TAG, "Removed service that has no process: " + r); 11701 } 11702 } else { 11703 if (DEBUG_SERVICE) Slog.v( 11704 TAG, "Removed service that is not running: " + r); 11705 } 11706 11707 if (r.bindings.size() > 0) { 11708 r.bindings.clear(); 11709 } 11710 11711 if (r.restarter instanceof ServiceRestarter) { 11712 ((ServiceRestarter)r.restarter).setService(null); 11713 } 11714 } 11715 11716 ComponentName startServiceLocked(IApplicationThread caller, 11717 Intent service, String resolvedType, 11718 int callingPid, int callingUid) { 11719 synchronized(this) { 11720 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11721 + " type=" + resolvedType + " args=" + service.getExtras()); 11722 11723 if (caller != null) { 11724 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11725 if (callerApp == null) { 11726 throw new SecurityException( 11727 "Unable to find app for caller " + caller 11728 + " (pid=" + Binder.getCallingPid() 11729 + ") when starting service " + service); 11730 } 11731 } 11732 11733 ServiceLookupResult res = 11734 retrieveServiceLocked(service, resolvedType, 11735 callingPid, callingUid, UserId.getUserId(callingUid)); 11736 if (res == null) { 11737 return null; 11738 } 11739 if (res.record == null) { 11740 return new ComponentName("!", res.permission != null 11741 ? res.permission : "private to package"); 11742 } 11743 ServiceRecord r = res.record; 11744 NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked( 11745 callingUid, r.packageName, service, service.getFlags(), null); 11746 if (unscheduleServiceRestartLocked(r)) { 11747 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 11748 } 11749 r.startRequested = true; 11750 r.callStart = false; 11751 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11752 service, neededGrants)); 11753 r.lastActivity = SystemClock.uptimeMillis(); 11754 synchronized (r.stats.getBatteryStats()) { 11755 r.stats.startRunningLocked(); 11756 } 11757 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11758 return new ComponentName("!", "Service process is bad"); 11759 } 11760 return r.name; 11761 } 11762 } 11763 11764 public ComponentName startService(IApplicationThread caller, Intent service, 11765 String resolvedType) { 11766 enforceNotIsolatedCaller("startService"); 11767 // Refuse possible leaked file descriptors 11768 if (service != null && service.hasFileDescriptors() == true) { 11769 throw new IllegalArgumentException("File descriptors passed in Intent"); 11770 } 11771 11772 if (DEBUG_SERVICE) 11773 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 11774 synchronized(this) { 11775 final int callingPid = Binder.getCallingPid(); 11776 final int callingUid = Binder.getCallingUid(); 11777 final long origId = Binder.clearCallingIdentity(); 11778 ComponentName res = startServiceLocked(caller, service, 11779 resolvedType, callingPid, callingUid); 11780 Binder.restoreCallingIdentity(origId); 11781 return res; 11782 } 11783 } 11784 11785 ComponentName startServiceInPackage(int uid, 11786 Intent service, String resolvedType) { 11787 synchronized(this) { 11788 if (DEBUG_SERVICE) 11789 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 11790 final long origId = Binder.clearCallingIdentity(); 11791 ComponentName res = startServiceLocked(null, service, 11792 resolvedType, -1, uid); 11793 Binder.restoreCallingIdentity(origId); 11794 return res; 11795 } 11796 } 11797 11798 private void stopServiceLocked(ServiceRecord service) { 11799 synchronized (service.stats.getBatteryStats()) { 11800 service.stats.stopRunningLocked(); 11801 } 11802 service.startRequested = false; 11803 service.callStart = false; 11804 bringDownServiceLocked(service, false); 11805 } 11806 11807 public int stopService(IApplicationThread caller, Intent service, 11808 String resolvedType) { 11809 enforceNotIsolatedCaller("stopService"); 11810 // Refuse possible leaked file descriptors 11811 if (service != null && service.hasFileDescriptors() == true) { 11812 throw new IllegalArgumentException("File descriptors passed in Intent"); 11813 } 11814 11815 synchronized(this) { 11816 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11817 + " type=" + resolvedType); 11818 11819 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11820 if (caller != null && callerApp == null) { 11821 throw new SecurityException( 11822 "Unable to find app for caller " + caller 11823 + " (pid=" + Binder.getCallingPid() 11824 + ") when stopping service " + service); 11825 } 11826 11827 // If this service is active, make sure it is stopped. 11828 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11829 callerApp == null ? UserId.getCallingUserId() : callerApp.userId); 11830 if (r != null) { 11831 if (r.record != null) { 11832 final long origId = Binder.clearCallingIdentity(); 11833 try { 11834 stopServiceLocked(r.record); 11835 } finally { 11836 Binder.restoreCallingIdentity(origId); 11837 } 11838 return 1; 11839 } 11840 return -1; 11841 } 11842 } 11843 11844 return 0; 11845 } 11846 11847 public IBinder peekService(Intent service, String resolvedType) { 11848 enforceNotIsolatedCaller("peekService"); 11849 // Refuse possible leaked file descriptors 11850 if (service != null && service.hasFileDescriptors() == true) { 11851 throw new IllegalArgumentException("File descriptors passed in Intent"); 11852 } 11853 11854 IBinder ret = null; 11855 11856 synchronized(this) { 11857 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11858 UserId.getCallingUserId()); 11859 11860 if (r != null) { 11861 // r.record is null if findServiceLocked() failed the caller permission check 11862 if (r.record == null) { 11863 throw new SecurityException( 11864 "Permission Denial: Accessing service " + r.record.name 11865 + " from pid=" + Binder.getCallingPid() 11866 + ", uid=" + Binder.getCallingUid() 11867 + " requires " + r.permission); 11868 } 11869 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11870 if (ib != null) { 11871 ret = ib.binder; 11872 } 11873 } 11874 } 11875 11876 return ret; 11877 } 11878 11879 public boolean stopServiceToken(ComponentName className, IBinder token, 11880 int startId) { 11881 synchronized(this) { 11882 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11883 + " " + token + " startId=" + startId); 11884 ServiceRecord r = findServiceLocked(className, token); 11885 if (r != null) { 11886 if (startId >= 0) { 11887 // Asked to only stop if done with all work. Note that 11888 // to avoid leaks, we will take this as dropping all 11889 // start items up to and including this one. 11890 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11891 if (si != null) { 11892 while (r.deliveredStarts.size() > 0) { 11893 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 11894 cur.removeUriPermissionsLocked(); 11895 if (cur == si) { 11896 break; 11897 } 11898 } 11899 } 11900 11901 if (r.getLastStartId() != startId) { 11902 return false; 11903 } 11904 11905 if (r.deliveredStarts.size() > 0) { 11906 Slog.w(TAG, "stopServiceToken startId " + startId 11907 + " is last, but have " + r.deliveredStarts.size() 11908 + " remaining args"); 11909 } 11910 } 11911 11912 synchronized (r.stats.getBatteryStats()) { 11913 r.stats.stopRunningLocked(); 11914 r.startRequested = false; 11915 r.callStart = false; 11916 } 11917 final long origId = Binder.clearCallingIdentity(); 11918 bringDownServiceLocked(r, false); 11919 Binder.restoreCallingIdentity(origId); 11920 return true; 11921 } 11922 } 11923 return false; 11924 } 11925 11926 public void setServiceForeground(ComponentName className, IBinder token, 11927 int id, Notification notification, boolean removeNotification) { 11928 final long origId = Binder.clearCallingIdentity(); 11929 try { 11930 synchronized(this) { 11931 ServiceRecord r = findServiceLocked(className, token); 11932 if (r != null) { 11933 if (id != 0) { 11934 if (notification == null) { 11935 throw new IllegalArgumentException("null notification"); 11936 } 11937 if (r.foregroundId != id) { 11938 r.cancelNotification(); 11939 r.foregroundId = id; 11940 } 11941 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11942 r.foregroundNoti = notification; 11943 r.isForeground = true; 11944 r.postNotification(); 11945 if (r.app != null) { 11946 updateServiceForegroundLocked(r.app, true); 11947 } 11948 } else { 11949 if (r.isForeground) { 11950 r.isForeground = false; 11951 if (r.app != null) { 11952 updateLruProcessLocked(r.app, false, true); 11953 updateServiceForegroundLocked(r.app, true); 11954 } 11955 } 11956 if (removeNotification) { 11957 r.cancelNotification(); 11958 r.foregroundId = 0; 11959 r.foregroundNoti = null; 11960 } 11961 } 11962 } 11963 } 11964 } finally { 11965 Binder.restoreCallingIdentity(origId); 11966 } 11967 } 11968 11969 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11970 boolean anyForeground = false; 11971 for (ServiceRecord sr : proc.services) { 11972 if (sr.isForeground) { 11973 anyForeground = true; 11974 break; 11975 } 11976 } 11977 if (anyForeground != proc.foregroundServices) { 11978 proc.foregroundServices = anyForeground; 11979 if (oomAdj) { 11980 updateOomAdjLocked(); 11981 } 11982 } 11983 } 11984 11985 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) { 11986 boolean result = false; 11987 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11988 result = false; 11989 } else if (componentProcessName == aInfo.packageName) { 11990 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11991 } else if ("system".equals(componentProcessName)) { 11992 result = true; 11993 } 11994 if (DEBUG_MU) { 11995 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result); 11996 } 11997 return result; 11998 } 11999 12000 public int bindService(IApplicationThread caller, IBinder token, 12001 Intent service, String resolvedType, 12002 IServiceConnection connection, int flags, int userId) { 12003 enforceNotIsolatedCaller("bindService"); 12004 // Refuse possible leaked file descriptors 12005 if (service != null && service.hasFileDescriptors() == true) { 12006 throw new IllegalArgumentException("File descriptors passed in Intent"); 12007 } 12008 12009 checkValidCaller(Binder.getCallingUid(), userId); 12010 12011 synchronized(this) { 12012 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 12013 + " type=" + resolvedType + " conn=" + connection.asBinder() 12014 + " flags=0x" + Integer.toHexString(flags)); 12015 if (DEBUG_MU) 12016 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid=" 12017 + Binder.getOrigCallingUid()); 12018 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12019 if (callerApp == null) { 12020 throw new SecurityException( 12021 "Unable to find app for caller " + caller 12022 + " (pid=" + Binder.getCallingPid() 12023 + ") when binding service " + service); 12024 } 12025 12026 ActivityRecord activity = null; 12027 if (token != null) { 12028 activity = mMainStack.isInStackLocked(token); 12029 if (activity == null) { 12030 Slog.w(TAG, "Binding with unknown activity: " + token); 12031 return 0; 12032 } 12033 } 12034 12035 int clientLabel = 0; 12036 PendingIntent clientIntent = null; 12037 12038 if (callerApp.info.uid == Process.SYSTEM_UID) { 12039 // Hacky kind of thing -- allow system stuff to tell us 12040 // what they are, so we can report this elsewhere for 12041 // others to know why certain services are running. 12042 try { 12043 clientIntent = (PendingIntent)service.getParcelableExtra( 12044 Intent.EXTRA_CLIENT_INTENT); 12045 } catch (RuntimeException e) { 12046 } 12047 if (clientIntent != null) { 12048 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 12049 if (clientLabel != 0) { 12050 // There are no useful extras in the intent, trash them. 12051 // System code calling with this stuff just needs to know 12052 // this will happen. 12053 service = service.cloneFilter(); 12054 } 12055 } 12056 } 12057 12058 ServiceLookupResult res = 12059 retrieveServiceLocked(service, resolvedType, 12060 Binder.getCallingPid(), Binder.getCallingUid(), userId); 12061 if (res == null) { 12062 return 0; 12063 } 12064 if (res.record == null) { 12065 return -1; 12066 } 12067 if (isSingleton(res.record.processName, res.record.appInfo)) { 12068 userId = 0; 12069 res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(), 12070 Binder.getCallingUid(), 0); 12071 } 12072 ServiceRecord s = res.record; 12073 12074 final long origId = Binder.clearCallingIdentity(); 12075 12076 if (unscheduleServiceRestartLocked(s)) { 12077 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 12078 + s); 12079 } 12080 12081 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 12082 ConnectionRecord c = new ConnectionRecord(b, activity, 12083 connection, flags, clientLabel, clientIntent); 12084 12085 IBinder binder = connection.asBinder(); 12086 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 12087 if (clist == null) { 12088 clist = new ArrayList<ConnectionRecord>(); 12089 s.connections.put(binder, clist); 12090 } 12091 clist.add(c); 12092 b.connections.add(c); 12093 if (activity != null) { 12094 if (activity.connections == null) { 12095 activity.connections = new HashSet<ConnectionRecord>(); 12096 } 12097 activity.connections.add(c); 12098 } 12099 b.client.connections.add(c); 12100 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 12101 b.client.hasAboveClient = true; 12102 } 12103 clist = mServiceConnections.get(binder); 12104 if (clist == null) { 12105 clist = new ArrayList<ConnectionRecord>(); 12106 mServiceConnections.put(binder, clist); 12107 } 12108 clist.add(c); 12109 12110 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 12111 s.lastActivity = SystemClock.uptimeMillis(); 12112 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 12113 return 0; 12114 } 12115 } 12116 12117 if (s.app != null) { 12118 // This could have made the service more important. 12119 updateOomAdjLocked(s.app); 12120 } 12121 12122 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 12123 + ": received=" + b.intent.received 12124 + " apps=" + b.intent.apps.size() 12125 + " doRebind=" + b.intent.doRebind); 12126 12127 if (s.app != null && b.intent.received) { 12128 // Service is already running, so we can immediately 12129 // publish the connection. 12130 try { 12131 c.conn.connected(s.name, b.intent.binder); 12132 } catch (Exception e) { 12133 Slog.w(TAG, "Failure sending service " + s.shortName 12134 + " to connection " + c.conn.asBinder() 12135 + " (in " + c.binding.client.processName + ")", e); 12136 } 12137 12138 // If this is the first app connected back to this binding, 12139 // and the service had previously asked to be told when 12140 // rebound, then do so. 12141 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 12142 requestServiceBindingLocked(s, b.intent, true); 12143 } 12144 } else if (!b.intent.requested) { 12145 requestServiceBindingLocked(s, b.intent, false); 12146 } 12147 12148 Binder.restoreCallingIdentity(origId); 12149 } 12150 12151 return 1; 12152 } 12153 12154 void removeConnectionLocked( 12155 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 12156 IBinder binder = c.conn.asBinder(); 12157 AppBindRecord b = c.binding; 12158 ServiceRecord s = b.service; 12159 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 12160 if (clist != null) { 12161 clist.remove(c); 12162 if (clist.size() == 0) { 12163 s.connections.remove(binder); 12164 } 12165 } 12166 b.connections.remove(c); 12167 if (c.activity != null && c.activity != skipAct) { 12168 if (c.activity.connections != null) { 12169 c.activity.connections.remove(c); 12170 } 12171 } 12172 if (b.client != skipApp) { 12173 b.client.connections.remove(c); 12174 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 12175 b.client.updateHasAboveClientLocked(); 12176 } 12177 } 12178 clist = mServiceConnections.get(binder); 12179 if (clist != null) { 12180 clist.remove(c); 12181 if (clist.size() == 0) { 12182 mServiceConnections.remove(binder); 12183 } 12184 } 12185 12186 if (b.connections.size() == 0) { 12187 b.intent.apps.remove(b.client); 12188 } 12189 12190 if (!c.serviceDead) { 12191 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 12192 + ": shouldUnbind=" + b.intent.hasBound); 12193 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 12194 && b.intent.hasBound) { 12195 try { 12196 bumpServiceExecutingLocked(s, "unbind"); 12197 updateOomAdjLocked(s.app); 12198 b.intent.hasBound = false; 12199 // Assume the client doesn't want to know about a rebind; 12200 // we will deal with that later if it asks for one. 12201 b.intent.doRebind = false; 12202 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 12203 } catch (Exception e) { 12204 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 12205 serviceDoneExecutingLocked(s, true); 12206 } 12207 } 12208 12209 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 12210 bringDownServiceLocked(s, false); 12211 } 12212 } 12213 } 12214 12215 public boolean unbindService(IServiceConnection connection) { 12216 synchronized (this) { 12217 IBinder binder = connection.asBinder(); 12218 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 12219 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 12220 if (clist == null) { 12221 Slog.w(TAG, "Unbind failed: could not find connection for " 12222 + connection.asBinder()); 12223 return false; 12224 } 12225 12226 final long origId = Binder.clearCallingIdentity(); 12227 12228 while (clist.size() > 0) { 12229 ConnectionRecord r = clist.get(0); 12230 removeConnectionLocked(r, null, null); 12231 12232 if (r.binding.service.app != null) { 12233 // This could have made the service less important. 12234 updateOomAdjLocked(r.binding.service.app); 12235 } 12236 } 12237 12238 Binder.restoreCallingIdentity(origId); 12239 } 12240 12241 return true; 12242 } 12243 12244 public void publishService(IBinder token, Intent intent, IBinder service) { 12245 // Refuse possible leaked file descriptors 12246 if (intent != null && intent.hasFileDescriptors() == true) { 12247 throw new IllegalArgumentException("File descriptors passed in Intent"); 12248 } 12249 12250 synchronized(this) { 12251 if (!(token instanceof ServiceRecord)) { 12252 throw new IllegalArgumentException("Invalid service token"); 12253 } 12254 ServiceRecord r = (ServiceRecord)token; 12255 12256 final long origId = Binder.clearCallingIdentity(); 12257 12258 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 12259 + " " + intent + ": " + service); 12260 if (r != null) { 12261 Intent.FilterComparison filter 12262 = new Intent.FilterComparison(intent); 12263 IntentBindRecord b = r.bindings.get(filter); 12264 if (b != null && !b.received) { 12265 b.binder = service; 12266 b.requested = true; 12267 b.received = true; 12268 if (r.connections.size() > 0) { 12269 Iterator<ArrayList<ConnectionRecord>> it 12270 = r.connections.values().iterator(); 12271 while (it.hasNext()) { 12272 ArrayList<ConnectionRecord> clist = it.next(); 12273 for (int i=0; i<clist.size(); i++) { 12274 ConnectionRecord c = clist.get(i); 12275 if (!filter.equals(c.binding.intent.intent)) { 12276 if (DEBUG_SERVICE) Slog.v( 12277 TAG, "Not publishing to: " + c); 12278 if (DEBUG_SERVICE) Slog.v( 12279 TAG, "Bound intent: " + c.binding.intent.intent); 12280 if (DEBUG_SERVICE) Slog.v( 12281 TAG, "Published intent: " + intent); 12282 continue; 12283 } 12284 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 12285 try { 12286 c.conn.connected(r.name, service); 12287 } catch (Exception e) { 12288 Slog.w(TAG, "Failure sending service " + r.name + 12289 " to connection " + c.conn.asBinder() + 12290 " (in " + c.binding.client.processName + ")", e); 12291 } 12292 } 12293 } 12294 } 12295 } 12296 12297 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 12298 12299 Binder.restoreCallingIdentity(origId); 12300 } 12301 } 12302 } 12303 12304 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12305 // Refuse possible leaked file descriptors 12306 if (intent != null && intent.hasFileDescriptors() == true) { 12307 throw new IllegalArgumentException("File descriptors passed in Intent"); 12308 } 12309 12310 synchronized(this) { 12311 if (!(token instanceof ServiceRecord)) { 12312 throw new IllegalArgumentException("Invalid service token"); 12313 } 12314 ServiceRecord r = (ServiceRecord)token; 12315 12316 final long origId = Binder.clearCallingIdentity(); 12317 12318 if (r != null) { 12319 Intent.FilterComparison filter 12320 = new Intent.FilterComparison(intent); 12321 IntentBindRecord b = r.bindings.get(filter); 12322 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 12323 + " at " + b + ": apps=" 12324 + (b != null ? b.apps.size() : 0)); 12325 12326 boolean inStopping = mStoppingServices.contains(r); 12327 if (b != null) { 12328 if (b.apps.size() > 0 && !inStopping) { 12329 // Applications have already bound since the last 12330 // unbind, so just rebind right here. 12331 requestServiceBindingLocked(r, b, true); 12332 } else { 12333 // Note to tell the service the next time there is 12334 // a new client. 12335 b.doRebind = true; 12336 } 12337 } 12338 12339 serviceDoneExecutingLocked(r, inStopping); 12340 12341 Binder.restoreCallingIdentity(origId); 12342 } 12343 } 12344 } 12345 12346 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12347 synchronized(this) { 12348 if (!(token instanceof ServiceRecord)) { 12349 throw new IllegalArgumentException("Invalid service token"); 12350 } 12351 ServiceRecord r = (ServiceRecord)token; 12352 boolean inStopping = mStoppingServices.contains(token); 12353 if (r != null) { 12354 if (r != token) { 12355 Slog.w(TAG, "Done executing service " + r.name 12356 + " with incorrect token: given " + token 12357 + ", expected " + r); 12358 return; 12359 } 12360 12361 if (type == 1) { 12362 // This is a call from a service start... take care of 12363 // book-keeping. 12364 r.callStart = true; 12365 switch (res) { 12366 case Service.START_STICKY_COMPATIBILITY: 12367 case Service.START_STICKY: { 12368 // We are done with the associated start arguments. 12369 r.findDeliveredStart(startId, true); 12370 // Don't stop if killed. 12371 r.stopIfKilled = false; 12372 break; 12373 } 12374 case Service.START_NOT_STICKY: { 12375 // We are done with the associated start arguments. 12376 r.findDeliveredStart(startId, true); 12377 if (r.getLastStartId() == startId) { 12378 // There is no more work, and this service 12379 // doesn't want to hang around if killed. 12380 r.stopIfKilled = true; 12381 } 12382 break; 12383 } 12384 case Service.START_REDELIVER_INTENT: { 12385 // We'll keep this item until they explicitly 12386 // call stop for it, but keep track of the fact 12387 // that it was delivered. 12388 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 12389 if (si != null) { 12390 si.deliveryCount = 0; 12391 si.doneExecutingCount++; 12392 // Don't stop if killed. 12393 r.stopIfKilled = true; 12394 } 12395 break; 12396 } 12397 case Service.START_TASK_REMOVED_COMPLETE: { 12398 // Special processing for onTaskRemoved(). Don't 12399 // impact normal onStartCommand() processing. 12400 r.findDeliveredStart(startId, true); 12401 break; 12402 } 12403 default: 12404 throw new IllegalArgumentException( 12405 "Unknown service start result: " + res); 12406 } 12407 if (res == Service.START_STICKY_COMPATIBILITY) { 12408 r.callStart = false; 12409 } 12410 } 12411 if (DEBUG_MU) 12412 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid=" 12413 + Binder.getOrigCallingUid()); 12414 final long origId = Binder.clearCallingIdentity(); 12415 serviceDoneExecutingLocked(r, inStopping); 12416 Binder.restoreCallingIdentity(origId); 12417 } else { 12418 Slog.w(TAG, "Done executing unknown service from pid " 12419 + Binder.getCallingPid()); 12420 } 12421 } 12422 } 12423 12424 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 12425 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 12426 + ": nesting=" + r.executeNesting 12427 + ", inStopping=" + inStopping + ", app=" + r.app); 12428 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 12429 r.executeNesting--; 12430 if (r.executeNesting <= 0 && r.app != null) { 12431 if (DEBUG_SERVICE) Slog.v(TAG, 12432 "Nesting at 0 of " + r.shortName); 12433 r.app.executingServices.remove(r); 12434 if (r.app.executingServices.size() == 0) { 12435 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 12436 "No more executingServices of " + r.shortName); 12437 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 12438 } 12439 if (inStopping) { 12440 if (DEBUG_SERVICE) Slog.v(TAG, 12441 "doneExecuting remove stopping " + r); 12442 mStoppingServices.remove(r); 12443 r.bindings.clear(); 12444 } 12445 updateOomAdjLocked(r.app); 12446 } 12447 } 12448 12449 void serviceTimeout(ProcessRecord proc) { 12450 String anrMessage = null; 12451 12452 synchronized(this) { 12453 if (proc.executingServices.size() == 0 || proc.thread == null) { 12454 return; 12455 } 12456 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 12457 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 12458 ServiceRecord timeout = null; 12459 long nextTime = 0; 12460 while (it.hasNext()) { 12461 ServiceRecord sr = it.next(); 12462 if (sr.executingStart < maxTime) { 12463 timeout = sr; 12464 break; 12465 } 12466 if (sr.executingStart > nextTime) { 12467 nextTime = sr.executingStart; 12468 } 12469 } 12470 if (timeout != null && mLruProcesses.contains(proc)) { 12471 Slog.w(TAG, "Timeout executing service: " + timeout); 12472 anrMessage = "Executing service " + timeout.shortName; 12473 } else { 12474 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 12475 msg.obj = proc; 12476 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 12477 } 12478 } 12479 12480 if (anrMessage != null) { 12481 appNotResponding(proc, null, null, anrMessage); 12482 } 12483 } 12484 12485 // ========================================================= 12486 // BACKUP AND RESTORE 12487 // ========================================================= 12488 12489 // Cause the target app to be launched if necessary and its backup agent 12490 // instantiated. The backup agent will invoke backupAgentCreated() on the 12491 // activity manager to announce its creation. 12492 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12493 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 12494 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 12495 12496 synchronized(this) { 12497 // !!! TODO: currently no check here that we're already bound 12498 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12499 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12500 synchronized (stats) { 12501 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12502 } 12503 12504 // Backup agent is now in use, its package can't be stopped. 12505 try { 12506 AppGlobals.getPackageManager().setPackageStoppedState( 12507 app.packageName, false, UserId.getUserId(app.uid)); 12508 } catch (RemoteException e) { 12509 } catch (IllegalArgumentException e) { 12510 Slog.w(TAG, "Failed trying to unstop package " 12511 + app.packageName + ": " + e); 12512 } 12513 12514 BackupRecord r = new BackupRecord(ss, app, backupMode); 12515 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12516 ? new ComponentName(app.packageName, app.backupAgentName) 12517 : new ComponentName("android", "FullBackupAgent"); 12518 // startProcessLocked() returns existing proc's record if it's already running 12519 ProcessRecord proc = startProcessLocked(app.processName, app, 12520 false, 0, "backup", hostingName, false, false); 12521 if (proc == null) { 12522 Slog.e(TAG, "Unable to start backup agent process " + r); 12523 return false; 12524 } 12525 12526 r.app = proc; 12527 mBackupTarget = r; 12528 mBackupAppName = app.packageName; 12529 12530 // Try not to kill the process during backup 12531 updateOomAdjLocked(proc); 12532 12533 // If the process is already attached, schedule the creation of the backup agent now. 12534 // If it is not yet live, this will be done when it attaches to the framework. 12535 if (proc.thread != null) { 12536 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12537 try { 12538 proc.thread.scheduleCreateBackupAgent(app, 12539 compatibilityInfoForPackageLocked(app), backupMode); 12540 } catch (RemoteException e) { 12541 // Will time out on the backup manager side 12542 } 12543 } else { 12544 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12545 } 12546 // Invariants: at this point, the target app process exists and the application 12547 // is either already running or in the process of coming up. mBackupTarget and 12548 // mBackupAppName describe the app, so that when it binds back to the AM we 12549 // know that it's scheduled for a backup-agent operation. 12550 } 12551 12552 return true; 12553 } 12554 12555 // A backup agent has just come up 12556 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12557 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12558 + " = " + agent); 12559 12560 synchronized(this) { 12561 if (!agentPackageName.equals(mBackupAppName)) { 12562 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12563 return; 12564 } 12565 } 12566 12567 long oldIdent = Binder.clearCallingIdentity(); 12568 try { 12569 IBackupManager bm = IBackupManager.Stub.asInterface( 12570 ServiceManager.getService(Context.BACKUP_SERVICE)); 12571 bm.agentConnected(agentPackageName, agent); 12572 } catch (RemoteException e) { 12573 // can't happen; the backup manager service is local 12574 } catch (Exception e) { 12575 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12576 e.printStackTrace(); 12577 } finally { 12578 Binder.restoreCallingIdentity(oldIdent); 12579 } 12580 } 12581 12582 // done with this agent 12583 public void unbindBackupAgent(ApplicationInfo appInfo) { 12584 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12585 if (appInfo == null) { 12586 Slog.w(TAG, "unbind backup agent for null app"); 12587 return; 12588 } 12589 12590 synchronized(this) { 12591 if (mBackupAppName == null) { 12592 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12593 return; 12594 } 12595 12596 if (!mBackupAppName.equals(appInfo.packageName)) { 12597 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12598 return; 12599 } 12600 12601 ProcessRecord proc = mBackupTarget.app; 12602 mBackupTarget = null; 12603 mBackupAppName = null; 12604 12605 // Not backing this app up any more; reset its OOM adjustment 12606 updateOomAdjLocked(proc); 12607 12608 // If the app crashed during backup, 'thread' will be null here 12609 if (proc.thread != null) { 12610 try { 12611 proc.thread.scheduleDestroyBackupAgent(appInfo, 12612 compatibilityInfoForPackageLocked(appInfo)); 12613 } catch (Exception e) { 12614 Slog.e(TAG, "Exception when unbinding backup agent:"); 12615 e.printStackTrace(); 12616 } 12617 } 12618 } 12619 } 12620 // ========================================================= 12621 // BROADCASTS 12622 // ========================================================= 12623 12624 private final List getStickiesLocked(String action, IntentFilter filter, 12625 List cur) { 12626 final ContentResolver resolver = mContext.getContentResolver(); 12627 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 12628 if (list == null) { 12629 return cur; 12630 } 12631 int N = list.size(); 12632 for (int i=0; i<N; i++) { 12633 Intent intent = list.get(i); 12634 if (filter.match(resolver, intent, true, TAG) >= 0) { 12635 if (cur == null) { 12636 cur = new ArrayList<Intent>(); 12637 } 12638 cur.add(intent); 12639 } 12640 } 12641 return cur; 12642 } 12643 12644 boolean isPendingBroadcastProcessLocked(int pid) { 12645 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12646 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12647 } 12648 12649 void skipPendingBroadcastLocked(int pid) { 12650 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12651 for (BroadcastQueue queue : mBroadcastQueues) { 12652 queue.skipPendingBroadcastLocked(pid); 12653 } 12654 } 12655 12656 // The app just attached; send any pending broadcasts that it should receive 12657 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12658 boolean didSomething = false; 12659 for (BroadcastQueue queue : mBroadcastQueues) { 12660 didSomething |= queue.sendPendingBroadcastsLocked(app); 12661 } 12662 return didSomething; 12663 } 12664 12665 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12666 IIntentReceiver receiver, IntentFilter filter, String permission) { 12667 enforceNotIsolatedCaller("registerReceiver"); 12668 synchronized(this) { 12669 ProcessRecord callerApp = null; 12670 if (caller != null) { 12671 callerApp = getRecordForAppLocked(caller); 12672 if (callerApp == null) { 12673 throw new SecurityException( 12674 "Unable to find app for caller " + caller 12675 + " (pid=" + Binder.getCallingPid() 12676 + ") when registering receiver " + receiver); 12677 } 12678 if (callerApp.info.uid != Process.SYSTEM_UID && 12679 !callerApp.pkgList.contains(callerPackage)) { 12680 throw new SecurityException("Given caller package " + callerPackage 12681 + " is not running in process " + callerApp); 12682 } 12683 } else { 12684 callerPackage = null; 12685 } 12686 12687 List allSticky = null; 12688 12689 // Look for any matching sticky broadcasts... 12690 Iterator actions = filter.actionsIterator(); 12691 if (actions != null) { 12692 while (actions.hasNext()) { 12693 String action = (String)actions.next(); 12694 allSticky = getStickiesLocked(action, filter, allSticky); 12695 } 12696 } else { 12697 allSticky = getStickiesLocked(null, filter, allSticky); 12698 } 12699 12700 // The first sticky in the list is returned directly back to 12701 // the client. 12702 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12703 12704 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12705 + ": " + sticky); 12706 12707 if (receiver == null) { 12708 return sticky; 12709 } 12710 12711 ReceiverList rl 12712 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12713 if (rl == null) { 12714 rl = new ReceiverList(this, callerApp, 12715 Binder.getCallingPid(), 12716 Binder.getCallingUid(), receiver); 12717 if (rl.app != null) { 12718 rl.app.receivers.add(rl); 12719 } else { 12720 try { 12721 receiver.asBinder().linkToDeath(rl, 0); 12722 } catch (RemoteException e) { 12723 return sticky; 12724 } 12725 rl.linkedToDeath = true; 12726 } 12727 mRegisteredReceivers.put(receiver.asBinder(), rl); 12728 } 12729 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 12730 rl.add(bf); 12731 if (!bf.debugCheck()) { 12732 Slog.w(TAG, "==> For Dynamic broadast"); 12733 } 12734 mReceiverResolver.addFilter(bf); 12735 12736 // Enqueue broadcasts for all existing stickies that match 12737 // this filter. 12738 if (allSticky != null) { 12739 ArrayList receivers = new ArrayList(); 12740 receivers.add(bf); 12741 12742 int N = allSticky.size(); 12743 for (int i=0; i<N; i++) { 12744 Intent intent = (Intent)allSticky.get(i); 12745 BroadcastQueue queue = broadcastQueueForIntent(intent); 12746 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12747 null, -1, -1, null, receivers, null, 0, null, null, 12748 false, true, true); 12749 queue.enqueueParallelBroadcastLocked(r); 12750 queue.scheduleBroadcastsLocked(); 12751 } 12752 } 12753 12754 return sticky; 12755 } 12756 } 12757 12758 public void unregisterReceiver(IIntentReceiver receiver) { 12759 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12760 12761 final long origId = Binder.clearCallingIdentity(); 12762 try { 12763 boolean doTrim = false; 12764 12765 synchronized(this) { 12766 ReceiverList rl 12767 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12768 if (rl != null) { 12769 if (rl.curBroadcast != null) { 12770 BroadcastRecord r = rl.curBroadcast; 12771 final boolean doNext = finishReceiverLocked( 12772 receiver.asBinder(), r.resultCode, r.resultData, 12773 r.resultExtras, r.resultAbort, true); 12774 if (doNext) { 12775 doTrim = true; 12776 r.queue.processNextBroadcast(false); 12777 } 12778 } 12779 12780 if (rl.app != null) { 12781 rl.app.receivers.remove(rl); 12782 } 12783 removeReceiverLocked(rl); 12784 if (rl.linkedToDeath) { 12785 rl.linkedToDeath = false; 12786 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12787 } 12788 } 12789 } 12790 12791 // If we actually concluded any broadcasts, we might now be able 12792 // to trim the recipients' apps from our working set 12793 if (doTrim) { 12794 trimApplications(); 12795 return; 12796 } 12797 12798 } finally { 12799 Binder.restoreCallingIdentity(origId); 12800 } 12801 } 12802 12803 void removeReceiverLocked(ReceiverList rl) { 12804 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12805 int N = rl.size(); 12806 for (int i=0; i<N; i++) { 12807 mReceiverResolver.removeFilter(rl.get(i)); 12808 } 12809 } 12810 12811 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12812 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12813 ProcessRecord r = mLruProcesses.get(i); 12814 if (r.thread != null) { 12815 try { 12816 r.thread.dispatchPackageBroadcast(cmd, packages); 12817 } catch (RemoteException ex) { 12818 } 12819 } 12820 } 12821 } 12822 12823 private final int broadcastIntentLocked(ProcessRecord callerApp, 12824 String callerPackage, Intent intent, String resolvedType, 12825 IIntentReceiver resultTo, int resultCode, String resultData, 12826 Bundle map, String requiredPermission, 12827 boolean ordered, boolean sticky, int callingPid, int callingUid, 12828 int userId) { 12829 intent = new Intent(intent); 12830 12831 // By default broadcasts do not go to stopped apps. 12832 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 12833 12834 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12835 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12836 + " ordered=" + ordered + " userid=" + userId); 12837 if ((resultTo != null) && !ordered) { 12838 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12839 } 12840 12841 // Handle special intents: if this broadcast is from the package 12842 // manager about a package being removed, we need to remove all of 12843 // its activities from the history stack. 12844 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 12845 intent.getAction()); 12846 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12847 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12848 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12849 || uidRemoved) { 12850 if (checkComponentPermission( 12851 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12852 callingPid, callingUid, -1, true) 12853 == PackageManager.PERMISSION_GRANTED) { 12854 if (uidRemoved) { 12855 final Bundle intentExtras = intent.getExtras(); 12856 final int uid = intentExtras != null 12857 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12858 if (uid >= 0) { 12859 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12860 synchronized (bs) { 12861 bs.removeUidStatsLocked(uid); 12862 } 12863 } 12864 } else { 12865 // If resources are unvailble just force stop all 12866 // those packages and flush the attribute cache as well. 12867 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12868 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12869 if (list != null && (list.length > 0)) { 12870 for (String pkg : list) { 12871 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 12872 } 12873 sendPackageBroadcastLocked( 12874 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12875 } 12876 } else { 12877 Uri data = intent.getData(); 12878 String ssp; 12879 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12880 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12881 forceStopPackageLocked(ssp, 12882 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 12883 false, userId); 12884 } 12885 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12886 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12887 new String[] {ssp}); 12888 } 12889 } 12890 } 12891 } 12892 } else { 12893 String msg = "Permission Denial: " + intent.getAction() 12894 + " broadcast from " + callerPackage + " (pid=" + callingPid 12895 + ", uid=" + callingUid + ")" 12896 + " requires " 12897 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12898 Slog.w(TAG, msg); 12899 throw new SecurityException(msg); 12900 } 12901 12902 // Special case for adding a package: by default turn on compatibility 12903 // mode. 12904 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12905 Uri data = intent.getData(); 12906 String ssp; 12907 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12908 mCompatModePackages.handlePackageAddedLocked(ssp, 12909 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12910 } 12911 } 12912 12913 /* 12914 * If this is the time zone changed action, queue up a message that will reset the timezone 12915 * of all currently running processes. This message will get queued up before the broadcast 12916 * happens. 12917 */ 12918 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12919 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12920 } 12921 12922 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12923 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12924 } 12925 12926 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12927 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12928 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12929 } 12930 12931 /* 12932 * Prevent non-system code (defined here to be non-persistent 12933 * processes) from sending protected broadcasts. 12934 */ 12935 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12936 || callingUid == Process.SHELL_UID || callingUid == 0) { 12937 // Always okay. 12938 } else if (callerApp == null || !callerApp.persistent) { 12939 try { 12940 if (AppGlobals.getPackageManager().isProtectedBroadcast( 12941 intent.getAction())) { 12942 String msg = "Permission Denial: not allowed to send broadcast " 12943 + intent.getAction() + " from pid=" 12944 + callingPid + ", uid=" + callingUid; 12945 Slog.w(TAG, msg); 12946 throw new SecurityException(msg); 12947 } 12948 } catch (RemoteException e) { 12949 Slog.w(TAG, "Remote exception", e); 12950 return ActivityManager.BROADCAST_SUCCESS; 12951 } 12952 } 12953 12954 // Add to the sticky list if requested. 12955 if (sticky) { 12956 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12957 callingPid, callingUid) 12958 != PackageManager.PERMISSION_GRANTED) { 12959 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12960 + callingPid + ", uid=" + callingUid 12961 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12962 Slog.w(TAG, msg); 12963 throw new SecurityException(msg); 12964 } 12965 if (requiredPermission != null) { 12966 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12967 + " and enforce permission " + requiredPermission); 12968 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12969 } 12970 if (intent.getComponent() != null) { 12971 throw new SecurityException( 12972 "Sticky broadcasts can't target a specific component"); 12973 } 12974 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12975 if (list == null) { 12976 list = new ArrayList<Intent>(); 12977 mStickyBroadcasts.put(intent.getAction(), list); 12978 } 12979 int N = list.size(); 12980 int i; 12981 for (i=0; i<N; i++) { 12982 if (intent.filterEquals(list.get(i))) { 12983 // This sticky already exists, replace it. 12984 list.set(i, new Intent(intent)); 12985 break; 12986 } 12987 } 12988 if (i >= N) { 12989 list.add(new Intent(intent)); 12990 } 12991 } 12992 12993 // Figure out who all will receive this broadcast. 12994 List receivers = null; 12995 List<BroadcastFilter> registeredReceivers = null; 12996 try { 12997 if (intent.getComponent() != null) { 12998 // Broadcast is going to one specific receiver class... 12999 ActivityInfo ai = AppGlobals.getPackageManager(). 13000 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId); 13001 if (ai != null) { 13002 receivers = new ArrayList(); 13003 ResolveInfo ri = new ResolveInfo(); 13004 if (isSingleton(ai.processName, ai.applicationInfo)) { 13005 ri.activityInfo = getActivityInfoForUser(ai, 0); 13006 } else { 13007 ri.activityInfo = getActivityInfoForUser(ai, userId); 13008 } 13009 receivers.add(ri); 13010 } 13011 } else { 13012 // Need to resolve the intent to interested receivers... 13013 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13014 == 0) { 13015 receivers = 13016 AppGlobals.getPackageManager().queryIntentReceivers( 13017 intent, resolvedType, STOCK_PM_FLAGS, userId); 13018 } 13019 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, 13020 userId); 13021 } 13022 } catch (RemoteException ex) { 13023 // pm is in same process, this will never happen. 13024 } 13025 13026 final boolean replacePending = 13027 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13028 13029 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13030 + " replacePending=" + replacePending); 13031 13032 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13033 if (!ordered && NR > 0) { 13034 // If we are not serializing this broadcast, then send the 13035 // registered receivers separately so they don't wait for the 13036 // components to be launched. 13037 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13038 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13039 callerPackage, callingPid, callingUid, requiredPermission, 13040 registeredReceivers, resultTo, resultCode, resultData, map, 13041 ordered, sticky, false); 13042 if (DEBUG_BROADCAST) Slog.v( 13043 TAG, "Enqueueing parallel broadcast " + r); 13044 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13045 if (!replaced) { 13046 queue.enqueueParallelBroadcastLocked(r); 13047 queue.scheduleBroadcastsLocked(); 13048 } 13049 registeredReceivers = null; 13050 NR = 0; 13051 } 13052 13053 // Merge into one list. 13054 int ir = 0; 13055 if (receivers != null) { 13056 // A special case for PACKAGE_ADDED: do not allow the package 13057 // being added to see this broadcast. This prevents them from 13058 // using this as a back door to get run as soon as they are 13059 // installed. Maybe in the future we want to have a special install 13060 // broadcast or such for apps, but we'd like to deliberately make 13061 // this decision. 13062 String skipPackages[] = null; 13063 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13064 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13065 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13066 Uri data = intent.getData(); 13067 if (data != null) { 13068 String pkgName = data.getSchemeSpecificPart(); 13069 if (pkgName != null) { 13070 skipPackages = new String[] { pkgName }; 13071 } 13072 } 13073 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13074 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13075 } 13076 if (skipPackages != null && (skipPackages.length > 0)) { 13077 for (String skipPackage : skipPackages) { 13078 if (skipPackage != null) { 13079 int NT = receivers.size(); 13080 for (int it=0; it<NT; it++) { 13081 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13082 if (curt.activityInfo.packageName.equals(skipPackage)) { 13083 receivers.remove(it); 13084 it--; 13085 NT--; 13086 } 13087 } 13088 } 13089 } 13090 } 13091 13092 int NT = receivers != null ? receivers.size() : 0; 13093 int it = 0; 13094 ResolveInfo curt = null; 13095 BroadcastFilter curr = null; 13096 while (it < NT && ir < NR) { 13097 if (curt == null) { 13098 curt = (ResolveInfo)receivers.get(it); 13099 } 13100 if (curr == null) { 13101 curr = registeredReceivers.get(ir); 13102 } 13103 if (curr.getPriority() >= curt.priority) { 13104 // Insert this broadcast record into the final list. 13105 receivers.add(it, curr); 13106 ir++; 13107 curr = null; 13108 it++; 13109 NT++; 13110 } else { 13111 // Skip to the next ResolveInfo in the final list. 13112 it++; 13113 curt = null; 13114 } 13115 } 13116 } 13117 while (ir < NR) { 13118 if (receivers == null) { 13119 receivers = new ArrayList(); 13120 } 13121 receivers.add(registeredReceivers.get(ir)); 13122 ir++; 13123 } 13124 13125 if ((receivers != null && receivers.size() > 0) 13126 || resultTo != null) { 13127 BroadcastQueue queue = broadcastQueueForIntent(intent); 13128 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13129 callerPackage, callingPid, callingUid, requiredPermission, 13130 receivers, resultTo, resultCode, resultData, map, ordered, 13131 sticky, false); 13132 if (DEBUG_BROADCAST) Slog.v( 13133 TAG, "Enqueueing ordered broadcast " + r 13134 + ": prev had " + queue.mOrderedBroadcasts.size()); 13135 if (DEBUG_BROADCAST) { 13136 int seq = r.intent.getIntExtra("seq", -1); 13137 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13138 } 13139 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13140 if (!replaced) { 13141 queue.enqueueOrderedBroadcastLocked(r); 13142 queue.scheduleBroadcastsLocked(); 13143 } 13144 } 13145 13146 return ActivityManager.BROADCAST_SUCCESS; 13147 } 13148 13149 final Intent verifyBroadcastLocked(Intent intent) { 13150 // Refuse possible leaked file descriptors 13151 if (intent != null && intent.hasFileDescriptors() == true) { 13152 throw new IllegalArgumentException("File descriptors passed in Intent"); 13153 } 13154 13155 int flags = intent.getFlags(); 13156 13157 if (!mProcessesReady) { 13158 // if the caller really truly claims to know what they're doing, go 13159 // ahead and allow the broadcast without launching any receivers 13160 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13161 intent = new Intent(intent); 13162 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13163 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13164 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13165 + " before boot completion"); 13166 throw new IllegalStateException("Cannot broadcast before boot completed"); 13167 } 13168 } 13169 13170 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13171 throw new IllegalArgumentException( 13172 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13173 } 13174 13175 return intent; 13176 } 13177 13178 public final int broadcastIntent(IApplicationThread caller, 13179 Intent intent, String resolvedType, IIntentReceiver resultTo, 13180 int resultCode, String resultData, Bundle map, 13181 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13182 enforceNotIsolatedCaller("broadcastIntent"); 13183 synchronized(this) { 13184 intent = verifyBroadcastLocked(intent); 13185 13186 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13187 final int callingPid = Binder.getCallingPid(); 13188 final int callingUid = Binder.getCallingUid(); 13189 final long origId = Binder.clearCallingIdentity(); 13190 int res = broadcastIntentLocked(callerApp, 13191 callerApp != null ? callerApp.info.packageName : null, 13192 intent, resolvedType, resultTo, 13193 resultCode, resultData, map, requiredPermission, serialized, sticky, 13194 callingPid, callingUid, userId); 13195 Binder.restoreCallingIdentity(origId); 13196 return res; 13197 } 13198 } 13199 13200 int broadcastIntentInPackage(String packageName, int uid, 13201 Intent intent, String resolvedType, IIntentReceiver resultTo, 13202 int resultCode, String resultData, Bundle map, 13203 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13204 synchronized(this) { 13205 intent = verifyBroadcastLocked(intent); 13206 13207 final long origId = Binder.clearCallingIdentity(); 13208 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13209 resultTo, resultCode, resultData, map, requiredPermission, 13210 serialized, sticky, -1, uid, userId); 13211 Binder.restoreCallingIdentity(origId); 13212 return res; 13213 } 13214 } 13215 13216 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 13217 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13218 // Refuse possible leaked file descriptors 13219 if (intent != null && intent.hasFileDescriptors() == true) { 13220 throw new IllegalArgumentException("File descriptors passed in Intent"); 13221 } 13222 13223 synchronized(this) { 13224 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13225 != PackageManager.PERMISSION_GRANTED) { 13226 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13227 + Binder.getCallingPid() 13228 + ", uid=" + Binder.getCallingUid() 13229 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13230 Slog.w(TAG, msg); 13231 throw new SecurityException(msg); 13232 } 13233 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 13234 if (list != null) { 13235 int N = list.size(); 13236 int i; 13237 for (i=0; i<N; i++) { 13238 if (intent.filterEquals(list.get(i))) { 13239 list.remove(i); 13240 break; 13241 } 13242 } 13243 } 13244 } 13245 } 13246 13247 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13248 String resultData, Bundle resultExtras, boolean resultAbort, 13249 boolean explicit) { 13250 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13251 if (r == null) { 13252 Slog.w(TAG, "finishReceiver called but not found on queue"); 13253 return false; 13254 } 13255 13256 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 13257 explicit); 13258 } 13259 13260 public void finishReceiver(IBinder who, int resultCode, String resultData, 13261 Bundle resultExtras, boolean resultAbort) { 13262 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13263 13264 // Refuse possible leaked file descriptors 13265 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13266 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13267 } 13268 13269 final long origId = Binder.clearCallingIdentity(); 13270 try { 13271 boolean doNext = false; 13272 BroadcastRecord r = null; 13273 13274 synchronized(this) { 13275 r = broadcastRecordForReceiverLocked(who); 13276 if (r != null) { 13277 doNext = r.queue.finishReceiverLocked(r, resultCode, 13278 resultData, resultExtras, resultAbort, true); 13279 } 13280 } 13281 13282 if (doNext) { 13283 r.queue.processNextBroadcast(false); 13284 } 13285 trimApplications(); 13286 } finally { 13287 Binder.restoreCallingIdentity(origId); 13288 } 13289 } 13290 13291 // ========================================================= 13292 // INSTRUMENTATION 13293 // ========================================================= 13294 13295 public boolean startInstrumentation(ComponentName className, 13296 String profileFile, int flags, Bundle arguments, 13297 IInstrumentationWatcher watcher) { 13298 enforceNotIsolatedCaller("startInstrumentation"); 13299 // Refuse possible leaked file descriptors 13300 if (arguments != null && arguments.hasFileDescriptors()) { 13301 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13302 } 13303 13304 synchronized(this) { 13305 InstrumentationInfo ii = null; 13306 ApplicationInfo ai = null; 13307 try { 13308 ii = mContext.getPackageManager().getInstrumentationInfo( 13309 className, STOCK_PM_FLAGS); 13310 ai = mContext.getPackageManager().getApplicationInfo( 13311 ii.targetPackage, STOCK_PM_FLAGS); 13312 } catch (PackageManager.NameNotFoundException e) { 13313 } 13314 if (ii == null) { 13315 reportStartInstrumentationFailure(watcher, className, 13316 "Unable to find instrumentation info for: " + className); 13317 return false; 13318 } 13319 if (ai == null) { 13320 reportStartInstrumentationFailure(watcher, className, 13321 "Unable to find instrumentation target package: " + ii.targetPackage); 13322 return false; 13323 } 13324 13325 int match = mContext.getPackageManager().checkSignatures( 13326 ii.targetPackage, ii.packageName); 13327 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13328 String msg = "Permission Denial: starting instrumentation " 13329 + className + " from pid=" 13330 + Binder.getCallingPid() 13331 + ", uid=" + Binder.getCallingPid() 13332 + " not allowed because package " + ii.packageName 13333 + " does not have a signature matching the target " 13334 + ii.targetPackage; 13335 reportStartInstrumentationFailure(watcher, className, msg); 13336 throw new SecurityException(msg); 13337 } 13338 13339 int userId = UserId.getCallingUserId(); 13340 final long origId = Binder.clearCallingIdentity(); 13341 // Instrumentation can kill and relaunch even persistent processes 13342 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 13343 ProcessRecord app = addAppLocked(ai, false); 13344 app.instrumentationClass = className; 13345 app.instrumentationInfo = ai; 13346 app.instrumentationProfileFile = profileFile; 13347 app.instrumentationArguments = arguments; 13348 app.instrumentationWatcher = watcher; 13349 app.instrumentationResultClass = className; 13350 Binder.restoreCallingIdentity(origId); 13351 } 13352 13353 return true; 13354 } 13355 13356 /** 13357 * Report errors that occur while attempting to start Instrumentation. Always writes the 13358 * error to the logs, but if somebody is watching, send the report there too. This enables 13359 * the "am" command to report errors with more information. 13360 * 13361 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13362 * @param cn The component name of the instrumentation. 13363 * @param report The error report. 13364 */ 13365 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13366 ComponentName cn, String report) { 13367 Slog.w(TAG, report); 13368 try { 13369 if (watcher != null) { 13370 Bundle results = new Bundle(); 13371 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13372 results.putString("Error", report); 13373 watcher.instrumentationStatus(cn, -1, results); 13374 } 13375 } catch (RemoteException e) { 13376 Slog.w(TAG, e); 13377 } 13378 } 13379 13380 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13381 if (app.instrumentationWatcher != null) { 13382 try { 13383 // NOTE: IInstrumentationWatcher *must* be oneway here 13384 app.instrumentationWatcher.instrumentationFinished( 13385 app.instrumentationClass, 13386 resultCode, 13387 results); 13388 } catch (RemoteException e) { 13389 } 13390 } 13391 app.instrumentationWatcher = null; 13392 app.instrumentationClass = null; 13393 app.instrumentationInfo = null; 13394 app.instrumentationProfileFile = null; 13395 app.instrumentationArguments = null; 13396 13397 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 13398 } 13399 13400 public void finishInstrumentation(IApplicationThread target, 13401 int resultCode, Bundle results) { 13402 int userId = UserId.getCallingUserId(); 13403 // Refuse possible leaked file descriptors 13404 if (results != null && results.hasFileDescriptors()) { 13405 throw new IllegalArgumentException("File descriptors passed in Intent"); 13406 } 13407 13408 synchronized(this) { 13409 ProcessRecord app = getRecordForAppLocked(target); 13410 if (app == null) { 13411 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13412 return; 13413 } 13414 final long origId = Binder.clearCallingIdentity(); 13415 finishInstrumentationLocked(app, resultCode, results); 13416 Binder.restoreCallingIdentity(origId); 13417 } 13418 } 13419 13420 // ========================================================= 13421 // CONFIGURATION 13422 // ========================================================= 13423 13424 public ConfigurationInfo getDeviceConfigurationInfo() { 13425 ConfigurationInfo config = new ConfigurationInfo(); 13426 synchronized (this) { 13427 config.reqTouchScreen = mConfiguration.touchscreen; 13428 config.reqKeyboardType = mConfiguration.keyboard; 13429 config.reqNavigation = mConfiguration.navigation; 13430 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13431 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13432 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13433 } 13434 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13435 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13436 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13437 } 13438 config.reqGlEsVersion = GL_ES_VERSION; 13439 } 13440 return config; 13441 } 13442 13443 public Configuration getConfiguration() { 13444 Configuration ci; 13445 synchronized(this) { 13446 ci = new Configuration(mConfiguration); 13447 } 13448 return ci; 13449 } 13450 13451 public void updatePersistentConfiguration(Configuration values) { 13452 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13453 "updateConfiguration()"); 13454 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13455 "updateConfiguration()"); 13456 if (values == null) { 13457 throw new NullPointerException("Configuration must not be null"); 13458 } 13459 13460 synchronized(this) { 13461 final long origId = Binder.clearCallingIdentity(); 13462 updateConfigurationLocked(values, null, true, false); 13463 Binder.restoreCallingIdentity(origId); 13464 } 13465 } 13466 13467 public void updateConfiguration(Configuration values) { 13468 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13469 "updateConfiguration()"); 13470 13471 synchronized(this) { 13472 if (values == null && mWindowManager != null) { 13473 // sentinel: fetch the current configuration from the window manager 13474 values = mWindowManager.computeNewConfiguration(); 13475 } 13476 13477 if (mWindowManager != null) { 13478 mProcessList.applyDisplaySize(mWindowManager); 13479 } 13480 13481 final long origId = Binder.clearCallingIdentity(); 13482 if (values != null) { 13483 Settings.System.clearConfiguration(values); 13484 } 13485 updateConfigurationLocked(values, null, false, false); 13486 Binder.restoreCallingIdentity(origId); 13487 } 13488 } 13489 13490 /** 13491 * Do either or both things: (1) change the current configuration, and (2) 13492 * make sure the given activity is running with the (now) current 13493 * configuration. Returns true if the activity has been left running, or 13494 * false if <var>starting</var> is being destroyed to match the new 13495 * configuration. 13496 * @param persistent TODO 13497 */ 13498 boolean updateConfigurationLocked(Configuration values, 13499 ActivityRecord starting, boolean persistent, boolean initLocale) { 13500 // do nothing if we are headless 13501 if (mHeadless) return true; 13502 13503 int changes = 0; 13504 13505 boolean kept = true; 13506 13507 if (values != null) { 13508 Configuration newConfig = new Configuration(mConfiguration); 13509 changes = newConfig.updateFrom(values); 13510 if (changes != 0) { 13511 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13512 Slog.i(TAG, "Updating configuration to: " + values); 13513 } 13514 13515 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13516 13517 if (values.locale != null && !initLocale) { 13518 saveLocaleLocked(values.locale, 13519 !values.locale.equals(mConfiguration.locale), 13520 values.userSetLocale); 13521 } 13522 13523 mConfigurationSeq++; 13524 if (mConfigurationSeq <= 0) { 13525 mConfigurationSeq = 1; 13526 } 13527 newConfig.seq = mConfigurationSeq; 13528 mConfiguration = newConfig; 13529 Slog.i(TAG, "Config changed: " + newConfig); 13530 13531 final Configuration configCopy = new Configuration(mConfiguration); 13532 13533 // TODO: If our config changes, should we auto dismiss any currently 13534 // showing dialogs? 13535 mShowDialogs = shouldShowDialogs(newConfig); 13536 13537 AttributeCache ac = AttributeCache.instance(); 13538 if (ac != null) { 13539 ac.updateConfiguration(configCopy); 13540 } 13541 13542 // Make sure all resources in our process are updated 13543 // right now, so that anyone who is going to retrieve 13544 // resource values after we return will be sure to get 13545 // the new ones. This is especially important during 13546 // boot, where the first config change needs to guarantee 13547 // all resources have that config before following boot 13548 // code is executed. 13549 mSystemThread.applyConfigurationToResources(configCopy); 13550 13551 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13552 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13553 msg.obj = new Configuration(configCopy); 13554 mHandler.sendMessage(msg); 13555 } 13556 13557 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13558 ProcessRecord app = mLruProcesses.get(i); 13559 try { 13560 if (app.thread != null) { 13561 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13562 + app.processName + " new config " + mConfiguration); 13563 app.thread.scheduleConfigurationChanged(configCopy); 13564 } 13565 } catch (Exception e) { 13566 } 13567 } 13568 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13569 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13570 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13571 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13572 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13573 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13574 broadcastIntentLocked(null, null, 13575 new Intent(Intent.ACTION_LOCALE_CHANGED), 13576 null, null, 0, null, null, 13577 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13578 } 13579 } 13580 } 13581 13582 if (changes != 0 && starting == null) { 13583 // If the configuration changed, and the caller is not already 13584 // in the process of starting an activity, then find the top 13585 // activity to check if its configuration needs to change. 13586 starting = mMainStack.topRunningActivityLocked(null); 13587 } 13588 13589 if (starting != null) { 13590 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 13591 // And we need to make sure at this point that all other activities 13592 // are made visible with the correct configuration. 13593 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 13594 } 13595 13596 if (values != null && mWindowManager != null) { 13597 mWindowManager.setNewConfiguration(mConfiguration); 13598 } 13599 13600 return kept; 13601 } 13602 13603 /** 13604 * Decide based on the configuration whether we should shouw the ANR, 13605 * crash, etc dialogs. The idea is that if there is no affordnace to 13606 * press the on-screen buttons, we shouldn't show the dialog. 13607 * 13608 * A thought: SystemUI might also want to get told about this, the Power 13609 * dialog / global actions also might want different behaviors. 13610 */ 13611 private static final boolean shouldShowDialogs(Configuration config) { 13612 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 13613 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 13614 } 13615 13616 /** 13617 * Save the locale. You must be inside a synchronized (this) block. 13618 */ 13619 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13620 if(isDiff) { 13621 SystemProperties.set("user.language", l.getLanguage()); 13622 SystemProperties.set("user.region", l.getCountry()); 13623 } 13624 13625 if(isPersist) { 13626 SystemProperties.set("persist.sys.language", l.getLanguage()); 13627 SystemProperties.set("persist.sys.country", l.getCountry()); 13628 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13629 } 13630 } 13631 13632 @Override 13633 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 13634 ActivityRecord srec = ActivityRecord.forToken(token); 13635 return srec != null && srec.task.affinity != null && 13636 srec.task.affinity.equals(destAffinity); 13637 } 13638 13639 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 13640 Intent resultData) { 13641 ComponentName dest = destIntent.getComponent(); 13642 13643 synchronized (this) { 13644 ActivityRecord srec = ActivityRecord.forToken(token); 13645 if (srec == null) { 13646 return false; 13647 } 13648 ArrayList<ActivityRecord> history = srec.stack.mHistory; 13649 final int start = history.indexOf(srec); 13650 if (start < 0) { 13651 // Current activity is not in history stack; do nothing. 13652 return false; 13653 } 13654 int finishTo = start - 1; 13655 ActivityRecord parent = null; 13656 boolean foundParentInTask = false; 13657 if (dest != null) { 13658 TaskRecord tr = srec.task; 13659 for (int i = start - 1; i >= 0; i--) { 13660 ActivityRecord r = history.get(i); 13661 if (tr != r.task) { 13662 // Couldn't find parent in the same task; stop at the one above this. 13663 // (Root of current task; in-app "home" behavior) 13664 // Always at least finish the current activity. 13665 finishTo = Math.min(start - 1, i + 1); 13666 parent = history.get(finishTo); 13667 break; 13668 } else if (r.info.packageName.equals(dest.getPackageName()) && 13669 r.info.name.equals(dest.getClassName())) { 13670 finishTo = i; 13671 parent = r; 13672 foundParentInTask = true; 13673 break; 13674 } 13675 } 13676 } 13677 13678 if (mController != null) { 13679 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 13680 if (next != null) { 13681 // ask watcher if this is allowed 13682 boolean resumeOK = true; 13683 try { 13684 resumeOK = mController.activityResuming(next.packageName); 13685 } catch (RemoteException e) { 13686 mController = null; 13687 } 13688 13689 if (!resumeOK) { 13690 return false; 13691 } 13692 } 13693 } 13694 final long origId = Binder.clearCallingIdentity(); 13695 for (int i = start; i > finishTo; i--) { 13696 ActivityRecord r = history.get(i); 13697 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 13698 "navigate-up"); 13699 // Only return the supplied result for the first activity finished 13700 resultCode = Activity.RESULT_CANCELED; 13701 resultData = null; 13702 } 13703 13704 if (parent != null && foundParentInTask) { 13705 final int parentLaunchMode = parent.info.launchMode; 13706 final int destIntentFlags = destIntent.getFlags(); 13707 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 13708 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 13709 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 13710 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 13711 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 13712 } else { 13713 try { 13714 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 13715 destIntent.getComponent(), 0, UserId.getCallingUserId()); 13716 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 13717 null, aInfo, parent.appToken, null, 13718 0, -1, parent.launchedFromUid, 0, null, true, null); 13719 foundParentInTask = res == ActivityManager.START_SUCCESS; 13720 } catch (RemoteException e) { 13721 foundParentInTask = false; 13722 } 13723 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 13724 resultData, "navigate-up"); 13725 } 13726 } 13727 Binder.restoreCallingIdentity(origId); 13728 return foundParentInTask; 13729 } 13730 } 13731 13732 public int getLaunchedFromUid(IBinder activityToken) { 13733 ActivityRecord srec = ActivityRecord.forToken(activityToken); 13734 if (srec == null) { 13735 return -1; 13736 } 13737 return srec.launchedFromUid; 13738 } 13739 13740 // ========================================================= 13741 // LIFETIME MANAGEMENT 13742 // ========================================================= 13743 13744 // Returns which broadcast queue the app is the current [or imminent] receiver 13745 // on, or 'null' if the app is not an active broadcast recipient. 13746 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 13747 BroadcastRecord r = app.curReceiver; 13748 if (r != null) { 13749 return r.queue; 13750 } 13751 13752 // It's not the current receiver, but it might be starting up to become one 13753 synchronized (this) { 13754 for (BroadcastQueue queue : mBroadcastQueues) { 13755 r = queue.mPendingBroadcast; 13756 if (r != null && r.curApp == app) { 13757 // found it; report which queue it's in 13758 return queue; 13759 } 13760 } 13761 } 13762 13763 return null; 13764 } 13765 13766 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13767 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 13768 if (mAdjSeq == app.adjSeq) { 13769 // This adjustment has already been computed. If we are calling 13770 // from the top, we may have already computed our adjustment with 13771 // an earlier hidden adjustment that isn't really for us... if 13772 // so, use the new hidden adjustment. 13773 if (!recursed && app.hidden) { 13774 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 13775 } 13776 return app.curRawAdj; 13777 } 13778 13779 if (app.thread == null) { 13780 app.adjSeq = mAdjSeq; 13781 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13782 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 13783 } 13784 13785 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13786 app.adjSource = null; 13787 app.adjTarget = null; 13788 app.empty = false; 13789 app.hidden = false; 13790 13791 final int activitiesSize = app.activities.size(); 13792 13793 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13794 // The max adjustment doesn't allow this app to be anything 13795 // below foreground, so it is not worth doing work for it. 13796 app.adjType = "fixed"; 13797 app.adjSeq = mAdjSeq; 13798 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 13799 app.foregroundActivities = false; 13800 app.keeping = true; 13801 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13802 // System process can do UI, and when they do we want to have 13803 // them trim their memory after the user leaves the UI. To 13804 // facilitate this, here we need to determine whether or not it 13805 // is currently showing UI. 13806 app.systemNoUi = true; 13807 if (app == TOP_APP) { 13808 app.systemNoUi = false; 13809 } else if (activitiesSize > 0) { 13810 for (int j = 0; j < activitiesSize; j++) { 13811 final ActivityRecord r = app.activities.get(j); 13812 if (r.visible) { 13813 app.systemNoUi = false; 13814 break; 13815 } 13816 } 13817 } 13818 return (app.curAdj=app.maxAdj); 13819 } 13820 13821 app.keeping = false; 13822 app.systemNoUi = false; 13823 13824 // Determine the importance of the process, starting with most 13825 // important to least, and assign an appropriate OOM adjustment. 13826 int adj; 13827 int schedGroup; 13828 boolean foregroundActivities = false; 13829 boolean interesting = false; 13830 BroadcastQueue queue; 13831 if (app == TOP_APP) { 13832 // The last app on the list is the foreground app. 13833 adj = ProcessList.FOREGROUND_APP_ADJ; 13834 schedGroup = Process.THREAD_GROUP_DEFAULT; 13835 app.adjType = "top-activity"; 13836 foregroundActivities = true; 13837 interesting = true; 13838 } else if (app.instrumentationClass != null) { 13839 // Don't want to kill running instrumentation. 13840 adj = ProcessList.FOREGROUND_APP_ADJ; 13841 schedGroup = Process.THREAD_GROUP_DEFAULT; 13842 app.adjType = "instrumentation"; 13843 interesting = true; 13844 } else if ((queue = isReceivingBroadcast(app)) != null) { 13845 // An app that is currently receiving a broadcast also 13846 // counts as being in the foreground for OOM killer purposes. 13847 // It's placed in a sched group based on the nature of the 13848 // broadcast as reflected by which queue it's active in. 13849 adj = ProcessList.FOREGROUND_APP_ADJ; 13850 schedGroup = (queue == mFgBroadcastQueue) 13851 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 13852 app.adjType = "broadcast"; 13853 } else if (app.executingServices.size() > 0) { 13854 // An app that is currently executing a service callback also 13855 // counts as being in the foreground. 13856 adj = ProcessList.FOREGROUND_APP_ADJ; 13857 schedGroup = Process.THREAD_GROUP_DEFAULT; 13858 app.adjType = "exec-service"; 13859 } else if (activitiesSize > 0) { 13860 // This app is in the background with paused activities. 13861 // We inspect activities to potentially upgrade adjustment further below. 13862 adj = hiddenAdj; 13863 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13864 app.hidden = true; 13865 app.adjType = "bg-activities"; 13866 } else { 13867 // A very not-needed process. If this is lower in the lru list, 13868 // we will push it in to the empty bucket. 13869 adj = hiddenAdj; 13870 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13871 app.hidden = true; 13872 app.empty = true; 13873 app.adjType = "bg-empty"; 13874 } 13875 13876 boolean hasStoppingActivities = false; 13877 13878 // Examine all activities if not already foreground. 13879 if (!foregroundActivities && activitiesSize > 0) { 13880 for (int j = 0; j < activitiesSize; j++) { 13881 final ActivityRecord r = app.activities.get(j); 13882 if (r.visible) { 13883 // App has a visible activity; only upgrade adjustment. 13884 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13885 adj = ProcessList.VISIBLE_APP_ADJ; 13886 app.adjType = "visible"; 13887 } 13888 schedGroup = Process.THREAD_GROUP_DEFAULT; 13889 app.hidden = false; 13890 foregroundActivities = true; 13891 break; 13892 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 13893 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13894 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13895 app.adjType = "pausing"; 13896 } 13897 app.hidden = false; 13898 foregroundActivities = true; 13899 } else if (r.state == ActivityState.STOPPING) { 13900 // We will apply the actual adjustment later, because 13901 // we want to allow this process to immediately go through 13902 // any memory trimming that is in effect. 13903 app.hidden = false; 13904 foregroundActivities = true; 13905 hasStoppingActivities = true; 13906 } 13907 } 13908 } 13909 13910 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13911 if (app.foregroundServices) { 13912 // The user is aware of this app, so make it visible. 13913 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13914 app.hidden = false; 13915 app.adjType = "foreground-service"; 13916 schedGroup = Process.THREAD_GROUP_DEFAULT; 13917 } else if (app.forcingToForeground != null) { 13918 // The user is aware of this app, so make it visible. 13919 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13920 app.hidden = false; 13921 app.adjType = "force-foreground"; 13922 app.adjSource = app.forcingToForeground; 13923 schedGroup = Process.THREAD_GROUP_DEFAULT; 13924 } 13925 } 13926 13927 if (app.foregroundServices) { 13928 interesting = true; 13929 } 13930 13931 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13932 // We don't want to kill the current heavy-weight process. 13933 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13934 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13935 app.hidden = false; 13936 app.adjType = "heavy"; 13937 } 13938 13939 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13940 // This process is hosting what we currently consider to be the 13941 // home app, so we don't want to let it go into the background. 13942 adj = ProcessList.HOME_APP_ADJ; 13943 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13944 app.hidden = false; 13945 app.adjType = "home"; 13946 } 13947 13948 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13949 && app.activities.size() > 0) { 13950 // This was the previous process that showed UI to the user. 13951 // We want to try to keep it around more aggressively, to give 13952 // a good experience around switching between two apps. 13953 adj = ProcessList.PREVIOUS_APP_ADJ; 13954 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13955 app.hidden = false; 13956 app.adjType = "previous"; 13957 } 13958 13959 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13960 + " reason=" + app.adjType); 13961 13962 // By default, we use the computed adjustment. It may be changed if 13963 // there are applications dependent on our services or providers, but 13964 // this gives us a baseline and makes sure we don't get into an 13965 // infinite recursion. 13966 app.adjSeq = mAdjSeq; 13967 app.curRawAdj = app.nonStoppingAdj = adj; 13968 13969 if (mBackupTarget != null && app == mBackupTarget.app) { 13970 // If possible we want to avoid killing apps while they're being backed up 13971 if (adj > ProcessList.BACKUP_APP_ADJ) { 13972 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13973 adj = ProcessList.BACKUP_APP_ADJ; 13974 app.adjType = "backup"; 13975 app.hidden = false; 13976 } 13977 } 13978 13979 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13980 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13981 final long now = SystemClock.uptimeMillis(); 13982 // This process is more important if the top activity is 13983 // bound to the service. 13984 Iterator<ServiceRecord> jt = app.services.iterator(); 13985 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13986 ServiceRecord s = jt.next(); 13987 if (s.startRequested) { 13988 if (app.hasShownUi && app != mHomeProcess) { 13989 // If this process has shown some UI, let it immediately 13990 // go to the LRU list because it may be pretty heavy with 13991 // UI stuff. We'll tag it with a label just to help 13992 // debug and understand what is going on. 13993 if (adj > ProcessList.SERVICE_ADJ) { 13994 app.adjType = "started-bg-ui-services"; 13995 } 13996 } else { 13997 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13998 // This service has seen some activity within 13999 // recent memory, so we will keep its process ahead 14000 // of the background processes. 14001 if (adj > ProcessList.SERVICE_ADJ) { 14002 adj = ProcessList.SERVICE_ADJ; 14003 app.adjType = "started-services"; 14004 app.hidden = false; 14005 } 14006 } 14007 // If we have let the service slide into the background 14008 // state, still have some text describing what it is doing 14009 // even though the service no longer has an impact. 14010 if (adj > ProcessList.SERVICE_ADJ) { 14011 app.adjType = "started-bg-services"; 14012 } 14013 } 14014 // Don't kill this process because it is doing work; it 14015 // has said it is doing work. 14016 app.keeping = true; 14017 } 14018 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14019 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14020 Iterator<ArrayList<ConnectionRecord>> kt 14021 = s.connections.values().iterator(); 14022 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 14023 ArrayList<ConnectionRecord> clist = kt.next(); 14024 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 14025 // XXX should compute this based on the max of 14026 // all connected clients. 14027 ConnectionRecord cr = clist.get(i); 14028 if (cr.binding.client == app) { 14029 // Binding to ourself is not interesting. 14030 continue; 14031 } 14032 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14033 ProcessRecord client = cr.binding.client; 14034 int clientAdj = adj; 14035 int myHiddenAdj = hiddenAdj; 14036 if (myHiddenAdj > client.hiddenAdj) { 14037 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 14038 myHiddenAdj = client.hiddenAdj; 14039 } else { 14040 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 14041 } 14042 } 14043 clientAdj = computeOomAdjLocked( 14044 client, myHiddenAdj, TOP_APP, true, doingAll); 14045 String adjType = null; 14046 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14047 // Not doing bind OOM management, so treat 14048 // this guy more like a started service. 14049 if (app.hasShownUi && app != mHomeProcess) { 14050 // If this process has shown some UI, let it immediately 14051 // go to the LRU list because it may be pretty heavy with 14052 // UI stuff. We'll tag it with a label just to help 14053 // debug and understand what is going on. 14054 if (adj > clientAdj) { 14055 adjType = "bound-bg-ui-services"; 14056 } 14057 app.hidden = false; 14058 clientAdj = adj; 14059 } else { 14060 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 14061 // This service has not seen activity within 14062 // recent memory, so allow it to drop to the 14063 // LRU list if there is no other reason to keep 14064 // it around. We'll also tag it with a label just 14065 // to help debug and undertand what is going on. 14066 if (adj > clientAdj) { 14067 adjType = "bound-bg-services"; 14068 } 14069 clientAdj = adj; 14070 } 14071 } 14072 } 14073 if (adj > clientAdj) { 14074 // If this process has recently shown UI, and 14075 // the process that is binding to it is less 14076 // important than being visible, then we don't 14077 // care about the binding as much as we care 14078 // about letting this process get into the LRU 14079 // list to be killed and restarted if needed for 14080 // memory. 14081 if (app.hasShownUi && app != mHomeProcess 14082 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14083 adjType = "bound-bg-ui-services"; 14084 } else { 14085 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14086 |Context.BIND_IMPORTANT)) != 0) { 14087 adj = clientAdj; 14088 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14089 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14090 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14091 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14092 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14093 adj = clientAdj; 14094 } else { 14095 app.pendingUiClean = true; 14096 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14097 adj = ProcessList.VISIBLE_APP_ADJ; 14098 } 14099 } 14100 if (!client.hidden) { 14101 app.hidden = false; 14102 } 14103 if (client.keeping) { 14104 app.keeping = true; 14105 } 14106 adjType = "service"; 14107 } 14108 } 14109 if (adjType != null) { 14110 app.adjType = adjType; 14111 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14112 .REASON_SERVICE_IN_USE; 14113 app.adjSource = cr.binding.client; 14114 app.adjSourceOom = clientAdj; 14115 app.adjTarget = s.name; 14116 } 14117 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14118 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14119 schedGroup = Process.THREAD_GROUP_DEFAULT; 14120 } 14121 } 14122 } 14123 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14124 ActivityRecord a = cr.activity; 14125 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14126 (a.visible || a.state == ActivityState.RESUMED 14127 || a.state == ActivityState.PAUSING)) { 14128 adj = ProcessList.FOREGROUND_APP_ADJ; 14129 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14130 schedGroup = Process.THREAD_GROUP_DEFAULT; 14131 } 14132 app.hidden = false; 14133 app.adjType = "service"; 14134 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14135 .REASON_SERVICE_IN_USE; 14136 app.adjSource = a; 14137 app.adjSourceOom = adj; 14138 app.adjTarget = s.name; 14139 } 14140 } 14141 } 14142 } 14143 } 14144 } 14145 14146 // Finally, if this process has active services running in it, we 14147 // would like to avoid killing it unless it would prevent the current 14148 // application from running. By default we put the process in 14149 // with the rest of the background processes; as we scan through 14150 // its services we may bump it up from there. 14151 if (adj > hiddenAdj) { 14152 adj = hiddenAdj; 14153 app.hidden = false; 14154 app.adjType = "bg-services"; 14155 } 14156 } 14157 14158 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14159 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14160 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 14161 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 14162 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14163 ContentProviderRecord cpr = jt.next(); 14164 for (int i = cpr.connections.size()-1; 14165 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14166 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 14167 i--) { 14168 ContentProviderConnection conn = cpr.connections.get(i); 14169 ProcessRecord client = conn.client; 14170 if (client == app) { 14171 // Being our own client is not interesting. 14172 continue; 14173 } 14174 int myHiddenAdj = hiddenAdj; 14175 if (myHiddenAdj > client.hiddenAdj) { 14176 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 14177 myHiddenAdj = client.hiddenAdj; 14178 } else { 14179 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 14180 } 14181 } 14182 int clientAdj = computeOomAdjLocked( 14183 client, myHiddenAdj, TOP_APP, true, doingAll); 14184 if (adj > clientAdj) { 14185 if (app.hasShownUi && app != mHomeProcess 14186 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14187 app.adjType = "bg-ui-provider"; 14188 } else { 14189 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14190 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14191 app.adjType = "provider"; 14192 } 14193 if (!client.hidden) { 14194 app.hidden = false; 14195 } 14196 if (client.keeping) { 14197 app.keeping = true; 14198 } 14199 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14200 .REASON_PROVIDER_IN_USE; 14201 app.adjSource = client; 14202 app.adjSourceOom = clientAdj; 14203 app.adjTarget = cpr.name; 14204 } 14205 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14206 schedGroup = Process.THREAD_GROUP_DEFAULT; 14207 } 14208 } 14209 // If the provider has external (non-framework) process 14210 // dependencies, ensure that its adjustment is at least 14211 // FOREGROUND_APP_ADJ. 14212 if (cpr.hasExternalProcessHandles()) { 14213 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14214 adj = ProcessList.FOREGROUND_APP_ADJ; 14215 schedGroup = Process.THREAD_GROUP_DEFAULT; 14216 app.hidden = false; 14217 app.keeping = true; 14218 app.adjType = "provider"; 14219 app.adjTarget = cpr.name; 14220 } 14221 } 14222 } 14223 } 14224 14225 if (adj == ProcessList.SERVICE_ADJ) { 14226 if (doingAll) { 14227 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 14228 mNewNumServiceProcs++; 14229 } 14230 if (app.serviceb) { 14231 adj = ProcessList.SERVICE_B_ADJ; 14232 } 14233 } else { 14234 app.serviceb = false; 14235 } 14236 14237 app.nonStoppingAdj = adj; 14238 14239 if (hasStoppingActivities) { 14240 // Only upgrade adjustment. 14241 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14242 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14243 app.adjType = "stopping"; 14244 } 14245 } 14246 14247 app.curRawAdj = adj; 14248 14249 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14250 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14251 if (adj > app.maxAdj) { 14252 adj = app.maxAdj; 14253 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14254 schedGroup = Process.THREAD_GROUP_DEFAULT; 14255 } 14256 } 14257 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14258 app.keeping = true; 14259 } 14260 14261 if (app.hasAboveClient) { 14262 // If this process has bound to any services with BIND_ABOVE_CLIENT, 14263 // then we need to drop its adjustment to be lower than the service's 14264 // in order to honor the request. We want to drop it by one adjustment 14265 // level... but there is special meaning applied to various levels so 14266 // we will skip some of them. 14267 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 14268 // System process will not get dropped, ever 14269 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 14270 adj = ProcessList.VISIBLE_APP_ADJ; 14271 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 14272 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14273 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14274 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 14275 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 14276 adj++; 14277 } 14278 } 14279 14280 int importance = app.memImportance; 14281 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14282 app.curAdj = adj; 14283 app.curSchedGroup = schedGroup; 14284 if (!interesting) { 14285 // For this reporting, if there is not something explicitly 14286 // interesting in this process then we will push it to the 14287 // background importance. 14288 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14289 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14290 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14291 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14292 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14293 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14294 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14295 } else if (adj >= ProcessList.SERVICE_ADJ) { 14296 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14297 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14298 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14299 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14300 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14301 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14302 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14303 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14304 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14305 } else { 14306 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14307 } 14308 } 14309 14310 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14311 if (foregroundActivities != app.foregroundActivities) { 14312 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14313 } 14314 if (changes != 0) { 14315 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14316 app.memImportance = importance; 14317 app.foregroundActivities = foregroundActivities; 14318 int i = mPendingProcessChanges.size()-1; 14319 ProcessChangeItem item = null; 14320 while (i >= 0) { 14321 item = mPendingProcessChanges.get(i); 14322 if (item.pid == app.pid) { 14323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14324 break; 14325 } 14326 i--; 14327 } 14328 if (i < 0) { 14329 // No existing item in pending changes; need a new one. 14330 final int NA = mAvailProcessChanges.size(); 14331 if (NA > 0) { 14332 item = mAvailProcessChanges.remove(NA-1); 14333 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14334 } else { 14335 item = new ProcessChangeItem(); 14336 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14337 } 14338 item.changes = 0; 14339 item.pid = app.pid; 14340 item.uid = app.info.uid; 14341 if (mPendingProcessChanges.size() == 0) { 14342 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14343 "*** Enqueueing dispatch processes changed!"); 14344 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14345 } 14346 mPendingProcessChanges.add(item); 14347 } 14348 item.changes |= changes; 14349 item.importance = importance; 14350 item.foregroundActivities = foregroundActivities; 14351 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14352 + Integer.toHexString(System.identityHashCode(item)) 14353 + " " + app.toShortString() + ": changes=" + item.changes 14354 + " importance=" + item.importance 14355 + " foreground=" + item.foregroundActivities 14356 + " type=" + app.adjType + " source=" + app.adjSource 14357 + " target=" + app.adjTarget); 14358 } 14359 14360 return app.curRawAdj; 14361 } 14362 14363 /** 14364 * Ask a given process to GC right now. 14365 */ 14366 final void performAppGcLocked(ProcessRecord app) { 14367 try { 14368 app.lastRequestedGc = SystemClock.uptimeMillis(); 14369 if (app.thread != null) { 14370 if (app.reportLowMemory) { 14371 app.reportLowMemory = false; 14372 app.thread.scheduleLowMemory(); 14373 } else { 14374 app.thread.processInBackground(); 14375 } 14376 } 14377 } catch (Exception e) { 14378 // whatever. 14379 } 14380 } 14381 14382 /** 14383 * Returns true if things are idle enough to perform GCs. 14384 */ 14385 private final boolean canGcNowLocked() { 14386 boolean processingBroadcasts = false; 14387 for (BroadcastQueue q : mBroadcastQueues) { 14388 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14389 processingBroadcasts = true; 14390 } 14391 } 14392 return !processingBroadcasts 14393 && (mSleeping || (mMainStack.mResumedActivity != null && 14394 mMainStack.mResumedActivity.idle)); 14395 } 14396 14397 /** 14398 * Perform GCs on all processes that are waiting for it, but only 14399 * if things are idle. 14400 */ 14401 final void performAppGcsLocked() { 14402 final int N = mProcessesToGc.size(); 14403 if (N <= 0) { 14404 return; 14405 } 14406 if (canGcNowLocked()) { 14407 while (mProcessesToGc.size() > 0) { 14408 ProcessRecord proc = mProcessesToGc.remove(0); 14409 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14410 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14411 <= SystemClock.uptimeMillis()) { 14412 // To avoid spamming the system, we will GC processes one 14413 // at a time, waiting a few seconds between each. 14414 performAppGcLocked(proc); 14415 scheduleAppGcsLocked(); 14416 return; 14417 } else { 14418 // It hasn't been long enough since we last GCed this 14419 // process... put it in the list to wait for its time. 14420 addProcessToGcListLocked(proc); 14421 break; 14422 } 14423 } 14424 } 14425 14426 scheduleAppGcsLocked(); 14427 } 14428 } 14429 14430 /** 14431 * If all looks good, perform GCs on all processes waiting for them. 14432 */ 14433 final void performAppGcsIfAppropriateLocked() { 14434 if (canGcNowLocked()) { 14435 performAppGcsLocked(); 14436 return; 14437 } 14438 // Still not idle, wait some more. 14439 scheduleAppGcsLocked(); 14440 } 14441 14442 /** 14443 * Schedule the execution of all pending app GCs. 14444 */ 14445 final void scheduleAppGcsLocked() { 14446 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14447 14448 if (mProcessesToGc.size() > 0) { 14449 // Schedule a GC for the time to the next process. 14450 ProcessRecord proc = mProcessesToGc.get(0); 14451 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14452 14453 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14454 long now = SystemClock.uptimeMillis(); 14455 if (when < (now+GC_TIMEOUT)) { 14456 when = now + GC_TIMEOUT; 14457 } 14458 mHandler.sendMessageAtTime(msg, when); 14459 } 14460 } 14461 14462 /** 14463 * Add a process to the array of processes waiting to be GCed. Keeps the 14464 * list in sorted order by the last GC time. The process can't already be 14465 * on the list. 14466 */ 14467 final void addProcessToGcListLocked(ProcessRecord proc) { 14468 boolean added = false; 14469 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14470 if (mProcessesToGc.get(i).lastRequestedGc < 14471 proc.lastRequestedGc) { 14472 added = true; 14473 mProcessesToGc.add(i+1, proc); 14474 break; 14475 } 14476 } 14477 if (!added) { 14478 mProcessesToGc.add(0, proc); 14479 } 14480 } 14481 14482 /** 14483 * Set up to ask a process to GC itself. This will either do it 14484 * immediately, or put it on the list of processes to gc the next 14485 * time things are idle. 14486 */ 14487 final void scheduleAppGcLocked(ProcessRecord app) { 14488 long now = SystemClock.uptimeMillis(); 14489 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14490 return; 14491 } 14492 if (!mProcessesToGc.contains(app)) { 14493 addProcessToGcListLocked(app); 14494 scheduleAppGcsLocked(); 14495 } 14496 } 14497 14498 final void checkExcessivePowerUsageLocked(boolean doKills) { 14499 updateCpuStatsNow(); 14500 14501 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14502 boolean doWakeKills = doKills; 14503 boolean doCpuKills = doKills; 14504 if (mLastPowerCheckRealtime == 0) { 14505 doWakeKills = false; 14506 } 14507 if (mLastPowerCheckUptime == 0) { 14508 doCpuKills = false; 14509 } 14510 if (stats.isScreenOn()) { 14511 doWakeKills = false; 14512 } 14513 final long curRealtime = SystemClock.elapsedRealtime(); 14514 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14515 final long curUptime = SystemClock.uptimeMillis(); 14516 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14517 mLastPowerCheckRealtime = curRealtime; 14518 mLastPowerCheckUptime = curUptime; 14519 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14520 doWakeKills = false; 14521 } 14522 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14523 doCpuKills = false; 14524 } 14525 int i = mLruProcesses.size(); 14526 while (i > 0) { 14527 i--; 14528 ProcessRecord app = mLruProcesses.get(i); 14529 if (!app.keeping) { 14530 long wtime; 14531 synchronized (stats) { 14532 wtime = stats.getProcessWakeTime(app.info.uid, 14533 app.pid, curRealtime); 14534 } 14535 long wtimeUsed = wtime - app.lastWakeTime; 14536 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14537 if (DEBUG_POWER) { 14538 StringBuilder sb = new StringBuilder(128); 14539 sb.append("Wake for "); 14540 app.toShortString(sb); 14541 sb.append(": over "); 14542 TimeUtils.formatDuration(realtimeSince, sb); 14543 sb.append(" used "); 14544 TimeUtils.formatDuration(wtimeUsed, sb); 14545 sb.append(" ("); 14546 sb.append((wtimeUsed*100)/realtimeSince); 14547 sb.append("%)"); 14548 Slog.i(TAG, sb.toString()); 14549 sb.setLength(0); 14550 sb.append("CPU for "); 14551 app.toShortString(sb); 14552 sb.append(": over "); 14553 TimeUtils.formatDuration(uptimeSince, sb); 14554 sb.append(" used "); 14555 TimeUtils.formatDuration(cputimeUsed, sb); 14556 sb.append(" ("); 14557 sb.append((cputimeUsed*100)/uptimeSince); 14558 sb.append("%)"); 14559 Slog.i(TAG, sb.toString()); 14560 } 14561 // If a process has held a wake lock for more 14562 // than 50% of the time during this period, 14563 // that sounds bad. Kill! 14564 if (doWakeKills && realtimeSince > 0 14565 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14566 synchronized (stats) { 14567 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14568 realtimeSince, wtimeUsed); 14569 } 14570 Slog.w(TAG, "Excessive wake lock in " + app.processName 14571 + " (pid " + app.pid + "): held " + wtimeUsed 14572 + " during " + realtimeSince); 14573 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14574 app.processName, app.setAdj, "excessive wake lock"); 14575 Process.killProcessQuiet(app.pid); 14576 } else if (doCpuKills && uptimeSince > 0 14577 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14578 synchronized (stats) { 14579 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 14580 uptimeSince, cputimeUsed); 14581 } 14582 Slog.w(TAG, "Excessive CPU in " + app.processName 14583 + " (pid " + app.pid + "): used " + cputimeUsed 14584 + " during " + uptimeSince); 14585 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14586 app.processName, app.setAdj, "excessive cpu"); 14587 Process.killProcessQuiet(app.pid); 14588 } else { 14589 app.lastWakeTime = wtime; 14590 app.lastCpuTime = app.curCpuTime; 14591 } 14592 } 14593 } 14594 } 14595 14596 private final boolean updateOomAdjLocked( 14597 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 14598 app.hiddenAdj = hiddenAdj; 14599 14600 if (app.thread == null) { 14601 return false; 14602 } 14603 14604 final boolean wasKeeping = app.keeping; 14605 14606 boolean success = true; 14607 14608 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 14609 14610 if (app.curRawAdj != app.setRawAdj) { 14611 if (wasKeeping && !app.keeping) { 14612 // This app is no longer something we want to keep. Note 14613 // its current wake lock time to later know to kill it if 14614 // it is not behaving well. 14615 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14616 synchronized (stats) { 14617 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 14618 app.pid, SystemClock.elapsedRealtime()); 14619 } 14620 app.lastCpuTime = app.curCpuTime; 14621 } 14622 14623 app.setRawAdj = app.curRawAdj; 14624 } 14625 14626 if (app.curAdj != app.setAdj) { 14627 if (Process.setOomAdj(app.pid, app.curAdj)) { 14628 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 14629 TAG, "Set " + app.pid + " " + app.processName + 14630 " adj " + app.curAdj + ": " + app.adjType); 14631 app.setAdj = app.curAdj; 14632 } else { 14633 success = false; 14634 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 14635 } 14636 } 14637 if (app.setSchedGroup != app.curSchedGroup) { 14638 app.setSchedGroup = app.curSchedGroup; 14639 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 14640 "Setting process group of " + app.processName 14641 + " to " + app.curSchedGroup); 14642 if (app.waitingToKill != null && 14643 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 14644 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 14645 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14646 app.processName, app.setAdj, app.waitingToKill); 14647 app.killedBackground = true; 14648 Process.killProcessQuiet(app.pid); 14649 success = false; 14650 } else { 14651 if (true) { 14652 long oldId = Binder.clearCallingIdentity(); 14653 try { 14654 Process.setProcessGroup(app.pid, app.curSchedGroup); 14655 } catch (Exception e) { 14656 Slog.w(TAG, "Failed setting process group of " + app.pid 14657 + " to " + app.curSchedGroup); 14658 e.printStackTrace(); 14659 } finally { 14660 Binder.restoreCallingIdentity(oldId); 14661 } 14662 } else { 14663 if (app.thread != null) { 14664 try { 14665 app.thread.setSchedulingGroup(app.curSchedGroup); 14666 } catch (RemoteException e) { 14667 } 14668 } 14669 } 14670 } 14671 } 14672 return success; 14673 } 14674 14675 private final ActivityRecord resumedAppLocked() { 14676 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 14677 if (resumedActivity == null || resumedActivity.app == null) { 14678 resumedActivity = mMainStack.mPausingActivity; 14679 if (resumedActivity == null || resumedActivity.app == null) { 14680 resumedActivity = mMainStack.topRunningActivityLocked(null); 14681 } 14682 } 14683 return resumedActivity; 14684 } 14685 14686 private final boolean updateOomAdjLocked(ProcessRecord app) { 14687 final ActivityRecord TOP_ACT = resumedAppLocked(); 14688 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14689 int curAdj = app.curAdj; 14690 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14691 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14692 14693 mAdjSeq++; 14694 14695 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 14696 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14697 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14698 if (nowHidden != wasHidden) { 14699 // Changed to/from hidden state, so apps after it in the LRU 14700 // list may also be changed. 14701 updateOomAdjLocked(); 14702 } 14703 return success; 14704 } 14705 14706 final void updateOomAdjLocked() { 14707 final ActivityRecord TOP_ACT = resumedAppLocked(); 14708 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14709 14710 if (false) { 14711 RuntimeException e = new RuntimeException(); 14712 e.fillInStackTrace(); 14713 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 14714 } 14715 14716 mAdjSeq++; 14717 mNewNumServiceProcs = 0; 14718 14719 // Let's determine how many processes we have running vs. 14720 // how many slots we have for background processes; we may want 14721 // to put multiple processes in a slot of there are enough of 14722 // them. 14723 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 14724 int factor = (mLruProcesses.size()-4)/numSlots; 14725 if (factor < 1) factor = 1; 14726 int step = 0; 14727 int numHidden = 0; 14728 int numTrimming = 0; 14729 14730 // First update the OOM adjustment for each of the 14731 // application processes based on their current state. 14732 int i = mLruProcesses.size(); 14733 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 14734 while (i > 0) { 14735 i--; 14736 ProcessRecord app = mLruProcesses.get(i); 14737 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 14738 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 14739 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 14740 && app.curAdj == curHiddenAdj) { 14741 step++; 14742 if (step >= factor) { 14743 step = 0; 14744 curHiddenAdj++; 14745 } 14746 } 14747 if (!app.killedBackground) { 14748 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14749 numHidden++; 14750 if (numHidden > mProcessLimit) { 14751 Slog.i(TAG, "No longer want " + app.processName 14752 + " (pid " + app.pid + "): hidden #" + numHidden); 14753 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14754 app.processName, app.setAdj, "too many background"); 14755 app.killedBackground = true; 14756 Process.killProcessQuiet(app.pid); 14757 } 14758 } 14759 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 14760 // If this is an isolated process, and there are no 14761 // services running in it, then the process is no longer 14762 // needed. We agressively kill these because we can by 14763 // definition not re-use the same process again, and it is 14764 // good to avoid having whatever code was running in them 14765 // left sitting around after no longer needed. 14766 Slog.i(TAG, "Isolated process " + app.processName 14767 + " (pid " + app.pid + ") no longer needed"); 14768 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14769 app.processName, app.setAdj, "isolated not needed"); 14770 app.killedBackground = true; 14771 Process.killProcessQuiet(app.pid); 14772 } 14773 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14774 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14775 && !app.killedBackground) { 14776 numTrimming++; 14777 } 14778 } 14779 } 14780 14781 mNumServiceProcs = mNewNumServiceProcs; 14782 14783 // Now determine the memory trimming level of background processes. 14784 // Unfortunately we need to start at the back of the list to do this 14785 // properly. We only do this if the number of background apps we 14786 // are managing to keep around is less than half the maximum we desire; 14787 // if we are keeping a good number around, we'll let them use whatever 14788 // memory they want. 14789 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 14790 final int N = mLruProcesses.size(); 14791 factor = numTrimming/3; 14792 int minFactor = 2; 14793 if (mHomeProcess != null) minFactor++; 14794 if (mPreviousProcess != null) minFactor++; 14795 if (factor < minFactor) factor = minFactor; 14796 step = 0; 14797 int fgTrimLevel; 14798 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 14799 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 14800 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 14801 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 14802 } else { 14803 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 14804 } 14805 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14806 for (i=0; i<N; i++) { 14807 ProcessRecord app = mLruProcesses.get(i); 14808 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14809 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14810 && !app.killedBackground) { 14811 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14812 try { 14813 app.thread.scheduleTrimMemory(curLevel); 14814 } catch (RemoteException e) { 14815 } 14816 if (false) { 14817 // For now we won't do this; our memory trimming seems 14818 // to be good enough at this point that destroying 14819 // activities causes more harm than good. 14820 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14821 && app != mHomeProcess && app != mPreviousProcess) { 14822 // Need to do this on its own message because the stack may not 14823 // be in a consistent state at this point. 14824 // For these apps we will also finish their activities 14825 // to help them free memory. 14826 mMainStack.scheduleDestroyActivities(app, false, "trim"); 14827 } 14828 } 14829 } 14830 app.trimMemoryLevel = curLevel; 14831 step++; 14832 if (step >= factor) { 14833 step = 0; 14834 switch (curLevel) { 14835 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14836 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14837 break; 14838 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14839 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14840 break; 14841 } 14842 } 14843 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14844 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14845 && app.thread != null) { 14846 try { 14847 app.thread.scheduleTrimMemory( 14848 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14849 } catch (RemoteException e) { 14850 } 14851 } 14852 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14853 } else { 14854 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14855 && app.pendingUiClean) { 14856 // If this application is now in the background and it 14857 // had done UI, then give it the special trim level to 14858 // have it free UI resources. 14859 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14860 if (app.trimMemoryLevel < level && app.thread != null) { 14861 try { 14862 app.thread.scheduleTrimMemory(level); 14863 } catch (RemoteException e) { 14864 } 14865 } 14866 app.pendingUiClean = false; 14867 } 14868 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 14869 try { 14870 app.thread.scheduleTrimMemory(fgTrimLevel); 14871 } catch (RemoteException e) { 14872 } 14873 } 14874 app.trimMemoryLevel = fgTrimLevel; 14875 } 14876 } 14877 } else { 14878 final int N = mLruProcesses.size(); 14879 for (i=0; i<N; i++) { 14880 ProcessRecord app = mLruProcesses.get(i); 14881 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14882 && app.pendingUiClean) { 14883 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14884 && app.thread != null) { 14885 try { 14886 app.thread.scheduleTrimMemory( 14887 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14888 } catch (RemoteException e) { 14889 } 14890 } 14891 app.pendingUiClean = false; 14892 } 14893 app.trimMemoryLevel = 0; 14894 } 14895 } 14896 14897 if (mAlwaysFinishActivities) { 14898 // Need to do this on its own message because the stack may not 14899 // be in a consistent state at this point. 14900 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 14901 } 14902 } 14903 14904 final void trimApplications() { 14905 synchronized (this) { 14906 int i; 14907 14908 // First remove any unused application processes whose package 14909 // has been removed. 14910 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14911 final ProcessRecord app = mRemovedProcesses.get(i); 14912 if (app.activities.size() == 0 14913 && app.curReceiver == null && app.services.size() == 0) { 14914 Slog.i( 14915 TAG, "Exiting empty application process " 14916 + app.processName + " (" 14917 + (app.thread != null ? app.thread.asBinder() : null) 14918 + ")\n"); 14919 if (app.pid > 0 && app.pid != MY_PID) { 14920 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14921 app.processName, app.setAdj, "empty"); 14922 Process.killProcessQuiet(app.pid); 14923 } else { 14924 try { 14925 app.thread.scheduleExit(); 14926 } catch (Exception e) { 14927 // Ignore exceptions. 14928 } 14929 } 14930 cleanUpApplicationRecordLocked(app, false, true, -1); 14931 mRemovedProcesses.remove(i); 14932 14933 if (app.persistent) { 14934 if (app.persistent) { 14935 addAppLocked(app.info, false); 14936 } 14937 } 14938 } 14939 } 14940 14941 // Now update the oom adj for all processes. 14942 updateOomAdjLocked(); 14943 } 14944 } 14945 14946 /** This method sends the specified signal to each of the persistent apps */ 14947 public void signalPersistentProcesses(int sig) throws RemoteException { 14948 if (sig != Process.SIGNAL_USR1) { 14949 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14950 } 14951 14952 synchronized (this) { 14953 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14954 != PackageManager.PERMISSION_GRANTED) { 14955 throw new SecurityException("Requires permission " 14956 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14957 } 14958 14959 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14960 ProcessRecord r = mLruProcesses.get(i); 14961 if (r.thread != null && r.persistent) { 14962 Process.sendSignal(r.pid, sig); 14963 } 14964 } 14965 } 14966 } 14967 14968 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14969 if (proc == null || proc == mProfileProc) { 14970 proc = mProfileProc; 14971 path = mProfileFile; 14972 profileType = mProfileType; 14973 clearProfilerLocked(); 14974 } 14975 if (proc == null) { 14976 return; 14977 } 14978 try { 14979 proc.thread.profilerControl(false, path, null, profileType); 14980 } catch (RemoteException e) { 14981 throw new IllegalStateException("Process disappeared"); 14982 } 14983 } 14984 14985 private void clearProfilerLocked() { 14986 if (mProfileFd != null) { 14987 try { 14988 mProfileFd.close(); 14989 } catch (IOException e) { 14990 } 14991 } 14992 mProfileApp = null; 14993 mProfileProc = null; 14994 mProfileFile = null; 14995 mProfileType = 0; 14996 mAutoStopProfiler = false; 14997 } 14998 14999 public boolean profileControl(String process, boolean start, 15000 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15001 15002 try { 15003 synchronized (this) { 15004 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15005 // its own permission. 15006 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15007 != PackageManager.PERMISSION_GRANTED) { 15008 throw new SecurityException("Requires permission " 15009 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15010 } 15011 15012 if (start && fd == null) { 15013 throw new IllegalArgumentException("null fd"); 15014 } 15015 15016 ProcessRecord proc = null; 15017 if (process != null) { 15018 try { 15019 int pid = Integer.parseInt(process); 15020 synchronized (mPidsSelfLocked) { 15021 proc = mPidsSelfLocked.get(pid); 15022 } 15023 } catch (NumberFormatException e) { 15024 } 15025 15026 if (proc == null) { 15027 HashMap<String, SparseArray<ProcessRecord>> all 15028 = mProcessNames.getMap(); 15029 SparseArray<ProcessRecord> procs = all.get(process); 15030 if (procs != null && procs.size() > 0) { 15031 proc = procs.valueAt(0); 15032 } 15033 } 15034 } 15035 15036 if (start && (proc == null || proc.thread == null)) { 15037 throw new IllegalArgumentException("Unknown process: " + process); 15038 } 15039 15040 if (start) { 15041 stopProfilerLocked(null, null, 0); 15042 setProfileApp(proc.info, proc.processName, path, fd, false); 15043 mProfileProc = proc; 15044 mProfileType = profileType; 15045 try { 15046 fd = fd.dup(); 15047 } catch (IOException e) { 15048 fd = null; 15049 } 15050 proc.thread.profilerControl(start, path, fd, profileType); 15051 fd = null; 15052 mProfileFd = null; 15053 } else { 15054 stopProfilerLocked(proc, path, profileType); 15055 if (fd != null) { 15056 try { 15057 fd.close(); 15058 } catch (IOException e) { 15059 } 15060 } 15061 } 15062 15063 return true; 15064 } 15065 } catch (RemoteException e) { 15066 throw new IllegalStateException("Process disappeared"); 15067 } finally { 15068 if (fd != null) { 15069 try { 15070 fd.close(); 15071 } catch (IOException e) { 15072 } 15073 } 15074 } 15075 } 15076 15077 public boolean dumpHeap(String process, boolean managed, 15078 String path, ParcelFileDescriptor fd) throws RemoteException { 15079 15080 try { 15081 synchronized (this) { 15082 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15083 // its own permission (same as profileControl). 15084 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15085 != PackageManager.PERMISSION_GRANTED) { 15086 throw new SecurityException("Requires permission " 15087 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15088 } 15089 15090 if (fd == null) { 15091 throw new IllegalArgumentException("null fd"); 15092 } 15093 15094 ProcessRecord proc = null; 15095 try { 15096 int pid = Integer.parseInt(process); 15097 synchronized (mPidsSelfLocked) { 15098 proc = mPidsSelfLocked.get(pid); 15099 } 15100 } catch (NumberFormatException e) { 15101 } 15102 15103 if (proc == null) { 15104 HashMap<String, SparseArray<ProcessRecord>> all 15105 = mProcessNames.getMap(); 15106 SparseArray<ProcessRecord> procs = all.get(process); 15107 if (procs != null && procs.size() > 0) { 15108 proc = procs.valueAt(0); 15109 } 15110 } 15111 15112 if (proc == null || proc.thread == null) { 15113 throw new IllegalArgumentException("Unknown process: " + process); 15114 } 15115 15116 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15117 if (!isDebuggable) { 15118 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15119 throw new SecurityException("Process not debuggable: " + proc); 15120 } 15121 } 15122 15123 proc.thread.dumpHeap(managed, path, fd); 15124 fd = null; 15125 return true; 15126 } 15127 } catch (RemoteException e) { 15128 throw new IllegalStateException("Process disappeared"); 15129 } finally { 15130 if (fd != null) { 15131 try { 15132 fd.close(); 15133 } catch (IOException e) { 15134 } 15135 } 15136 } 15137 } 15138 15139 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15140 public void monitor() { 15141 synchronized (this) { } 15142 } 15143 15144 void onCoreSettingsChange(Bundle settings) { 15145 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15146 ProcessRecord processRecord = mLruProcesses.get(i); 15147 try { 15148 if (processRecord.thread != null) { 15149 processRecord.thread.setCoreSettings(settings); 15150 } 15151 } catch (RemoteException re) { 15152 /* ignore */ 15153 } 15154 } 15155 } 15156 15157 // Multi-user methods 15158 15159 private int mCurrentUserId; 15160 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 15161 15162 public boolean switchUser(int userId) { 15163 final int callingUid = Binder.getCallingUid(); 15164 if (callingUid != 0 && callingUid != Process.myUid()) { 15165 Slog.e(TAG, "Trying to switch user from unauthorized app"); 15166 return false; 15167 } 15168 if (mCurrentUserId == userId) 15169 return true; 15170 15171 synchronized (this) { 15172 // Check if user is already logged in, otherwise check if user exists first before 15173 // adding to the list of logged in users. 15174 if (mLoggedInUsers.indexOfKey(userId) < 0) { 15175 if (!userExists(userId)) { 15176 return false; 15177 } 15178 mLoggedInUsers.append(userId, userId); 15179 } 15180 15181 mCurrentUserId = userId; 15182 boolean haveActivities = mMainStack.switchUser(userId); 15183 if (!haveActivities) { 15184 startHomeActivityLocked(userId); 15185 } 15186 15187 } 15188 15189 // Inform of user switch 15190 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 15191 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 15192 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 15193 15194 return true; 15195 } 15196 15197 @Override 15198 public UserInfo getCurrentUser() throws RemoteException { 15199 final int callingUid = Binder.getCallingUid(); 15200 if (callingUid != 0 && callingUid != Process.myUid()) { 15201 Slog.e(TAG, "Trying to get user from unauthorized app"); 15202 return null; 15203 } 15204 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 15205 } 15206 15207 private void onUserRemoved(Intent intent) { 15208 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 15209 if (extraUserId < 1) return; 15210 15211 // Kill all the processes for the user 15212 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 15213 synchronized (this) { 15214 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 15215 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 15216 SparseArray<ProcessRecord> uids = uidMap.getValue(); 15217 for (int i = 0; i < uids.size(); i++) { 15218 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 15219 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 15220 } 15221 } 15222 } 15223 15224 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 15225 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 15226 false, false, true, true, extraUserId); 15227 } 15228 } 15229 } 15230 15231 private boolean userExists(int userId) { 15232 try { 15233 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 15234 return user != null; 15235 } catch (RemoteException re) { 15236 // Won't happen, in same process 15237 } 15238 15239 return false; 15240 } 15241 15242 private void checkValidCaller(int uid, int userId) { 15243 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 15244 15245 throw new SecurityException("Caller uid=" + uid 15246 + " is not privileged to communicate with user=" + userId); 15247 } 15248 15249 private int applyUserId(int uid, int userId) { 15250 return UserId.getUid(userId, uid); 15251 } 15252 15253 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 15254 if (info == null) return null; 15255 ApplicationInfo newInfo = new ApplicationInfo(info); 15256 newInfo.uid = applyUserId(info.uid, userId); 15257 newInfo.dataDir = USER_DATA_DIR + userId + "/" 15258 + info.packageName; 15259 return newInfo; 15260 } 15261 15262 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 15263 if (aInfo == null 15264 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 15265 return aInfo; 15266 } 15267 15268 ActivityInfo info = new ActivityInfo(aInfo); 15269 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 15270 return info; 15271 } 15272 15273 static class ServiceMap { 15274 15275 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser 15276 = new SparseArray<HashMap<ComponentName, ServiceRecord>>(); 15277 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>> 15278 mServicesByIntentPerUser = new SparseArray< 15279 HashMap<Intent.FilterComparison, ServiceRecord>>(); 15280 15281 ServiceRecord getServiceByName(ComponentName name, int callingUser) { 15282 // TODO: Deal with global services 15283 if (DEBUG_MU) 15284 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser); 15285 return getServices(callingUser).get(name); 15286 } 15287 15288 ServiceRecord getServiceByName(ComponentName name) { 15289 return getServiceByName(name, -1); 15290 } 15291 15292 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15293 // TODO: Deal with global services 15294 if (DEBUG_MU) 15295 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser); 15296 return getServicesByIntent(callingUser).get(filter); 15297 } 15298 15299 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) { 15300 return getServiceByIntent(filter, -1); 15301 } 15302 15303 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) { 15304 // TODO: Deal with global services 15305 getServices(callingUser).put(name, value); 15306 } 15307 15308 void putServiceByIntent(Intent.FilterComparison filter, int callingUser, 15309 ServiceRecord value) { 15310 // TODO: Deal with global services 15311 getServicesByIntent(callingUser).put(filter, value); 15312 } 15313 15314 void removeServiceByName(ComponentName name, int callingUser) { 15315 // TODO: Deal with global services 15316 ServiceRecord removed = getServices(callingUser).remove(name); 15317 if (DEBUG_MU) 15318 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name 15319 + " removed=" + removed); 15320 } 15321 15322 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15323 // TODO: Deal with global services 15324 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter); 15325 if (DEBUG_MU) 15326 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter 15327 + " removed=" + removed); 15328 } 15329 15330 Collection<ServiceRecord> getAllServices(int callingUser) { 15331 // TODO: Deal with global services 15332 return getServices(callingUser).values(); 15333 } 15334 15335 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) { 15336 HashMap map = mServicesByNamePerUser.get(callingUser); 15337 if (map == null) { 15338 map = new HashMap<ComponentName, ServiceRecord>(); 15339 mServicesByNamePerUser.put(callingUser, map); 15340 } 15341 return map; 15342 } 15343 15344 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent( 15345 int callingUser) { 15346 HashMap map = mServicesByIntentPerUser.get(callingUser); 15347 if (map == null) { 15348 map = new HashMap<Intent.FilterComparison, ServiceRecord>(); 15349 mServicesByIntentPerUser.put(callingUser, map); 15350 } 15351 return map; 15352 } 15353 } 15354} 15355