ActivityManagerService.java revision 1927ae8a56a010919a7535231fa0f7db70f7e152
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, oomAdj, 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, oomAdj, 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); 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 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5708 SparseArray<ProcessRecord> appProcs 5709 = mProcessNames.getMap().get(component.getPackageName()); 5710 if (appProcs != null) { 5711 for (int i=0; i<appProcs.size(); i++) { 5712 procs.add(appProcs.valueAt(i)); 5713 } 5714 } 5715 5716 // Kill the running processes. 5717 for (int i=0; i<procs.size(); i++) { 5718 ProcessRecord pr = procs.get(i); 5719 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 5720 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task"); 5721 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, 5722 pr.processName, pr.setAdj, "remove task"); 5723 Process.killProcessQuiet(pr.pid); 5724 } else { 5725 pr.waitingToKill = "remove task"; 5726 } 5727 } 5728 } 5729 } 5730 5731 public boolean removeTask(int taskId, int flags) { 5732 synchronized (this) { 5733 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 5734 "removeTask()"); 5735 long ident = Binder.clearCallingIdentity(); 5736 try { 5737 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1, 5738 false); 5739 if (r != null) { 5740 mRecentTasks.remove(r.task); 5741 cleanUpRemovedTaskLocked(r.task, flags); 5742 return true; 5743 } else { 5744 TaskRecord tr = null; 5745 int i=0; 5746 while (i < mRecentTasks.size()) { 5747 TaskRecord t = mRecentTasks.get(i); 5748 if (t.taskId == taskId) { 5749 tr = t; 5750 break; 5751 } 5752 i++; 5753 } 5754 if (tr != null) { 5755 if (tr.numActivities <= 0) { 5756 // Caller is just removing a recent task that is 5757 // not actively running. That is easy! 5758 mRecentTasks.remove(i); 5759 cleanUpRemovedTaskLocked(tr, flags); 5760 return true; 5761 } else { 5762 Slog.w(TAG, "removeTask: task " + taskId 5763 + " does not have activities to remove, " 5764 + " but numActivities=" + tr.numActivities 5765 + ": " + tr); 5766 } 5767 } 5768 } 5769 } finally { 5770 Binder.restoreCallingIdentity(ident); 5771 } 5772 } 5773 return false; 5774 } 5775 5776 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 5777 int j; 5778 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 5779 TaskRecord jt = startTask; 5780 5781 // First look backwards 5782 for (j=startIndex-1; j>=0; j--) { 5783 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5784 if (r.task != jt) { 5785 jt = r.task; 5786 if (affinity.equals(jt.affinity)) { 5787 return j; 5788 } 5789 } 5790 } 5791 5792 // Now look forwards 5793 final int N = mMainStack.mHistory.size(); 5794 jt = startTask; 5795 for (j=startIndex+1; j<N; j++) { 5796 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); 5797 if (r.task != jt) { 5798 if (affinity.equals(jt.affinity)) { 5799 return j; 5800 } 5801 jt = r.task; 5802 } 5803 } 5804 5805 // Might it be at the top? 5806 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { 5807 return N-1; 5808 } 5809 5810 return -1; 5811 } 5812 5813 /** 5814 * TODO: Add mController hook 5815 */ 5816 public void moveTaskToFront(int task, int flags, Bundle options) { 5817 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5818 "moveTaskToFront()"); 5819 5820 synchronized(this) { 5821 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5822 Binder.getCallingUid(), "Task to front")) { 5823 ActivityOptions.abort(options); 5824 return; 5825 } 5826 final long origId = Binder.clearCallingIdentity(); 5827 try { 5828 TaskRecord tr = taskForIdLocked(task); 5829 if (tr != null) { 5830 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5831 mMainStack.mUserLeaving = true; 5832 } 5833 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5834 // Caller wants the home activity moved with it. To accomplish this, 5835 // we'll just move the home task to the top first. 5836 mMainStack.moveHomeToFrontLocked(); 5837 } 5838 mMainStack.moveTaskToFrontLocked(tr, null, options); 5839 return; 5840 } 5841 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 5842 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); 5843 if (hr.task.taskId == task) { 5844 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { 5845 mMainStack.mUserLeaving = true; 5846 } 5847 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { 5848 // Caller wants the home activity moved with it. To accomplish this, 5849 // we'll just move the home task to the top first. 5850 mMainStack.moveHomeToFrontLocked(); 5851 } 5852 mMainStack.moveTaskToFrontLocked(hr.task, null, options); 5853 return; 5854 } 5855 } 5856 } finally { 5857 Binder.restoreCallingIdentity(origId); 5858 } 5859 ActivityOptions.abort(options); 5860 } 5861 } 5862 5863 public void moveTaskToBack(int task) { 5864 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5865 "moveTaskToBack()"); 5866 5867 synchronized(this) { 5868 if (mMainStack.mResumedActivity != null 5869 && mMainStack.mResumedActivity.task.taskId == task) { 5870 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5871 Binder.getCallingUid(), "Task to back")) { 5872 return; 5873 } 5874 } 5875 final long origId = Binder.clearCallingIdentity(); 5876 mMainStack.moveTaskToBackLocked(task, null); 5877 Binder.restoreCallingIdentity(origId); 5878 } 5879 } 5880 5881 /** 5882 * Moves an activity, and all of the other activities within the same task, to the bottom 5883 * of the history stack. The activity's order within the task is unchanged. 5884 * 5885 * @param token A reference to the activity we wish to move 5886 * @param nonRoot If false then this only works if the activity is the root 5887 * of a task; if true it will work for any activity in a task. 5888 * @return Returns true if the move completed, false if not. 5889 */ 5890 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 5891 enforceNotIsolatedCaller("moveActivityTaskToBack"); 5892 synchronized(this) { 5893 final long origId = Binder.clearCallingIdentity(); 5894 int taskId = getTaskForActivityLocked(token, !nonRoot); 5895 if (taskId >= 0) { 5896 return mMainStack.moveTaskToBackLocked(taskId, null); 5897 } 5898 Binder.restoreCallingIdentity(origId); 5899 } 5900 return false; 5901 } 5902 5903 public void moveTaskBackwards(int task) { 5904 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 5905 "moveTaskBackwards()"); 5906 5907 synchronized(this) { 5908 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 5909 Binder.getCallingUid(), "Task backwards")) { 5910 return; 5911 } 5912 final long origId = Binder.clearCallingIdentity(); 5913 moveTaskBackwardsLocked(task); 5914 Binder.restoreCallingIdentity(origId); 5915 } 5916 } 5917 5918 private final void moveTaskBackwardsLocked(int task) { 5919 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 5920 } 5921 5922 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 5923 synchronized(this) { 5924 return getTaskForActivityLocked(token, onlyRoot); 5925 } 5926 } 5927 5928 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 5929 final int N = mMainStack.mHistory.size(); 5930 TaskRecord lastTask = null; 5931 for (int i=0; i<N; i++) { 5932 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 5933 if (r.appToken == token) { 5934 if (!onlyRoot || lastTask != r.task) { 5935 return r.task.taskId; 5936 } 5937 return -1; 5938 } 5939 lastTask = r.task; 5940 } 5941 5942 return -1; 5943 } 5944 5945 // ========================================================= 5946 // THUMBNAILS 5947 // ========================================================= 5948 5949 public void reportThumbnail(IBinder token, 5950 Bitmap thumbnail, CharSequence description) { 5951 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 5952 final long origId = Binder.clearCallingIdentity(); 5953 sendPendingThumbnail(null, token, thumbnail, description, true); 5954 Binder.restoreCallingIdentity(origId); 5955 } 5956 5957 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 5958 Bitmap thumbnail, CharSequence description, boolean always) { 5959 TaskRecord task = null; 5960 ArrayList receivers = null; 5961 5962 //System.out.println("Send pending thumbnail: " + r); 5963 5964 synchronized(this) { 5965 if (r == null) { 5966 r = mMainStack.isInStackLocked(token); 5967 if (r == null) { 5968 return; 5969 } 5970 } 5971 if (thumbnail == null && r.thumbHolder != null) { 5972 thumbnail = r.thumbHolder.lastThumbnail; 5973 description = r.thumbHolder.lastDescription; 5974 } 5975 if (thumbnail == null && !always) { 5976 // If there is no thumbnail, and this entry is not actually 5977 // going away, then abort for now and pick up the next 5978 // thumbnail we get. 5979 return; 5980 } 5981 task = r.task; 5982 5983 int N = mPendingThumbnails.size(); 5984 int i=0; 5985 while (i<N) { 5986 PendingThumbnailsRecord pr = 5987 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 5988 //System.out.println("Looking in " + pr.pendingRecords); 5989 if (pr.pendingRecords.remove(r)) { 5990 if (receivers == null) { 5991 receivers = new ArrayList(); 5992 } 5993 receivers.add(pr); 5994 if (pr.pendingRecords.size() == 0) { 5995 pr.finished = true; 5996 mPendingThumbnails.remove(i); 5997 N--; 5998 continue; 5999 } 6000 } 6001 i++; 6002 } 6003 } 6004 6005 if (receivers != null) { 6006 final int N = receivers.size(); 6007 for (int i=0; i<N; i++) { 6008 try { 6009 PendingThumbnailsRecord pr = 6010 (PendingThumbnailsRecord)receivers.get(i); 6011 pr.receiver.newThumbnail( 6012 task != null ? task.taskId : -1, thumbnail, description); 6013 if (pr.finished) { 6014 pr.receiver.finished(); 6015 } 6016 } catch (Exception e) { 6017 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 6018 } 6019 } 6020 } 6021 } 6022 6023 // ========================================================= 6024 // CONTENT PROVIDERS 6025 // ========================================================= 6026 6027 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 6028 List<ProviderInfo> providers = null; 6029 try { 6030 providers = AppGlobals.getPackageManager(). 6031 queryContentProviders(app.processName, app.uid, 6032 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6033 } catch (RemoteException ex) { 6034 } 6035 if (DEBUG_MU) 6036 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 6037 int userId = app.userId; 6038 if (providers != null) { 6039 final int N = providers.size(); 6040 for (int i=0; i<N; i++) { 6041 ProviderInfo cpi = 6042 (ProviderInfo)providers.get(i); 6043 6044 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6045 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 6046 if (cpr == null) { 6047 cpr = new ContentProviderRecord(this, cpi, app.info, comp); 6048 mProviderMap.putProviderByClass(comp, cpr); 6049 } 6050 if (DEBUG_MU) 6051 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 6052 app.pubProviders.put(cpi.name, cpr); 6053 app.addPackage(cpi.applicationInfo.packageName); 6054 ensurePackageDexOpt(cpi.applicationInfo.packageName); 6055 } 6056 } 6057 return providers; 6058 } 6059 6060 /** 6061 * Check if {@link ProcessRecord} has a possible chance at accessing the 6062 * given {@link ProviderInfo}. Final permission checking is always done 6063 * in {@link ContentProvider}. 6064 */ 6065 private final String checkContentProviderPermissionLocked( 6066 ProviderInfo cpi, ProcessRecord r) { 6067 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6068 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 6069 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6070 cpi.applicationInfo.uid, cpi.exported) 6071 == PackageManager.PERMISSION_GRANTED) { 6072 return null; 6073 } 6074 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6075 cpi.applicationInfo.uid, cpi.exported) 6076 == PackageManager.PERMISSION_GRANTED) { 6077 return null; 6078 } 6079 6080 PathPermission[] pps = cpi.pathPermissions; 6081 if (pps != null) { 6082 int i = pps.length; 6083 while (i > 0) { 6084 i--; 6085 PathPermission pp = pps[i]; 6086 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 6087 cpi.applicationInfo.uid, cpi.exported) 6088 == PackageManager.PERMISSION_GRANTED) { 6089 return null; 6090 } 6091 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 6092 cpi.applicationInfo.uid, cpi.exported) 6093 == PackageManager.PERMISSION_GRANTED) { 6094 return null; 6095 } 6096 } 6097 } 6098 6099 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6100 if (perms != null) { 6101 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 6102 if (uri.getKey().getAuthority().equals(cpi.authority)) { 6103 return null; 6104 } 6105 } 6106 } 6107 6108 String msg; 6109 if (!cpi.exported) { 6110 msg = "Permission Denial: opening provider " + cpi.name 6111 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6112 + ", uid=" + callingUid + ") that is not exported from uid " 6113 + cpi.applicationInfo.uid; 6114 } else { 6115 msg = "Permission Denial: opening provider " + cpi.name 6116 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6117 + ", uid=" + callingUid + ") requires " 6118 + cpi.readPermission + " or " + cpi.writePermission; 6119 } 6120 Slog.w(TAG, msg); 6121 return msg; 6122 } 6123 6124 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 6125 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6126 if (r != null) { 6127 for (int i=0; i<r.conProviders.size(); i++) { 6128 ContentProviderConnection conn = r.conProviders.get(i); 6129 if (conn.provider == cpr) { 6130 if (DEBUG_PROVIDER) Slog.v(TAG, 6131 "Adding provider requested by " 6132 + r.processName + " from process " 6133 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6134 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6135 if (stable) { 6136 conn.stableCount++; 6137 conn.numStableIncs++; 6138 } else { 6139 conn.unstableCount++; 6140 conn.numUnstableIncs++; 6141 } 6142 return conn; 6143 } 6144 } 6145 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 6146 if (stable) { 6147 conn.stableCount = 1; 6148 conn.numStableIncs = 1; 6149 } else { 6150 conn.unstableCount = 1; 6151 conn.numUnstableIncs = 1; 6152 } 6153 cpr.connections.add(conn); 6154 r.conProviders.add(conn); 6155 return conn; 6156 } 6157 cpr.addExternalProcessHandleLocked(externalProcessToken); 6158 return null; 6159 } 6160 6161 boolean decProviderCountLocked(ContentProviderConnection conn, 6162 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 6163 if (conn != null) { 6164 cpr = conn.provider; 6165 if (DEBUG_PROVIDER) Slog.v(TAG, 6166 "Removing provider requested by " 6167 + conn.client.processName + " from process " 6168 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 6169 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 6170 if (stable) { 6171 conn.stableCount--; 6172 } else { 6173 conn.unstableCount--; 6174 } 6175 if (conn.stableCount == 0 && conn.unstableCount == 0) { 6176 cpr.connections.remove(conn); 6177 conn.client.conProviders.remove(conn); 6178 return true; 6179 } 6180 return false; 6181 } 6182 cpr.removeExternalProcessHandleLocked(externalProcessToken); 6183 return false; 6184 } 6185 6186 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 6187 String name, IBinder token, boolean stable) { 6188 ContentProviderRecord cpr; 6189 ContentProviderConnection conn = null; 6190 ProviderInfo cpi = null; 6191 6192 synchronized(this) { 6193 ProcessRecord r = null; 6194 if (caller != null) { 6195 r = getRecordForAppLocked(caller); 6196 if (r == null) { 6197 throw new SecurityException( 6198 "Unable to find app for caller " + caller 6199 + " (pid=" + Binder.getCallingPid() 6200 + ") when getting content provider " + name); 6201 } 6202 } 6203 6204 // First check if this content provider has been published... 6205 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid()); 6206 cpr = mProviderMap.getProviderByName(name, userId); 6207 boolean providerRunning = cpr != null; 6208 if (providerRunning) { 6209 cpi = cpr.info; 6210 String msg; 6211 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6212 throw new SecurityException(msg); 6213 } 6214 6215 if (r != null && cpr.canRunHere(r)) { 6216 // This provider has been published or is in the process 6217 // of being published... but it is also allowed to run 6218 // in the caller's process, so don't make a connection 6219 // and just let the caller instantiate its own instance. 6220 ContentProviderHolder holder = cpr.newHolder(null); 6221 // don't give caller the provider object, it needs 6222 // to make its own. 6223 holder.provider = null; 6224 return holder; 6225 } 6226 6227 final long origId = Binder.clearCallingIdentity(); 6228 6229 // In this case the provider instance already exists, so we can 6230 // return it right away. 6231 conn = incProviderCountLocked(r, cpr, token, stable); 6232 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 6233 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 6234 // If this is a perceptible app accessing the provider, 6235 // make sure to count it as being accessed and thus 6236 // back up on the LRU list. This is good because 6237 // content providers are often expensive to start. 6238 updateLruProcessLocked(cpr.proc, false, true); 6239 } 6240 } 6241 6242 if (cpr.proc != null) { 6243 if (false) { 6244 if (cpr.name.flattenToShortString().equals( 6245 "com.android.providers.calendar/.CalendarProvider2")) { 6246 Slog.v(TAG, "****************** KILLING " 6247 + cpr.name.flattenToShortString()); 6248 Process.killProcess(cpr.proc.pid); 6249 } 6250 } 6251 boolean success = updateOomAdjLocked(cpr.proc); 6252 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 6253 // NOTE: there is still a race here where a signal could be 6254 // pending on the process even though we managed to update its 6255 // adj level. Not sure what to do about this, but at least 6256 // the race is now smaller. 6257 if (!success) { 6258 // Uh oh... it looks like the provider's process 6259 // has been killed on us. We need to wait for a new 6260 // process to be started, and make sure its death 6261 // doesn't kill our process. 6262 Slog.i(TAG, 6263 "Existing provider " + cpr.name.flattenToShortString() 6264 + " is crashing; detaching " + r); 6265 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 6266 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 6267 if (!lastRef) { 6268 // This wasn't the last ref our process had on 6269 // the provider... we have now been killed, bail. 6270 return null; 6271 } 6272 providerRunning = false; 6273 conn = null; 6274 } 6275 } 6276 6277 Binder.restoreCallingIdentity(origId); 6278 } 6279 6280 if (!providerRunning) { 6281 try { 6282 cpi = AppGlobals.getPackageManager(). 6283 resolveContentProvider(name, 6284 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 6285 } catch (RemoteException ex) { 6286 } 6287 if (cpi == null) { 6288 return null; 6289 } 6290 if (isSingleton(cpi.processName, cpi.applicationInfo)) { 6291 userId = 0; 6292 } 6293 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 6294 6295 String msg; 6296 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 6297 throw new SecurityException(msg); 6298 } 6299 6300 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 6301 && !cpi.processName.equals("system")) { 6302 // If this content provider does not run in the system 6303 // process, and the system is not yet ready to run other 6304 // processes, then fail fast instead of hanging. 6305 throw new IllegalArgumentException( 6306 "Attempt to launch content provider before system ready"); 6307 } 6308 6309 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 6310 cpr = mProviderMap.getProviderByClass(comp, userId); 6311 final boolean firstClass = cpr == null; 6312 if (firstClass) { 6313 try { 6314 ApplicationInfo ai = 6315 AppGlobals.getPackageManager(). 6316 getApplicationInfo( 6317 cpi.applicationInfo.packageName, 6318 STOCK_PM_FLAGS, userId); 6319 if (ai == null) { 6320 Slog.w(TAG, "No package info for content provider " 6321 + cpi.name); 6322 return null; 6323 } 6324 ai = getAppInfoForUser(ai, userId); 6325 cpr = new ContentProviderRecord(this, cpi, ai, comp); 6326 } catch (RemoteException ex) { 6327 // pm is in same process, this will never happen. 6328 } 6329 } 6330 6331 if (r != null && cpr.canRunHere(r)) { 6332 // If this is a multiprocess provider, then just return its 6333 // info and allow the caller to instantiate it. Only do 6334 // this if the provider is the same user as the caller's 6335 // process, or can run as root (so can be in any process). 6336 return cpr.newHolder(null); 6337 } 6338 6339 if (DEBUG_PROVIDER) { 6340 RuntimeException e = new RuntimeException("here"); 6341 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid 6342 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 6343 } 6344 6345 // This is single process, and our app is now connecting to it. 6346 // See if we are already in the process of launching this 6347 // provider. 6348 final int N = mLaunchingProviders.size(); 6349 int i; 6350 for (i=0; i<N; i++) { 6351 if (mLaunchingProviders.get(i) == cpr) { 6352 break; 6353 } 6354 } 6355 6356 // If the provider is not already being launched, then get it 6357 // started. 6358 if (i >= N) { 6359 final long origId = Binder.clearCallingIdentity(); 6360 6361 try { 6362 // Content provider is now in use, its package can't be stopped. 6363 try { 6364 AppGlobals.getPackageManager().setPackageStoppedState( 6365 cpr.appInfo.packageName, false, userId); 6366 } catch (RemoteException e) { 6367 } catch (IllegalArgumentException e) { 6368 Slog.w(TAG, "Failed trying to unstop package " 6369 + cpr.appInfo.packageName + ": " + e); 6370 } 6371 6372 ProcessRecord proc = startProcessLocked(cpi.processName, 6373 cpr.appInfo, false, 0, "content provider", 6374 new ComponentName(cpi.applicationInfo.packageName, 6375 cpi.name), false, false); 6376 if (proc == null) { 6377 Slog.w(TAG, "Unable to launch app " 6378 + cpi.applicationInfo.packageName + "/" 6379 + cpi.applicationInfo.uid + " for provider " 6380 + name + ": process is bad"); 6381 return null; 6382 } 6383 cpr.launchingApp = proc; 6384 mLaunchingProviders.add(cpr); 6385 } finally { 6386 Binder.restoreCallingIdentity(origId); 6387 } 6388 } 6389 6390 // Make sure the provider is published (the same provider class 6391 // may be published under multiple names). 6392 if (firstClass) { 6393 mProviderMap.putProviderByClass(comp, cpr); 6394 } 6395 6396 mProviderMap.putProviderByName(name, cpr); 6397 conn = incProviderCountLocked(r, cpr, token, stable); 6398 if (conn != null) { 6399 conn.waiting = true; 6400 } 6401 } 6402 } 6403 6404 // Wait for the provider to be published... 6405 synchronized (cpr) { 6406 while (cpr.provider == null) { 6407 if (cpr.launchingApp == null) { 6408 Slog.w(TAG, "Unable to launch app " 6409 + cpi.applicationInfo.packageName + "/" 6410 + cpi.applicationInfo.uid + " for provider " 6411 + name + ": launching app became null"); 6412 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 6413 cpi.applicationInfo.packageName, 6414 cpi.applicationInfo.uid, name); 6415 return null; 6416 } 6417 try { 6418 if (DEBUG_MU) { 6419 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 6420 + cpr.launchingApp); 6421 } 6422 if (conn != null) { 6423 conn.waiting = true; 6424 } 6425 cpr.wait(); 6426 } catch (InterruptedException ex) { 6427 } finally { 6428 if (conn != null) { 6429 conn.waiting = false; 6430 } 6431 } 6432 } 6433 } 6434 return cpr != null ? cpr.newHolder(conn) : null; 6435 } 6436 6437 public final ContentProviderHolder getContentProvider( 6438 IApplicationThread caller, String name, boolean stable) { 6439 enforceNotIsolatedCaller("getContentProvider"); 6440 if (caller == null) { 6441 String msg = "null IApplicationThread when getting content provider " 6442 + name; 6443 Slog.w(TAG, msg); 6444 throw new SecurityException(msg); 6445 } 6446 6447 return getContentProviderImpl(caller, name, null, stable); 6448 } 6449 6450 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) { 6451 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6452 "Do not have permission in call getContentProviderExternal()"); 6453 return getContentProviderExternalUnchecked(name, token); 6454 } 6455 6456 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) { 6457 return getContentProviderImpl(null, name, token, true); 6458 } 6459 6460 /** 6461 * Drop a content provider from a ProcessRecord's bookkeeping 6462 * @param cpr 6463 */ 6464 public void removeContentProvider(IBinder connection, boolean stable) { 6465 enforceNotIsolatedCaller("removeContentProvider"); 6466 synchronized (this) { 6467 ContentProviderConnection conn; 6468 try { 6469 conn = (ContentProviderConnection)connection; 6470 } catch (ClassCastException e) { 6471 String msg ="removeContentProvider: " + connection 6472 + " not a ContentProviderConnection"; 6473 Slog.w(TAG, msg); 6474 throw new IllegalArgumentException(msg); 6475 } 6476 if (conn == null) { 6477 throw new NullPointerException("connection is null"); 6478 } 6479 if (decProviderCountLocked(conn, null, null, stable)) { 6480 updateOomAdjLocked(); 6481 } 6482 } 6483 } 6484 6485 public void removeContentProviderExternal(String name, IBinder token) { 6486 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 6487 "Do not have permission in call removeContentProviderExternal()"); 6488 removeContentProviderExternalUnchecked(name, token); 6489 } 6490 6491 private void removeContentProviderExternalUnchecked(String name, IBinder token) { 6492 synchronized (this) { 6493 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, 6494 Binder.getOrigCallingUser()); 6495 if(cpr == null) { 6496 //remove from mProvidersByClass 6497 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 6498 return; 6499 } 6500 6501 //update content provider record entry info 6502 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 6503 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, 6504 Binder.getOrigCallingUser()); 6505 if (localCpr.hasExternalProcessHandles()) { 6506 if (localCpr.removeExternalProcessHandleLocked(token)) { 6507 updateOomAdjLocked(); 6508 } else { 6509 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 6510 + " with no external reference for token: " 6511 + token + "."); 6512 } 6513 } else { 6514 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 6515 + " with no external references."); 6516 } 6517 } 6518 } 6519 6520 public final void publishContentProviders(IApplicationThread caller, 6521 List<ContentProviderHolder> providers) { 6522 if (providers == null) { 6523 return; 6524 } 6525 6526 enforceNotIsolatedCaller("publishContentProviders"); 6527 synchronized (this) { 6528 final ProcessRecord r = getRecordForAppLocked(caller); 6529 if (DEBUG_MU) 6530 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 6531 if (r == null) { 6532 throw new SecurityException( 6533 "Unable to find app for caller " + caller 6534 + " (pid=" + Binder.getCallingPid() 6535 + ") when publishing content providers"); 6536 } 6537 6538 final long origId = Binder.clearCallingIdentity(); 6539 6540 final int N = providers.size(); 6541 for (int i=0; i<N; i++) { 6542 ContentProviderHolder src = providers.get(i); 6543 if (src == null || src.info == null || src.provider == null) { 6544 continue; 6545 } 6546 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 6547 if (DEBUG_MU) 6548 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 6549 if (dst != null) { 6550 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 6551 mProviderMap.putProviderByClass(comp, dst); 6552 String names[] = dst.info.authority.split(";"); 6553 for (int j = 0; j < names.length; j++) { 6554 mProviderMap.putProviderByName(names[j], dst); 6555 } 6556 6557 int NL = mLaunchingProviders.size(); 6558 int j; 6559 for (j=0; j<NL; j++) { 6560 if (mLaunchingProviders.get(j) == dst) { 6561 mLaunchingProviders.remove(j); 6562 j--; 6563 NL--; 6564 } 6565 } 6566 synchronized (dst) { 6567 dst.provider = src.provider; 6568 dst.proc = r; 6569 dst.notifyAll(); 6570 } 6571 updateOomAdjLocked(r); 6572 } 6573 } 6574 6575 Binder.restoreCallingIdentity(origId); 6576 } 6577 } 6578 6579 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 6580 ContentProviderConnection conn; 6581 try { 6582 conn = (ContentProviderConnection)connection; 6583 } catch (ClassCastException e) { 6584 String msg ="refContentProvider: " + connection 6585 + " not a ContentProviderConnection"; 6586 Slog.w(TAG, msg); 6587 throw new IllegalArgumentException(msg); 6588 } 6589 if (conn == null) { 6590 throw new NullPointerException("connection is null"); 6591 } 6592 6593 synchronized (this) { 6594 if (stable > 0) { 6595 conn.numStableIncs += stable; 6596 } 6597 stable = conn.stableCount + stable; 6598 if (stable < 0) { 6599 throw new IllegalStateException("stableCount < 0: " + stable); 6600 } 6601 6602 if (unstable > 0) { 6603 conn.numUnstableIncs += unstable; 6604 } 6605 unstable = conn.unstableCount + unstable; 6606 if (unstable < 0) { 6607 throw new IllegalStateException("unstableCount < 0: " + unstable); 6608 } 6609 6610 if ((stable+unstable) <= 0) { 6611 throw new IllegalStateException("ref counts can't go to zero here: stable=" 6612 + stable + " unstable=" + unstable); 6613 } 6614 conn.stableCount = stable; 6615 conn.unstableCount = unstable; 6616 return !conn.dead; 6617 } 6618 } 6619 6620 public void unstableProviderDied(IBinder connection) { 6621 ContentProviderConnection conn; 6622 try { 6623 conn = (ContentProviderConnection)connection; 6624 } catch (ClassCastException e) { 6625 String msg ="refContentProvider: " + connection 6626 + " not a ContentProviderConnection"; 6627 Slog.w(TAG, msg); 6628 throw new IllegalArgumentException(msg); 6629 } 6630 if (conn == null) { 6631 throw new NullPointerException("connection is null"); 6632 } 6633 6634 // Safely retrieve the content provider associated with the connection. 6635 IContentProvider provider; 6636 synchronized (this) { 6637 provider = conn.provider.provider; 6638 } 6639 6640 if (provider == null) { 6641 // Um, yeah, we're way ahead of you. 6642 return; 6643 } 6644 6645 // Make sure the caller is being honest with us. 6646 if (provider.asBinder().pingBinder()) { 6647 // Er, no, still looks good to us. 6648 synchronized (this) { 6649 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 6650 + " says " + conn + " died, but we don't agree"); 6651 return; 6652 } 6653 } 6654 6655 // Well look at that! It's dead! 6656 synchronized (this) { 6657 if (conn.provider.provider != provider) { 6658 // But something changed... good enough. 6659 return; 6660 } 6661 6662 ProcessRecord proc = conn.provider.proc; 6663 if (proc == null || proc.thread == null) { 6664 // Seems like the process is already cleaned up. 6665 return; 6666 } 6667 6668 // As far as we're concerned, this is just like receiving a 6669 // death notification... just a bit prematurely. 6670 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 6671 + ") early provider death"); 6672 final long ident = Binder.clearCallingIdentity(); 6673 try { 6674 appDiedLocked(proc, proc.pid, proc.thread); 6675 } finally { 6676 Binder.restoreCallingIdentity(ident); 6677 } 6678 } 6679 } 6680 6681 public static final void installSystemProviders() { 6682 List<ProviderInfo> providers; 6683 synchronized (mSelf) { 6684 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 6685 providers = mSelf.generateApplicationProvidersLocked(app); 6686 if (providers != null) { 6687 for (int i=providers.size()-1; i>=0; i--) { 6688 ProviderInfo pi = (ProviderInfo)providers.get(i); 6689 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 6690 Slog.w(TAG, "Not installing system proc provider " + pi.name 6691 + ": not system .apk"); 6692 providers.remove(i); 6693 } 6694 } 6695 } 6696 } 6697 if (providers != null) { 6698 mSystemThread.installSystemProviders(providers); 6699 } 6700 6701 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 6702 6703 mSelf.mUsageStatsService.monitorPackages(); 6704 } 6705 6706 /** 6707 * Allows app to retrieve the MIME type of a URI without having permission 6708 * to access its content provider. 6709 * 6710 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 6711 * 6712 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 6713 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 6714 */ 6715 public String getProviderMimeType(Uri uri) { 6716 enforceNotIsolatedCaller("getProviderMimeType"); 6717 final String name = uri.getAuthority(); 6718 final long ident = Binder.clearCallingIdentity(); 6719 ContentProviderHolder holder = null; 6720 6721 try { 6722 holder = getContentProviderExternalUnchecked(name, null); 6723 if (holder != null) { 6724 return holder.provider.getType(uri); 6725 } 6726 } catch (RemoteException e) { 6727 Log.w(TAG, "Content provider dead retrieving " + uri, e); 6728 return null; 6729 } finally { 6730 if (holder != null) { 6731 removeContentProviderExternalUnchecked(name, null); 6732 } 6733 Binder.restoreCallingIdentity(ident); 6734 } 6735 6736 return null; 6737 } 6738 6739 // ========================================================= 6740 // GLOBAL MANAGEMENT 6741 // ========================================================= 6742 6743 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 6744 ApplicationInfo info, String customProcess, boolean isolated) { 6745 String proc = customProcess != null ? customProcess : info.processName; 6746 BatteryStatsImpl.Uid.Proc ps = null; 6747 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 6748 int uid = info.uid; 6749 if (isolated) { 6750 int userId = UserId.getUserId(uid); 6751 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 6752 uid = 0; 6753 while (true) { 6754 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 6755 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 6756 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 6757 } 6758 uid = UserId.getUid(userId, mNextIsolatedProcessUid); 6759 mNextIsolatedProcessUid++; 6760 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 6761 // No process for this uid, use it. 6762 break; 6763 } 6764 stepsLeft--; 6765 if (stepsLeft <= 0) { 6766 return null; 6767 } 6768 } 6769 } 6770 synchronized (stats) { 6771 ps = stats.getProcessStatsLocked(info.uid, proc); 6772 } 6773 return new ProcessRecord(ps, thread, info, proc, uid); 6774 } 6775 6776 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 6777 ProcessRecord app; 6778 if (!isolated) { 6779 app = getProcessRecordLocked(info.processName, info.uid); 6780 } else { 6781 app = null; 6782 } 6783 6784 if (app == null) { 6785 app = newProcessRecordLocked(null, info, null, isolated); 6786 mProcessNames.put(info.processName, app.uid, app); 6787 if (isolated) { 6788 mIsolatedProcesses.put(app.uid, app); 6789 } 6790 updateLruProcessLocked(app, true, true); 6791 } 6792 6793 // This package really, really can not be stopped. 6794 try { 6795 AppGlobals.getPackageManager().setPackageStoppedState( 6796 info.packageName, false, UserId.getUserId(app.uid)); 6797 } catch (RemoteException e) { 6798 } catch (IllegalArgumentException e) { 6799 Slog.w(TAG, "Failed trying to unstop package " 6800 + info.packageName + ": " + e); 6801 } 6802 6803 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 6804 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 6805 app.persistent = true; 6806 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 6807 } 6808 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 6809 mPersistentStartingProcesses.add(app); 6810 startProcessLocked(app, "added application", app.processName); 6811 } 6812 6813 return app; 6814 } 6815 6816 public void unhandledBack() { 6817 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 6818 "unhandledBack()"); 6819 6820 synchronized(this) { 6821 int count = mMainStack.mHistory.size(); 6822 if (DEBUG_SWITCH) Slog.d( 6823 TAG, "Performing unhandledBack(): stack size = " + count); 6824 if (count > 1) { 6825 final long origId = Binder.clearCallingIdentity(); 6826 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), 6827 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 6828 Binder.restoreCallingIdentity(origId); 6829 } 6830 } 6831 } 6832 6833 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 6834 enforceNotIsolatedCaller("openContentUri"); 6835 String name = uri.getAuthority(); 6836 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null); 6837 ParcelFileDescriptor pfd = null; 6838 if (cph != null) { 6839 // We record the binder invoker's uid in thread-local storage before 6840 // going to the content provider to open the file. Later, in the code 6841 // that handles all permissions checks, we look for this uid and use 6842 // that rather than the Activity Manager's own uid. The effect is that 6843 // we do the check against the caller's permissions even though it looks 6844 // to the content provider like the Activity Manager itself is making 6845 // the request. 6846 sCallerIdentity.set(new Identity( 6847 Binder.getCallingPid(), Binder.getCallingUid())); 6848 try { 6849 pfd = cph.provider.openFile(uri, "r"); 6850 } catch (FileNotFoundException e) { 6851 // do nothing; pfd will be returned null 6852 } finally { 6853 // Ensure that whatever happens, we clean up the identity state 6854 sCallerIdentity.remove(); 6855 } 6856 6857 // We've got the fd now, so we're done with the provider. 6858 removeContentProviderExternalUnchecked(name, null); 6859 } else { 6860 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 6861 } 6862 return pfd; 6863 } 6864 6865 // Actually is sleeping or shutting down or whatever else in the future 6866 // is an inactive state. 6867 public boolean isSleeping() { 6868 return mSleeping || mShuttingDown; 6869 } 6870 6871 public void goingToSleep() { 6872 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6873 != PackageManager.PERMISSION_GRANTED) { 6874 throw new SecurityException("Requires permission " 6875 + android.Manifest.permission.DEVICE_POWER); 6876 } 6877 6878 synchronized(this) { 6879 mWentToSleep = true; 6880 updateEventDispatchingLocked(); 6881 6882 if (!mSleeping) { 6883 mSleeping = true; 6884 mMainStack.stopIfSleepingLocked(); 6885 6886 // Initialize the wake times of all processes. 6887 checkExcessivePowerUsageLocked(false); 6888 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6889 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6890 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6891 } 6892 } 6893 } 6894 6895 public boolean shutdown(int timeout) { 6896 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 6897 != PackageManager.PERMISSION_GRANTED) { 6898 throw new SecurityException("Requires permission " 6899 + android.Manifest.permission.SHUTDOWN); 6900 } 6901 6902 boolean timedout = false; 6903 6904 synchronized(this) { 6905 mShuttingDown = true; 6906 updateEventDispatchingLocked(); 6907 6908 if (mMainStack.mResumedActivity != null) { 6909 mMainStack.stopIfSleepingLocked(); 6910 final long endTime = System.currentTimeMillis() + timeout; 6911 while (mMainStack.mResumedActivity != null 6912 || mMainStack.mPausingActivity != null) { 6913 long delay = endTime - System.currentTimeMillis(); 6914 if (delay <= 0) { 6915 Slog.w(TAG, "Activity manager shutdown timed out"); 6916 timedout = true; 6917 break; 6918 } 6919 try { 6920 this.wait(); 6921 } catch (InterruptedException e) { 6922 } 6923 } 6924 } 6925 } 6926 6927 mUsageStatsService.shutdown(); 6928 mBatteryStatsService.shutdown(); 6929 6930 return timedout; 6931 } 6932 6933 public final void activitySlept(IBinder token) { 6934 if (localLOGV) Slog.v( 6935 TAG, "Activity slept: token=" + token); 6936 6937 ActivityRecord r = null; 6938 6939 final long origId = Binder.clearCallingIdentity(); 6940 6941 synchronized (this) { 6942 r = mMainStack.isInStackLocked(token); 6943 if (r != null) { 6944 mMainStack.activitySleptLocked(r); 6945 } 6946 } 6947 6948 Binder.restoreCallingIdentity(origId); 6949 } 6950 6951 private void comeOutOfSleepIfNeededLocked() { 6952 if (!mWentToSleep && !mLockScreenShown) { 6953 if (mSleeping) { 6954 mSleeping = false; 6955 mMainStack.awakeFromSleepingLocked(); 6956 mMainStack.resumeTopActivityLocked(null); 6957 } 6958 } 6959 } 6960 6961 public void wakingUp() { 6962 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6963 != PackageManager.PERMISSION_GRANTED) { 6964 throw new SecurityException("Requires permission " 6965 + android.Manifest.permission.DEVICE_POWER); 6966 } 6967 6968 synchronized(this) { 6969 mWentToSleep = false; 6970 updateEventDispatchingLocked(); 6971 comeOutOfSleepIfNeededLocked(); 6972 } 6973 } 6974 6975 private void updateEventDispatchingLocked() { 6976 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 6977 } 6978 6979 public void setLockScreenShown(boolean shown) { 6980 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 6981 != PackageManager.PERMISSION_GRANTED) { 6982 throw new SecurityException("Requires permission " 6983 + android.Manifest.permission.DEVICE_POWER); 6984 } 6985 6986 synchronized(this) { 6987 mLockScreenShown = shown; 6988 comeOutOfSleepIfNeededLocked(); 6989 } 6990 } 6991 6992 public void stopAppSwitches() { 6993 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 6994 != PackageManager.PERMISSION_GRANTED) { 6995 throw new SecurityException("Requires permission " 6996 + android.Manifest.permission.STOP_APP_SWITCHES); 6997 } 6998 6999 synchronized(this) { 7000 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7001 + APP_SWITCH_DELAY_TIME; 7002 mDidAppSwitch = false; 7003 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7004 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7005 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7006 } 7007 } 7008 7009 public void resumeAppSwitches() { 7010 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7011 != PackageManager.PERMISSION_GRANTED) { 7012 throw new SecurityException("Requires permission " 7013 + android.Manifest.permission.STOP_APP_SWITCHES); 7014 } 7015 7016 synchronized(this) { 7017 // Note that we don't execute any pending app switches... we will 7018 // let those wait until either the timeout, or the next start 7019 // activity request. 7020 mAppSwitchesAllowedTime = 0; 7021 } 7022 } 7023 7024 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7025 String name) { 7026 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7027 return true; 7028 } 7029 7030 final int perm = checkComponentPermission( 7031 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7032 callingUid, -1, true); 7033 if (perm == PackageManager.PERMISSION_GRANTED) { 7034 return true; 7035 } 7036 7037 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 7038 return false; 7039 } 7040 7041 public void setDebugApp(String packageName, boolean waitForDebugger, 7042 boolean persistent) { 7043 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7044 "setDebugApp()"); 7045 7046 // Note that this is not really thread safe if there are multiple 7047 // callers into it at the same time, but that's not a situation we 7048 // care about. 7049 if (persistent) { 7050 final ContentResolver resolver = mContext.getContentResolver(); 7051 Settings.System.putString( 7052 resolver, Settings.System.DEBUG_APP, 7053 packageName); 7054 Settings.System.putInt( 7055 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7056 waitForDebugger ? 1 : 0); 7057 } 7058 7059 synchronized (this) { 7060 if (!persistent) { 7061 mOrigDebugApp = mDebugApp; 7062 mOrigWaitForDebugger = mWaitForDebugger; 7063 } 7064 mDebugApp = packageName; 7065 mWaitForDebugger = waitForDebugger; 7066 mDebugTransient = !persistent; 7067 if (packageName != null) { 7068 final long origId = Binder.clearCallingIdentity(); 7069 forceStopPackageLocked(packageName, -1, false, false, true, true, 0); 7070 Binder.restoreCallingIdentity(origId); 7071 } 7072 } 7073 } 7074 7075 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 7076 synchronized (this) { 7077 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7078 if (!isDebuggable) { 7079 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7080 throw new SecurityException("Process not debuggable: " + app.packageName); 7081 } 7082 } 7083 7084 mOpenGlTraceApp = processName; 7085 } 7086 } 7087 7088 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 7089 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 7090 synchronized (this) { 7091 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 7092 if (!isDebuggable) { 7093 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 7094 throw new SecurityException("Process not debuggable: " + app.packageName); 7095 } 7096 } 7097 mProfileApp = processName; 7098 mProfileFile = profileFile; 7099 if (mProfileFd != null) { 7100 try { 7101 mProfileFd.close(); 7102 } catch (IOException e) { 7103 } 7104 mProfileFd = null; 7105 } 7106 mProfileFd = profileFd; 7107 mProfileType = 0; 7108 mAutoStopProfiler = autoStopProfiler; 7109 } 7110 } 7111 7112 public void setAlwaysFinish(boolean enabled) { 7113 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7114 "setAlwaysFinish()"); 7115 7116 Settings.System.putInt( 7117 mContext.getContentResolver(), 7118 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7119 7120 synchronized (this) { 7121 mAlwaysFinishActivities = enabled; 7122 } 7123 } 7124 7125 public void setActivityController(IActivityController controller) { 7126 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7127 "setActivityController()"); 7128 synchronized (this) { 7129 mController = controller; 7130 } 7131 } 7132 7133 public boolean isUserAMonkey() { 7134 // For now the fact that there is a controller implies 7135 // we have a monkey. 7136 synchronized (this) { 7137 return mController != null; 7138 } 7139 } 7140 7141 public void registerProcessObserver(IProcessObserver observer) { 7142 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7143 "registerProcessObserver()"); 7144 synchronized (this) { 7145 mProcessObservers.register(observer); 7146 } 7147 } 7148 7149 public void unregisterProcessObserver(IProcessObserver observer) { 7150 synchronized (this) { 7151 mProcessObservers.unregister(observer); 7152 } 7153 } 7154 7155 public void setImmersive(IBinder token, boolean immersive) { 7156 synchronized(this) { 7157 ActivityRecord r = mMainStack.isInStackLocked(token); 7158 if (r == null) { 7159 throw new IllegalArgumentException(); 7160 } 7161 r.immersive = immersive; 7162 } 7163 } 7164 7165 public boolean isImmersive(IBinder token) { 7166 synchronized (this) { 7167 ActivityRecord r = mMainStack.isInStackLocked(token); 7168 if (r == null) { 7169 throw new IllegalArgumentException(); 7170 } 7171 return r.immersive; 7172 } 7173 } 7174 7175 public boolean isTopActivityImmersive() { 7176 enforceNotIsolatedCaller("startActivity"); 7177 synchronized (this) { 7178 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7179 return (r != null) ? r.immersive : false; 7180 } 7181 } 7182 7183 public final void enterSafeMode() { 7184 synchronized(this) { 7185 // It only makes sense to do this before the system is ready 7186 // and started launching other packages. 7187 if (!mSystemReady) { 7188 try { 7189 AppGlobals.getPackageManager().enterSafeMode(); 7190 } catch (RemoteException e) { 7191 } 7192 } 7193 } 7194 } 7195 7196 public final void showSafeModeOverlay() { 7197 View v = LayoutInflater.from(mContext).inflate( 7198 com.android.internal.R.layout.safe_mode, null); 7199 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7200 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 7201 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7202 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7203 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 7204 lp.format = v.getBackground().getOpacity(); 7205 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7206 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7207 ((WindowManager)mContext.getSystemService( 7208 Context.WINDOW_SERVICE)).addView(v, lp); 7209 } 7210 7211 public void noteWakeupAlarm(IIntentSender sender) { 7212 if (!(sender instanceof PendingIntentRecord)) { 7213 return; 7214 } 7215 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7216 synchronized (stats) { 7217 if (mBatteryStatsService.isOnBattery()) { 7218 mBatteryStatsService.enforceCallingPermission(); 7219 PendingIntentRecord rec = (PendingIntentRecord)sender; 7220 int MY_UID = Binder.getCallingUid(); 7221 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7222 BatteryStatsImpl.Uid.Pkg pkg = 7223 stats.getPackageStatsLocked(uid, rec.key.packageName); 7224 pkg.incWakeupsLocked(); 7225 } 7226 } 7227 } 7228 7229 public boolean killPids(int[] pids, String pReason, boolean secure) { 7230 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7231 throw new SecurityException("killPids only available to the system"); 7232 } 7233 String reason = (pReason == null) ? "Unknown" : pReason; 7234 // XXX Note: don't acquire main activity lock here, because the window 7235 // manager calls in with its locks held. 7236 7237 boolean killed = false; 7238 synchronized (mPidsSelfLocked) { 7239 int[] types = new int[pids.length]; 7240 int worstType = 0; 7241 for (int i=0; i<pids.length; i++) { 7242 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7243 if (proc != null) { 7244 int type = proc.setAdj; 7245 types[i] = type; 7246 if (type > worstType) { 7247 worstType = type; 7248 } 7249 } 7250 } 7251 7252 // If the worst oom_adj is somewhere in the hidden proc LRU range, 7253 // then constrain it so we will kill all hidden procs. 7254 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ 7255 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) { 7256 worstType = ProcessList.HIDDEN_APP_MIN_ADJ; 7257 } 7258 7259 // If this is not a secure call, don't let it kill processes that 7260 // are important. 7261 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 7262 worstType = ProcessList.SERVICE_ADJ; 7263 } 7264 7265 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 7266 for (int i=0; i<pids.length; i++) { 7267 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7268 if (proc == null) { 7269 continue; 7270 } 7271 int adj = proc.setAdj; 7272 if (adj >= worstType && !proc.killedBackground) { 7273 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7274 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 7275 proc.processName, adj, reason); 7276 killed = true; 7277 proc.killedBackground = true; 7278 Process.killProcessQuiet(pids[i]); 7279 } 7280 } 7281 } 7282 return killed; 7283 } 7284 7285 @Override 7286 public boolean killProcessesBelowForeground(String reason) { 7287 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7288 throw new SecurityException("killProcessesBelowForeground() only available to system"); 7289 } 7290 7291 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 7292 } 7293 7294 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 7295 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7296 throw new SecurityException("killProcessesBelowAdj() only available to system"); 7297 } 7298 7299 boolean killed = false; 7300 synchronized (mPidsSelfLocked) { 7301 final int size = mPidsSelfLocked.size(); 7302 for (int i = 0; i < size; i++) { 7303 final int pid = mPidsSelfLocked.keyAt(i); 7304 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7305 if (proc == null) continue; 7306 7307 final int adj = proc.setAdj; 7308 if (adj > belowAdj && !proc.killedBackground) { 7309 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 7310 EventLog.writeEvent( 7311 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); 7312 killed = true; 7313 proc.killedBackground = true; 7314 Process.killProcessQuiet(pid); 7315 } 7316 } 7317 } 7318 return killed; 7319 } 7320 7321 public final void startRunning(String pkg, String cls, String action, 7322 String data) { 7323 synchronized(this) { 7324 if (mStartRunning) { 7325 return; 7326 } 7327 mStartRunning = true; 7328 mTopComponent = pkg != null && cls != null 7329 ? new ComponentName(pkg, cls) : null; 7330 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7331 mTopData = data; 7332 if (!mSystemReady) { 7333 return; 7334 } 7335 } 7336 7337 systemReady(null); 7338 } 7339 7340 private void retrieveSettings() { 7341 final ContentResolver resolver = mContext.getContentResolver(); 7342 String debugApp = Settings.System.getString( 7343 resolver, Settings.System.DEBUG_APP); 7344 boolean waitForDebugger = Settings.System.getInt( 7345 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7346 boolean alwaysFinishActivities = Settings.System.getInt( 7347 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7348 7349 Configuration configuration = new Configuration(); 7350 Settings.System.getConfiguration(resolver, configuration); 7351 7352 synchronized (this) { 7353 mDebugApp = mOrigDebugApp = debugApp; 7354 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7355 mAlwaysFinishActivities = alwaysFinishActivities; 7356 // This happens before any activities are started, so we can 7357 // change mConfiguration in-place. 7358 updateConfigurationLocked(configuration, null, false, true); 7359 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 7360 } 7361 } 7362 7363 public boolean testIsSystemReady() { 7364 // no need to synchronize(this) just to read & return the value 7365 return mSystemReady; 7366 } 7367 7368 private static File getCalledPreBootReceiversFile() { 7369 File dataDir = Environment.getDataDirectory(); 7370 File systemDir = new File(dataDir, "system"); 7371 File fname = new File(systemDir, "called_pre_boots.dat"); 7372 return fname; 7373 } 7374 7375 static final int LAST_DONE_VERSION = 10000; 7376 7377 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 7378 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 7379 File file = getCalledPreBootReceiversFile(); 7380 FileInputStream fis = null; 7381 try { 7382 fis = new FileInputStream(file); 7383 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 7384 int fvers = dis.readInt(); 7385 if (fvers == LAST_DONE_VERSION) { 7386 String vers = dis.readUTF(); 7387 String codename = dis.readUTF(); 7388 String build = dis.readUTF(); 7389 if (android.os.Build.VERSION.RELEASE.equals(vers) 7390 && android.os.Build.VERSION.CODENAME.equals(codename) 7391 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 7392 int num = dis.readInt(); 7393 while (num > 0) { 7394 num--; 7395 String pkg = dis.readUTF(); 7396 String cls = dis.readUTF(); 7397 lastDoneReceivers.add(new ComponentName(pkg, cls)); 7398 } 7399 } 7400 } 7401 } catch (FileNotFoundException e) { 7402 } catch (IOException e) { 7403 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 7404 } finally { 7405 if (fis != null) { 7406 try { 7407 fis.close(); 7408 } catch (IOException e) { 7409 } 7410 } 7411 } 7412 return lastDoneReceivers; 7413 } 7414 7415 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 7416 File file = getCalledPreBootReceiversFile(); 7417 FileOutputStream fos = null; 7418 DataOutputStream dos = null; 7419 try { 7420 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 7421 fos = new FileOutputStream(file); 7422 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 7423 dos.writeInt(LAST_DONE_VERSION); 7424 dos.writeUTF(android.os.Build.VERSION.RELEASE); 7425 dos.writeUTF(android.os.Build.VERSION.CODENAME); 7426 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 7427 dos.writeInt(list.size()); 7428 for (int i=0; i<list.size(); i++) { 7429 dos.writeUTF(list.get(i).getPackageName()); 7430 dos.writeUTF(list.get(i).getClassName()); 7431 } 7432 } catch (IOException e) { 7433 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 7434 file.delete(); 7435 } finally { 7436 FileUtils.sync(fos); 7437 if (dos != null) { 7438 try { 7439 dos.close(); 7440 } catch (IOException e) { 7441 // TODO Auto-generated catch block 7442 e.printStackTrace(); 7443 } 7444 } 7445 } 7446 } 7447 7448 public void systemReady(final Runnable goingCallback) { 7449 synchronized(this) { 7450 if (mSystemReady) { 7451 if (goingCallback != null) goingCallback.run(); 7452 return; 7453 } 7454 7455 // Check to see if there are any update receivers to run. 7456 if (!mDidUpdate) { 7457 if (mWaitingUpdate) { 7458 return; 7459 } 7460 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 7461 List<ResolveInfo> ris = null; 7462 try { 7463 ris = AppGlobals.getPackageManager().queryIntentReceivers( 7464 intent, null, 0, 0); 7465 } catch (RemoteException e) { 7466 } 7467 if (ris != null) { 7468 for (int i=ris.size()-1; i>=0; i--) { 7469 if ((ris.get(i).activityInfo.applicationInfo.flags 7470 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7471 ris.remove(i); 7472 } 7473 } 7474 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 7475 7476 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 7477 7478 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 7479 for (int i=0; i<ris.size(); i++) { 7480 ActivityInfo ai = ris.get(i).activityInfo; 7481 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7482 if (lastDoneReceivers.contains(comp)) { 7483 ris.remove(i); 7484 i--; 7485 } 7486 } 7487 7488 for (int i=0; i<ris.size(); i++) { 7489 ActivityInfo ai = ris.get(i).activityInfo; 7490 ComponentName comp = new ComponentName(ai.packageName, ai.name); 7491 doneReceivers.add(comp); 7492 intent.setComponent(comp); 7493 IIntentReceiver finisher = null; 7494 if (i == ris.size()-1) { 7495 finisher = new IIntentReceiver.Stub() { 7496 public void performReceive(Intent intent, int resultCode, 7497 String data, Bundle extras, boolean ordered, 7498 boolean sticky) { 7499 // The raw IIntentReceiver interface is called 7500 // with the AM lock held, so redispatch to 7501 // execute our code without the lock. 7502 mHandler.post(new Runnable() { 7503 public void run() { 7504 synchronized (ActivityManagerService.this) { 7505 mDidUpdate = true; 7506 } 7507 writeLastDonePreBootReceivers(doneReceivers); 7508 showBootMessage(mContext.getText( 7509 R.string.android_upgrading_complete), 7510 false); 7511 systemReady(goingCallback); 7512 } 7513 }); 7514 } 7515 }; 7516 } 7517 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 7518 /* TODO: Send this to all users */ 7519 broadcastIntentLocked(null, null, intent, null, finisher, 7520 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, 7521 0 /* UserId zero */); 7522 if (finisher != null) { 7523 mWaitingUpdate = true; 7524 } 7525 } 7526 } 7527 if (mWaitingUpdate) { 7528 return; 7529 } 7530 mDidUpdate = true; 7531 } 7532 7533 mSystemReady = true; 7534 if (!mStartRunning) { 7535 return; 7536 } 7537 } 7538 7539 ArrayList<ProcessRecord> procsToKill = null; 7540 synchronized(mPidsSelfLocked) { 7541 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 7542 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 7543 if (!isAllowedWhileBooting(proc.info)){ 7544 if (procsToKill == null) { 7545 procsToKill = new ArrayList<ProcessRecord>(); 7546 } 7547 procsToKill.add(proc); 7548 } 7549 } 7550 } 7551 7552 synchronized(this) { 7553 if (procsToKill != null) { 7554 for (int i=procsToKill.size()-1; i>=0; i--) { 7555 ProcessRecord proc = procsToKill.get(i); 7556 Slog.i(TAG, "Removing system update proc: " + proc); 7557 removeProcessLocked(proc, true, false, "system update done"); 7558 } 7559 } 7560 7561 // Now that we have cleaned up any update processes, we 7562 // are ready to start launching real processes and know that 7563 // we won't trample on them any more. 7564 mProcessesReady = true; 7565 } 7566 7567 Slog.i(TAG, "System now ready"); 7568 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 7569 SystemClock.uptimeMillis()); 7570 7571 synchronized(this) { 7572 // Make sure we have no pre-ready processes sitting around. 7573 7574 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7575 ResolveInfo ri = mContext.getPackageManager() 7576 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7577 STOCK_PM_FLAGS); 7578 CharSequence errorMsg = null; 7579 if (ri != null) { 7580 ActivityInfo ai = ri.activityInfo; 7581 ApplicationInfo app = ai.applicationInfo; 7582 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7583 mTopAction = Intent.ACTION_FACTORY_TEST; 7584 mTopData = null; 7585 mTopComponent = new ComponentName(app.packageName, 7586 ai.name); 7587 } else { 7588 errorMsg = mContext.getResources().getText( 7589 com.android.internal.R.string.factorytest_not_system); 7590 } 7591 } else { 7592 errorMsg = mContext.getResources().getText( 7593 com.android.internal.R.string.factorytest_no_action); 7594 } 7595 if (errorMsg != null) { 7596 mTopAction = null; 7597 mTopData = null; 7598 mTopComponent = null; 7599 Message msg = Message.obtain(); 7600 msg.what = SHOW_FACTORY_ERROR_MSG; 7601 msg.getData().putCharSequence("msg", errorMsg); 7602 mHandler.sendMessage(msg); 7603 } 7604 } 7605 } 7606 7607 retrieveSettings(); 7608 7609 if (goingCallback != null) goingCallback.run(); 7610 7611 synchronized (this) { 7612 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7613 try { 7614 List apps = AppGlobals.getPackageManager(). 7615 getPersistentApplications(STOCK_PM_FLAGS); 7616 if (apps != null) { 7617 int N = apps.size(); 7618 int i; 7619 for (i=0; i<N; i++) { 7620 ApplicationInfo info 7621 = (ApplicationInfo)apps.get(i); 7622 if (info != null && 7623 !info.packageName.equals("android")) { 7624 addAppLocked(info, false); 7625 } 7626 } 7627 } 7628 } catch (RemoteException ex) { 7629 // pm is in same process, this will never happen. 7630 } 7631 } 7632 7633 // Start up initial activity. 7634 mBooting = true; 7635 7636 try { 7637 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 7638 Message msg = Message.obtain(); 7639 msg.what = SHOW_UID_ERROR_MSG; 7640 mHandler.sendMessage(msg); 7641 } 7642 } catch (RemoteException e) { 7643 } 7644 7645 mMainStack.resumeTopActivityLocked(null); 7646 } 7647 } 7648 7649 private boolean makeAppCrashingLocked(ProcessRecord app, 7650 String shortMsg, String longMsg, String stackTrace) { 7651 app.crashing = true; 7652 app.crashingReport = generateProcessError(app, 7653 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 7654 startAppProblemLocked(app); 7655 app.stopFreezingAllLocked(); 7656 return handleAppCrashLocked(app); 7657 } 7658 7659 private void makeAppNotRespondingLocked(ProcessRecord app, 7660 String activity, String shortMsg, String longMsg) { 7661 app.notResponding = true; 7662 app.notRespondingReport = generateProcessError(app, 7663 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 7664 activity, shortMsg, longMsg, null); 7665 startAppProblemLocked(app); 7666 app.stopFreezingAllLocked(); 7667 } 7668 7669 /** 7670 * Generate a process error record, suitable for attachment to a ProcessRecord. 7671 * 7672 * @param app The ProcessRecord in which the error occurred. 7673 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7674 * ActivityManager.AppErrorStateInfo 7675 * @param activity The activity associated with the crash, if known. 7676 * @param shortMsg Short message describing the crash. 7677 * @param longMsg Long message describing the crash. 7678 * @param stackTrace Full crash stack trace, may be null. 7679 * 7680 * @return Returns a fully-formed AppErrorStateInfo record. 7681 */ 7682 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7683 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 7684 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7685 7686 report.condition = condition; 7687 report.processName = app.processName; 7688 report.pid = app.pid; 7689 report.uid = app.info.uid; 7690 report.tag = activity; 7691 report.shortMsg = shortMsg; 7692 report.longMsg = longMsg; 7693 report.stackTrace = stackTrace; 7694 7695 return report; 7696 } 7697 7698 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 7699 synchronized (this) { 7700 app.crashing = false; 7701 app.crashingReport = null; 7702 app.notResponding = false; 7703 app.notRespondingReport = null; 7704 if (app.anrDialog == fromDialog) { 7705 app.anrDialog = null; 7706 } 7707 if (app.waitDialog == fromDialog) { 7708 app.waitDialog = null; 7709 } 7710 if (app.pid > 0 && app.pid != MY_PID) { 7711 handleAppCrashLocked(app); 7712 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request"); 7713 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 7714 app.processName, app.setAdj, "user's request after error"); 7715 Process.killProcessQuiet(app.pid); 7716 } 7717 } 7718 } 7719 7720 private boolean handleAppCrashLocked(ProcessRecord app) { 7721 if (mHeadless) { 7722 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 7723 return false; 7724 } 7725 long now = SystemClock.uptimeMillis(); 7726 7727 Long crashTime; 7728 if (!app.isolated) { 7729 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 7730 } else { 7731 crashTime = null; 7732 } 7733 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 7734 // This process loses! 7735 Slog.w(TAG, "Process " + app.info.processName 7736 + " has crashed too many times: killing!"); 7737 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 7738 app.info.processName, app.uid); 7739 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { 7740 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); 7741 if (r.app == app) { 7742 Slog.w(TAG, " Force finishing activity " 7743 + r.intent.getComponent().flattenToShortString()); 7744 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 7745 } 7746 } 7747 if (!app.persistent) { 7748 // We don't want to start this process again until the user 7749 // explicitly does so... but for persistent process, we really 7750 // need to keep it running. If a persistent process is actually 7751 // repeatedly crashing, then badness for everyone. 7752 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid, 7753 app.info.processName); 7754 if (!app.isolated) { 7755 // XXX We don't have a way to mark isolated processes 7756 // as bad, since they don't have a peristent identity. 7757 mBadProcesses.put(app.info.processName, app.uid, now); 7758 mProcessCrashTimes.remove(app.info.processName, app.uid); 7759 } 7760 app.bad = true; 7761 app.removed = true; 7762 // Don't let services in this process be restarted and potentially 7763 // annoy the user repeatedly. Unless it is persistent, since those 7764 // processes run critical code. 7765 removeProcessLocked(app, false, false, "crash"); 7766 mMainStack.resumeTopActivityLocked(null); 7767 return false; 7768 } 7769 mMainStack.resumeTopActivityLocked(null); 7770 } else { 7771 ActivityRecord r = mMainStack.topRunningActivityLocked(null); 7772 if (r != null && r.app == app) { 7773 // If the top running activity is from this crashing 7774 // process, then terminate it to avoid getting in a loop. 7775 Slog.w(TAG, " Force finishing activity " 7776 + r.intent.getComponent().flattenToShortString()); 7777 int index = mMainStack.indexOfActivityLocked(r); 7778 r.stack.finishActivityLocked(r, index, 7779 Activity.RESULT_CANCELED, null, "crashed"); 7780 // Also terminate any activities below it that aren't yet 7781 // stopped, to avoid a situation where one will get 7782 // re-start our crashing activity once it gets resumed again. 7783 index--; 7784 if (index >= 0) { 7785 r = (ActivityRecord)mMainStack.mHistory.get(index); 7786 if (r.state == ActivityState.RESUMED 7787 || r.state == ActivityState.PAUSING 7788 || r.state == ActivityState.PAUSED) { 7789 if (!r.isHomeActivity || mHomeProcess != r.app) { 7790 Slog.w(TAG, " Force finishing activity " 7791 + r.intent.getComponent().flattenToShortString()); 7792 r.stack.finishActivityLocked(r, index, 7793 Activity.RESULT_CANCELED, null, "crashed"); 7794 } 7795 } 7796 } 7797 } 7798 } 7799 7800 // Bump up the crash count of any services currently running in the proc. 7801 if (app.services.size() != 0) { 7802 // Any services running in the application need to be placed 7803 // back in the pending list. 7804 Iterator<ServiceRecord> it = app.services.iterator(); 7805 while (it.hasNext()) { 7806 ServiceRecord sr = it.next(); 7807 sr.crashCount++; 7808 } 7809 } 7810 7811 // If the crashing process is what we consider to be the "home process" and it has been 7812 // replaced by a third-party app, clear the package preferred activities from packages 7813 // with a home activity running in the process to prevent a repeatedly crashing app 7814 // from blocking the user to manually clear the list. 7815 if (app == mHomeProcess && mHomeProcess.activities.size() > 0 7816 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 7817 Iterator it = mHomeProcess.activities.iterator(); 7818 while (it.hasNext()) { 7819 ActivityRecord r = (ActivityRecord)it.next(); 7820 if (r.isHomeActivity) { 7821 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 7822 try { 7823 ActivityThread.getPackageManager() 7824 .clearPackagePreferredActivities(r.packageName); 7825 } catch (RemoteException c) { 7826 // pm is in same process, this will never happen. 7827 } 7828 } 7829 } 7830 } 7831 7832 if (!app.isolated) { 7833 // XXX Can't keep track of crash times for isolated processes, 7834 // because they don't have a perisistent identity. 7835 mProcessCrashTimes.put(app.info.processName, app.uid, now); 7836 } 7837 7838 return true; 7839 } 7840 7841 void startAppProblemLocked(ProcessRecord app) { 7842 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 7843 mContext, app.info.packageName, app.info.flags); 7844 skipCurrentReceiverLocked(app); 7845 } 7846 7847 void skipCurrentReceiverLocked(ProcessRecord app) { 7848 for (BroadcastQueue queue : mBroadcastQueues) { 7849 queue.skipCurrentReceiverLocked(app); 7850 } 7851 } 7852 7853 /** 7854 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 7855 * The application process will exit immediately after this call returns. 7856 * @param app object of the crashing app, null for the system server 7857 * @param crashInfo describing the exception 7858 */ 7859 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 7860 ProcessRecord r = findAppProcess(app, "Crash"); 7861 final String processName = app == null ? "system_server" 7862 : (r == null ? "unknown" : r.processName); 7863 7864 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 7865 processName, 7866 r == null ? -1 : r.info.flags, 7867 crashInfo.exceptionClassName, 7868 crashInfo.exceptionMessage, 7869 crashInfo.throwFileName, 7870 crashInfo.throwLineNumber); 7871 7872 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo); 7873 7874 crashApplication(r, crashInfo); 7875 } 7876 7877 public void handleApplicationStrictModeViolation( 7878 IBinder app, 7879 int violationMask, 7880 StrictMode.ViolationInfo info) { 7881 ProcessRecord r = findAppProcess(app, "StrictMode"); 7882 if (r == null) { 7883 return; 7884 } 7885 7886 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 7887 Integer stackFingerprint = info.hashCode(); 7888 boolean logIt = true; 7889 synchronized (mAlreadyLoggedViolatedStacks) { 7890 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 7891 logIt = false; 7892 // TODO: sub-sample into EventLog for these, with 7893 // the info.durationMillis? Then we'd get 7894 // the relative pain numbers, without logging all 7895 // the stack traces repeatedly. We'd want to do 7896 // likewise in the client code, which also does 7897 // dup suppression, before the Binder call. 7898 } else { 7899 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 7900 mAlreadyLoggedViolatedStacks.clear(); 7901 } 7902 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 7903 } 7904 } 7905 if (logIt) { 7906 logStrictModeViolationToDropBox(r, info); 7907 } 7908 } 7909 7910 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 7911 AppErrorResult result = new AppErrorResult(); 7912 synchronized (this) { 7913 final long origId = Binder.clearCallingIdentity(); 7914 7915 Message msg = Message.obtain(); 7916 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 7917 HashMap<String, Object> data = new HashMap<String, Object>(); 7918 data.put("result", result); 7919 data.put("app", r); 7920 data.put("violationMask", violationMask); 7921 data.put("info", info); 7922 msg.obj = data; 7923 mHandler.sendMessage(msg); 7924 7925 Binder.restoreCallingIdentity(origId); 7926 } 7927 int res = result.get(); 7928 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 7929 } 7930 } 7931 7932 // Depending on the policy in effect, there could be a bunch of 7933 // these in quick succession so we try to batch these together to 7934 // minimize disk writes, number of dropbox entries, and maximize 7935 // compression, by having more fewer, larger records. 7936 private void logStrictModeViolationToDropBox( 7937 ProcessRecord process, 7938 StrictMode.ViolationInfo info) { 7939 if (info == null) { 7940 return; 7941 } 7942 final boolean isSystemApp = process == null || 7943 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 7944 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 7945 final String processName = process == null ? "unknown" : process.processName; 7946 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 7947 final DropBoxManager dbox = (DropBoxManager) 7948 mContext.getSystemService(Context.DROPBOX_SERVICE); 7949 7950 // Exit early if the dropbox isn't configured to accept this report type. 7951 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 7952 7953 boolean bufferWasEmpty; 7954 boolean needsFlush; 7955 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 7956 synchronized (sb) { 7957 bufferWasEmpty = sb.length() == 0; 7958 appendDropBoxProcessHeaders(process, processName, sb); 7959 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 7960 sb.append("System-App: ").append(isSystemApp).append("\n"); 7961 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 7962 if (info.violationNumThisLoop != 0) { 7963 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 7964 } 7965 if (info.numAnimationsRunning != 0) { 7966 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 7967 } 7968 if (info.broadcastIntentAction != null) { 7969 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 7970 } 7971 if (info.durationMillis != -1) { 7972 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 7973 } 7974 if (info.numInstances != -1) { 7975 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 7976 } 7977 if (info.tags != null) { 7978 for (String tag : info.tags) { 7979 sb.append("Span-Tag: ").append(tag).append("\n"); 7980 } 7981 } 7982 sb.append("\n"); 7983 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 7984 sb.append(info.crashInfo.stackTrace); 7985 } 7986 sb.append("\n"); 7987 7988 // Only buffer up to ~64k. Various logging bits truncate 7989 // things at 128k. 7990 needsFlush = (sb.length() > 64 * 1024); 7991 } 7992 7993 // Flush immediately if the buffer's grown too large, or this 7994 // is a non-system app. Non-system apps are isolated with a 7995 // different tag & policy and not batched. 7996 // 7997 // Batching is useful during internal testing with 7998 // StrictMode settings turned up high. Without batching, 7999 // thousands of separate files could be created on boot. 8000 if (!isSystemApp || needsFlush) { 8001 new Thread("Error dump: " + dropboxTag) { 8002 @Override 8003 public void run() { 8004 String report; 8005 synchronized (sb) { 8006 report = sb.toString(); 8007 sb.delete(0, sb.length()); 8008 sb.trimToSize(); 8009 } 8010 if (report.length() != 0) { 8011 dbox.addText(dropboxTag, report); 8012 } 8013 } 8014 }.start(); 8015 return; 8016 } 8017 8018 // System app batching: 8019 if (!bufferWasEmpty) { 8020 // An existing dropbox-writing thread is outstanding, so 8021 // we don't need to start it up. The existing thread will 8022 // catch the buffer appends we just did. 8023 return; 8024 } 8025 8026 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 8027 // (After this point, we shouldn't access AMS internal data structures.) 8028 new Thread("Error dump: " + dropboxTag) { 8029 @Override 8030 public void run() { 8031 // 5 second sleep to let stacks arrive and be batched together 8032 try { 8033 Thread.sleep(5000); // 5 seconds 8034 } catch (InterruptedException e) {} 8035 8036 String errorReport; 8037 synchronized (mStrictModeBuffer) { 8038 errorReport = mStrictModeBuffer.toString(); 8039 if (errorReport.length() == 0) { 8040 return; 8041 } 8042 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 8043 mStrictModeBuffer.trimToSize(); 8044 } 8045 dbox.addText(dropboxTag, errorReport); 8046 } 8047 }.start(); 8048 } 8049 8050 /** 8051 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8052 * @param app object of the crashing app, null for the system server 8053 * @param tag reported by the caller 8054 * @param crashInfo describing the context of the error 8055 * @return true if the process should exit immediately (WTF is fatal) 8056 */ 8057 public boolean handleApplicationWtf(IBinder app, String tag, 8058 ApplicationErrorReport.CrashInfo crashInfo) { 8059 ProcessRecord r = findAppProcess(app, "WTF"); 8060 final String processName = app == null ? "system_server" 8061 : (r == null ? "unknown" : r.processName); 8062 8063 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8064 processName, 8065 r == null ? -1 : r.info.flags, 8066 tag, crashInfo.exceptionMessage); 8067 8068 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 8069 8070 if (r != null && r.pid != Process.myPid() && 8071 Settings.Secure.getInt(mContext.getContentResolver(), 8072 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8073 crashApplication(r, crashInfo); 8074 return true; 8075 } else { 8076 return false; 8077 } 8078 } 8079 8080 /** 8081 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8082 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8083 */ 8084 private ProcessRecord findAppProcess(IBinder app, String reason) { 8085 if (app == null) { 8086 return null; 8087 } 8088 8089 synchronized (this) { 8090 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8091 final int NA = apps.size(); 8092 for (int ia=0; ia<NA; ia++) { 8093 ProcessRecord p = apps.valueAt(ia); 8094 if (p.thread != null && p.thread.asBinder() == app) { 8095 return p; 8096 } 8097 } 8098 } 8099 8100 Slog.w(TAG, "Can't find mystery application for " + reason 8101 + " from pid=" + Binder.getCallingPid() 8102 + " uid=" + Binder.getCallingUid() + ": " + app); 8103 return null; 8104 } 8105 } 8106 8107 /** 8108 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 8109 * to append various headers to the dropbox log text. 8110 */ 8111 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 8112 StringBuilder sb) { 8113 // Watchdog thread ends up invoking this function (with 8114 // a null ProcessRecord) to add the stack file to dropbox. 8115 // Do not acquire a lock on this (am) in such cases, as it 8116 // could cause a potential deadlock, if and when watchdog 8117 // is invoked due to unavailability of lock on am and it 8118 // would prevent watchdog from killing system_server. 8119 if (process == null) { 8120 sb.append("Process: ").append(processName).append("\n"); 8121 return; 8122 } 8123 // Note: ProcessRecord 'process' is guarded by the service 8124 // instance. (notably process.pkgList, which could otherwise change 8125 // concurrently during execution of this method) 8126 synchronized (this) { 8127 sb.append("Process: ").append(processName).append("\n"); 8128 int flags = process.info.flags; 8129 IPackageManager pm = AppGlobals.getPackageManager(); 8130 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8131 for (String pkg : process.pkgList) { 8132 sb.append("Package: ").append(pkg); 8133 try { 8134 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0); 8135 if (pi != null) { 8136 sb.append(" v").append(pi.versionCode); 8137 if (pi.versionName != null) { 8138 sb.append(" (").append(pi.versionName).append(")"); 8139 } 8140 } 8141 } catch (RemoteException e) { 8142 Slog.e(TAG, "Error getting package info: " + pkg, e); 8143 } 8144 sb.append("\n"); 8145 } 8146 } 8147 } 8148 8149 private static String processClass(ProcessRecord process) { 8150 if (process == null || process.pid == MY_PID) { 8151 return "system_server"; 8152 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8153 return "system_app"; 8154 } else { 8155 return "data_app"; 8156 } 8157 } 8158 8159 /** 8160 * Write a description of an error (crash, WTF, ANR) to the drop box. 8161 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8162 * @param process which caused the error, null means the system server 8163 * @param activity which triggered the error, null if unknown 8164 * @param parent activity related to the error, null if unknown 8165 * @param subject line related to the error, null if absent 8166 * @param report in long form describing the error, null if absent 8167 * @param logFile to include in the report, null if none 8168 * @param crashInfo giving an application stack trace, null if absent 8169 */ 8170 public void addErrorToDropBox(String eventType, 8171 ProcessRecord process, String processName, ActivityRecord activity, 8172 ActivityRecord parent, String subject, 8173 final String report, final File logFile, 8174 final ApplicationErrorReport.CrashInfo crashInfo) { 8175 // NOTE -- this must never acquire the ActivityManagerService lock, 8176 // otherwise the watchdog may be prevented from resetting the system. 8177 8178 final String dropboxTag = processClass(process) + "_" + eventType; 8179 final DropBoxManager dbox = (DropBoxManager) 8180 mContext.getSystemService(Context.DROPBOX_SERVICE); 8181 8182 // Exit early if the dropbox isn't configured to accept this report type. 8183 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 8184 8185 final StringBuilder sb = new StringBuilder(1024); 8186 appendDropBoxProcessHeaders(process, processName, sb); 8187 if (activity != null) { 8188 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8189 } 8190 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8191 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8192 } 8193 if (parent != null && parent != activity) { 8194 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8195 } 8196 if (subject != null) { 8197 sb.append("Subject: ").append(subject).append("\n"); 8198 } 8199 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8200 if (Debug.isDebuggerConnected()) { 8201 sb.append("Debugger: Connected\n"); 8202 } 8203 sb.append("\n"); 8204 8205 // Do the rest in a worker thread to avoid blocking the caller on I/O 8206 // (After this point, we shouldn't access AMS internal data structures.) 8207 Thread worker = new Thread("Error dump: " + dropboxTag) { 8208 @Override 8209 public void run() { 8210 if (report != null) { 8211 sb.append(report); 8212 } 8213 if (logFile != null) { 8214 try { 8215 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8216 } catch (IOException e) { 8217 Slog.e(TAG, "Error reading " + logFile, e); 8218 } 8219 } 8220 if (crashInfo != null && crashInfo.stackTrace != null) { 8221 sb.append(crashInfo.stackTrace); 8222 } 8223 8224 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 8225 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 8226 if (lines > 0) { 8227 sb.append("\n"); 8228 8229 // Merge several logcat streams, and take the last N lines 8230 InputStreamReader input = null; 8231 try { 8232 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 8233 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 8234 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 8235 8236 try { logcat.getOutputStream().close(); } catch (IOException e) {} 8237 try { logcat.getErrorStream().close(); } catch (IOException e) {} 8238 input = new InputStreamReader(logcat.getInputStream()); 8239 8240 int num; 8241 char[] buf = new char[8192]; 8242 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 8243 } catch (IOException e) { 8244 Slog.e(TAG, "Error running logcat", e); 8245 } finally { 8246 if (input != null) try { input.close(); } catch (IOException e) {} 8247 } 8248 } 8249 8250 dbox.addText(dropboxTag, sb.toString()); 8251 } 8252 }; 8253 8254 if (process == null) { 8255 // If process is null, we are being called from some internal code 8256 // and may be about to die -- run this synchronously. 8257 worker.run(); 8258 } else { 8259 worker.start(); 8260 } 8261 } 8262 8263 /** 8264 * Bring up the "unexpected error" dialog box for a crashing app. 8265 * Deal with edge cases (intercepts from instrumented applications, 8266 * ActivityController, error intent receivers, that sort of thing). 8267 * @param r the application crashing 8268 * @param crashInfo describing the failure 8269 */ 8270 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8271 long timeMillis = System.currentTimeMillis(); 8272 String shortMsg = crashInfo.exceptionClassName; 8273 String longMsg = crashInfo.exceptionMessage; 8274 String stackTrace = crashInfo.stackTrace; 8275 if (shortMsg != null && longMsg != null) { 8276 longMsg = shortMsg + ": " + longMsg; 8277 } else if (shortMsg != null) { 8278 longMsg = shortMsg; 8279 } 8280 8281 AppErrorResult result = new AppErrorResult(); 8282 synchronized (this) { 8283 if (mController != null) { 8284 try { 8285 String name = r != null ? r.processName : null; 8286 int pid = r != null ? r.pid : Binder.getCallingPid(); 8287 if (!mController.appCrashed(name, pid, 8288 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8289 Slog.w(TAG, "Force-killing crashed app " + name 8290 + " at watcher's request"); 8291 Process.killProcess(pid); 8292 return; 8293 } 8294 } catch (RemoteException e) { 8295 mController = null; 8296 } 8297 } 8298 8299 final long origId = Binder.clearCallingIdentity(); 8300 8301 // If this process is running instrumentation, finish it. 8302 if (r != null && r.instrumentationClass != null) { 8303 Slog.w(TAG, "Error in app " + r.processName 8304 + " running instrumentation " + r.instrumentationClass + ":"); 8305 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 8306 if (longMsg != null) Slog.w(TAG, " " + longMsg); 8307 Bundle info = new Bundle(); 8308 info.putString("shortMsg", shortMsg); 8309 info.putString("longMsg", longMsg); 8310 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8311 Binder.restoreCallingIdentity(origId); 8312 return; 8313 } 8314 8315 // If we can't identify the process or it's already exceeded its crash quota, 8316 // quit right away without showing a crash dialog. 8317 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8318 Binder.restoreCallingIdentity(origId); 8319 return; 8320 } 8321 8322 Message msg = Message.obtain(); 8323 msg.what = SHOW_ERROR_MSG; 8324 HashMap data = new HashMap(); 8325 data.put("result", result); 8326 data.put("app", r); 8327 msg.obj = data; 8328 mHandler.sendMessage(msg); 8329 8330 Binder.restoreCallingIdentity(origId); 8331 } 8332 8333 int res = result.get(); 8334 8335 Intent appErrorIntent = null; 8336 synchronized (this) { 8337 if (r != null && !r.isolated) { 8338 // XXX Can't keep track of crash time for isolated processes, 8339 // since they don't have a persistent identity. 8340 mProcessCrashTimes.put(r.info.processName, r.uid, 8341 SystemClock.uptimeMillis()); 8342 } 8343 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8344 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8345 } 8346 } 8347 8348 if (appErrorIntent != null) { 8349 try { 8350 mContext.startActivity(appErrorIntent); 8351 } catch (ActivityNotFoundException e) { 8352 Slog.w(TAG, "bug report receiver dissappeared", e); 8353 } 8354 } 8355 } 8356 8357 Intent createAppErrorIntentLocked(ProcessRecord r, 8358 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8359 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 8360 if (report == null) { 8361 return null; 8362 } 8363 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8364 result.setComponent(r.errorReportReceiver); 8365 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8366 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8367 return result; 8368 } 8369 8370 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 8371 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 8372 if (r.errorReportReceiver == null) { 8373 return null; 8374 } 8375 8376 if (!r.crashing && !r.notResponding) { 8377 return null; 8378 } 8379 8380 ApplicationErrorReport report = new ApplicationErrorReport(); 8381 report.packageName = r.info.packageName; 8382 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8383 report.processName = r.processName; 8384 report.time = timeMillis; 8385 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 8386 8387 if (r.crashing) { 8388 report.type = ApplicationErrorReport.TYPE_CRASH; 8389 report.crashInfo = crashInfo; 8390 } else if (r.notResponding) { 8391 report.type = ApplicationErrorReport.TYPE_ANR; 8392 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8393 8394 report.anrInfo.activity = r.notRespondingReport.tag; 8395 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8396 report.anrInfo.info = r.notRespondingReport.longMsg; 8397 } 8398 8399 return report; 8400 } 8401 8402 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8403 enforceNotIsolatedCaller("getProcessesInErrorState"); 8404 // assume our apps are happy - lazy create the list 8405 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8406 8407 synchronized (this) { 8408 8409 // iterate across all processes 8410 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8411 ProcessRecord app = mLruProcesses.get(i); 8412 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8413 // This one's in trouble, so we'll generate a report for it 8414 // crashes are higher priority (in case there's a crash *and* an anr) 8415 ActivityManager.ProcessErrorStateInfo report = null; 8416 if (app.crashing) { 8417 report = app.crashingReport; 8418 } else if (app.notResponding) { 8419 report = app.notRespondingReport; 8420 } 8421 8422 if (report != null) { 8423 if (errList == null) { 8424 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8425 } 8426 errList.add(report); 8427 } else { 8428 Slog.w(TAG, "Missing app error report, app = " + app.processName + 8429 " crashing = " + app.crashing + 8430 " notResponding = " + app.notResponding); 8431 } 8432 } 8433 } 8434 } 8435 8436 return errList; 8437 } 8438 8439 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 8440 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 8441 if (currApp != null) { 8442 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 8443 } 8444 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8445 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 8446 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8447 } else if (adj >= ProcessList.HOME_APP_ADJ) { 8448 if (currApp != null) { 8449 currApp.lru = 0; 8450 } 8451 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8452 } else if (adj >= ProcessList.SERVICE_ADJ) { 8453 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8454 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 8455 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 8456 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 8457 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 8458 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 8459 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8460 } else { 8461 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8462 } 8463 } 8464 8465 private void fillInProcMemInfo(ProcessRecord app, 8466 ActivityManager.RunningAppProcessInfo outInfo) { 8467 outInfo.pid = app.pid; 8468 outInfo.uid = app.info.uid; 8469 if (mHeavyWeightProcess == app) { 8470 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8471 } 8472 if (app.persistent) { 8473 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 8474 } 8475 outInfo.lastTrimLevel = app.trimMemoryLevel; 8476 int adj = app.curAdj; 8477 outInfo.importance = oomAdjToImportance(adj, outInfo); 8478 outInfo.importanceReasonCode = app.adjTypeCode; 8479 } 8480 8481 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8482 enforceNotIsolatedCaller("getRunningAppProcesses"); 8483 // Lazy instantiation of list 8484 List<ActivityManager.RunningAppProcessInfo> runList = null; 8485 synchronized (this) { 8486 // Iterate across all processes 8487 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8488 ProcessRecord app = mLruProcesses.get(i); 8489 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8490 // Generate process state info for running application 8491 ActivityManager.RunningAppProcessInfo currApp = 8492 new ActivityManager.RunningAppProcessInfo(app.processName, 8493 app.pid, app.getPackageList()); 8494 fillInProcMemInfo(app, currApp); 8495 if (app.adjSource instanceof ProcessRecord) { 8496 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 8497 currApp.importanceReasonImportance = oomAdjToImportance( 8498 app.adjSourceOom, null); 8499 } else if (app.adjSource instanceof ActivityRecord) { 8500 ActivityRecord r = (ActivityRecord)app.adjSource; 8501 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 8502 } 8503 if (app.adjTarget instanceof ComponentName) { 8504 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 8505 } 8506 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8507 // + " lru=" + currApp.lru); 8508 if (runList == null) { 8509 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8510 } 8511 runList.add(currApp); 8512 } 8513 } 8514 } 8515 return runList; 8516 } 8517 8518 public List<ApplicationInfo> getRunningExternalApplications() { 8519 enforceNotIsolatedCaller("getRunningExternalApplications"); 8520 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 8521 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 8522 if (runningApps != null && runningApps.size() > 0) { 8523 Set<String> extList = new HashSet<String>(); 8524 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 8525 if (app.pkgList != null) { 8526 for (String pkg : app.pkgList) { 8527 extList.add(pkg); 8528 } 8529 } 8530 } 8531 IPackageManager pm = AppGlobals.getPackageManager(); 8532 for (String pkg : extList) { 8533 try { 8534 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId()); 8535 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 8536 retList.add(info); 8537 } 8538 } catch (RemoteException e) { 8539 } 8540 } 8541 } 8542 return retList; 8543 } 8544 8545 @Override 8546 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 8547 enforceNotIsolatedCaller("getMyMemoryState"); 8548 synchronized (this) { 8549 ProcessRecord proc; 8550 synchronized (mPidsSelfLocked) { 8551 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 8552 } 8553 fillInProcMemInfo(proc, outInfo); 8554 } 8555 } 8556 8557 @Override 8558 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8559 if (checkCallingPermission(android.Manifest.permission.DUMP) 8560 != PackageManager.PERMISSION_GRANTED) { 8561 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8562 + Binder.getCallingPid() 8563 + ", uid=" + Binder.getCallingUid() 8564 + " without permission " 8565 + android.Manifest.permission.DUMP); 8566 return; 8567 } 8568 8569 boolean dumpAll = false; 8570 boolean dumpClient = false; 8571 String dumpPackage = null; 8572 8573 int opti = 0; 8574 while (opti < args.length) { 8575 String opt = args[opti]; 8576 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 8577 break; 8578 } 8579 opti++; 8580 if ("-a".equals(opt)) { 8581 dumpAll = true; 8582 } else if ("-c".equals(opt)) { 8583 dumpClient = true; 8584 } else if ("-h".equals(opt)) { 8585 pw.println("Activity manager dump options:"); 8586 pw.println(" [-a] [-c] [-h] [cmd] ..."); 8587 pw.println(" cmd may be one of:"); 8588 pw.println(" a[ctivities]: activity stack state"); 8589 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state"); 8590 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 8591 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 8592 pw.println(" o[om]: out of memory management"); 8593 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 8594 pw.println(" provider [COMP_SPEC]: provider client-side state"); 8595 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 8596 pw.println(" service [COMP_SPEC]: service client-side state"); 8597 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 8598 pw.println(" all: dump all activities"); 8599 pw.println(" top: dump the top activity"); 8600 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 8601 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 8602 pw.println(" a partial substring in a component name, a"); 8603 pw.println(" hex object identifier."); 8604 pw.println(" -a: include all available server state."); 8605 pw.println(" -c: include client state."); 8606 return; 8607 } else { 8608 pw.println("Unknown argument: " + opt + "; use -h for help"); 8609 } 8610 } 8611 8612 long origId = Binder.clearCallingIdentity(); 8613 boolean more = false; 8614 // Is the caller requesting to dump a particular piece of data? 8615 if (opti < args.length) { 8616 String cmd = args[opti]; 8617 opti++; 8618 if ("activities".equals(cmd) || "a".equals(cmd)) { 8619 synchronized (this) { 8620 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 8621 } 8622 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 8623 String[] newArgs; 8624 String name; 8625 if (opti >= args.length) { 8626 name = null; 8627 newArgs = EMPTY_STRING_ARRAY; 8628 } else { 8629 name = args[opti]; 8630 opti++; 8631 newArgs = new String[args.length - opti]; 8632 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8633 args.length - opti); 8634 } 8635 synchronized (this) { 8636 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 8637 } 8638 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 8639 String[] newArgs; 8640 String name; 8641 if (opti >= args.length) { 8642 name = null; 8643 newArgs = EMPTY_STRING_ARRAY; 8644 } else { 8645 name = args[opti]; 8646 opti++; 8647 newArgs = new String[args.length - opti]; 8648 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8649 args.length - opti); 8650 } 8651 synchronized (this) { 8652 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 8653 } 8654 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 8655 String[] newArgs; 8656 String name; 8657 if (opti >= args.length) { 8658 name = null; 8659 newArgs = EMPTY_STRING_ARRAY; 8660 } else { 8661 name = args[opti]; 8662 opti++; 8663 newArgs = new String[args.length - opti]; 8664 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8665 args.length - opti); 8666 } 8667 synchronized (this) { 8668 dumpProcessesLocked(fd, pw, args, opti, true, name); 8669 } 8670 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 8671 synchronized (this) { 8672 dumpOomLocked(fd, pw, args, opti, true); 8673 } 8674 } else if ("provider".equals(cmd)) { 8675 String[] newArgs; 8676 String name; 8677 if (opti >= args.length) { 8678 name = null; 8679 newArgs = EMPTY_STRING_ARRAY; 8680 } else { 8681 name = args[opti]; 8682 opti++; 8683 newArgs = new String[args.length - opti]; 8684 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 8685 } 8686 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 8687 pw.println("No providers match: " + name); 8688 pw.println("Use -h for help."); 8689 } 8690 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 8691 synchronized (this) { 8692 dumpProvidersLocked(fd, pw, args, opti, true, null); 8693 } 8694 } else if ("service".equals(cmd)) { 8695 String[] newArgs; 8696 String name; 8697 if (opti >= args.length) { 8698 name = null; 8699 newArgs = EMPTY_STRING_ARRAY; 8700 } else { 8701 name = args[opti]; 8702 opti++; 8703 newArgs = new String[args.length - opti]; 8704 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8705 args.length - opti); 8706 } 8707 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 8708 pw.println("No services match: " + name); 8709 pw.println("Use -h for help."); 8710 } 8711 } else if ("package".equals(cmd)) { 8712 String[] newArgs; 8713 if (opti >= args.length) { 8714 pw.println("package: no package name specified"); 8715 pw.println("Use -h for help."); 8716 } else { 8717 dumpPackage = args[opti]; 8718 opti++; 8719 newArgs = new String[args.length - opti]; 8720 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 8721 args.length - opti); 8722 args = newArgs; 8723 opti = 0; 8724 more = true; 8725 } 8726 } else if ("services".equals(cmd) || "s".equals(cmd)) { 8727 synchronized (this) { 8728 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 8729 } 8730 } else { 8731 // Dumping a single activity? 8732 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 8733 pw.println("Bad activity command, or no activities match: " + cmd); 8734 pw.println("Use -h for help."); 8735 } 8736 } 8737 if (!more) { 8738 Binder.restoreCallingIdentity(origId); 8739 return; 8740 } 8741 } 8742 8743 // No piece of data specified, dump everything. 8744 synchronized (this) { 8745 boolean needSep; 8746 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8747 if (needSep) { 8748 pw.println(" "); 8749 } 8750 if (dumpAll) { 8751 pw.println("-------------------------------------------------------------------------------"); 8752 } 8753 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8754 if (needSep) { 8755 pw.println(" "); 8756 } 8757 if (dumpAll) { 8758 pw.println("-------------------------------------------------------------------------------"); 8759 } 8760 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8761 if (needSep) { 8762 pw.println(" "); 8763 } 8764 if (dumpAll) { 8765 pw.println("-------------------------------------------------------------------------------"); 8766 } 8767 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8768 if (needSep) { 8769 pw.println(" "); 8770 } 8771 if (dumpAll) { 8772 pw.println("-------------------------------------------------------------------------------"); 8773 } 8774 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 8775 if (needSep) { 8776 pw.println(" "); 8777 } 8778 if (dumpAll) { 8779 pw.println("-------------------------------------------------------------------------------"); 8780 } 8781 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 8782 } 8783 Binder.restoreCallingIdentity(origId); 8784 } 8785 8786 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8787 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 8788 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 8789 pw.println(" Main stack:"); 8790 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, 8791 dumpPackage); 8792 pw.println(" "); 8793 pw.println(" Running activities (most recent first):"); 8794 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, 8795 dumpPackage); 8796 if (mMainStack.mWaitingVisibleActivities.size() > 0) { 8797 pw.println(" "); 8798 pw.println(" Activities waiting for another to become visible:"); 8799 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false, 8800 !dumpAll, false, dumpPackage); 8801 } 8802 if (mMainStack.mStoppingActivities.size() > 0) { 8803 pw.println(" "); 8804 pw.println(" Activities waiting to stop:"); 8805 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false, 8806 !dumpAll, false, dumpPackage); 8807 } 8808 if (mMainStack.mGoingToSleepActivities.size() > 0) { 8809 pw.println(" "); 8810 pw.println(" Activities waiting to sleep:"); 8811 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false, 8812 !dumpAll, false, dumpPackage); 8813 } 8814 if (mMainStack.mFinishingActivities.size() > 0) { 8815 pw.println(" "); 8816 pw.println(" Activities waiting to finish:"); 8817 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false, 8818 !dumpAll, false, dumpPackage); 8819 } 8820 8821 pw.println(" "); 8822 if (mMainStack.mPausingActivity != null) { 8823 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); 8824 } 8825 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); 8826 pw.println(" mFocusedActivity: " + mFocusedActivity); 8827 if (dumpAll) { 8828 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity); 8829 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout); 8830 pw.println(" mDismissKeyguardOnNextActivity: " 8831 + mMainStack.mDismissKeyguardOnNextActivity); 8832 } 8833 8834 if (mRecentTasks.size() > 0) { 8835 pw.println(); 8836 pw.println(" Recent tasks:"); 8837 8838 final int N = mRecentTasks.size(); 8839 for (int i=0; i<N; i++) { 8840 TaskRecord tr = mRecentTasks.get(i); 8841 if (dumpPackage != null) { 8842 if (tr.realActivity == null || 8843 !dumpPackage.equals(tr.realActivity)) { 8844 continue; 8845 } 8846 } 8847 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8848 pw.println(tr); 8849 if (dumpAll) { 8850 mRecentTasks.get(i).dump(pw, " "); 8851 } 8852 } 8853 } 8854 8855 if (dumpAll) { 8856 pw.println(" "); 8857 pw.println(" mCurTask: " + mCurTask); 8858 } 8859 8860 return true; 8861 } 8862 8863 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 8864 int opti, boolean dumpAll, String dumpPackage) { 8865 boolean needSep = false; 8866 int numPers = 0; 8867 8868 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 8869 8870 if (dumpAll) { 8871 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8872 final int NA = procs.size(); 8873 for (int ia=0; ia<NA; ia++) { 8874 ProcessRecord r = procs.valueAt(ia); 8875 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8876 continue; 8877 } 8878 if (!needSep) { 8879 pw.println(" All known processes:"); 8880 needSep = true; 8881 } 8882 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8883 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8884 pw.print(" "); pw.println(r); 8885 r.dump(pw, " "); 8886 if (r.persistent) { 8887 numPers++; 8888 } 8889 } 8890 } 8891 } 8892 8893 if (mIsolatedProcesses.size() > 0) { 8894 if (needSep) pw.println(" "); 8895 needSep = true; 8896 pw.println(" Isolated process list (sorted by uid):"); 8897 for (int i=0; i<mIsolatedProcesses.size(); i++) { 8898 ProcessRecord r = mIsolatedProcesses.valueAt(i); 8899 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8900 continue; 8901 } 8902 pw.println(String.format("%sIsolated #%2d: %s", 8903 " ", i, r.toString())); 8904 } 8905 } 8906 8907 if (mLruProcesses.size() > 0) { 8908 if (needSep) pw.println(" "); 8909 needSep = true; 8910 pw.println(" Process LRU list (sorted by oom_adj):"); 8911 dumpProcessOomList(pw, this, mLruProcesses, " ", 8912 "Proc", "PERS", false, dumpPackage); 8913 needSep = true; 8914 } 8915 8916 if (dumpAll) { 8917 synchronized (mPidsSelfLocked) { 8918 boolean printed = false; 8919 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8920 ProcessRecord r = mPidsSelfLocked.valueAt(i); 8921 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 8922 continue; 8923 } 8924 if (!printed) { 8925 if (needSep) pw.println(" "); 8926 needSep = true; 8927 pw.println(" PID mappings:"); 8928 printed = true; 8929 } 8930 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8931 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8932 } 8933 } 8934 } 8935 8936 if (mForegroundProcesses.size() > 0) { 8937 synchronized (mPidsSelfLocked) { 8938 boolean printed = false; 8939 for (int i=0; i<mForegroundProcesses.size(); i++) { 8940 ProcessRecord r = mPidsSelfLocked.get( 8941 mForegroundProcesses.valueAt(i).pid); 8942 if (dumpPackage != null && (r == null 8943 || !dumpPackage.equals(r.info.packageName))) { 8944 continue; 8945 } 8946 if (!printed) { 8947 if (needSep) pw.println(" "); 8948 needSep = true; 8949 pw.println(" Foreground Processes:"); 8950 printed = true; 8951 } 8952 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8953 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8954 } 8955 } 8956 } 8957 8958 if (mPersistentStartingProcesses.size() > 0) { 8959 if (needSep) pw.println(" "); 8960 needSep = true; 8961 pw.println(" Persisent processes that are starting:"); 8962 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 8963 "Starting Norm", "Restarting PERS", dumpPackage); 8964 } 8965 8966 if (mRemovedProcesses.size() > 0) { 8967 if (needSep) pw.println(" "); 8968 needSep = true; 8969 pw.println(" Processes that are being removed:"); 8970 dumpProcessList(pw, this, mRemovedProcesses, " ", 8971 "Removed Norm", "Removed PERS", dumpPackage); 8972 } 8973 8974 if (mProcessesOnHold.size() > 0) { 8975 if (needSep) pw.println(" "); 8976 needSep = true; 8977 pw.println(" Processes that are on old until the system is ready:"); 8978 dumpProcessList(pw, this, mProcessesOnHold, " ", 8979 "OnHold Norm", "OnHold PERS", dumpPackage); 8980 } 8981 8982 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 8983 8984 if (mProcessCrashTimes.getMap().size() > 0) { 8985 boolean printed = false; 8986 long now = SystemClock.uptimeMillis(); 8987 for (Map.Entry<String, SparseArray<Long>> procs 8988 : mProcessCrashTimes.getMap().entrySet()) { 8989 String pname = procs.getKey(); 8990 SparseArray<Long> uids = procs.getValue(); 8991 final int N = uids.size(); 8992 for (int i=0; i<N; i++) { 8993 int puid = uids.keyAt(i); 8994 ProcessRecord r = mProcessNames.get(pname, puid); 8995 if (dumpPackage != null && (r == null 8996 || !dumpPackage.equals(r.info.packageName))) { 8997 continue; 8998 } 8999 if (!printed) { 9000 if (needSep) pw.println(" "); 9001 needSep = true; 9002 pw.println(" Time since processes crashed:"); 9003 printed = true; 9004 } 9005 pw.print(" Process "); pw.print(pname); 9006 pw.print(" uid "); pw.print(puid); 9007 pw.print(": last crashed "); 9008 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 9009 pw.println(" ago"); 9010 } 9011 } 9012 } 9013 9014 if (mBadProcesses.getMap().size() > 0) { 9015 boolean printed = false; 9016 for (Map.Entry<String, SparseArray<Long>> procs 9017 : mBadProcesses.getMap().entrySet()) { 9018 String pname = procs.getKey(); 9019 SparseArray<Long> uids = procs.getValue(); 9020 final int N = uids.size(); 9021 for (int i=0; i<N; i++) { 9022 int puid = uids.keyAt(i); 9023 ProcessRecord r = mProcessNames.get(pname, puid); 9024 if (dumpPackage != null && (r == null 9025 || !dumpPackage.equals(r.info.packageName))) { 9026 continue; 9027 } 9028 if (!printed) { 9029 if (needSep) pw.println(" "); 9030 needSep = true; 9031 pw.println(" Bad processes:"); 9032 } 9033 pw.print(" Bad process "); pw.print(pname); 9034 pw.print(" uid "); pw.print(puid); 9035 pw.print(": crashed at time "); 9036 pw.println(uids.valueAt(i)); 9037 } 9038 } 9039 } 9040 9041 pw.println(); 9042 pw.println(" mHomeProcess: " + mHomeProcess); 9043 pw.println(" mPreviousProcess: " + mPreviousProcess); 9044 if (dumpAll) { 9045 StringBuilder sb = new StringBuilder(128); 9046 sb.append(" mPreviousProcessVisibleTime: "); 9047 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 9048 pw.println(sb); 9049 } 9050 if (mHeavyWeightProcess != null) { 9051 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9052 } 9053 pw.println(" mConfiguration: " + mConfiguration); 9054 if (dumpAll) { 9055 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange); 9056 if (mCompatModePackages.getPackages().size() > 0) { 9057 boolean printed = false; 9058 for (Map.Entry<String, Integer> entry 9059 : mCompatModePackages.getPackages().entrySet()) { 9060 String pkg = entry.getKey(); 9061 int mode = entry.getValue(); 9062 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 9063 continue; 9064 } 9065 if (!printed) { 9066 pw.println(" mScreenCompatPackages:"); 9067 printed = true; 9068 } 9069 pw.print(" "); pw.print(pkg); pw.print(": "); 9070 pw.print(mode); pw.println(); 9071 } 9072 } 9073 } 9074 if (mSleeping || mWentToSleep || mLockScreenShown) { 9075 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 9076 + " mLockScreenShown " + mLockScreenShown); 9077 } 9078 if (mShuttingDown) { 9079 pw.println(" mShuttingDown=" + mShuttingDown); 9080 } 9081 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9082 || mOrigWaitForDebugger) { 9083 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9084 + " mDebugTransient=" + mDebugTransient 9085 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9086 } 9087 if (mOpenGlTraceApp != null) { 9088 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 9089 } 9090 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 9091 || mProfileFd != null) { 9092 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 9093 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 9094 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 9095 + mAutoStopProfiler); 9096 } 9097 if (mAlwaysFinishActivities || mController != null) { 9098 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9099 + " mController=" + mController); 9100 } 9101 if (dumpAll) { 9102 pw.println(" Total persistent processes: " + numPers); 9103 pw.println(" mStartRunning=" + mStartRunning 9104 + " mProcessesReady=" + mProcessesReady 9105 + " mSystemReady=" + mSystemReady); 9106 pw.println(" mBooting=" + mBooting 9107 + " mBooted=" + mBooted 9108 + " mFactoryTest=" + mFactoryTest); 9109 pw.print(" mLastPowerCheckRealtime="); 9110 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 9111 pw.println(""); 9112 pw.print(" mLastPowerCheckUptime="); 9113 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 9114 pw.println(""); 9115 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); 9116 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity); 9117 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9118 pw.println(" mNumServiceProcs=" + mNumServiceProcs 9119 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 9120 } 9121 9122 return true; 9123 } 9124 9125 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 9126 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 9127 if (mProcessesToGc.size() > 0) { 9128 boolean printed = false; 9129 long now = SystemClock.uptimeMillis(); 9130 for (int i=0; i<mProcessesToGc.size(); i++) { 9131 ProcessRecord proc = mProcessesToGc.get(i); 9132 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 9133 continue; 9134 } 9135 if (!printed) { 9136 if (needSep) pw.println(" "); 9137 needSep = true; 9138 pw.println(" Processes that are waiting to GC:"); 9139 printed = true; 9140 } 9141 pw.print(" Process "); pw.println(proc); 9142 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9143 pw.print(", last gced="); 9144 pw.print(now-proc.lastRequestedGc); 9145 pw.print(" ms ago, last lowMem="); 9146 pw.print(now-proc.lastLowMemory); 9147 pw.println(" ms ago"); 9148 9149 } 9150 } 9151 return needSep; 9152 } 9153 9154 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9155 int opti, boolean dumpAll) { 9156 boolean needSep = false; 9157 9158 if (mLruProcesses.size() > 0) { 9159 if (needSep) pw.println(" "); 9160 needSep = true; 9161 pw.println(" OOM levels:"); 9162 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ); 9163 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ); 9164 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ); 9165 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ); 9166 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ); 9167 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ); 9168 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ); 9169 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ); 9170 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ); 9171 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ); 9172 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ); 9173 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ); 9174 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ); 9175 9176 if (needSep) pw.println(" "); 9177 needSep = true; 9178 pw.println(" Process OOM control:"); 9179 dumpProcessOomList(pw, this, mLruProcesses, " ", 9180 "Proc", "PERS", true, null); 9181 needSep = true; 9182 } 9183 9184 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 9185 9186 pw.println(); 9187 pw.println(" mHomeProcess: " + mHomeProcess); 9188 pw.println(" mPreviousProcess: " + mPreviousProcess); 9189 if (mHeavyWeightProcess != null) { 9190 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 9191 } 9192 9193 return true; 9194 } 9195 9196 /** 9197 * There are three ways to call this: 9198 * - no service specified: dump all the services 9199 * - a flattened component name that matched an existing service was specified as the 9200 * first arg: dump that one service 9201 * - the first arg isn't the flattened component name of an existing service: 9202 * dump all services whose component contains the first arg as a substring 9203 */ 9204 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9205 int opti, boolean dumpAll) { 9206 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 9207 9208 if ("all".equals(name)) { 9209 synchronized (this) { 9210 try { 9211 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9212 for (UserInfo user : users) { 9213 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9214 services.add(r1); 9215 } 9216 } 9217 } catch (RemoteException re) { 9218 } 9219 } 9220 } else { 9221 ComponentName componentName = name != null 9222 ? ComponentName.unflattenFromString(name) : null; 9223 int objectId = 0; 9224 if (componentName == null) { 9225 // Not a '/' separated full component name; maybe an object ID? 9226 try { 9227 objectId = Integer.parseInt(name, 16); 9228 name = null; 9229 componentName = null; 9230 } catch (RuntimeException e) { 9231 } 9232 } 9233 9234 synchronized (this) { 9235 try { 9236 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9237 for (UserInfo user : users) { 9238 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) { 9239 if (componentName != null) { 9240 if (r1.name.equals(componentName)) { 9241 services.add(r1); 9242 } 9243 } else if (name != null) { 9244 if (r1.name.flattenToString().contains(name)) { 9245 services.add(r1); 9246 } 9247 } else if (System.identityHashCode(r1) == objectId) { 9248 services.add(r1); 9249 } 9250 } 9251 } 9252 } catch (RemoteException re) { 9253 } 9254 } 9255 } 9256 9257 if (services.size() <= 0) { 9258 return false; 9259 } 9260 9261 boolean needSep = false; 9262 for (int i=0; i<services.size(); i++) { 9263 if (needSep) { 9264 pw.println(); 9265 } 9266 needSep = true; 9267 dumpService("", fd, pw, services.get(i), args, dumpAll); 9268 } 9269 return true; 9270 } 9271 9272 /** 9273 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9274 * there is a thread associated with the service. 9275 */ 9276 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw, 9277 final ServiceRecord r, String[] args, boolean dumpAll) { 9278 String innerPrefix = prefix + " "; 9279 synchronized (this) { 9280 pw.print(prefix); pw.print("SERVICE "); 9281 pw.print(r.shortName); pw.print(" "); 9282 pw.print(Integer.toHexString(System.identityHashCode(r))); 9283 pw.print(" pid="); 9284 if (r.app != null) pw.println(r.app.pid); 9285 else pw.println("(not running)"); 9286 if (dumpAll) { 9287 r.dump(pw, innerPrefix); 9288 } 9289 } 9290 if (r.app != null && r.app.thread != null) { 9291 pw.print(prefix); pw.println(" Client:"); 9292 pw.flush(); 9293 try { 9294 TransferPipe tp = new TransferPipe(); 9295 try { 9296 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args); 9297 tp.setBufferPrefix(prefix + " "); 9298 tp.go(fd); 9299 } finally { 9300 tp.kill(); 9301 } 9302 } catch (IOException e) { 9303 pw.println(prefix + " Failure while dumping the service: " + e); 9304 } catch (RemoteException e) { 9305 pw.println(prefix + " Got a RemoteException while dumping the service"); 9306 } 9307 } 9308 } 9309 9310 /** 9311 * There are three ways to call this: 9312 * - no provider specified: dump all the providers 9313 * - a flattened component name that matched an existing provider was specified as the 9314 * first arg: dump that one provider 9315 * - the first arg isn't the flattened component name of an existing provider: 9316 * dump all providers whose component contains the first arg as a substring 9317 */ 9318 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9319 int opti, boolean dumpAll) { 9320 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 9321 } 9322 9323 static class ItemMatcher { 9324 ArrayList<ComponentName> components; 9325 ArrayList<String> strings; 9326 ArrayList<Integer> objects; 9327 boolean all; 9328 9329 ItemMatcher() { 9330 all = true; 9331 } 9332 9333 void build(String name) { 9334 ComponentName componentName = ComponentName.unflattenFromString(name); 9335 if (componentName != null) { 9336 if (components == null) { 9337 components = new ArrayList<ComponentName>(); 9338 } 9339 components.add(componentName); 9340 all = false; 9341 } else { 9342 int objectId = 0; 9343 // Not a '/' separated full component name; maybe an object ID? 9344 try { 9345 objectId = Integer.parseInt(name, 16); 9346 if (objects == null) { 9347 objects = new ArrayList<Integer>(); 9348 } 9349 objects.add(objectId); 9350 all = false; 9351 } catch (RuntimeException e) { 9352 // Not an integer; just do string match. 9353 if (strings == null) { 9354 strings = new ArrayList<String>(); 9355 } 9356 strings.add(name); 9357 all = false; 9358 } 9359 } 9360 } 9361 9362 int build(String[] args, int opti) { 9363 for (; opti<args.length; opti++) { 9364 String name = args[opti]; 9365 if ("--".equals(name)) { 9366 return opti+1; 9367 } 9368 build(name); 9369 } 9370 return opti; 9371 } 9372 9373 boolean match(Object object, ComponentName comp) { 9374 if (all) { 9375 return true; 9376 } 9377 if (components != null) { 9378 for (int i=0; i<components.size(); i++) { 9379 if (components.get(i).equals(comp)) { 9380 return true; 9381 } 9382 } 9383 } 9384 if (objects != null) { 9385 for (int i=0; i<objects.size(); i++) { 9386 if (System.identityHashCode(object) == objects.get(i)) { 9387 return true; 9388 } 9389 } 9390 } 9391 if (strings != null) { 9392 String flat = comp.flattenToString(); 9393 for (int i=0; i<strings.size(); i++) { 9394 if (flat.contains(strings.get(i))) { 9395 return true; 9396 } 9397 } 9398 } 9399 return false; 9400 } 9401 } 9402 9403 /** 9404 * There are three things that cmd can be: 9405 * - a flattened component name that matches an existing activity 9406 * - the cmd arg isn't the flattened component name of an existing activity: 9407 * dump all activity whose component contains the cmd as a substring 9408 * - A hex number of the ActivityRecord object instance. 9409 */ 9410 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 9411 int opti, boolean dumpAll) { 9412 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 9413 9414 if ("all".equals(name)) { 9415 synchronized (this) { 9416 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9417 activities.add(r1); 9418 } 9419 } 9420 } else if ("top".equals(name)) { 9421 synchronized (this) { 9422 final int N = mMainStack.mHistory.size(); 9423 if (N > 0) { 9424 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); 9425 } 9426 } 9427 } else { 9428 ItemMatcher matcher = new ItemMatcher(); 9429 matcher.build(name); 9430 9431 synchronized (this) { 9432 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { 9433 if (matcher.match(r1, r1.intent.getComponent())) { 9434 activities.add(r1); 9435 } 9436 } 9437 } 9438 } 9439 9440 if (activities.size() <= 0) { 9441 return false; 9442 } 9443 9444 String[] newArgs = new String[args.length - opti]; 9445 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9446 9447 TaskRecord lastTask = null; 9448 boolean needSep = false; 9449 for (int i=activities.size()-1; i>=0; i--) { 9450 ActivityRecord r = (ActivityRecord)activities.get(i); 9451 if (needSep) { 9452 pw.println(); 9453 } 9454 needSep = true; 9455 synchronized (this) { 9456 if (lastTask != r.task) { 9457 lastTask = r.task; 9458 pw.print("TASK "); pw.print(lastTask.affinity); 9459 pw.print(" id="); pw.println(lastTask.taskId); 9460 if (dumpAll) { 9461 lastTask.dump(pw, " "); 9462 } 9463 } 9464 } 9465 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 9466 } 9467 return true; 9468 } 9469 9470 /** 9471 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 9472 * there is a thread associated with the activity. 9473 */ 9474 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 9475 final ActivityRecord r, String[] args, boolean dumpAll) { 9476 String innerPrefix = prefix + " "; 9477 synchronized (this) { 9478 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 9479 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 9480 pw.print(" pid="); 9481 if (r.app != null) pw.println(r.app.pid); 9482 else pw.println("(not running)"); 9483 if (dumpAll) { 9484 r.dump(pw, innerPrefix); 9485 } 9486 } 9487 if (r.app != null && r.app.thread != null) { 9488 // flush anything that is already in the PrintWriter since the thread is going 9489 // to write to the file descriptor directly 9490 pw.flush(); 9491 try { 9492 TransferPipe tp = new TransferPipe(); 9493 try { 9494 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9495 r.appToken, innerPrefix, args); 9496 tp.go(fd); 9497 } finally { 9498 tp.kill(); 9499 } 9500 } catch (IOException e) { 9501 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9502 } catch (RemoteException e) { 9503 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9504 } 9505 } 9506 } 9507 9508 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9509 int opti, boolean dumpAll, String dumpPackage) { 9510 boolean needSep = false; 9511 9512 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 9513 if (dumpAll) { 9514 if (mRegisteredReceivers.size() > 0) { 9515 boolean printed = false; 9516 Iterator it = mRegisteredReceivers.values().iterator(); 9517 while (it.hasNext()) { 9518 ReceiverList r = (ReceiverList)it.next(); 9519 if (dumpPackage != null && (r.app == null || 9520 !dumpPackage.equals(r.app.info.packageName))) { 9521 continue; 9522 } 9523 if (!printed) { 9524 pw.println(" Registered Receivers:"); 9525 needSep = true; 9526 printed = true; 9527 } 9528 pw.print(" * "); pw.println(r); 9529 r.dump(pw, " "); 9530 } 9531 } 9532 9533 if (mReceiverResolver.dump(pw, needSep ? 9534 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 9535 " ", dumpPackage, false)) { 9536 needSep = true; 9537 } 9538 } 9539 9540 for (BroadcastQueue q : mBroadcastQueues) { 9541 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 9542 } 9543 9544 needSep = true; 9545 9546 if (mStickyBroadcasts != null && dumpPackage == null) { 9547 if (needSep) { 9548 pw.println(); 9549 } 9550 needSep = true; 9551 pw.println(" Sticky broadcasts:"); 9552 StringBuilder sb = new StringBuilder(128); 9553 for (Map.Entry<String, ArrayList<Intent>> ent 9554 : mStickyBroadcasts.entrySet()) { 9555 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9556 if (dumpAll) { 9557 pw.println(":"); 9558 ArrayList<Intent> intents = ent.getValue(); 9559 final int N = intents.size(); 9560 for (int i=0; i<N; i++) { 9561 sb.setLength(0); 9562 sb.append(" Intent: "); 9563 intents.get(i).toShortString(sb, false, true, false, false); 9564 pw.println(sb.toString()); 9565 Bundle bundle = intents.get(i).getExtras(); 9566 if (bundle != null) { 9567 pw.print(" "); 9568 pw.println(bundle.toString()); 9569 } 9570 } 9571 } else { 9572 pw.println(""); 9573 } 9574 } 9575 needSep = true; 9576 } 9577 9578 if (dumpAll) { 9579 pw.println(); 9580 for (BroadcastQueue queue : mBroadcastQueues) { 9581 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 9582 + queue.mBroadcastsScheduled); 9583 } 9584 pw.println(" mHandler:"); 9585 mHandler.dump(new PrintWriterPrinter(pw), " "); 9586 needSep = true; 9587 } 9588 9589 return needSep; 9590 } 9591 9592 /** 9593 * Prints a list of ServiceRecords (dumpsys activity services) 9594 */ 9595 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9596 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 9597 boolean needSep = false; 9598 9599 ItemMatcher matcher = new ItemMatcher(); 9600 matcher.build(args, opti); 9601 9602 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)"); 9603 try { 9604 List<UserInfo> users = AppGlobals.getPackageManager().getUsers(); 9605 for (UserInfo user : users) { 9606 if (mServiceMap.getAllServices(user.id).size() > 0) { 9607 boolean printed = false; 9608 long nowReal = SystemClock.elapsedRealtime(); 9609 Iterator<ServiceRecord> it = mServiceMap.getAllServices( 9610 user.id).iterator(); 9611 needSep = false; 9612 while (it.hasNext()) { 9613 ServiceRecord r = it.next(); 9614 if (!matcher.match(r, r.name)) { 9615 continue; 9616 } 9617 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9618 continue; 9619 } 9620 if (!printed) { 9621 pw.println(" Active services:"); 9622 printed = true; 9623 } 9624 if (needSep) { 9625 pw.println(); 9626 } 9627 pw.print(" * "); 9628 pw.println(r); 9629 if (dumpAll) { 9630 r.dump(pw, " "); 9631 needSep = true; 9632 } else { 9633 pw.print(" app="); 9634 pw.println(r.app); 9635 pw.print(" created="); 9636 TimeUtils.formatDuration(r.createTime, nowReal, pw); 9637 pw.print(" started="); 9638 pw.print(r.startRequested); 9639 pw.print(" connections="); 9640 pw.println(r.connections.size()); 9641 if (r.connections.size() > 0) { 9642 pw.println(" Connections:"); 9643 for (ArrayList<ConnectionRecord> clist : r.connections.values()) { 9644 for (int i = 0; i < clist.size(); i++) { 9645 ConnectionRecord conn = clist.get(i); 9646 pw.print(" "); 9647 pw.print(conn.binding.intent.intent.getIntent() 9648 .toShortString(false, false, false, false)); 9649 pw.print(" -> "); 9650 ProcessRecord proc = conn.binding.client; 9651 pw.println(proc != null ? proc.toShortString() : "null"); 9652 } 9653 } 9654 } 9655 } 9656 if (dumpClient && r.app != null && r.app.thread != null) { 9657 pw.println(" Client:"); 9658 pw.flush(); 9659 try { 9660 TransferPipe tp = new TransferPipe(); 9661 try { 9662 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), 9663 r, args); 9664 tp.setBufferPrefix(" "); 9665 // Short timeout, since blocking here can 9666 // deadlock with the application. 9667 tp.go(fd, 2000); 9668 } finally { 9669 tp.kill(); 9670 } 9671 } catch (IOException e) { 9672 pw.println(" Failure while dumping the service: " + e); 9673 } catch (RemoteException e) { 9674 pw.println(" Got a RemoteException while dumping the service"); 9675 } 9676 needSep = true; 9677 } 9678 } 9679 needSep = printed; 9680 } 9681 } 9682 } catch (RemoteException re) { 9683 9684 } 9685 9686 if (mPendingServices.size() > 0) { 9687 boolean printed = false; 9688 for (int i=0; i<mPendingServices.size(); i++) { 9689 ServiceRecord r = mPendingServices.get(i); 9690 if (!matcher.match(r, r.name)) { 9691 continue; 9692 } 9693 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9694 continue; 9695 } 9696 if (!printed) { 9697 if (needSep) pw.println(" "); 9698 needSep = true; 9699 pw.println(" Pending services:"); 9700 printed = true; 9701 } 9702 pw.print(" * Pending "); pw.println(r); 9703 r.dump(pw, " "); 9704 } 9705 needSep = true; 9706 } 9707 9708 if (mRestartingServices.size() > 0) { 9709 boolean printed = false; 9710 for (int i=0; i<mRestartingServices.size(); i++) { 9711 ServiceRecord r = mRestartingServices.get(i); 9712 if (!matcher.match(r, r.name)) { 9713 continue; 9714 } 9715 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9716 continue; 9717 } 9718 if (!printed) { 9719 if (needSep) pw.println(" "); 9720 needSep = true; 9721 pw.println(" Restarting services:"); 9722 printed = true; 9723 } 9724 pw.print(" * Restarting "); pw.println(r); 9725 r.dump(pw, " "); 9726 } 9727 needSep = true; 9728 } 9729 9730 if (mStoppingServices.size() > 0) { 9731 boolean printed = false; 9732 for (int i=0; i<mStoppingServices.size(); i++) { 9733 ServiceRecord r = mStoppingServices.get(i); 9734 if (!matcher.match(r, r.name)) { 9735 continue; 9736 } 9737 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { 9738 continue; 9739 } 9740 if (!printed) { 9741 if (needSep) pw.println(" "); 9742 needSep = true; 9743 pw.println(" Stopping services:"); 9744 printed = true; 9745 } 9746 pw.print(" * Stopping "); pw.println(r); 9747 r.dump(pw, " "); 9748 } 9749 needSep = true; 9750 } 9751 9752 if (dumpAll) { 9753 if (mServiceConnections.size() > 0) { 9754 boolean printed = false; 9755 Iterator<ArrayList<ConnectionRecord>> it 9756 = mServiceConnections.values().iterator(); 9757 while (it.hasNext()) { 9758 ArrayList<ConnectionRecord> r = it.next(); 9759 for (int i=0; i<r.size(); i++) { 9760 ConnectionRecord cr = r.get(i); 9761 if (!matcher.match(cr.binding.service, cr.binding.service.name)) { 9762 continue; 9763 } 9764 if (dumpPackage != null && (cr.binding.client == null 9765 || !dumpPackage.equals(cr.binding.client.info.packageName))) { 9766 continue; 9767 } 9768 if (!printed) { 9769 if (needSep) pw.println(" "); 9770 needSep = true; 9771 pw.println(" Connection bindings to services:"); 9772 printed = true; 9773 } 9774 pw.print(" * "); pw.println(cr); 9775 cr.dump(pw, " "); 9776 } 9777 } 9778 needSep = true; 9779 } 9780 } 9781 9782 return needSep; 9783 } 9784 9785 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9786 int opti, boolean dumpAll, String dumpPackage) { 9787 boolean needSep = true; 9788 9789 ItemMatcher matcher = new ItemMatcher(); 9790 matcher.build(args, opti); 9791 9792 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 9793 9794 mProviderMap.dumpProvidersLocked(pw, dumpAll); 9795 9796 if (mLaunchingProviders.size() > 0) { 9797 boolean printed = false; 9798 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9799 ContentProviderRecord r = mLaunchingProviders.get(i); 9800 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 9801 continue; 9802 } 9803 if (!printed) { 9804 if (needSep) pw.println(" "); 9805 needSep = true; 9806 pw.println(" Launching content providers:"); 9807 printed = true; 9808 } 9809 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9810 pw.println(r); 9811 } 9812 } 9813 9814 if (mGrantedUriPermissions.size() > 0) { 9815 if (needSep) pw.println(); 9816 needSep = true; 9817 pw.println("Granted Uri Permissions:"); 9818 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9819 int uid = mGrantedUriPermissions.keyAt(i); 9820 HashMap<Uri, UriPermission> perms 9821 = mGrantedUriPermissions.valueAt(i); 9822 pw.print(" * UID "); pw.print(uid); 9823 pw.println(" holds:"); 9824 for (UriPermission perm : perms.values()) { 9825 pw.print(" "); pw.println(perm); 9826 if (dumpAll) { 9827 perm.dump(pw, " "); 9828 } 9829 } 9830 } 9831 needSep = true; 9832 } 9833 9834 return needSep; 9835 } 9836 9837 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9838 int opti, boolean dumpAll, String dumpPackage) { 9839 boolean needSep = false; 9840 9841 if (mIntentSenderRecords.size() > 0) { 9842 boolean printed = false; 9843 Iterator<WeakReference<PendingIntentRecord>> it 9844 = mIntentSenderRecords.values().iterator(); 9845 while (it.hasNext()) { 9846 WeakReference<PendingIntentRecord> ref = it.next(); 9847 PendingIntentRecord rec = ref != null ? ref.get(): null; 9848 if (dumpPackage != null && (rec == null 9849 || !dumpPackage.equals(rec.key.packageName))) { 9850 continue; 9851 } 9852 if (!printed) { 9853 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 9854 printed = true; 9855 } 9856 needSep = true; 9857 if (rec != null) { 9858 pw.print(" * "); pw.println(rec); 9859 if (dumpAll) { 9860 rec.dump(pw, " "); 9861 } 9862 } else { 9863 pw.print(" * "); pw.println(ref); 9864 } 9865 } 9866 } 9867 9868 return needSep; 9869 } 9870 9871 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, 9872 String prefix, String label, boolean complete, boolean brief, boolean client, 9873 String dumpPackage) { 9874 TaskRecord lastTask = null; 9875 boolean needNL = false; 9876 final String innerPrefix = prefix + " "; 9877 final String[] args = new String[0]; 9878 for (int i=list.size()-1; i>=0; i--) { 9879 final ActivityRecord r = (ActivityRecord)list.get(i); 9880 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) { 9881 continue; 9882 } 9883 final boolean full = !brief && (complete || !r.isInHistory()); 9884 if (needNL) { 9885 pw.println(" "); 9886 needNL = false; 9887 } 9888 if (lastTask != r.task) { 9889 lastTask = r.task; 9890 pw.print(prefix); 9891 pw.print(full ? "* " : " "); 9892 pw.println(lastTask); 9893 if (full) { 9894 lastTask.dump(pw, prefix + " "); 9895 } else if (complete) { 9896 // Complete + brief == give a summary. Isn't that obvious?!? 9897 if (lastTask.intent != null) { 9898 pw.print(prefix); pw.print(" "); 9899 pw.println(lastTask.intent.toInsecureStringWithClip()); 9900 } 9901 } 9902 } 9903 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9904 pw.print(" #"); pw.print(i); pw.print(": "); 9905 pw.println(r); 9906 if (full) { 9907 r.dump(pw, innerPrefix); 9908 } else if (complete) { 9909 // Complete + brief == give a summary. Isn't that obvious?!? 9910 pw.print(innerPrefix); pw.println(r.intent.toInsecureString()); 9911 if (r.app != null) { 9912 pw.print(innerPrefix); pw.println(r.app); 9913 } 9914 } 9915 if (client && r.app != null && r.app.thread != null) { 9916 // flush anything that is already in the PrintWriter since the thread is going 9917 // to write to the file descriptor directly 9918 pw.flush(); 9919 try { 9920 TransferPipe tp = new TransferPipe(); 9921 try { 9922 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 9923 r.appToken, innerPrefix, args); 9924 // Short timeout, since blocking here can 9925 // deadlock with the application. 9926 tp.go(fd, 2000); 9927 } finally { 9928 tp.kill(); 9929 } 9930 } catch (IOException e) { 9931 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 9932 } catch (RemoteException e) { 9933 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 9934 } 9935 needNL = true; 9936 } 9937 } 9938 } 9939 9940 private static String buildOomTag(String prefix, String space, int val, int base) { 9941 if (val == base) { 9942 if (space == null) return prefix; 9943 return prefix + " "; 9944 } 9945 return prefix + "+" + Integer.toString(val-base); 9946 } 9947 9948 private static final int dumpProcessList(PrintWriter pw, 9949 ActivityManagerService service, List list, 9950 String prefix, String normalLabel, String persistentLabel, 9951 String dumpPackage) { 9952 int numPers = 0; 9953 final int N = list.size()-1; 9954 for (int i=N; i>=0; i--) { 9955 ProcessRecord r = (ProcessRecord)list.get(i); 9956 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9957 continue; 9958 } 9959 pw.println(String.format("%s%s #%2d: %s", 9960 prefix, (r.persistent ? persistentLabel : normalLabel), 9961 i, r.toString())); 9962 if (r.persistent) { 9963 numPers++; 9964 } 9965 } 9966 return numPers; 9967 } 9968 9969 private static final boolean dumpProcessOomList(PrintWriter pw, 9970 ActivityManagerService service, List<ProcessRecord> origList, 9971 String prefix, String normalLabel, String persistentLabel, 9972 boolean inclDetails, String dumpPackage) { 9973 9974 ArrayList<Pair<ProcessRecord, Integer>> list 9975 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 9976 for (int i=0; i<origList.size(); i++) { 9977 ProcessRecord r = origList.get(i); 9978 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 9979 continue; 9980 } 9981 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 9982 } 9983 9984 if (list.size() <= 0) { 9985 return false; 9986 } 9987 9988 Comparator<Pair<ProcessRecord, Integer>> comparator 9989 = new Comparator<Pair<ProcessRecord, Integer>>() { 9990 @Override 9991 public int compare(Pair<ProcessRecord, Integer> object1, 9992 Pair<ProcessRecord, Integer> object2) { 9993 if (object1.first.setAdj != object2.first.setAdj) { 9994 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 9995 } 9996 if (object1.second.intValue() != object2.second.intValue()) { 9997 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 9998 } 9999 return 0; 10000 } 10001 }; 10002 10003 Collections.sort(list, comparator); 10004 10005 final long curRealtime = SystemClock.elapsedRealtime(); 10006 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 10007 final long curUptime = SystemClock.uptimeMillis(); 10008 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 10009 10010 for (int i=list.size()-1; i>=0; i--) { 10011 ProcessRecord r = list.get(i).first; 10012 String oomAdj; 10013 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 10014 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ); 10015 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) { 10016 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ); 10017 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 10018 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ); 10019 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) { 10020 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ); 10021 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) { 10022 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ); 10023 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) { 10024 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ); 10025 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10026 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ); 10027 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10028 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ); 10029 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) { 10030 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ); 10031 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 10032 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ); 10033 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 10034 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ); 10035 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) { 10036 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ); 10037 } else { 10038 oomAdj = Integer.toString(r.setAdj); 10039 } 10040 String schedGroup; 10041 switch (r.setSchedGroup) { 10042 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10043 schedGroup = "B"; 10044 break; 10045 case Process.THREAD_GROUP_DEFAULT: 10046 schedGroup = "F"; 10047 break; 10048 default: 10049 schedGroup = Integer.toString(r.setSchedGroup); 10050 break; 10051 } 10052 String foreground; 10053 if (r.foregroundActivities) { 10054 foreground = "A"; 10055 } else if (r.foregroundServices) { 10056 foreground = "S"; 10057 } else { 10058 foreground = " "; 10059 } 10060 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)", 10061 prefix, (r.persistent ? persistentLabel : normalLabel), 10062 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup, 10063 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType)); 10064 if (r.adjSource != null || r.adjTarget != null) { 10065 pw.print(prefix); 10066 pw.print(" "); 10067 if (r.adjTarget instanceof ComponentName) { 10068 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 10069 } else if (r.adjTarget != null) { 10070 pw.print(r.adjTarget.toString()); 10071 } else { 10072 pw.print("{null}"); 10073 } 10074 pw.print("<="); 10075 if (r.adjSource instanceof ProcessRecord) { 10076 pw.print("Proc{"); 10077 pw.print(((ProcessRecord)r.adjSource).toShortString()); 10078 pw.println("}"); 10079 } else if (r.adjSource != null) { 10080 pw.println(r.adjSource.toString()); 10081 } else { 10082 pw.println("{null}"); 10083 } 10084 } 10085 if (inclDetails) { 10086 pw.print(prefix); 10087 pw.print(" "); 10088 pw.print("oom: max="); pw.print(r.maxAdj); 10089 pw.print(" hidden="); pw.print(r.hiddenAdj); 10090 pw.print(" curRaw="); pw.print(r.curRawAdj); 10091 pw.print(" setRaw="); pw.print(r.setRawAdj); 10092 pw.print(" cur="); pw.print(r.curAdj); 10093 pw.print(" set="); pw.println(r.setAdj); 10094 pw.print(prefix); 10095 pw.print(" "); 10096 pw.print("keeping="); pw.print(r.keeping); 10097 pw.print(" hidden="); pw.print(r.hidden); 10098 pw.print(" empty="); pw.print(r.empty); 10099 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 10100 10101 if (!r.keeping) { 10102 if (r.lastWakeTime != 0) { 10103 long wtime; 10104 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 10105 synchronized (stats) { 10106 wtime = stats.getProcessWakeTime(r.info.uid, 10107 r.pid, curRealtime); 10108 } 10109 long timeUsed = wtime - r.lastWakeTime; 10110 pw.print(prefix); 10111 pw.print(" "); 10112 pw.print("keep awake over "); 10113 TimeUtils.formatDuration(realtimeSince, pw); 10114 pw.print(" used "); 10115 TimeUtils.formatDuration(timeUsed, pw); 10116 pw.print(" ("); 10117 pw.print((timeUsed*100)/realtimeSince); 10118 pw.println("%)"); 10119 } 10120 if (r.lastCpuTime != 0) { 10121 long timeUsed = r.curCpuTime - r.lastCpuTime; 10122 pw.print(prefix); 10123 pw.print(" "); 10124 pw.print("run cpu over "); 10125 TimeUtils.formatDuration(uptimeSince, pw); 10126 pw.print(" used "); 10127 TimeUtils.formatDuration(timeUsed, pw); 10128 pw.print(" ("); 10129 pw.print((timeUsed*100)/uptimeSince); 10130 pw.println("%)"); 10131 } 10132 } 10133 } 10134 } 10135 return true; 10136 } 10137 10138 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 10139 ArrayList<ProcessRecord> procs; 10140 synchronized (this) { 10141 if (args != null && args.length > start 10142 && args[start].charAt(0) != '-') { 10143 procs = new ArrayList<ProcessRecord>(); 10144 int pid = -1; 10145 try { 10146 pid = Integer.parseInt(args[start]); 10147 } catch (NumberFormatException e) { 10148 10149 } 10150 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10151 ProcessRecord proc = mLruProcesses.get(i); 10152 if (proc.pid == pid) { 10153 procs.add(proc); 10154 } else if (proc.processName.equals(args[start])) { 10155 procs.add(proc); 10156 } 10157 } 10158 if (procs.size() <= 0) { 10159 pw.println("No process found for: " + args[start]); 10160 return null; 10161 } 10162 } else { 10163 procs = new ArrayList<ProcessRecord>(mLruProcesses); 10164 } 10165 } 10166 return procs; 10167 } 10168 10169 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 10170 PrintWriter pw, String[] args) { 10171 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10172 if (procs == null) { 10173 return; 10174 } 10175 10176 long uptime = SystemClock.uptimeMillis(); 10177 long realtime = SystemClock.elapsedRealtime(); 10178 pw.println("Applications Graphics Acceleration Info:"); 10179 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10180 10181 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10182 ProcessRecord r = procs.get(i); 10183 if (r.thread != null) { 10184 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 10185 pw.flush(); 10186 try { 10187 TransferPipe tp = new TransferPipe(); 10188 try { 10189 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 10190 tp.go(fd); 10191 } finally { 10192 tp.kill(); 10193 } 10194 } catch (IOException e) { 10195 pw.println("Failure while dumping the app: " + r); 10196 pw.flush(); 10197 } catch (RemoteException e) { 10198 pw.println("Got a RemoteException while dumping the app " + r); 10199 pw.flush(); 10200 } 10201 } 10202 } 10203 } 10204 10205 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 10206 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 10207 if (procs == null) { 10208 return; 10209 } 10210 10211 pw.println("Applications Database Info:"); 10212 10213 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10214 ProcessRecord r = procs.get(i); 10215 if (r.thread != null) { 10216 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 10217 pw.flush(); 10218 try { 10219 TransferPipe tp = new TransferPipe(); 10220 try { 10221 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 10222 tp.go(fd); 10223 } finally { 10224 tp.kill(); 10225 } 10226 } catch (IOException e) { 10227 pw.println("Failure while dumping the app: " + r); 10228 pw.flush(); 10229 } catch (RemoteException e) { 10230 pw.println("Got a RemoteException while dumping the app " + r); 10231 pw.flush(); 10232 } 10233 } 10234 } 10235 } 10236 10237 final static class MemItem { 10238 final String label; 10239 final String shortLabel; 10240 final long pss; 10241 final int id; 10242 ArrayList<MemItem> subitems; 10243 10244 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 10245 label = _label; 10246 shortLabel = _shortLabel; 10247 pss = _pss; 10248 id = _id; 10249 } 10250 } 10251 10252 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, 10253 boolean sort) { 10254 if (sort) { 10255 Collections.sort(items, new Comparator<MemItem>() { 10256 @Override 10257 public int compare(MemItem lhs, MemItem rhs) { 10258 if (lhs.pss < rhs.pss) { 10259 return 1; 10260 } else if (lhs.pss > rhs.pss) { 10261 return -1; 10262 } 10263 return 0; 10264 } 10265 }); 10266 } 10267 10268 for (int i=0; i<items.size(); i++) { 10269 MemItem mi = items.get(i); 10270 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 10271 if (mi.subitems != null) { 10272 dumpMemItems(pw, prefix + " ", mi.subitems, true); 10273 } 10274 } 10275 } 10276 10277 // These are in KB. 10278 static final long[] DUMP_MEM_BUCKETS = new long[] { 10279 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 10280 120*1024, 160*1024, 200*1024, 10281 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 10282 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 10283 }; 10284 10285 static final void appendMemBucket(StringBuilder out, long memKB, String label, 10286 boolean stackLike) { 10287 int start = label.lastIndexOf('.'); 10288 if (start >= 0) start++; 10289 else start = 0; 10290 int end = label.length(); 10291 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 10292 if (DUMP_MEM_BUCKETS[i] >= memKB) { 10293 long bucket = DUMP_MEM_BUCKETS[i]/1024; 10294 out.append(bucket); 10295 out.append(stackLike ? "MB." : "MB "); 10296 out.append(label, start, end); 10297 return; 10298 } 10299 } 10300 out.append(memKB/1024); 10301 out.append(stackLike ? "MB." : "MB "); 10302 out.append(label, start, end); 10303 } 10304 10305 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 10306 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 10307 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 10308 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 10309 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ 10310 }; 10311 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 10312 "System", "Persistent", "Foreground", 10313 "Visible", "Perceptible", "Heavy Weight", 10314 "Backup", "A Services", "Home", "Previous", 10315 "B Services", "Background" 10316 }; 10317 10318 final void dumpApplicationMemoryUsage(FileDescriptor fd, 10319 PrintWriter pw, String prefix, String[] args, boolean brief, 10320 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { 10321 boolean dumpAll = false; 10322 boolean oomOnly = false; 10323 10324 int opti = 0; 10325 while (opti < args.length) { 10326 String opt = args[opti]; 10327 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10328 break; 10329 } 10330 opti++; 10331 if ("-a".equals(opt)) { 10332 dumpAll = true; 10333 } else if ("--oom".equals(opt)) { 10334 oomOnly = true; 10335 } else if ("-h".equals(opt)) { 10336 pw.println("meminfo dump options: [-a] [--oom] [process]"); 10337 pw.println(" -a: include all available information for each process."); 10338 pw.println(" --oom: only show processes organized by oom adj."); 10339 pw.println("If [process] is specified it can be the name or "); 10340 pw.println("pid of a specific process to dump."); 10341 return; 10342 } else { 10343 pw.println("Unknown argument: " + opt + "; use -h for help"); 10344 } 10345 } 10346 10347 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 10348 if (procs == null) { 10349 return; 10350 } 10351 10352 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10353 long uptime = SystemClock.uptimeMillis(); 10354 long realtime = SystemClock.elapsedRealtime(); 10355 10356 if (procs.size() == 1 || isCheckinRequest) { 10357 dumpAll = true; 10358 } 10359 10360 if (isCheckinRequest) { 10361 // short checkin version 10362 pw.println(uptime + "," + realtime); 10363 pw.flush(); 10364 } else { 10365 pw.println("Applications Memory Usage (kB):"); 10366 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10367 } 10368 10369 String[] innerArgs = new String[args.length-opti]; 10370 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 10371 10372 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 10373 long nativePss=0, dalvikPss=0, otherPss=0; 10374 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 10375 10376 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 10377 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 10378 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 10379 10380 long totalPss = 0; 10381 10382 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 10383 ProcessRecord r = procs.get(i); 10384 if (r.thread != null) { 10385 if (!isCheckinRequest && dumpAll) { 10386 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10387 pw.flush(); 10388 } 10389 Debug.MemoryInfo mi = null; 10390 if (dumpAll) { 10391 try { 10392 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); 10393 } catch (RemoteException e) { 10394 if (!isCheckinRequest) { 10395 pw.println("Got RemoteException!"); 10396 pw.flush(); 10397 } 10398 } 10399 } else { 10400 mi = new Debug.MemoryInfo(); 10401 Debug.getMemoryInfo(r.pid, mi); 10402 } 10403 10404 if (!isCheckinRequest && mi != null) { 10405 long myTotalPss = mi.getTotalPss(); 10406 totalPss += myTotalPss; 10407 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", 10408 r.processName, myTotalPss, 0); 10409 procMems.add(pssItem); 10410 10411 nativePss += mi.nativePss; 10412 dalvikPss += mi.dalvikPss; 10413 otherPss += mi.otherPss; 10414 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10415 long mem = mi.getOtherPss(j); 10416 miscPss[j] += mem; 10417 otherPss -= mem; 10418 } 10419 10420 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 10421 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 10422 || oomIndex == (oomPss.length-1)) { 10423 oomPss[oomIndex] += myTotalPss; 10424 if (oomProcs[oomIndex] == null) { 10425 oomProcs[oomIndex] = new ArrayList<MemItem>(); 10426 } 10427 oomProcs[oomIndex].add(pssItem); 10428 break; 10429 } 10430 } 10431 } 10432 } 10433 } 10434 10435 if (!isCheckinRequest && procs.size() > 1) { 10436 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 10437 10438 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 10439 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 10440 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 10441 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 10442 String label = Debug.MemoryInfo.getOtherLabel(j); 10443 catMems.add(new MemItem(label, label, miscPss[j], j)); 10444 } 10445 10446 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 10447 for (int j=0; j<oomPss.length; j++) { 10448 if (oomPss[j] != 0) { 10449 String label = DUMP_MEM_OOM_LABEL[j]; 10450 MemItem item = new MemItem(label, label, oomPss[j], 10451 DUMP_MEM_OOM_ADJ[j]); 10452 item.subitems = oomProcs[j]; 10453 oomMems.add(item); 10454 } 10455 } 10456 10457 if (outTag != null || outStack != null) { 10458 if (outTag != null) { 10459 appendMemBucket(outTag, totalPss, "total", false); 10460 } 10461 if (outStack != null) { 10462 appendMemBucket(outStack, totalPss, "total", true); 10463 } 10464 boolean firstLine = true; 10465 for (int i=0; i<oomMems.size(); i++) { 10466 MemItem miCat = oomMems.get(i); 10467 if (miCat.subitems == null || miCat.subitems.size() < 1) { 10468 continue; 10469 } 10470 if (miCat.id < ProcessList.SERVICE_ADJ 10471 || miCat.id == ProcessList.HOME_APP_ADJ 10472 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { 10473 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10474 outTag.append(" / "); 10475 } 10476 if (outStack != null) { 10477 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10478 if (firstLine) { 10479 outStack.append(":"); 10480 firstLine = false; 10481 } 10482 outStack.append("\n\t at "); 10483 } else { 10484 outStack.append("$"); 10485 } 10486 } 10487 for (int j=0; j<miCat.subitems.size(); j++) { 10488 MemItem mi = miCat.subitems.get(j); 10489 if (j > 0) { 10490 if (outTag != null) { 10491 outTag.append(" "); 10492 } 10493 if (outStack != null) { 10494 outStack.append("$"); 10495 } 10496 } 10497 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) { 10498 appendMemBucket(outTag, mi.pss, mi.shortLabel, false); 10499 } 10500 if (outStack != null) { 10501 appendMemBucket(outStack, mi.pss, mi.shortLabel, true); 10502 } 10503 } 10504 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) { 10505 outStack.append("("); 10506 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 10507 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) { 10508 outStack.append(DUMP_MEM_OOM_LABEL[k]); 10509 outStack.append(":"); 10510 outStack.append(DUMP_MEM_OOM_ADJ[k]); 10511 } 10512 } 10513 outStack.append(")"); 10514 } 10515 } 10516 } 10517 } 10518 10519 if (!brief && !oomOnly) { 10520 pw.println(); 10521 pw.println("Total PSS by process:"); 10522 dumpMemItems(pw, " ", procMems, true); 10523 pw.println(); 10524 } 10525 pw.println("Total PSS by OOM adjustment:"); 10526 dumpMemItems(pw, " ", oomMems, false); 10527 if (!oomOnly) { 10528 PrintWriter out = categoryPw != null ? categoryPw : pw; 10529 out.println(); 10530 out.println("Total PSS by category:"); 10531 dumpMemItems(out, " ", catMems, true); 10532 } 10533 pw.println(); 10534 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); 10535 final int[] SINGLE_LONG_FORMAT = new int[] { 10536 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 10537 }; 10538 long[] longOut = new long[1]; 10539 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 10540 SINGLE_LONG_FORMAT, null, longOut, null); 10541 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10542 longOut[0] = 0; 10543 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 10544 SINGLE_LONG_FORMAT, null, longOut, null); 10545 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10546 longOut[0] = 0; 10547 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 10548 SINGLE_LONG_FORMAT, null, longOut, null); 10549 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10550 longOut[0] = 0; 10551 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 10552 SINGLE_LONG_FORMAT, null, longOut, null); 10553 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 10554 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared "); 10555 pw.print(shared); pw.println(" kB"); 10556 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 10557 pw.print(voltile); pw.println(" kB volatile"); 10558 } 10559 } 10560 10561 /** 10562 * Searches array of arguments for the specified string 10563 * @param args array of argument strings 10564 * @param value value to search for 10565 * @return true if the value is contained in the array 10566 */ 10567 private static boolean scanArgs(String[] args, String value) { 10568 if (args != null) { 10569 for (String arg : args) { 10570 if (value.equals(arg)) { 10571 return true; 10572 } 10573 } 10574 } 10575 return false; 10576 } 10577 10578 private final void killServicesLocked(ProcessRecord app, 10579 boolean allowRestart) { 10580 // Report disconnected services. 10581 if (false) { 10582 // XXX we are letting the client link to the service for 10583 // death notifications. 10584 if (app.services.size() > 0) { 10585 Iterator<ServiceRecord> it = app.services.iterator(); 10586 while (it.hasNext()) { 10587 ServiceRecord r = it.next(); 10588 if (r.connections.size() > 0) { 10589 Iterator<ArrayList<ConnectionRecord>> jt 10590 = r.connections.values().iterator(); 10591 while (jt.hasNext()) { 10592 ArrayList<ConnectionRecord> cl = jt.next(); 10593 for (int i=0; i<cl.size(); i++) { 10594 ConnectionRecord c = cl.get(i); 10595 if (c.binding.client != app) { 10596 try { 10597 //c.conn.connected(r.className, null); 10598 } catch (Exception e) { 10599 // todo: this should be asynchronous! 10600 Slog.w(TAG, "Exception thrown disconnected servce " 10601 + r.shortName 10602 + " from app " + app.processName, e); 10603 } 10604 } 10605 } 10606 } 10607 } 10608 } 10609 } 10610 } 10611 10612 // Clean up any connections this application has to other services. 10613 if (app.connections.size() > 0) { 10614 Iterator<ConnectionRecord> it = app.connections.iterator(); 10615 while (it.hasNext()) { 10616 ConnectionRecord r = it.next(); 10617 removeConnectionLocked(r, app, null); 10618 } 10619 } 10620 app.connections.clear(); 10621 10622 if (app.services.size() != 0) { 10623 // Any services running in the application need to be placed 10624 // back in the pending list. 10625 Iterator<ServiceRecord> it = app.services.iterator(); 10626 while (it.hasNext()) { 10627 ServiceRecord sr = it.next(); 10628 synchronized (sr.stats.getBatteryStats()) { 10629 sr.stats.stopLaunchedLocked(); 10630 } 10631 sr.app = null; 10632 sr.isolatedProc = null; 10633 sr.executeNesting = 0; 10634 if (mStoppingServices.remove(sr)) { 10635 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10636 } 10637 10638 boolean hasClients = sr.bindings.size() > 0; 10639 if (hasClients) { 10640 Iterator<IntentBindRecord> bindings 10641 = sr.bindings.values().iterator(); 10642 while (bindings.hasNext()) { 10643 IntentBindRecord b = bindings.next(); 10644 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10645 + ": shouldUnbind=" + b.hasBound); 10646 b.binder = null; 10647 b.requested = b.received = b.hasBound = false; 10648 } 10649 } 10650 10651 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags 10652 &ApplicationInfo.FLAG_PERSISTENT) == 0) { 10653 Slog.w(TAG, "Service crashed " + sr.crashCount 10654 + " times, stopping: " + sr); 10655 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10656 sr.crashCount, sr.shortName, app.pid); 10657 bringDownServiceLocked(sr, true); 10658 } else if (!allowRestart) { 10659 bringDownServiceLocked(sr, true); 10660 } else { 10661 boolean canceled = scheduleServiceRestartLocked(sr, true); 10662 10663 // Should the service remain running? Note that in the 10664 // extreme case of so many attempts to deliver a command 10665 // that it failed we also will stop it here. 10666 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10667 if (sr.pendingStarts.size() == 0) { 10668 sr.startRequested = false; 10669 if (!hasClients) { 10670 // Whoops, no reason to restart! 10671 bringDownServiceLocked(sr, true); 10672 } 10673 } 10674 } 10675 } 10676 } 10677 10678 if (!allowRestart) { 10679 app.services.clear(); 10680 } 10681 } 10682 10683 // Make sure we have no more records on the stopping list. 10684 int i = mStoppingServices.size(); 10685 while (i > 0) { 10686 i--; 10687 ServiceRecord sr = mStoppingServices.get(i); 10688 if (sr.app == app) { 10689 mStoppingServices.remove(i); 10690 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr); 10691 } 10692 } 10693 10694 app.executingServices.clear(); 10695 } 10696 10697 private final boolean removeDyingProviderLocked(ProcessRecord proc, 10698 ContentProviderRecord cpr, boolean always) { 10699 final boolean inLaunching = mLaunchingProviders.contains(cpr); 10700 10701 if (!inLaunching || always) { 10702 synchronized (cpr) { 10703 cpr.launchingApp = null; 10704 cpr.notifyAll(); 10705 } 10706 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid)); 10707 String names[] = cpr.info.authority.split(";"); 10708 for (int j = 0; j < names.length; j++) { 10709 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid)); 10710 } 10711 } 10712 10713 for (int i=0; i<cpr.connections.size(); i++) { 10714 ContentProviderConnection conn = cpr.connections.get(i); 10715 if (conn.waiting) { 10716 // If this connection is waiting for the provider, then we don't 10717 // need to mess with its process unless we are always removing 10718 // or for some reason the provider is not currently launching. 10719 if (inLaunching && !always) { 10720 continue; 10721 } 10722 } 10723 ProcessRecord capp = conn.client; 10724 conn.dead = true; 10725 if (conn.stableCount > 0) { 10726 if (!capp.persistent && capp.thread != null 10727 && capp.pid != 0 10728 && capp.pid != MY_PID) { 10729 Slog.i(TAG, "Kill " + capp.processName 10730 + " (pid " + capp.pid + "): provider " + cpr.info.name 10731 + " in dying process " + (proc != null ? proc.processName : "??")); 10732 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10733 capp.processName, capp.setAdj, "dying provider " 10734 + cpr.name.toShortString()); 10735 Process.killProcessQuiet(capp.pid); 10736 } 10737 } else if (capp.thread != null && conn.provider.provider != null) { 10738 try { 10739 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 10740 } catch (RemoteException e) { 10741 } 10742 // In the protocol here, we don't expect the client to correctly 10743 // clean up this connection, we'll just remove it. 10744 cpr.connections.remove(i); 10745 conn.client.conProviders.remove(conn); 10746 } 10747 } 10748 10749 if (inLaunching && always) { 10750 mLaunchingProviders.remove(cpr); 10751 } 10752 return inLaunching; 10753 } 10754 10755 /** 10756 * Main code for cleaning up a process when it has gone away. This is 10757 * called both as a result of the process dying, or directly when stopping 10758 * a process when running in single process mode. 10759 */ 10760 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10761 boolean restarting, boolean allowRestart, int index) { 10762 if (index >= 0) { 10763 mLruProcesses.remove(index); 10764 } 10765 10766 mProcessesToGc.remove(app); 10767 10768 // Dismiss any open dialogs. 10769 if (app.crashDialog != null) { 10770 app.crashDialog.dismiss(); 10771 app.crashDialog = null; 10772 } 10773 if (app.anrDialog != null) { 10774 app.anrDialog.dismiss(); 10775 app.anrDialog = null; 10776 } 10777 if (app.waitDialog != null) { 10778 app.waitDialog.dismiss(); 10779 app.waitDialog = null; 10780 } 10781 10782 app.crashing = false; 10783 app.notResponding = false; 10784 10785 app.resetPackageList(); 10786 app.unlinkDeathRecipient(); 10787 app.thread = null; 10788 app.forcingToForeground = null; 10789 app.foregroundServices = false; 10790 app.foregroundActivities = false; 10791 app.hasShownUi = false; 10792 app.hasAboveClient = false; 10793 10794 killServicesLocked(app, allowRestart); 10795 10796 boolean restart = false; 10797 10798 // Remove published content providers. 10799 if (!app.pubProviders.isEmpty()) { 10800 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); 10801 while (it.hasNext()) { 10802 ContentProviderRecord cpr = it.next(); 10803 10804 final boolean always = app.bad || !allowRestart; 10805 if (removeDyingProviderLocked(app, cpr, always) || always) { 10806 // We left the provider in the launching list, need to 10807 // restart it. 10808 restart = true; 10809 } 10810 10811 cpr.provider = null; 10812 cpr.proc = null; 10813 } 10814 app.pubProviders.clear(); 10815 } 10816 10817 // Take care of any launching providers waiting for this process. 10818 if (checkAppInLaunchingProvidersLocked(app, false)) { 10819 restart = true; 10820 } 10821 10822 // Unregister from connected content providers. 10823 if (!app.conProviders.isEmpty()) { 10824 for (int i=0; i<app.conProviders.size(); i++) { 10825 ContentProviderConnection conn = app.conProviders.get(i); 10826 conn.provider.connections.remove(conn); 10827 } 10828 app.conProviders.clear(); 10829 } 10830 10831 // At this point there may be remaining entries in mLaunchingProviders 10832 // where we were the only one waiting, so they are no longer of use. 10833 // Look for these and clean up if found. 10834 // XXX Commented out for now. Trying to figure out a way to reproduce 10835 // the actual situation to identify what is actually going on. 10836 if (false) { 10837 for (int i=0; i<mLaunchingProviders.size(); i++) { 10838 ContentProviderRecord cpr = (ContentProviderRecord) 10839 mLaunchingProviders.get(i); 10840 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 10841 synchronized (cpr) { 10842 cpr.launchingApp = null; 10843 cpr.notifyAll(); 10844 } 10845 } 10846 } 10847 } 10848 10849 skipCurrentReceiverLocked(app); 10850 10851 // Unregister any receivers. 10852 if (app.receivers.size() > 0) { 10853 Iterator<ReceiverList> it = app.receivers.iterator(); 10854 while (it.hasNext()) { 10855 removeReceiverLocked(it.next()); 10856 } 10857 app.receivers.clear(); 10858 } 10859 10860 // If the app is undergoing backup, tell the backup manager about it 10861 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10862 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10863 try { 10864 IBackupManager bm = IBackupManager.Stub.asInterface( 10865 ServiceManager.getService(Context.BACKUP_SERVICE)); 10866 bm.agentDisconnected(app.info.packageName); 10867 } catch (RemoteException e) { 10868 // can't happen; backup manager is local 10869 } 10870 } 10871 10872 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 10873 ProcessChangeItem item = mPendingProcessChanges.get(i); 10874 if (item.pid == app.pid) { 10875 mPendingProcessChanges.remove(i); 10876 mAvailProcessChanges.add(item); 10877 } 10878 } 10879 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 10880 10881 // If the caller is restarting this app, then leave it in its 10882 // current lists and let the caller take care of it. 10883 if (restarting) { 10884 return; 10885 } 10886 10887 if (!app.persistent || app.isolated) { 10888 if (DEBUG_PROCESSES) Slog.v(TAG, 10889 "Removing non-persistent process during cleanup: " + app); 10890 mProcessNames.remove(app.processName, app.uid); 10891 mIsolatedProcesses.remove(app.uid); 10892 if (mHeavyWeightProcess == app) { 10893 mHeavyWeightProcess = null; 10894 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG); 10895 } 10896 } else if (!app.removed) { 10897 // This app is persistent, so we need to keep its record around. 10898 // If it is not already on the pending app list, add it there 10899 // and start a new process for it. 10900 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10901 mPersistentStartingProcesses.add(app); 10902 restart = true; 10903 } 10904 } 10905 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 10906 "Clean-up removing on hold: " + app); 10907 mProcessesOnHold.remove(app); 10908 10909 if (app == mHomeProcess) { 10910 mHomeProcess = null; 10911 } 10912 if (app == mPreviousProcess) { 10913 mPreviousProcess = null; 10914 } 10915 10916 if (restart && !app.isolated) { 10917 // We have components that still need to be running in the 10918 // process, so re-launch it. 10919 mProcessNames.put(app.processName, app.uid, app); 10920 startProcessLocked(app, "restart", app.processName); 10921 } else if (app.pid > 0 && app.pid != MY_PID) { 10922 // Goodbye! 10923 synchronized (mPidsSelfLocked) { 10924 mPidsSelfLocked.remove(app.pid); 10925 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10926 } 10927 app.setPid(0); 10928 } 10929 } 10930 10931 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10932 // Look through the content providers we are waiting to have launched, 10933 // and if any run in this process then either schedule a restart of 10934 // the process or kill the client waiting for it if this process has 10935 // gone bad. 10936 int NL = mLaunchingProviders.size(); 10937 boolean restart = false; 10938 for (int i=0; i<NL; i++) { 10939 ContentProviderRecord cpr = mLaunchingProviders.get(i); 10940 if (cpr.launchingApp == app) { 10941 if (!alwaysBad && !app.bad) { 10942 restart = true; 10943 } else { 10944 removeDyingProviderLocked(app, cpr, true); 10945 NL = mLaunchingProviders.size(); 10946 } 10947 } 10948 } 10949 return restart; 10950 } 10951 10952 // ========================================================= 10953 // SERVICES 10954 // ========================================================= 10955 10956 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10957 ActivityManager.RunningServiceInfo info = 10958 new ActivityManager.RunningServiceInfo(); 10959 info.service = r.name; 10960 if (r.app != null) { 10961 info.pid = r.app.pid; 10962 } 10963 info.uid = r.appInfo.uid; 10964 info.process = r.processName; 10965 info.foreground = r.isForeground; 10966 info.activeSince = r.createTime; 10967 info.started = r.startRequested; 10968 info.clientCount = r.connections.size(); 10969 info.crashCount = r.crashCount; 10970 info.lastActivityTime = r.lastActivity; 10971 if (r.isForeground) { 10972 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10973 } 10974 if (r.startRequested) { 10975 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10976 } 10977 if (r.app != null && r.app.pid == MY_PID) { 10978 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10979 } 10980 if (r.app != null && r.app.persistent) { 10981 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10982 } 10983 10984 for (ArrayList<ConnectionRecord> connl : r.connections.values()) { 10985 for (int i=0; i<connl.size(); i++) { 10986 ConnectionRecord conn = connl.get(i); 10987 if (conn.clientLabel != 0) { 10988 info.clientPackage = conn.binding.client.info.packageName; 10989 info.clientLabel = conn.clientLabel; 10990 return info; 10991 } 10992 } 10993 } 10994 return info; 10995 } 10996 10997 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10998 int flags) { 10999 enforceNotIsolatedCaller("getServices"); 11000 synchronized (this) { 11001 ArrayList<ActivityManager.RunningServiceInfo> res 11002 = new ArrayList<ActivityManager.RunningServiceInfo>(); 11003 11004 int userId = UserId.getUserId(Binder.getCallingUid()); 11005 if (mServiceMap.getAllServices(userId).size() > 0) { 11006 Iterator<ServiceRecord> it 11007 = mServiceMap.getAllServices(userId).iterator(); 11008 while (it.hasNext() && res.size() < maxNum) { 11009 res.add(makeRunningServiceInfoLocked(it.next())); 11010 } 11011 } 11012 11013 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 11014 ServiceRecord r = mRestartingServices.get(i); 11015 ActivityManager.RunningServiceInfo info = 11016 makeRunningServiceInfoLocked(r); 11017 info.restarting = r.nextRestartTime; 11018 res.add(info); 11019 } 11020 11021 return res; 11022 } 11023 } 11024 11025 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 11026 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 11027 synchronized (this) { 11028 int userId = UserId.getUserId(Binder.getCallingUid()); 11029 ServiceRecord r = mServiceMap.getServiceByName(name, userId); 11030 if (r != null) { 11031 for (ArrayList<ConnectionRecord> conn : r.connections.values()) { 11032 for (int i=0; i<conn.size(); i++) { 11033 if (conn.get(i).clientIntent != null) { 11034 return conn.get(i).clientIntent; 11035 } 11036 } 11037 } 11038 } 11039 } 11040 return null; 11041 } 11042 11043 private final ServiceRecord findServiceLocked(ComponentName name, 11044 IBinder token) { 11045 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 11046 return r == token ? r : null; 11047 } 11048 11049 private final class ServiceLookupResult { 11050 final ServiceRecord record; 11051 final String permission; 11052 11053 ServiceLookupResult(ServiceRecord _record, String _permission) { 11054 record = _record; 11055 permission = _permission; 11056 } 11057 }; 11058 11059 private ServiceLookupResult findServiceLocked(Intent service, 11060 String resolvedType, int userId) { 11061 ServiceRecord r = null; 11062 if (service.getComponent() != null) { 11063 r = mServiceMap.getServiceByName(service.getComponent(), userId); 11064 } 11065 if (r == null) { 11066 Intent.FilterComparison filter = new Intent.FilterComparison(service); 11067 r = mServiceMap.getServiceByIntent(filter, userId); 11068 } 11069 11070 if (r == null) { 11071 try { 11072 ResolveInfo rInfo = 11073 AppGlobals.getPackageManager().resolveService( 11074 service, resolvedType, 0, userId); 11075 ServiceInfo sInfo = 11076 rInfo != null ? rInfo.serviceInfo : null; 11077 if (sInfo == null) { 11078 return null; 11079 } 11080 11081 ComponentName name = new ComponentName( 11082 sInfo.applicationInfo.packageName, sInfo.name); 11083 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser()); 11084 } catch (RemoteException ex) { 11085 // pm is in same process, this will never happen. 11086 } 11087 } 11088 if (r != null) { 11089 int callingPid = Binder.getCallingPid(); 11090 int callingUid = Binder.getCallingUid(); 11091 if (checkComponentPermission(r.permission, 11092 callingPid, callingUid, r.appInfo.uid, r.exported) 11093 != PackageManager.PERMISSION_GRANTED) { 11094 if (!r.exported) { 11095 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11096 + " from pid=" + callingPid 11097 + ", uid=" + callingUid 11098 + " that is not exported from uid " + r.appInfo.uid); 11099 return new ServiceLookupResult(null, "not exported from uid " 11100 + r.appInfo.uid); 11101 } 11102 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11103 + " from pid=" + callingPid 11104 + ", uid=" + callingUid 11105 + " requires " + r.permission); 11106 return new ServiceLookupResult(null, r.permission); 11107 } 11108 return new ServiceLookupResult(r, null); 11109 } 11110 return null; 11111 } 11112 11113 private class ServiceRestarter implements Runnable { 11114 private ServiceRecord mService; 11115 11116 void setService(ServiceRecord service) { 11117 mService = service; 11118 } 11119 11120 public void run() { 11121 synchronized(ActivityManagerService.this) { 11122 performServiceRestartLocked(mService); 11123 } 11124 } 11125 } 11126 11127 private ServiceLookupResult retrieveServiceLocked(Intent service, 11128 String resolvedType, int callingPid, int callingUid, int userId) { 11129 ServiceRecord r = null; 11130 if (DEBUG_SERVICE) 11131 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType 11132 + " callingUid=" + callingUid); 11133 11134 if (service.getComponent() != null) { 11135 r = mServiceMap.getServiceByName(service.getComponent(), userId); 11136 } 11137 if (r == null) { 11138 Intent.FilterComparison filter = new Intent.FilterComparison(service); 11139 r = mServiceMap.getServiceByIntent(filter, userId); 11140 } 11141 if (r == null) { 11142 try { 11143 ResolveInfo rInfo = 11144 AppGlobals.getPackageManager().resolveService( 11145 service, resolvedType, STOCK_PM_FLAGS, userId); 11146 ServiceInfo sInfo = 11147 rInfo != null ? rInfo.serviceInfo : null; 11148 if (sInfo == null) { 11149 Slog.w(TAG, "Unable to start service " + service + 11150 ": not found"); 11151 return null; 11152 } 11153 if (userId > 0) { 11154 if (isSingleton(sInfo.processName, sInfo.applicationInfo)) { 11155 userId = 0; 11156 } 11157 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId); 11158 } 11159 ComponentName name = new ComponentName( 11160 sInfo.applicationInfo.packageName, sInfo.name); 11161 r = mServiceMap.getServiceByName(name, userId); 11162 if (r == null) { 11163 Intent.FilterComparison filter = new Intent.FilterComparison( 11164 service.cloneFilter()); 11165 ServiceRestarter res = new ServiceRestarter(); 11166 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11167 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11168 synchronized (stats) { 11169 ss = stats.getServiceStatsLocked( 11170 sInfo.applicationInfo.uid, sInfo.packageName, 11171 sInfo.name); 11172 } 11173 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 11174 res.setService(r); 11175 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r); 11176 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r); 11177 11178 // Make sure this component isn't in the pending list. 11179 int N = mPendingServices.size(); 11180 for (int i=0; i<N; i++) { 11181 ServiceRecord pr = mPendingServices.get(i); 11182 if (pr.name.equals(name)) { 11183 mPendingServices.remove(i); 11184 i--; 11185 N--; 11186 } 11187 } 11188 } 11189 } catch (RemoteException ex) { 11190 // pm is in same process, this will never happen. 11191 } 11192 } 11193 if (r != null) { 11194 if (checkComponentPermission(r.permission, 11195 callingPid, callingUid, r.appInfo.uid, r.exported) 11196 != PackageManager.PERMISSION_GRANTED) { 11197 if (!r.exported) { 11198 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11199 + " from pid=" + callingPid 11200 + ", uid=" + callingUid 11201 + " that is not exported from uid " + r.appInfo.uid); 11202 return new ServiceLookupResult(null, "not exported from uid " 11203 + r.appInfo.uid); 11204 } 11205 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 11206 + " from pid=" + callingPid 11207 + ", uid=" + callingUid 11208 + " requires " + r.permission); 11209 return new ServiceLookupResult(null, r.permission); 11210 } 11211 return new ServiceLookupResult(r, null); 11212 } 11213 return null; 11214 } 11215 11216 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) { 11217 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING " 11218 + why + " of " + r + " in app " + r.app); 11219 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING " 11220 + why + " of " + r.shortName); 11221 long now = SystemClock.uptimeMillis(); 11222 if (r.executeNesting == 0 && r.app != null) { 11223 if (r.app.executingServices.size() == 0) { 11224 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11225 msg.obj = r.app; 11226 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 11227 } 11228 r.app.executingServices.add(r); 11229 } 11230 r.executeNesting++; 11231 r.executingStart = now; 11232 } 11233 11234 private final void sendServiceArgsLocked(ServiceRecord r, 11235 boolean oomAdjusted) { 11236 final int N = r.pendingStarts.size(); 11237 if (N == 0) { 11238 return; 11239 } 11240 11241 while (r.pendingStarts.size() > 0) { 11242 try { 11243 ServiceRecord.StartItem si = r.pendingStarts.remove(0); 11244 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: " 11245 + r + " " + r.intent + " args=" + si.intent); 11246 if (si.intent == null && N > 1) { 11247 // If somehow we got a dummy null intent in the middle, 11248 // then skip it. DO NOT skip a null intent when it is 11249 // the only one in the list -- this is to support the 11250 // onStartCommand(null) case. 11251 continue; 11252 } 11253 si.deliveredTime = SystemClock.uptimeMillis(); 11254 r.deliveredStarts.add(si); 11255 si.deliveryCount++; 11256 if (si.neededGrants != null) { 11257 grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, 11258 si.getUriPermissionsLocked()); 11259 } 11260 bumpServiceExecutingLocked(r, "start"); 11261 if (!oomAdjusted) { 11262 oomAdjusted = true; 11263 updateOomAdjLocked(r.app); 11264 } 11265 int flags = 0; 11266 if (si.deliveryCount > 1) { 11267 flags |= Service.START_FLAG_RETRY; 11268 } 11269 if (si.doneExecutingCount > 0) { 11270 flags |= Service.START_FLAG_REDELIVERY; 11271 } 11272 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); 11273 } catch (RemoteException e) { 11274 // Remote process gone... we'll let the normal cleanup take 11275 // care of this. 11276 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r); 11277 break; 11278 } catch (Exception e) { 11279 Slog.w(TAG, "Unexpected exception", e); 11280 break; 11281 } 11282 } 11283 } 11284 11285 private final boolean requestServiceBindingLocked(ServiceRecord r, 11286 IntentBindRecord i, boolean rebind) { 11287 if (r.app == null || r.app.thread == null) { 11288 // If service is not currently running, can't yet bind. 11289 return false; 11290 } 11291 if ((!i.requested || rebind) && i.apps.size() > 0) { 11292 try { 11293 bumpServiceExecutingLocked(r, "bind"); 11294 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 11295 if (!rebind) { 11296 i.requested = true; 11297 } 11298 i.hasBound = true; 11299 i.doRebind = false; 11300 } catch (RemoteException e) { 11301 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); 11302 return false; 11303 } 11304 } 11305 return true; 11306 } 11307 11308 private final void requestServiceBindingsLocked(ServiceRecord r) { 11309 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 11310 while (bindings.hasNext()) { 11311 IntentBindRecord i = bindings.next(); 11312 if (!requestServiceBindingLocked(r, i, false)) { 11313 break; 11314 } 11315 } 11316 } 11317 11318 private final void realStartServiceLocked(ServiceRecord r, 11319 ProcessRecord app) throws RemoteException { 11320 if (app.thread == null) { 11321 throw new RemoteException(); 11322 } 11323 if (DEBUG_MU) 11324 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid 11325 + ", ProcessRecord.uid = " + app.uid); 11326 r.app = app; 11327 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 11328 11329 app.services.add(r); 11330 bumpServiceExecutingLocked(r, "create"); 11331 updateLruProcessLocked(app, true, true); 11332 11333 boolean created = false; 11334 try { 11335 mStringBuilder.setLength(0); 11336 r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false); 11337 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 11338 System.identityHashCode(r), r.shortName, 11339 mStringBuilder.toString(), r.app.pid); 11340 synchronized (r.stats.getBatteryStats()) { 11341 r.stats.startLaunchedLocked(); 11342 } 11343 ensurePackageDexOpt(r.serviceInfo.packageName); 11344 app.thread.scheduleCreateService(r, r.serviceInfo, 11345 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo)); 11346 r.postNotification(); 11347 created = true; 11348 } finally { 11349 if (!created) { 11350 app.services.remove(r); 11351 scheduleServiceRestartLocked(r, false); 11352 } 11353 } 11354 11355 requestServiceBindingsLocked(r); 11356 11357 // If the service is in the started state, and there are no 11358 // pending arguments, then fake up one so its onStartCommand() will 11359 // be called. 11360 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 11361 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11362 null, null)); 11363 } 11364 11365 sendServiceArgsLocked(r, true); 11366 } 11367 11368 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 11369 boolean allowCancel) { 11370 boolean canceled = false; 11371 11372 final long now = SystemClock.uptimeMillis(); 11373 long minDuration = SERVICE_RESTART_DURATION; 11374 long resetTime = SERVICE_RESET_RUN_DURATION; 11375 11376 if ((r.serviceInfo.applicationInfo.flags 11377 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11378 minDuration /= 4; 11379 } 11380 11381 // Any delivered but not yet finished starts should be put back 11382 // on the pending list. 11383 final int N = r.deliveredStarts.size(); 11384 if (N > 0) { 11385 for (int i=N-1; i>=0; i--) { 11386 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 11387 si.removeUriPermissionsLocked(); 11388 if (si.intent == null) { 11389 // We'll generate this again if needed. 11390 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 11391 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 11392 r.pendingStarts.add(0, si); 11393 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 11394 dur *= 2; 11395 if (minDuration < dur) minDuration = dur; 11396 if (resetTime < dur) resetTime = dur; 11397 } else { 11398 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 11399 + r.name); 11400 canceled = true; 11401 } 11402 } 11403 r.deliveredStarts.clear(); 11404 } 11405 11406 r.totalRestartCount++; 11407 if (r.restartDelay == 0) { 11408 r.restartCount++; 11409 r.restartDelay = minDuration; 11410 } else { 11411 // If it has been a "reasonably long time" since the service 11412 // was started, then reset our restart duration back to 11413 // the beginning, so we don't infinitely increase the duration 11414 // on a service that just occasionally gets killed (which is 11415 // a normal case, due to process being killed to reclaim memory). 11416 if (now > (r.restartTime+resetTime)) { 11417 r.restartCount = 1; 11418 r.restartDelay = minDuration; 11419 } else { 11420 if ((r.serviceInfo.applicationInfo.flags 11421 &ApplicationInfo.FLAG_PERSISTENT) != 0) { 11422 // Services in peristent processes will restart much more 11423 // quickly, since they are pretty important. (Think SystemUI). 11424 r.restartDelay += minDuration/2; 11425 } else { 11426 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 11427 if (r.restartDelay < minDuration) { 11428 r.restartDelay = minDuration; 11429 } 11430 } 11431 } 11432 } 11433 11434 r.nextRestartTime = now + r.restartDelay; 11435 11436 // Make sure that we don't end up restarting a bunch of services 11437 // all at the same time. 11438 boolean repeat; 11439 do { 11440 repeat = false; 11441 for (int i=mRestartingServices.size()-1; i>=0; i--) { 11442 ServiceRecord r2 = mRestartingServices.get(i); 11443 if (r2 != r && r.nextRestartTime 11444 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 11445 && r.nextRestartTime 11446 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 11447 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 11448 r.restartDelay = r.nextRestartTime - now; 11449 repeat = true; 11450 break; 11451 } 11452 } 11453 } while (repeat); 11454 11455 if (!mRestartingServices.contains(r)) { 11456 mRestartingServices.add(r); 11457 } 11458 11459 r.cancelNotification(); 11460 11461 mHandler.removeCallbacks(r.restarter); 11462 mHandler.postAtTime(r.restarter, r.nextRestartTime); 11463 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 11464 Slog.w(TAG, "Scheduling restart of crashed service " 11465 + r.shortName + " in " + r.restartDelay + "ms"); 11466 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 11467 r.shortName, r.restartDelay); 11468 11469 return canceled; 11470 } 11471 11472 final void performServiceRestartLocked(ServiceRecord r) { 11473 if (!mRestartingServices.contains(r)) { 11474 return; 11475 } 11476 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 11477 } 11478 11479 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 11480 if (r.restartDelay == 0) { 11481 return false; 11482 } 11483 r.resetRestartCounter(); 11484 mRestartingServices.remove(r); 11485 mHandler.removeCallbacks(r.restarter); 11486 return true; 11487 } 11488 11489 private final boolean bringUpServiceLocked(ServiceRecord r, 11490 int intentFlags, boolean whileRestarting) { 11491 //Slog.i(TAG, "Bring up service:"); 11492 //r.dump(" "); 11493 11494 if (r.app != null && r.app.thread != null) { 11495 sendServiceArgsLocked(r, false); 11496 return true; 11497 } 11498 11499 if (!whileRestarting && r.restartDelay > 0) { 11500 // If waiting for a restart, then do nothing. 11501 return true; 11502 } 11503 11504 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent); 11505 11506 // We are now bringing the service up, so no longer in the 11507 // restarting state. 11508 mRestartingServices.remove(r); 11509 11510 // Service is now being launched, its package can't be stopped. 11511 try { 11512 AppGlobals.getPackageManager().setPackageStoppedState( 11513 r.packageName, false, r.userId); 11514 } catch (RemoteException e) { 11515 } catch (IllegalArgumentException e) { 11516 Slog.w(TAG, "Failed trying to unstop package " 11517 + r.packageName + ": " + e); 11518 } 11519 11520 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; 11521 final String appName = r.processName; 11522 ProcessRecord app; 11523 11524 if (!isolated) { 11525 app = getProcessRecordLocked(appName, r.appInfo.uid); 11526 if (DEBUG_MU) 11527 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); 11528 if (app != null && app.thread != null) { 11529 try { 11530 app.addPackage(r.appInfo.packageName); 11531 realStartServiceLocked(r, app); 11532 return true; 11533 } catch (RemoteException e) { 11534 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 11535 } 11536 11537 // If a dead object exception was thrown -- fall through to 11538 // restart the application. 11539 } 11540 } else { 11541 // If this service runs in an isolated process, then each time 11542 // we call startProcessLocked() we will get a new isolated 11543 // process, starting another process if we are currently waiting 11544 // for a previous process to come up. To deal with this, we store 11545 // in the service any current isolated process it is running in or 11546 // waiting to have come up. 11547 app = r.isolatedProc; 11548 } 11549 11550 // Not running -- get it started, and enqueue this service record 11551 // to be executed when the app comes up. 11552 if (app == null) { 11553 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags, 11554 "service", r.name, false, isolated)) == null) { 11555 Slog.w(TAG, "Unable to launch app " 11556 + r.appInfo.packageName + "/" 11557 + r.appInfo.uid + " for service " 11558 + r.intent.getIntent() + ": process is bad"); 11559 bringDownServiceLocked(r, true); 11560 return false; 11561 } 11562 if (isolated) { 11563 r.isolatedProc = app; 11564 } 11565 } 11566 11567 if (!mPendingServices.contains(r)) { 11568 mPendingServices.add(r); 11569 } 11570 11571 return true; 11572 } 11573 11574 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 11575 //Slog.i(TAG, "Bring down service:"); 11576 //r.dump(" "); 11577 11578 // Does it still need to run? 11579 if (!force && r.startRequested) { 11580 return; 11581 } 11582 if (r.connections.size() > 0) { 11583 if (!force) { 11584 // XXX should probably keep a count of the number of auto-create 11585 // connections directly in the service. 11586 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11587 while (it.hasNext()) { 11588 ArrayList<ConnectionRecord> cr = it.next(); 11589 for (int i=0; i<cr.size(); i++) { 11590 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 11591 return; 11592 } 11593 } 11594 } 11595 } 11596 11597 // Report to all of the connections that the service is no longer 11598 // available. 11599 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator(); 11600 while (it.hasNext()) { 11601 ArrayList<ConnectionRecord> c = it.next(); 11602 for (int i=0; i<c.size(); i++) { 11603 ConnectionRecord cr = c.get(i); 11604 // There is still a connection to the service that is 11605 // being brought down. Mark it as dead. 11606 cr.serviceDead = true; 11607 try { 11608 cr.conn.connected(r.name, null); 11609 } catch (Exception e) { 11610 Slog.w(TAG, "Failure disconnecting service " + r.name + 11611 " to connection " + c.get(i).conn.asBinder() + 11612 " (in " + c.get(i).binding.client.processName + ")", e); 11613 } 11614 } 11615 } 11616 } 11617 11618 // Tell the service that it has been unbound. 11619 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 11620 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 11621 while (it.hasNext()) { 11622 IntentBindRecord ibr = it.next(); 11623 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 11624 + ": hasBound=" + ibr.hasBound); 11625 if (r.app != null && r.app.thread != null && ibr.hasBound) { 11626 try { 11627 bumpServiceExecutingLocked(r, "bring down unbind"); 11628 updateOomAdjLocked(r.app); 11629 ibr.hasBound = false; 11630 r.app.thread.scheduleUnbindService(r, 11631 ibr.intent.getIntent()); 11632 } catch (Exception e) { 11633 Slog.w(TAG, "Exception when unbinding service " 11634 + r.shortName, e); 11635 serviceDoneExecutingLocked(r, true); 11636 } 11637 } 11638 } 11639 } 11640 11641 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent); 11642 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 11643 System.identityHashCode(r), r.shortName, 11644 (r.app != null) ? r.app.pid : -1); 11645 11646 mServiceMap.removeServiceByName(r.name, r.userId); 11647 mServiceMap.removeServiceByIntent(r.intent, r.userId); 11648 r.totalRestartCount = 0; 11649 unscheduleServiceRestartLocked(r); 11650 11651 // Also make sure it is not on the pending list. 11652 int N = mPendingServices.size(); 11653 for (int i=0; i<N; i++) { 11654 if (mPendingServices.get(i) == r) { 11655 mPendingServices.remove(i); 11656 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r); 11657 i--; 11658 N--; 11659 } 11660 } 11661 11662 r.cancelNotification(); 11663 r.isForeground = false; 11664 r.foregroundId = 0; 11665 r.foregroundNoti = null; 11666 11667 // Clear start entries. 11668 r.clearDeliveredStartsLocked(); 11669 r.pendingStarts.clear(); 11670 11671 if (r.app != null) { 11672 synchronized (r.stats.getBatteryStats()) { 11673 r.stats.stopLaunchedLocked(); 11674 } 11675 r.app.services.remove(r); 11676 if (r.app.thread != null) { 11677 try { 11678 bumpServiceExecutingLocked(r, "stop"); 11679 mStoppingServices.add(r); 11680 updateOomAdjLocked(r.app); 11681 r.app.thread.scheduleStopService(r); 11682 } catch (Exception e) { 11683 Slog.w(TAG, "Exception when stopping service " 11684 + r.shortName, e); 11685 serviceDoneExecutingLocked(r, true); 11686 } 11687 updateServiceForegroundLocked(r.app, false); 11688 } else { 11689 if (DEBUG_SERVICE) Slog.v( 11690 TAG, "Removed service that has no process: " + r); 11691 } 11692 } else { 11693 if (DEBUG_SERVICE) Slog.v( 11694 TAG, "Removed service that is not running: " + r); 11695 } 11696 11697 if (r.bindings.size() > 0) { 11698 r.bindings.clear(); 11699 } 11700 11701 if (r.restarter instanceof ServiceRestarter) { 11702 ((ServiceRestarter)r.restarter).setService(null); 11703 } 11704 } 11705 11706 ComponentName startServiceLocked(IApplicationThread caller, 11707 Intent service, String resolvedType, 11708 int callingPid, int callingUid) { 11709 synchronized(this) { 11710 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11711 + " type=" + resolvedType + " args=" + service.getExtras()); 11712 11713 if (caller != null) { 11714 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11715 if (callerApp == null) { 11716 throw new SecurityException( 11717 "Unable to find app for caller " + caller 11718 + " (pid=" + Binder.getCallingPid() 11719 + ") when starting service " + service); 11720 } 11721 } 11722 11723 ServiceLookupResult res = 11724 retrieveServiceLocked(service, resolvedType, 11725 callingPid, callingUid, UserId.getUserId(callingUid)); 11726 if (res == null) { 11727 return null; 11728 } 11729 if (res.record == null) { 11730 return new ComponentName("!", res.permission != null 11731 ? res.permission : "private to package"); 11732 } 11733 ServiceRecord r = res.record; 11734 NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked( 11735 callingUid, r.packageName, service, service.getFlags(), null); 11736 if (unscheduleServiceRestartLocked(r)) { 11737 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r); 11738 } 11739 r.startRequested = true; 11740 r.callStart = false; 11741 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), 11742 service, neededGrants)); 11743 r.lastActivity = SystemClock.uptimeMillis(); 11744 synchronized (r.stats.getBatteryStats()) { 11745 r.stats.startRunningLocked(); 11746 } 11747 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11748 return new ComponentName("!", "Service process is bad"); 11749 } 11750 return r.name; 11751 } 11752 } 11753 11754 public ComponentName startService(IApplicationThread caller, Intent service, 11755 String resolvedType) { 11756 enforceNotIsolatedCaller("startService"); 11757 // Refuse possible leaked file descriptors 11758 if (service != null && service.hasFileDescriptors() == true) { 11759 throw new IllegalArgumentException("File descriptors passed in Intent"); 11760 } 11761 11762 if (DEBUG_SERVICE) 11763 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 11764 synchronized(this) { 11765 final int callingPid = Binder.getCallingPid(); 11766 final int callingUid = Binder.getCallingUid(); 11767 final long origId = Binder.clearCallingIdentity(); 11768 ComponentName res = startServiceLocked(caller, service, 11769 resolvedType, callingPid, callingUid); 11770 Binder.restoreCallingIdentity(origId); 11771 return res; 11772 } 11773 } 11774 11775 ComponentName startServiceInPackage(int uid, 11776 Intent service, String resolvedType) { 11777 synchronized(this) { 11778 if (DEBUG_SERVICE) 11779 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 11780 final long origId = Binder.clearCallingIdentity(); 11781 ComponentName res = startServiceLocked(null, service, 11782 resolvedType, -1, uid); 11783 Binder.restoreCallingIdentity(origId); 11784 return res; 11785 } 11786 } 11787 11788 private void stopServiceLocked(ServiceRecord service) { 11789 synchronized (service.stats.getBatteryStats()) { 11790 service.stats.stopRunningLocked(); 11791 } 11792 service.startRequested = false; 11793 service.callStart = false; 11794 bringDownServiceLocked(service, false); 11795 } 11796 11797 public int stopService(IApplicationThread caller, Intent service, 11798 String resolvedType) { 11799 enforceNotIsolatedCaller("stopService"); 11800 // Refuse possible leaked file descriptors 11801 if (service != null && service.hasFileDescriptors() == true) { 11802 throw new IllegalArgumentException("File descriptors passed in Intent"); 11803 } 11804 11805 synchronized(this) { 11806 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11807 + " type=" + resolvedType); 11808 11809 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11810 if (caller != null && callerApp == null) { 11811 throw new SecurityException( 11812 "Unable to find app for caller " + caller 11813 + " (pid=" + Binder.getCallingPid() 11814 + ") when stopping service " + service); 11815 } 11816 11817 // If this service is active, make sure it is stopped. 11818 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11819 callerApp == null ? UserId.getCallingUserId() : callerApp.userId); 11820 if (r != null) { 11821 if (r.record != null) { 11822 final long origId = Binder.clearCallingIdentity(); 11823 try { 11824 stopServiceLocked(r.record); 11825 } finally { 11826 Binder.restoreCallingIdentity(origId); 11827 } 11828 return 1; 11829 } 11830 return -1; 11831 } 11832 } 11833 11834 return 0; 11835 } 11836 11837 public IBinder peekService(Intent service, String resolvedType) { 11838 enforceNotIsolatedCaller("peekService"); 11839 // Refuse possible leaked file descriptors 11840 if (service != null && service.hasFileDescriptors() == true) { 11841 throw new IllegalArgumentException("File descriptors passed in Intent"); 11842 } 11843 11844 IBinder ret = null; 11845 11846 synchronized(this) { 11847 ServiceLookupResult r = findServiceLocked(service, resolvedType, 11848 UserId.getCallingUserId()); 11849 11850 if (r != null) { 11851 // r.record is null if findServiceLocked() failed the caller permission check 11852 if (r.record == null) { 11853 throw new SecurityException( 11854 "Permission Denial: Accessing service " + r.record.name 11855 + " from pid=" + Binder.getCallingPid() 11856 + ", uid=" + Binder.getCallingUid() 11857 + " requires " + r.permission); 11858 } 11859 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11860 if (ib != null) { 11861 ret = ib.binder; 11862 } 11863 } 11864 } 11865 11866 return ret; 11867 } 11868 11869 public boolean stopServiceToken(ComponentName className, IBinder token, 11870 int startId) { 11871 synchronized(this) { 11872 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11873 + " " + token + " startId=" + startId); 11874 ServiceRecord r = findServiceLocked(className, token); 11875 if (r != null) { 11876 if (startId >= 0) { 11877 // Asked to only stop if done with all work. Note that 11878 // to avoid leaks, we will take this as dropping all 11879 // start items up to and including this one. 11880 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11881 if (si != null) { 11882 while (r.deliveredStarts.size() > 0) { 11883 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); 11884 cur.removeUriPermissionsLocked(); 11885 if (cur == si) { 11886 break; 11887 } 11888 } 11889 } 11890 11891 if (r.getLastStartId() != startId) { 11892 return false; 11893 } 11894 11895 if (r.deliveredStarts.size() > 0) { 11896 Slog.w(TAG, "stopServiceToken startId " + startId 11897 + " is last, but have " + r.deliveredStarts.size() 11898 + " remaining args"); 11899 } 11900 } 11901 11902 synchronized (r.stats.getBatteryStats()) { 11903 r.stats.stopRunningLocked(); 11904 r.startRequested = false; 11905 r.callStart = false; 11906 } 11907 final long origId = Binder.clearCallingIdentity(); 11908 bringDownServiceLocked(r, false); 11909 Binder.restoreCallingIdentity(origId); 11910 return true; 11911 } 11912 } 11913 return false; 11914 } 11915 11916 public void setServiceForeground(ComponentName className, IBinder token, 11917 int id, Notification notification, boolean removeNotification) { 11918 final long origId = Binder.clearCallingIdentity(); 11919 try { 11920 synchronized(this) { 11921 ServiceRecord r = findServiceLocked(className, token); 11922 if (r != null) { 11923 if (id != 0) { 11924 if (notification == null) { 11925 throw new IllegalArgumentException("null notification"); 11926 } 11927 if (r.foregroundId != id) { 11928 r.cancelNotification(); 11929 r.foregroundId = id; 11930 } 11931 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11932 r.foregroundNoti = notification; 11933 r.isForeground = true; 11934 r.postNotification(); 11935 if (r.app != null) { 11936 updateServiceForegroundLocked(r.app, true); 11937 } 11938 } else { 11939 if (r.isForeground) { 11940 r.isForeground = false; 11941 if (r.app != null) { 11942 updateLruProcessLocked(r.app, false, true); 11943 updateServiceForegroundLocked(r.app, true); 11944 } 11945 } 11946 if (removeNotification) { 11947 r.cancelNotification(); 11948 r.foregroundId = 0; 11949 r.foregroundNoti = null; 11950 } 11951 } 11952 } 11953 } 11954 } finally { 11955 Binder.restoreCallingIdentity(origId); 11956 } 11957 } 11958 11959 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11960 boolean anyForeground = false; 11961 for (ServiceRecord sr : proc.services) { 11962 if (sr.isForeground) { 11963 anyForeground = true; 11964 break; 11965 } 11966 } 11967 if (anyForeground != proc.foregroundServices) { 11968 proc.foregroundServices = anyForeground; 11969 if (oomAdj) { 11970 updateOomAdjLocked(); 11971 } 11972 } 11973 } 11974 11975 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) { 11976 boolean result = false; 11977 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 11978 result = false; 11979 } else if (componentProcessName == aInfo.packageName) { 11980 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 11981 } else if ("system".equals(componentProcessName)) { 11982 result = true; 11983 } 11984 if (DEBUG_MU) { 11985 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result); 11986 } 11987 return result; 11988 } 11989 11990 public int bindService(IApplicationThread caller, IBinder token, 11991 Intent service, String resolvedType, 11992 IServiceConnection connection, int flags, int userId) { 11993 enforceNotIsolatedCaller("bindService"); 11994 // Refuse possible leaked file descriptors 11995 if (service != null && service.hasFileDescriptors() == true) { 11996 throw new IllegalArgumentException("File descriptors passed in Intent"); 11997 } 11998 11999 checkValidCaller(Binder.getCallingUid(), userId); 12000 12001 synchronized(this) { 12002 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 12003 + " type=" + resolvedType + " conn=" + connection.asBinder() 12004 + " flags=0x" + Integer.toHexString(flags)); 12005 if (DEBUG_MU) 12006 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid=" 12007 + Binder.getOrigCallingUid()); 12008 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12009 if (callerApp == null) { 12010 throw new SecurityException( 12011 "Unable to find app for caller " + caller 12012 + " (pid=" + Binder.getCallingPid() 12013 + ") when binding service " + service); 12014 } 12015 12016 ActivityRecord activity = null; 12017 if (token != null) { 12018 activity = mMainStack.isInStackLocked(token); 12019 if (activity == null) { 12020 Slog.w(TAG, "Binding with unknown activity: " + token); 12021 return 0; 12022 } 12023 } 12024 12025 int clientLabel = 0; 12026 PendingIntent clientIntent = null; 12027 12028 if (callerApp.info.uid == Process.SYSTEM_UID) { 12029 // Hacky kind of thing -- allow system stuff to tell us 12030 // what they are, so we can report this elsewhere for 12031 // others to know why certain services are running. 12032 try { 12033 clientIntent = (PendingIntent)service.getParcelableExtra( 12034 Intent.EXTRA_CLIENT_INTENT); 12035 } catch (RuntimeException e) { 12036 } 12037 if (clientIntent != null) { 12038 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 12039 if (clientLabel != 0) { 12040 // There are no useful extras in the intent, trash them. 12041 // System code calling with this stuff just needs to know 12042 // this will happen. 12043 service = service.cloneFilter(); 12044 } 12045 } 12046 } 12047 12048 ServiceLookupResult res = 12049 retrieveServiceLocked(service, resolvedType, 12050 Binder.getCallingPid(), Binder.getCallingUid(), userId); 12051 if (res == null) { 12052 return 0; 12053 } 12054 if (res.record == null) { 12055 return -1; 12056 } 12057 if (isSingleton(res.record.processName, res.record.appInfo)) { 12058 userId = 0; 12059 res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(), 12060 Binder.getCallingUid(), 0); 12061 } 12062 ServiceRecord s = res.record; 12063 12064 final long origId = Binder.clearCallingIdentity(); 12065 12066 if (unscheduleServiceRestartLocked(s)) { 12067 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 12068 + s); 12069 } 12070 12071 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 12072 ConnectionRecord c = new ConnectionRecord(b, activity, 12073 connection, flags, clientLabel, clientIntent); 12074 12075 IBinder binder = connection.asBinder(); 12076 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 12077 if (clist == null) { 12078 clist = new ArrayList<ConnectionRecord>(); 12079 s.connections.put(binder, clist); 12080 } 12081 clist.add(c); 12082 b.connections.add(c); 12083 if (activity != null) { 12084 if (activity.connections == null) { 12085 activity.connections = new HashSet<ConnectionRecord>(); 12086 } 12087 activity.connections.add(c); 12088 } 12089 b.client.connections.add(c); 12090 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 12091 b.client.hasAboveClient = true; 12092 } 12093 clist = mServiceConnections.get(binder); 12094 if (clist == null) { 12095 clist = new ArrayList<ConnectionRecord>(); 12096 mServiceConnections.put(binder, clist); 12097 } 12098 clist.add(c); 12099 12100 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 12101 s.lastActivity = SystemClock.uptimeMillis(); 12102 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 12103 return 0; 12104 } 12105 } 12106 12107 if (s.app != null) { 12108 // This could have made the service more important. 12109 updateOomAdjLocked(s.app); 12110 } 12111 12112 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 12113 + ": received=" + b.intent.received 12114 + " apps=" + b.intent.apps.size() 12115 + " doRebind=" + b.intent.doRebind); 12116 12117 if (s.app != null && b.intent.received) { 12118 // Service is already running, so we can immediately 12119 // publish the connection. 12120 try { 12121 c.conn.connected(s.name, b.intent.binder); 12122 } catch (Exception e) { 12123 Slog.w(TAG, "Failure sending service " + s.shortName 12124 + " to connection " + c.conn.asBinder() 12125 + " (in " + c.binding.client.processName + ")", e); 12126 } 12127 12128 // If this is the first app connected back to this binding, 12129 // and the service had previously asked to be told when 12130 // rebound, then do so. 12131 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 12132 requestServiceBindingLocked(s, b.intent, true); 12133 } 12134 } else if (!b.intent.requested) { 12135 requestServiceBindingLocked(s, b.intent, false); 12136 } 12137 12138 Binder.restoreCallingIdentity(origId); 12139 } 12140 12141 return 1; 12142 } 12143 12144 void removeConnectionLocked( 12145 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { 12146 IBinder binder = c.conn.asBinder(); 12147 AppBindRecord b = c.binding; 12148 ServiceRecord s = b.service; 12149 ArrayList<ConnectionRecord> clist = s.connections.get(binder); 12150 if (clist != null) { 12151 clist.remove(c); 12152 if (clist.size() == 0) { 12153 s.connections.remove(binder); 12154 } 12155 } 12156 b.connections.remove(c); 12157 if (c.activity != null && c.activity != skipAct) { 12158 if (c.activity.connections != null) { 12159 c.activity.connections.remove(c); 12160 } 12161 } 12162 if (b.client != skipApp) { 12163 b.client.connections.remove(c); 12164 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { 12165 b.client.updateHasAboveClientLocked(); 12166 } 12167 } 12168 clist = mServiceConnections.get(binder); 12169 if (clist != null) { 12170 clist.remove(c); 12171 if (clist.size() == 0) { 12172 mServiceConnections.remove(binder); 12173 } 12174 } 12175 12176 if (b.connections.size() == 0) { 12177 b.intent.apps.remove(b.client); 12178 } 12179 12180 if (!c.serviceDead) { 12181 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 12182 + ": shouldUnbind=" + b.intent.hasBound); 12183 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 12184 && b.intent.hasBound) { 12185 try { 12186 bumpServiceExecutingLocked(s, "unbind"); 12187 updateOomAdjLocked(s.app); 12188 b.intent.hasBound = false; 12189 // Assume the client doesn't want to know about a rebind; 12190 // we will deal with that later if it asks for one. 12191 b.intent.doRebind = false; 12192 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 12193 } catch (Exception e) { 12194 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 12195 serviceDoneExecutingLocked(s, true); 12196 } 12197 } 12198 12199 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 12200 bringDownServiceLocked(s, false); 12201 } 12202 } 12203 } 12204 12205 public boolean unbindService(IServiceConnection connection) { 12206 synchronized (this) { 12207 IBinder binder = connection.asBinder(); 12208 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 12209 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); 12210 if (clist == null) { 12211 Slog.w(TAG, "Unbind failed: could not find connection for " 12212 + connection.asBinder()); 12213 return false; 12214 } 12215 12216 final long origId = Binder.clearCallingIdentity(); 12217 12218 while (clist.size() > 0) { 12219 ConnectionRecord r = clist.get(0); 12220 removeConnectionLocked(r, null, null); 12221 12222 if (r.binding.service.app != null) { 12223 // This could have made the service less important. 12224 updateOomAdjLocked(r.binding.service.app); 12225 } 12226 } 12227 12228 Binder.restoreCallingIdentity(origId); 12229 } 12230 12231 return true; 12232 } 12233 12234 public void publishService(IBinder token, Intent intent, IBinder service) { 12235 // Refuse possible leaked file descriptors 12236 if (intent != null && intent.hasFileDescriptors() == true) { 12237 throw new IllegalArgumentException("File descriptors passed in Intent"); 12238 } 12239 12240 synchronized(this) { 12241 if (!(token instanceof ServiceRecord)) { 12242 throw new IllegalArgumentException("Invalid service token"); 12243 } 12244 ServiceRecord r = (ServiceRecord)token; 12245 12246 final long origId = Binder.clearCallingIdentity(); 12247 12248 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r 12249 + " " + intent + ": " + service); 12250 if (r != null) { 12251 Intent.FilterComparison filter 12252 = new Intent.FilterComparison(intent); 12253 IntentBindRecord b = r.bindings.get(filter); 12254 if (b != null && !b.received) { 12255 b.binder = service; 12256 b.requested = true; 12257 b.received = true; 12258 if (r.connections.size() > 0) { 12259 Iterator<ArrayList<ConnectionRecord>> it 12260 = r.connections.values().iterator(); 12261 while (it.hasNext()) { 12262 ArrayList<ConnectionRecord> clist = it.next(); 12263 for (int i=0; i<clist.size(); i++) { 12264 ConnectionRecord c = clist.get(i); 12265 if (!filter.equals(c.binding.intent.intent)) { 12266 if (DEBUG_SERVICE) Slog.v( 12267 TAG, "Not publishing to: " + c); 12268 if (DEBUG_SERVICE) Slog.v( 12269 TAG, "Bound intent: " + c.binding.intent.intent); 12270 if (DEBUG_SERVICE) Slog.v( 12271 TAG, "Published intent: " + intent); 12272 continue; 12273 } 12274 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 12275 try { 12276 c.conn.connected(r.name, service); 12277 } catch (Exception e) { 12278 Slog.w(TAG, "Failure sending service " + r.name + 12279 " to connection " + c.conn.asBinder() + 12280 " (in " + c.binding.client.processName + ")", e); 12281 } 12282 } 12283 } 12284 } 12285 } 12286 12287 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 12288 12289 Binder.restoreCallingIdentity(origId); 12290 } 12291 } 12292 } 12293 12294 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12295 // Refuse possible leaked file descriptors 12296 if (intent != null && intent.hasFileDescriptors() == true) { 12297 throw new IllegalArgumentException("File descriptors passed in Intent"); 12298 } 12299 12300 synchronized(this) { 12301 if (!(token instanceof ServiceRecord)) { 12302 throw new IllegalArgumentException("Invalid service token"); 12303 } 12304 ServiceRecord r = (ServiceRecord)token; 12305 12306 final long origId = Binder.clearCallingIdentity(); 12307 12308 if (r != null) { 12309 Intent.FilterComparison filter 12310 = new Intent.FilterComparison(intent); 12311 IntentBindRecord b = r.bindings.get(filter); 12312 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 12313 + " at " + b + ": apps=" 12314 + (b != null ? b.apps.size() : 0)); 12315 12316 boolean inStopping = mStoppingServices.contains(r); 12317 if (b != null) { 12318 if (b.apps.size() > 0 && !inStopping) { 12319 // Applications have already bound since the last 12320 // unbind, so just rebind right here. 12321 requestServiceBindingLocked(r, b, true); 12322 } else { 12323 // Note to tell the service the next time there is 12324 // a new client. 12325 b.doRebind = true; 12326 } 12327 } 12328 12329 serviceDoneExecutingLocked(r, inStopping); 12330 12331 Binder.restoreCallingIdentity(origId); 12332 } 12333 } 12334 } 12335 12336 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12337 synchronized(this) { 12338 if (!(token instanceof ServiceRecord)) { 12339 throw new IllegalArgumentException("Invalid service token"); 12340 } 12341 ServiceRecord r = (ServiceRecord)token; 12342 boolean inStopping = mStoppingServices.contains(token); 12343 if (r != null) { 12344 if (r != token) { 12345 Slog.w(TAG, "Done executing service " + r.name 12346 + " with incorrect token: given " + token 12347 + ", expected " + r); 12348 return; 12349 } 12350 12351 if (type == 1) { 12352 // This is a call from a service start... take care of 12353 // book-keeping. 12354 r.callStart = true; 12355 switch (res) { 12356 case Service.START_STICKY_COMPATIBILITY: 12357 case Service.START_STICKY: { 12358 // We are done with the associated start arguments. 12359 r.findDeliveredStart(startId, true); 12360 // Don't stop if killed. 12361 r.stopIfKilled = false; 12362 break; 12363 } 12364 case Service.START_NOT_STICKY: { 12365 // We are done with the associated start arguments. 12366 r.findDeliveredStart(startId, true); 12367 if (r.getLastStartId() == startId) { 12368 // There is no more work, and this service 12369 // doesn't want to hang around if killed. 12370 r.stopIfKilled = true; 12371 } 12372 break; 12373 } 12374 case Service.START_REDELIVER_INTENT: { 12375 // We'll keep this item until they explicitly 12376 // call stop for it, but keep track of the fact 12377 // that it was delivered. 12378 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 12379 if (si != null) { 12380 si.deliveryCount = 0; 12381 si.doneExecutingCount++; 12382 // Don't stop if killed. 12383 r.stopIfKilled = true; 12384 } 12385 break; 12386 } 12387 case Service.START_TASK_REMOVED_COMPLETE: { 12388 // Special processing for onTaskRemoved(). Don't 12389 // impact normal onStartCommand() processing. 12390 r.findDeliveredStart(startId, true); 12391 break; 12392 } 12393 default: 12394 throw new IllegalArgumentException( 12395 "Unknown service start result: " + res); 12396 } 12397 if (res == Service.START_STICKY_COMPATIBILITY) { 12398 r.callStart = false; 12399 } 12400 } 12401 if (DEBUG_MU) 12402 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid=" 12403 + Binder.getOrigCallingUid()); 12404 final long origId = Binder.clearCallingIdentity(); 12405 serviceDoneExecutingLocked(r, inStopping); 12406 Binder.restoreCallingIdentity(origId); 12407 } else { 12408 Slog.w(TAG, "Done executing unknown service from pid " 12409 + Binder.getCallingPid()); 12410 } 12411 } 12412 } 12413 12414 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 12415 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r 12416 + ": nesting=" + r.executeNesting 12417 + ", inStopping=" + inStopping + ", app=" + r.app); 12418 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName); 12419 r.executeNesting--; 12420 if (r.executeNesting <= 0 && r.app != null) { 12421 if (DEBUG_SERVICE) Slog.v(TAG, 12422 "Nesting at 0 of " + r.shortName); 12423 r.app.executingServices.remove(r); 12424 if (r.app.executingServices.size() == 0) { 12425 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG, 12426 "No more executingServices of " + r.shortName); 12427 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 12428 } 12429 if (inStopping) { 12430 if (DEBUG_SERVICE) Slog.v(TAG, 12431 "doneExecuting remove stopping " + r); 12432 mStoppingServices.remove(r); 12433 r.bindings.clear(); 12434 } 12435 updateOomAdjLocked(r.app); 12436 } 12437 } 12438 12439 void serviceTimeout(ProcessRecord proc) { 12440 String anrMessage = null; 12441 12442 synchronized(this) { 12443 if (proc.executingServices.size() == 0 || proc.thread == null) { 12444 return; 12445 } 12446 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 12447 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 12448 ServiceRecord timeout = null; 12449 long nextTime = 0; 12450 while (it.hasNext()) { 12451 ServiceRecord sr = it.next(); 12452 if (sr.executingStart < maxTime) { 12453 timeout = sr; 12454 break; 12455 } 12456 if (sr.executingStart > nextTime) { 12457 nextTime = sr.executingStart; 12458 } 12459 } 12460 if (timeout != null && mLruProcesses.contains(proc)) { 12461 Slog.w(TAG, "Timeout executing service: " + timeout); 12462 anrMessage = "Executing service " + timeout.shortName; 12463 } else { 12464 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 12465 msg.obj = proc; 12466 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 12467 } 12468 } 12469 12470 if (anrMessage != null) { 12471 appNotResponding(proc, null, null, anrMessage); 12472 } 12473 } 12474 12475 // ========================================================= 12476 // BACKUP AND RESTORE 12477 // ========================================================= 12478 12479 // Cause the target app to be launched if necessary and its backup agent 12480 // instantiated. The backup agent will invoke backupAgentCreated() on the 12481 // activity manager to announce its creation. 12482 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12483 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 12484 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 12485 12486 synchronized(this) { 12487 // !!! TODO: currently no check here that we're already bound 12488 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12489 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12490 synchronized (stats) { 12491 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12492 } 12493 12494 // Backup agent is now in use, its package can't be stopped. 12495 try { 12496 AppGlobals.getPackageManager().setPackageStoppedState( 12497 app.packageName, false, UserId.getUserId(app.uid)); 12498 } catch (RemoteException e) { 12499 } catch (IllegalArgumentException e) { 12500 Slog.w(TAG, "Failed trying to unstop package " 12501 + app.packageName + ": " + e); 12502 } 12503 12504 BackupRecord r = new BackupRecord(ss, app, backupMode); 12505 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12506 ? new ComponentName(app.packageName, app.backupAgentName) 12507 : new ComponentName("android", "FullBackupAgent"); 12508 // startProcessLocked() returns existing proc's record if it's already running 12509 ProcessRecord proc = startProcessLocked(app.processName, app, 12510 false, 0, "backup", hostingName, false, false); 12511 if (proc == null) { 12512 Slog.e(TAG, "Unable to start backup agent process " + r); 12513 return false; 12514 } 12515 12516 r.app = proc; 12517 mBackupTarget = r; 12518 mBackupAppName = app.packageName; 12519 12520 // Try not to kill the process during backup 12521 updateOomAdjLocked(proc); 12522 12523 // If the process is already attached, schedule the creation of the backup agent now. 12524 // If it is not yet live, this will be done when it attaches to the framework. 12525 if (proc.thread != null) { 12526 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12527 try { 12528 proc.thread.scheduleCreateBackupAgent(app, 12529 compatibilityInfoForPackageLocked(app), backupMode); 12530 } catch (RemoteException e) { 12531 // Will time out on the backup manager side 12532 } 12533 } else { 12534 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12535 } 12536 // Invariants: at this point, the target app process exists and the application 12537 // is either already running or in the process of coming up. mBackupTarget and 12538 // mBackupAppName describe the app, so that when it binds back to the AM we 12539 // know that it's scheduled for a backup-agent operation. 12540 } 12541 12542 return true; 12543 } 12544 12545 // A backup agent has just come up 12546 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12547 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12548 + " = " + agent); 12549 12550 synchronized(this) { 12551 if (!agentPackageName.equals(mBackupAppName)) { 12552 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12553 return; 12554 } 12555 } 12556 12557 long oldIdent = Binder.clearCallingIdentity(); 12558 try { 12559 IBackupManager bm = IBackupManager.Stub.asInterface( 12560 ServiceManager.getService(Context.BACKUP_SERVICE)); 12561 bm.agentConnected(agentPackageName, agent); 12562 } catch (RemoteException e) { 12563 // can't happen; the backup manager service is local 12564 } catch (Exception e) { 12565 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12566 e.printStackTrace(); 12567 } finally { 12568 Binder.restoreCallingIdentity(oldIdent); 12569 } 12570 } 12571 12572 // done with this agent 12573 public void unbindBackupAgent(ApplicationInfo appInfo) { 12574 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12575 if (appInfo == null) { 12576 Slog.w(TAG, "unbind backup agent for null app"); 12577 return; 12578 } 12579 12580 synchronized(this) { 12581 if (mBackupAppName == null) { 12582 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12583 return; 12584 } 12585 12586 if (!mBackupAppName.equals(appInfo.packageName)) { 12587 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12588 return; 12589 } 12590 12591 ProcessRecord proc = mBackupTarget.app; 12592 mBackupTarget = null; 12593 mBackupAppName = null; 12594 12595 // Not backing this app up any more; reset its OOM adjustment 12596 updateOomAdjLocked(proc); 12597 12598 // If the app crashed during backup, 'thread' will be null here 12599 if (proc.thread != null) { 12600 try { 12601 proc.thread.scheduleDestroyBackupAgent(appInfo, 12602 compatibilityInfoForPackageLocked(appInfo)); 12603 } catch (Exception e) { 12604 Slog.e(TAG, "Exception when unbinding backup agent:"); 12605 e.printStackTrace(); 12606 } 12607 } 12608 } 12609 } 12610 // ========================================================= 12611 // BROADCASTS 12612 // ========================================================= 12613 12614 private final List getStickiesLocked(String action, IntentFilter filter, 12615 List cur) { 12616 final ContentResolver resolver = mContext.getContentResolver(); 12617 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 12618 if (list == null) { 12619 return cur; 12620 } 12621 int N = list.size(); 12622 for (int i=0; i<N; i++) { 12623 Intent intent = list.get(i); 12624 if (filter.match(resolver, intent, true, TAG) >= 0) { 12625 if (cur == null) { 12626 cur = new ArrayList<Intent>(); 12627 } 12628 cur.add(intent); 12629 } 12630 } 12631 return cur; 12632 } 12633 12634 boolean isPendingBroadcastProcessLocked(int pid) { 12635 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12636 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12637 } 12638 12639 void skipPendingBroadcastLocked(int pid) { 12640 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12641 for (BroadcastQueue queue : mBroadcastQueues) { 12642 queue.skipPendingBroadcastLocked(pid); 12643 } 12644 } 12645 12646 // The app just attached; send any pending broadcasts that it should receive 12647 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12648 boolean didSomething = false; 12649 for (BroadcastQueue queue : mBroadcastQueues) { 12650 didSomething |= queue.sendPendingBroadcastsLocked(app); 12651 } 12652 return didSomething; 12653 } 12654 12655 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12656 IIntentReceiver receiver, IntentFilter filter, String permission) { 12657 enforceNotIsolatedCaller("registerReceiver"); 12658 synchronized(this) { 12659 ProcessRecord callerApp = null; 12660 if (caller != null) { 12661 callerApp = getRecordForAppLocked(caller); 12662 if (callerApp == null) { 12663 throw new SecurityException( 12664 "Unable to find app for caller " + caller 12665 + " (pid=" + Binder.getCallingPid() 12666 + ") when registering receiver " + receiver); 12667 } 12668 if (callerApp.info.uid != Process.SYSTEM_UID && 12669 !callerApp.pkgList.contains(callerPackage)) { 12670 throw new SecurityException("Given caller package " + callerPackage 12671 + " is not running in process " + callerApp); 12672 } 12673 } else { 12674 callerPackage = null; 12675 } 12676 12677 List allSticky = null; 12678 12679 // Look for any matching sticky broadcasts... 12680 Iterator actions = filter.actionsIterator(); 12681 if (actions != null) { 12682 while (actions.hasNext()) { 12683 String action = (String)actions.next(); 12684 allSticky = getStickiesLocked(action, filter, allSticky); 12685 } 12686 } else { 12687 allSticky = getStickiesLocked(null, filter, allSticky); 12688 } 12689 12690 // The first sticky in the list is returned directly back to 12691 // the client. 12692 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12693 12694 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12695 + ": " + sticky); 12696 12697 if (receiver == null) { 12698 return sticky; 12699 } 12700 12701 ReceiverList rl 12702 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12703 if (rl == null) { 12704 rl = new ReceiverList(this, callerApp, 12705 Binder.getCallingPid(), 12706 Binder.getCallingUid(), receiver); 12707 if (rl.app != null) { 12708 rl.app.receivers.add(rl); 12709 } else { 12710 try { 12711 receiver.asBinder().linkToDeath(rl, 0); 12712 } catch (RemoteException e) { 12713 return sticky; 12714 } 12715 rl.linkedToDeath = true; 12716 } 12717 mRegisteredReceivers.put(receiver.asBinder(), rl); 12718 } 12719 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission); 12720 rl.add(bf); 12721 if (!bf.debugCheck()) { 12722 Slog.w(TAG, "==> For Dynamic broadast"); 12723 } 12724 mReceiverResolver.addFilter(bf); 12725 12726 // Enqueue broadcasts for all existing stickies that match 12727 // this filter. 12728 if (allSticky != null) { 12729 ArrayList receivers = new ArrayList(); 12730 receivers.add(bf); 12731 12732 int N = allSticky.size(); 12733 for (int i=0; i<N; i++) { 12734 Intent intent = (Intent)allSticky.get(i); 12735 BroadcastQueue queue = broadcastQueueForIntent(intent); 12736 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12737 null, -1, -1, null, receivers, null, 0, null, null, 12738 false, true, true); 12739 queue.enqueueParallelBroadcastLocked(r); 12740 queue.scheduleBroadcastsLocked(); 12741 } 12742 } 12743 12744 return sticky; 12745 } 12746 } 12747 12748 public void unregisterReceiver(IIntentReceiver receiver) { 12749 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12750 12751 final long origId = Binder.clearCallingIdentity(); 12752 try { 12753 boolean doTrim = false; 12754 12755 synchronized(this) { 12756 ReceiverList rl 12757 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12758 if (rl != null) { 12759 if (rl.curBroadcast != null) { 12760 BroadcastRecord r = rl.curBroadcast; 12761 final boolean doNext = finishReceiverLocked( 12762 receiver.asBinder(), r.resultCode, r.resultData, 12763 r.resultExtras, r.resultAbort, true); 12764 if (doNext) { 12765 doTrim = true; 12766 r.queue.processNextBroadcast(false); 12767 } 12768 } 12769 12770 if (rl.app != null) { 12771 rl.app.receivers.remove(rl); 12772 } 12773 removeReceiverLocked(rl); 12774 if (rl.linkedToDeath) { 12775 rl.linkedToDeath = false; 12776 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12777 } 12778 } 12779 } 12780 12781 // If we actually concluded any broadcasts, we might now be able 12782 // to trim the recipients' apps from our working set 12783 if (doTrim) { 12784 trimApplications(); 12785 return; 12786 } 12787 12788 } finally { 12789 Binder.restoreCallingIdentity(origId); 12790 } 12791 } 12792 12793 void removeReceiverLocked(ReceiverList rl) { 12794 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12795 int N = rl.size(); 12796 for (int i=0; i<N; i++) { 12797 mReceiverResolver.removeFilter(rl.get(i)); 12798 } 12799 } 12800 12801 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12802 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12803 ProcessRecord r = mLruProcesses.get(i); 12804 if (r.thread != null) { 12805 try { 12806 r.thread.dispatchPackageBroadcast(cmd, packages); 12807 } catch (RemoteException ex) { 12808 } 12809 } 12810 } 12811 } 12812 12813 private final int broadcastIntentLocked(ProcessRecord callerApp, 12814 String callerPackage, Intent intent, String resolvedType, 12815 IIntentReceiver resultTo, int resultCode, String resultData, 12816 Bundle map, String requiredPermission, 12817 boolean ordered, boolean sticky, int callingPid, int callingUid, 12818 int userId) { 12819 intent = new Intent(intent); 12820 12821 // By default broadcasts do not go to stopped apps. 12822 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 12823 12824 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12825 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12826 + " ordered=" + ordered + " userid=" + userId); 12827 if ((resultTo != null) && !ordered) { 12828 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12829 } 12830 12831 // Handle special intents: if this broadcast is from the package 12832 // manager about a package being removed, we need to remove all of 12833 // its activities from the history stack. 12834 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 12835 intent.getAction()); 12836 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12837 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12838 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12839 || uidRemoved) { 12840 if (checkComponentPermission( 12841 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12842 callingPid, callingUid, -1, true) 12843 == PackageManager.PERMISSION_GRANTED) { 12844 if (uidRemoved) { 12845 final Bundle intentExtras = intent.getExtras(); 12846 final int uid = intentExtras != null 12847 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12848 if (uid >= 0) { 12849 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12850 synchronized (bs) { 12851 bs.removeUidStatsLocked(uid); 12852 } 12853 } 12854 } else { 12855 // If resources are unvailble just force stop all 12856 // those packages and flush the attribute cache as well. 12857 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12858 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12859 if (list != null && (list.length > 0)) { 12860 for (String pkg : list) { 12861 forceStopPackageLocked(pkg, -1, false, true, true, false, userId); 12862 } 12863 sendPackageBroadcastLocked( 12864 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12865 } 12866 } else { 12867 Uri data = intent.getData(); 12868 String ssp; 12869 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12870 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12871 forceStopPackageLocked(ssp, 12872 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, 12873 false, userId); 12874 } 12875 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12876 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12877 new String[] {ssp}); 12878 } 12879 } 12880 } 12881 } 12882 } else { 12883 String msg = "Permission Denial: " + intent.getAction() 12884 + " broadcast from " + callerPackage + " (pid=" + callingPid 12885 + ", uid=" + callingUid + ")" 12886 + " requires " 12887 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12888 Slog.w(TAG, msg); 12889 throw new SecurityException(msg); 12890 } 12891 12892 // Special case for adding a package: by default turn on compatibility 12893 // mode. 12894 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12895 Uri data = intent.getData(); 12896 String ssp; 12897 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12898 mCompatModePackages.handlePackageAddedLocked(ssp, 12899 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 12900 } 12901 } 12902 12903 /* 12904 * If this is the time zone changed action, queue up a message that will reset the timezone 12905 * of all currently running processes. This message will get queued up before the broadcast 12906 * happens. 12907 */ 12908 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12909 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12910 } 12911 12912 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 12913 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE); 12914 } 12915 12916 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 12917 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 12918 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy)); 12919 } 12920 12921 /* 12922 * Prevent non-system code (defined here to be non-persistent 12923 * processes) from sending protected broadcasts. 12924 */ 12925 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12926 || callingUid == Process.SHELL_UID || callingUid == 0) { 12927 // Always okay. 12928 } else if (callerApp == null || !callerApp.persistent) { 12929 try { 12930 if (AppGlobals.getPackageManager().isProtectedBroadcast( 12931 intent.getAction())) { 12932 String msg = "Permission Denial: not allowed to send broadcast " 12933 + intent.getAction() + " from pid=" 12934 + callingPid + ", uid=" + callingUid; 12935 Slog.w(TAG, msg); 12936 throw new SecurityException(msg); 12937 } 12938 } catch (RemoteException e) { 12939 Slog.w(TAG, "Remote exception", e); 12940 return ActivityManager.BROADCAST_SUCCESS; 12941 } 12942 } 12943 12944 // Add to the sticky list if requested. 12945 if (sticky) { 12946 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12947 callingPid, callingUid) 12948 != PackageManager.PERMISSION_GRANTED) { 12949 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12950 + callingPid + ", uid=" + callingUid 12951 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12952 Slog.w(TAG, msg); 12953 throw new SecurityException(msg); 12954 } 12955 if (requiredPermission != null) { 12956 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12957 + " and enforce permission " + requiredPermission); 12958 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12959 } 12960 if (intent.getComponent() != null) { 12961 throw new SecurityException( 12962 "Sticky broadcasts can't target a specific component"); 12963 } 12964 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12965 if (list == null) { 12966 list = new ArrayList<Intent>(); 12967 mStickyBroadcasts.put(intent.getAction(), list); 12968 } 12969 int N = list.size(); 12970 int i; 12971 for (i=0; i<N; i++) { 12972 if (intent.filterEquals(list.get(i))) { 12973 // This sticky already exists, replace it. 12974 list.set(i, new Intent(intent)); 12975 break; 12976 } 12977 } 12978 if (i >= N) { 12979 list.add(new Intent(intent)); 12980 } 12981 } 12982 12983 // Figure out who all will receive this broadcast. 12984 List receivers = null; 12985 List<BroadcastFilter> registeredReceivers = null; 12986 try { 12987 if (intent.getComponent() != null) { 12988 // Broadcast is going to one specific receiver class... 12989 ActivityInfo ai = AppGlobals.getPackageManager(). 12990 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId); 12991 if (ai != null) { 12992 receivers = new ArrayList(); 12993 ResolveInfo ri = new ResolveInfo(); 12994 if (isSingleton(ai.processName, ai.applicationInfo)) { 12995 ri.activityInfo = getActivityInfoForUser(ai, 0); 12996 } else { 12997 ri.activityInfo = getActivityInfoForUser(ai, userId); 12998 } 12999 receivers.add(ri); 13000 } 13001 } else { 13002 // Need to resolve the intent to interested receivers... 13003 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13004 == 0) { 13005 receivers = 13006 AppGlobals.getPackageManager().queryIntentReceivers( 13007 intent, resolvedType, STOCK_PM_FLAGS, userId); 13008 } 13009 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, 13010 userId); 13011 } 13012 } catch (RemoteException ex) { 13013 // pm is in same process, this will never happen. 13014 } 13015 13016 final boolean replacePending = 13017 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13018 13019 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13020 + " replacePending=" + replacePending); 13021 13022 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13023 if (!ordered && NR > 0) { 13024 // If we are not serializing this broadcast, then send the 13025 // registered receivers separately so they don't wait for the 13026 // components to be launched. 13027 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13028 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13029 callerPackage, callingPid, callingUid, requiredPermission, 13030 registeredReceivers, resultTo, resultCode, resultData, map, 13031 ordered, sticky, false); 13032 if (DEBUG_BROADCAST) Slog.v( 13033 TAG, "Enqueueing parallel broadcast " + r); 13034 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13035 if (!replaced) { 13036 queue.enqueueParallelBroadcastLocked(r); 13037 queue.scheduleBroadcastsLocked(); 13038 } 13039 registeredReceivers = null; 13040 NR = 0; 13041 } 13042 13043 // Merge into one list. 13044 int ir = 0; 13045 if (receivers != null) { 13046 // A special case for PACKAGE_ADDED: do not allow the package 13047 // being added to see this broadcast. This prevents them from 13048 // using this as a back door to get run as soon as they are 13049 // installed. Maybe in the future we want to have a special install 13050 // broadcast or such for apps, but we'd like to deliberately make 13051 // this decision. 13052 String skipPackages[] = null; 13053 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13054 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13055 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13056 Uri data = intent.getData(); 13057 if (data != null) { 13058 String pkgName = data.getSchemeSpecificPart(); 13059 if (pkgName != null) { 13060 skipPackages = new String[] { pkgName }; 13061 } 13062 } 13063 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13064 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13065 } 13066 if (skipPackages != null && (skipPackages.length > 0)) { 13067 for (String skipPackage : skipPackages) { 13068 if (skipPackage != null) { 13069 int NT = receivers.size(); 13070 for (int it=0; it<NT; it++) { 13071 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13072 if (curt.activityInfo.packageName.equals(skipPackage)) { 13073 receivers.remove(it); 13074 it--; 13075 NT--; 13076 } 13077 } 13078 } 13079 } 13080 } 13081 13082 int NT = receivers != null ? receivers.size() : 0; 13083 int it = 0; 13084 ResolveInfo curt = null; 13085 BroadcastFilter curr = null; 13086 while (it < NT && ir < NR) { 13087 if (curt == null) { 13088 curt = (ResolveInfo)receivers.get(it); 13089 } 13090 if (curr == null) { 13091 curr = registeredReceivers.get(ir); 13092 } 13093 if (curr.getPriority() >= curt.priority) { 13094 // Insert this broadcast record into the final list. 13095 receivers.add(it, curr); 13096 ir++; 13097 curr = null; 13098 it++; 13099 NT++; 13100 } else { 13101 // Skip to the next ResolveInfo in the final list. 13102 it++; 13103 curt = null; 13104 } 13105 } 13106 } 13107 while (ir < NR) { 13108 if (receivers == null) { 13109 receivers = new ArrayList(); 13110 } 13111 receivers.add(registeredReceivers.get(ir)); 13112 ir++; 13113 } 13114 13115 if ((receivers != null && receivers.size() > 0) 13116 || resultTo != null) { 13117 BroadcastQueue queue = broadcastQueueForIntent(intent); 13118 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13119 callerPackage, callingPid, callingUid, requiredPermission, 13120 receivers, resultTo, resultCode, resultData, map, ordered, 13121 sticky, false); 13122 if (DEBUG_BROADCAST) Slog.v( 13123 TAG, "Enqueueing ordered broadcast " + r 13124 + ": prev had " + queue.mOrderedBroadcasts.size()); 13125 if (DEBUG_BROADCAST) { 13126 int seq = r.intent.getIntExtra("seq", -1); 13127 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13128 } 13129 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13130 if (!replaced) { 13131 queue.enqueueOrderedBroadcastLocked(r); 13132 queue.scheduleBroadcastsLocked(); 13133 } 13134 } 13135 13136 return ActivityManager.BROADCAST_SUCCESS; 13137 } 13138 13139 final Intent verifyBroadcastLocked(Intent intent) { 13140 // Refuse possible leaked file descriptors 13141 if (intent != null && intent.hasFileDescriptors() == true) { 13142 throw new IllegalArgumentException("File descriptors passed in Intent"); 13143 } 13144 13145 int flags = intent.getFlags(); 13146 13147 if (!mProcessesReady) { 13148 // if the caller really truly claims to know what they're doing, go 13149 // ahead and allow the broadcast without launching any receivers 13150 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13151 intent = new Intent(intent); 13152 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13153 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13154 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13155 + " before boot completion"); 13156 throw new IllegalStateException("Cannot broadcast before boot completed"); 13157 } 13158 } 13159 13160 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13161 throw new IllegalArgumentException( 13162 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13163 } 13164 13165 return intent; 13166 } 13167 13168 public final int broadcastIntent(IApplicationThread caller, 13169 Intent intent, String resolvedType, IIntentReceiver resultTo, 13170 int resultCode, String resultData, Bundle map, 13171 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13172 enforceNotIsolatedCaller("broadcastIntent"); 13173 synchronized(this) { 13174 intent = verifyBroadcastLocked(intent); 13175 13176 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13177 final int callingPid = Binder.getCallingPid(); 13178 final int callingUid = Binder.getCallingUid(); 13179 final long origId = Binder.clearCallingIdentity(); 13180 int res = broadcastIntentLocked(callerApp, 13181 callerApp != null ? callerApp.info.packageName : null, 13182 intent, resolvedType, resultTo, 13183 resultCode, resultData, map, requiredPermission, serialized, sticky, 13184 callingPid, callingUid, userId); 13185 Binder.restoreCallingIdentity(origId); 13186 return res; 13187 } 13188 } 13189 13190 int broadcastIntentInPackage(String packageName, int uid, 13191 Intent intent, String resolvedType, IIntentReceiver resultTo, 13192 int resultCode, String resultData, Bundle map, 13193 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13194 synchronized(this) { 13195 intent = verifyBroadcastLocked(intent); 13196 13197 final long origId = Binder.clearCallingIdentity(); 13198 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13199 resultTo, resultCode, resultData, map, requiredPermission, 13200 serialized, sticky, -1, uid, userId); 13201 Binder.restoreCallingIdentity(origId); 13202 return res; 13203 } 13204 } 13205 13206 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user. 13207 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13208 // Refuse possible leaked file descriptors 13209 if (intent != null && intent.hasFileDescriptors() == true) { 13210 throw new IllegalArgumentException("File descriptors passed in Intent"); 13211 } 13212 13213 synchronized(this) { 13214 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13215 != PackageManager.PERMISSION_GRANTED) { 13216 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13217 + Binder.getCallingPid() 13218 + ", uid=" + Binder.getCallingUid() 13219 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13220 Slog.w(TAG, msg); 13221 throw new SecurityException(msg); 13222 } 13223 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 13224 if (list != null) { 13225 int N = list.size(); 13226 int i; 13227 for (i=0; i<N; i++) { 13228 if (intent.filterEquals(list.get(i))) { 13229 list.remove(i); 13230 break; 13231 } 13232 } 13233 } 13234 } 13235 } 13236 13237 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13238 String resultData, Bundle resultExtras, boolean resultAbort, 13239 boolean explicit) { 13240 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13241 if (r == null) { 13242 Slog.w(TAG, "finishReceiver called but not found on queue"); 13243 return false; 13244 } 13245 13246 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, 13247 explicit); 13248 } 13249 13250 public void finishReceiver(IBinder who, int resultCode, String resultData, 13251 Bundle resultExtras, boolean resultAbort) { 13252 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13253 13254 // Refuse possible leaked file descriptors 13255 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13256 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13257 } 13258 13259 final long origId = Binder.clearCallingIdentity(); 13260 try { 13261 boolean doNext = false; 13262 BroadcastRecord r = null; 13263 13264 synchronized(this) { 13265 r = broadcastRecordForReceiverLocked(who); 13266 if (r != null) { 13267 doNext = r.queue.finishReceiverLocked(r, resultCode, 13268 resultData, resultExtras, resultAbort, true); 13269 } 13270 } 13271 13272 if (doNext) { 13273 r.queue.processNextBroadcast(false); 13274 } 13275 trimApplications(); 13276 } finally { 13277 Binder.restoreCallingIdentity(origId); 13278 } 13279 } 13280 13281 // ========================================================= 13282 // INSTRUMENTATION 13283 // ========================================================= 13284 13285 public boolean startInstrumentation(ComponentName className, 13286 String profileFile, int flags, Bundle arguments, 13287 IInstrumentationWatcher watcher) { 13288 enforceNotIsolatedCaller("startInstrumentation"); 13289 // Refuse possible leaked file descriptors 13290 if (arguments != null && arguments.hasFileDescriptors()) { 13291 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13292 } 13293 13294 synchronized(this) { 13295 InstrumentationInfo ii = null; 13296 ApplicationInfo ai = null; 13297 try { 13298 ii = mContext.getPackageManager().getInstrumentationInfo( 13299 className, STOCK_PM_FLAGS); 13300 ai = mContext.getPackageManager().getApplicationInfo( 13301 ii.targetPackage, STOCK_PM_FLAGS); 13302 } catch (PackageManager.NameNotFoundException e) { 13303 } 13304 if (ii == null) { 13305 reportStartInstrumentationFailure(watcher, className, 13306 "Unable to find instrumentation info for: " + className); 13307 return false; 13308 } 13309 if (ai == null) { 13310 reportStartInstrumentationFailure(watcher, className, 13311 "Unable to find instrumentation target package: " + ii.targetPackage); 13312 return false; 13313 } 13314 13315 int match = mContext.getPackageManager().checkSignatures( 13316 ii.targetPackage, ii.packageName); 13317 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13318 String msg = "Permission Denial: starting instrumentation " 13319 + className + " from pid=" 13320 + Binder.getCallingPid() 13321 + ", uid=" + Binder.getCallingPid() 13322 + " not allowed because package " + ii.packageName 13323 + " does not have a signature matching the target " 13324 + ii.targetPackage; 13325 reportStartInstrumentationFailure(watcher, className, msg); 13326 throw new SecurityException(msg); 13327 } 13328 13329 int userId = UserId.getCallingUserId(); 13330 final long origId = Binder.clearCallingIdentity(); 13331 // Instrumentation can kill and relaunch even persistent processes 13332 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId); 13333 ProcessRecord app = addAppLocked(ai, false); 13334 app.instrumentationClass = className; 13335 app.instrumentationInfo = ai; 13336 app.instrumentationProfileFile = profileFile; 13337 app.instrumentationArguments = arguments; 13338 app.instrumentationWatcher = watcher; 13339 app.instrumentationResultClass = className; 13340 Binder.restoreCallingIdentity(origId); 13341 } 13342 13343 return true; 13344 } 13345 13346 /** 13347 * Report errors that occur while attempting to start Instrumentation. Always writes the 13348 * error to the logs, but if somebody is watching, send the report there too. This enables 13349 * the "am" command to report errors with more information. 13350 * 13351 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13352 * @param cn The component name of the instrumentation. 13353 * @param report The error report. 13354 */ 13355 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13356 ComponentName cn, String report) { 13357 Slog.w(TAG, report); 13358 try { 13359 if (watcher != null) { 13360 Bundle results = new Bundle(); 13361 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13362 results.putString("Error", report); 13363 watcher.instrumentationStatus(cn, -1, results); 13364 } 13365 } catch (RemoteException e) { 13366 Slog.w(TAG, e); 13367 } 13368 } 13369 13370 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13371 if (app.instrumentationWatcher != null) { 13372 try { 13373 // NOTE: IInstrumentationWatcher *must* be oneway here 13374 app.instrumentationWatcher.instrumentationFinished( 13375 app.instrumentationClass, 13376 resultCode, 13377 results); 13378 } catch (RemoteException e) { 13379 } 13380 } 13381 app.instrumentationWatcher = null; 13382 app.instrumentationClass = null; 13383 app.instrumentationInfo = null; 13384 app.instrumentationProfileFile = null; 13385 app.instrumentationArguments = null; 13386 13387 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId); 13388 } 13389 13390 public void finishInstrumentation(IApplicationThread target, 13391 int resultCode, Bundle results) { 13392 int userId = UserId.getCallingUserId(); 13393 // Refuse possible leaked file descriptors 13394 if (results != null && results.hasFileDescriptors()) { 13395 throw new IllegalArgumentException("File descriptors passed in Intent"); 13396 } 13397 13398 synchronized(this) { 13399 ProcessRecord app = getRecordForAppLocked(target); 13400 if (app == null) { 13401 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13402 return; 13403 } 13404 final long origId = Binder.clearCallingIdentity(); 13405 finishInstrumentationLocked(app, resultCode, results); 13406 Binder.restoreCallingIdentity(origId); 13407 } 13408 } 13409 13410 // ========================================================= 13411 // CONFIGURATION 13412 // ========================================================= 13413 13414 public ConfigurationInfo getDeviceConfigurationInfo() { 13415 ConfigurationInfo config = new ConfigurationInfo(); 13416 synchronized (this) { 13417 config.reqTouchScreen = mConfiguration.touchscreen; 13418 config.reqKeyboardType = mConfiguration.keyboard; 13419 config.reqNavigation = mConfiguration.navigation; 13420 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13421 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13422 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13423 } 13424 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13425 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13426 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13427 } 13428 config.reqGlEsVersion = GL_ES_VERSION; 13429 } 13430 return config; 13431 } 13432 13433 public Configuration getConfiguration() { 13434 Configuration ci; 13435 synchronized(this) { 13436 ci = new Configuration(mConfiguration); 13437 } 13438 return ci; 13439 } 13440 13441 public void updatePersistentConfiguration(Configuration values) { 13442 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13443 "updateConfiguration()"); 13444 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13445 "updateConfiguration()"); 13446 if (values == null) { 13447 throw new NullPointerException("Configuration must not be null"); 13448 } 13449 13450 synchronized(this) { 13451 final long origId = Binder.clearCallingIdentity(); 13452 updateConfigurationLocked(values, null, true, false); 13453 Binder.restoreCallingIdentity(origId); 13454 } 13455 } 13456 13457 public void updateConfiguration(Configuration values) { 13458 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13459 "updateConfiguration()"); 13460 13461 synchronized(this) { 13462 if (values == null && mWindowManager != null) { 13463 // sentinel: fetch the current configuration from the window manager 13464 values = mWindowManager.computeNewConfiguration(); 13465 } 13466 13467 if (mWindowManager != null) { 13468 mProcessList.applyDisplaySize(mWindowManager); 13469 } 13470 13471 final long origId = Binder.clearCallingIdentity(); 13472 if (values != null) { 13473 Settings.System.clearConfiguration(values); 13474 } 13475 updateConfigurationLocked(values, null, false, false); 13476 Binder.restoreCallingIdentity(origId); 13477 } 13478 } 13479 13480 /** 13481 * Do either or both things: (1) change the current configuration, and (2) 13482 * make sure the given activity is running with the (now) current 13483 * configuration. Returns true if the activity has been left running, or 13484 * false if <var>starting</var> is being destroyed to match the new 13485 * configuration. 13486 * @param persistent TODO 13487 */ 13488 boolean updateConfigurationLocked(Configuration values, 13489 ActivityRecord starting, boolean persistent, boolean initLocale) { 13490 // do nothing if we are headless 13491 if (mHeadless) return true; 13492 13493 int changes = 0; 13494 13495 boolean kept = true; 13496 13497 if (values != null) { 13498 Configuration newConfig = new Configuration(mConfiguration); 13499 changes = newConfig.updateFrom(values); 13500 if (changes != 0) { 13501 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13502 Slog.i(TAG, "Updating configuration to: " + values); 13503 } 13504 13505 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13506 13507 if (values.locale != null && !initLocale) { 13508 saveLocaleLocked(values.locale, 13509 !values.locale.equals(mConfiguration.locale), 13510 values.userSetLocale); 13511 } 13512 13513 mConfigurationSeq++; 13514 if (mConfigurationSeq <= 0) { 13515 mConfigurationSeq = 1; 13516 } 13517 newConfig.seq = mConfigurationSeq; 13518 mConfiguration = newConfig; 13519 Slog.i(TAG, "Config changed: " + newConfig); 13520 13521 final Configuration configCopy = new Configuration(mConfiguration); 13522 13523 // TODO: If our config changes, should we auto dismiss any currently 13524 // showing dialogs? 13525 mShowDialogs = shouldShowDialogs(newConfig); 13526 13527 AttributeCache ac = AttributeCache.instance(); 13528 if (ac != null) { 13529 ac.updateConfiguration(configCopy); 13530 } 13531 13532 // Make sure all resources in our process are updated 13533 // right now, so that anyone who is going to retrieve 13534 // resource values after we return will be sure to get 13535 // the new ones. This is especially important during 13536 // boot, where the first config change needs to guarantee 13537 // all resources have that config before following boot 13538 // code is executed. 13539 mSystemThread.applyConfigurationToResources(configCopy); 13540 13541 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13542 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13543 msg.obj = new Configuration(configCopy); 13544 mHandler.sendMessage(msg); 13545 } 13546 13547 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13548 ProcessRecord app = mLruProcesses.get(i); 13549 try { 13550 if (app.thread != null) { 13551 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13552 + app.processName + " new config " + mConfiguration); 13553 app.thread.scheduleConfigurationChanged(configCopy); 13554 } 13555 } catch (Exception e) { 13556 } 13557 } 13558 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13559 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13560 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13561 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13562 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13563 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13564 broadcastIntentLocked(null, null, 13565 new Intent(Intent.ACTION_LOCALE_CHANGED), 13566 null, null, 0, null, null, 13567 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 13568 } 13569 } 13570 } 13571 13572 if (changes != 0 && starting == null) { 13573 // If the configuration changed, and the caller is not already 13574 // in the process of starting an activity, then find the top 13575 // activity to check if its configuration needs to change. 13576 starting = mMainStack.topRunningActivityLocked(null); 13577 } 13578 13579 if (starting != null) { 13580 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes); 13581 // And we need to make sure at this point that all other activities 13582 // are made visible with the correct configuration. 13583 mMainStack.ensureActivitiesVisibleLocked(starting, changes); 13584 } 13585 13586 if (values != null && mWindowManager != null) { 13587 mWindowManager.setNewConfiguration(mConfiguration); 13588 } 13589 13590 return kept; 13591 } 13592 13593 /** 13594 * Decide based on the configuration whether we should shouw the ANR, 13595 * crash, etc dialogs. The idea is that if there is no affordnace to 13596 * press the on-screen buttons, we shouldn't show the dialog. 13597 * 13598 * A thought: SystemUI might also want to get told about this, the Power 13599 * dialog / global actions also might want different behaviors. 13600 */ 13601 private static final boolean shouldShowDialogs(Configuration config) { 13602 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 13603 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 13604 } 13605 13606 /** 13607 * Save the locale. You must be inside a synchronized (this) block. 13608 */ 13609 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13610 if(isDiff) { 13611 SystemProperties.set("user.language", l.getLanguage()); 13612 SystemProperties.set("user.region", l.getCountry()); 13613 } 13614 13615 if(isPersist) { 13616 SystemProperties.set("persist.sys.language", l.getLanguage()); 13617 SystemProperties.set("persist.sys.country", l.getCountry()); 13618 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13619 } 13620 } 13621 13622 @Override 13623 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 13624 ActivityRecord srec = ActivityRecord.forToken(token); 13625 return srec != null && srec.task.affinity != null && 13626 srec.task.affinity.equals(destAffinity); 13627 } 13628 13629 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 13630 Intent resultData) { 13631 ComponentName dest = destIntent.getComponent(); 13632 13633 synchronized (this) { 13634 ActivityRecord srec = ActivityRecord.forToken(token); 13635 if (srec == null) { 13636 return false; 13637 } 13638 ArrayList<ActivityRecord> history = srec.stack.mHistory; 13639 final int start = history.indexOf(srec); 13640 if (start < 0) { 13641 // Current activity is not in history stack; do nothing. 13642 return false; 13643 } 13644 int finishTo = start - 1; 13645 ActivityRecord parent = null; 13646 boolean foundParentInTask = false; 13647 if (dest != null) { 13648 TaskRecord tr = srec.task; 13649 for (int i = start - 1; i >= 0; i--) { 13650 ActivityRecord r = history.get(i); 13651 if (tr != r.task) { 13652 // Couldn't find parent in the same task; stop at the one above this. 13653 // (Root of current task; in-app "home" behavior) 13654 // Always at least finish the current activity. 13655 finishTo = Math.min(start - 1, i + 1); 13656 parent = history.get(finishTo); 13657 break; 13658 } else if (r.info.packageName.equals(dest.getPackageName()) && 13659 r.info.name.equals(dest.getClassName())) { 13660 finishTo = i; 13661 parent = r; 13662 foundParentInTask = true; 13663 break; 13664 } 13665 } 13666 } 13667 13668 if (mController != null) { 13669 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); 13670 if (next != null) { 13671 // ask watcher if this is allowed 13672 boolean resumeOK = true; 13673 try { 13674 resumeOK = mController.activityResuming(next.packageName); 13675 } catch (RemoteException e) { 13676 mController = null; 13677 } 13678 13679 if (!resumeOK) { 13680 return false; 13681 } 13682 } 13683 } 13684 final long origId = Binder.clearCallingIdentity(); 13685 for (int i = start; i > finishTo; i--) { 13686 ActivityRecord r = history.get(i); 13687 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, 13688 "navigate-up"); 13689 // Only return the supplied result for the first activity finished 13690 resultCode = Activity.RESULT_CANCELED; 13691 resultData = null; 13692 } 13693 13694 if (parent != null && foundParentInTask) { 13695 final int parentLaunchMode = parent.info.launchMode; 13696 final int destIntentFlags = destIntent.getFlags(); 13697 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || 13698 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || 13699 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || 13700 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 13701 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); 13702 } else { 13703 try { 13704 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( 13705 destIntent.getComponent(), 0, UserId.getCallingUserId()); 13706 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, 13707 null, aInfo, parent.appToken, null, 13708 0, -1, parent.launchedFromUid, 0, null, true, null); 13709 foundParentInTask = res == ActivityManager.START_SUCCESS; 13710 } catch (RemoteException e) { 13711 foundParentInTask = false; 13712 } 13713 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, 13714 resultData, "navigate-up"); 13715 } 13716 } 13717 Binder.restoreCallingIdentity(origId); 13718 return foundParentInTask; 13719 } 13720 } 13721 13722 public int getLaunchedFromUid(IBinder activityToken) { 13723 ActivityRecord srec = ActivityRecord.forToken(activityToken); 13724 if (srec == null) { 13725 return -1; 13726 } 13727 return srec.launchedFromUid; 13728 } 13729 13730 // ========================================================= 13731 // LIFETIME MANAGEMENT 13732 // ========================================================= 13733 13734 // Returns which broadcast queue the app is the current [or imminent] receiver 13735 // on, or 'null' if the app is not an active broadcast recipient. 13736 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 13737 BroadcastRecord r = app.curReceiver; 13738 if (r != null) { 13739 return r.queue; 13740 } 13741 13742 // It's not the current receiver, but it might be starting up to become one 13743 synchronized (this) { 13744 for (BroadcastQueue queue : mBroadcastQueues) { 13745 r = queue.mPendingBroadcast; 13746 if (r != null && r.curApp == app) { 13747 // found it; report which queue it's in 13748 return queue; 13749 } 13750 } 13751 } 13752 13753 return null; 13754 } 13755 13756 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13757 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) { 13758 if (mAdjSeq == app.adjSeq) { 13759 // This adjustment has already been computed. If we are calling 13760 // from the top, we may have already computed our adjustment with 13761 // an earlier hidden adjustment that isn't really for us... if 13762 // so, use the new hidden adjustment. 13763 if (!recursed && app.hidden) { 13764 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj; 13765 } 13766 return app.curRawAdj; 13767 } 13768 13769 if (app.thread == null) { 13770 app.adjSeq = mAdjSeq; 13771 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13772 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ); 13773 } 13774 13775 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13776 app.adjSource = null; 13777 app.adjTarget = null; 13778 app.empty = false; 13779 app.hidden = false; 13780 13781 final int activitiesSize = app.activities.size(); 13782 13783 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 13784 // The max adjustment doesn't allow this app to be anything 13785 // below foreground, so it is not worth doing work for it. 13786 app.adjType = "fixed"; 13787 app.adjSeq = mAdjSeq; 13788 app.curRawAdj = app.nonStoppingAdj = app.maxAdj; 13789 app.foregroundActivities = false; 13790 app.keeping = true; 13791 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13792 // System process can do UI, and when they do we want to have 13793 // them trim their memory after the user leaves the UI. To 13794 // facilitate this, here we need to determine whether or not it 13795 // is currently showing UI. 13796 app.systemNoUi = true; 13797 if (app == TOP_APP) { 13798 app.systemNoUi = false; 13799 } else if (activitiesSize > 0) { 13800 for (int j = 0; j < activitiesSize; j++) { 13801 final ActivityRecord r = app.activities.get(j); 13802 if (r.visible) { 13803 app.systemNoUi = false; 13804 break; 13805 } 13806 } 13807 } 13808 return (app.curAdj=app.maxAdj); 13809 } 13810 13811 app.keeping = false; 13812 app.systemNoUi = false; 13813 13814 // Determine the importance of the process, starting with most 13815 // important to least, and assign an appropriate OOM adjustment. 13816 int adj; 13817 int schedGroup; 13818 boolean foregroundActivities = false; 13819 boolean interesting = false; 13820 BroadcastQueue queue; 13821 if (app == TOP_APP) { 13822 // The last app on the list is the foreground app. 13823 adj = ProcessList.FOREGROUND_APP_ADJ; 13824 schedGroup = Process.THREAD_GROUP_DEFAULT; 13825 app.adjType = "top-activity"; 13826 foregroundActivities = true; 13827 interesting = true; 13828 } else if (app.instrumentationClass != null) { 13829 // Don't want to kill running instrumentation. 13830 adj = ProcessList.FOREGROUND_APP_ADJ; 13831 schedGroup = Process.THREAD_GROUP_DEFAULT; 13832 app.adjType = "instrumentation"; 13833 interesting = true; 13834 } else if ((queue = isReceivingBroadcast(app)) != null) { 13835 // An app that is currently receiving a broadcast also 13836 // counts as being in the foreground for OOM killer purposes. 13837 // It's placed in a sched group based on the nature of the 13838 // broadcast as reflected by which queue it's active in. 13839 adj = ProcessList.FOREGROUND_APP_ADJ; 13840 schedGroup = (queue == mFgBroadcastQueue) 13841 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 13842 app.adjType = "broadcast"; 13843 } else if (app.executingServices.size() > 0) { 13844 // An app that is currently executing a service callback also 13845 // counts as being in the foreground. 13846 adj = ProcessList.FOREGROUND_APP_ADJ; 13847 schedGroup = Process.THREAD_GROUP_DEFAULT; 13848 app.adjType = "exec-service"; 13849 } else if (activitiesSize > 0) { 13850 // This app is in the background with paused activities. 13851 // We inspect activities to potentially upgrade adjustment further below. 13852 adj = hiddenAdj; 13853 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13854 app.hidden = true; 13855 app.adjType = "bg-activities"; 13856 } else { 13857 // A very not-needed process. If this is lower in the lru list, 13858 // we will push it in to the empty bucket. 13859 adj = hiddenAdj; 13860 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13861 app.hidden = true; 13862 app.empty = true; 13863 app.adjType = "bg-empty"; 13864 } 13865 13866 boolean hasStoppingActivities = false; 13867 13868 // Examine all activities if not already foreground. 13869 if (!foregroundActivities && activitiesSize > 0) { 13870 for (int j = 0; j < activitiesSize; j++) { 13871 final ActivityRecord r = app.activities.get(j); 13872 if (r.visible) { 13873 // App has a visible activity; only upgrade adjustment. 13874 if (adj > ProcessList.VISIBLE_APP_ADJ) { 13875 adj = ProcessList.VISIBLE_APP_ADJ; 13876 app.adjType = "visible"; 13877 } 13878 schedGroup = Process.THREAD_GROUP_DEFAULT; 13879 app.hidden = false; 13880 foregroundActivities = true; 13881 break; 13882 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 13883 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13884 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13885 app.adjType = "pausing"; 13886 } 13887 app.hidden = false; 13888 foregroundActivities = true; 13889 } else if (r.state == ActivityState.STOPPING) { 13890 // We will apply the actual adjustment later, because 13891 // we want to allow this process to immediately go through 13892 // any memory trimming that is in effect. 13893 app.hidden = false; 13894 foregroundActivities = true; 13895 hasStoppingActivities = true; 13896 } 13897 } 13898 } 13899 13900 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 13901 if (app.foregroundServices) { 13902 // The user is aware of this app, so make it visible. 13903 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13904 app.hidden = false; 13905 app.adjType = "foreground-service"; 13906 schedGroup = Process.THREAD_GROUP_DEFAULT; 13907 } else if (app.forcingToForeground != null) { 13908 // The user is aware of this app, so make it visible. 13909 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 13910 app.hidden = false; 13911 app.adjType = "force-foreground"; 13912 app.adjSource = app.forcingToForeground; 13913 schedGroup = Process.THREAD_GROUP_DEFAULT; 13914 } 13915 } 13916 13917 if (app.foregroundServices) { 13918 interesting = true; 13919 } 13920 13921 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) { 13922 // We don't want to kill the current heavy-weight process. 13923 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 13924 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13925 app.hidden = false; 13926 app.adjType = "heavy"; 13927 } 13928 13929 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) { 13930 // This process is hosting what we currently consider to be the 13931 // home app, so we don't want to let it go into the background. 13932 adj = ProcessList.HOME_APP_ADJ; 13933 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13934 app.hidden = false; 13935 app.adjType = "home"; 13936 } 13937 13938 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess 13939 && app.activities.size() > 0) { 13940 // This was the previous process that showed UI to the user. 13941 // We want to try to keep it around more aggressively, to give 13942 // a good experience around switching between two apps. 13943 adj = ProcessList.PREVIOUS_APP_ADJ; 13944 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13945 app.hidden = false; 13946 app.adjType = "previous"; 13947 } 13948 13949 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 13950 + " reason=" + app.adjType); 13951 13952 // By default, we use the computed adjustment. It may be changed if 13953 // there are applications dependent on our services or providers, but 13954 // this gives us a baseline and makes sure we don't get into an 13955 // infinite recursion. 13956 app.adjSeq = mAdjSeq; 13957 app.curRawAdj = app.nonStoppingAdj = adj; 13958 13959 if (mBackupTarget != null && app == mBackupTarget.app) { 13960 // If possible we want to avoid killing apps while they're being backed up 13961 if (adj > ProcessList.BACKUP_APP_ADJ) { 13962 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13963 adj = ProcessList.BACKUP_APP_ADJ; 13964 app.adjType = "backup"; 13965 app.hidden = false; 13966 } 13967 } 13968 13969 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 13970 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13971 final long now = SystemClock.uptimeMillis(); 13972 // This process is more important if the top activity is 13973 // bound to the service. 13974 Iterator<ServiceRecord> jt = app.services.iterator(); 13975 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 13976 ServiceRecord s = jt.next(); 13977 if (s.startRequested) { 13978 if (app.hasShownUi && app != mHomeProcess) { 13979 // If this process has shown some UI, let it immediately 13980 // go to the LRU list because it may be pretty heavy with 13981 // UI stuff. We'll tag it with a label just to help 13982 // debug and understand what is going on. 13983 if (adj > ProcessList.SERVICE_ADJ) { 13984 app.adjType = "started-bg-ui-services"; 13985 } 13986 } else { 13987 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13988 // This service has seen some activity within 13989 // recent memory, so we will keep its process ahead 13990 // of the background processes. 13991 if (adj > ProcessList.SERVICE_ADJ) { 13992 adj = ProcessList.SERVICE_ADJ; 13993 app.adjType = "started-services"; 13994 app.hidden = false; 13995 } 13996 } 13997 // If we have let the service slide into the background 13998 // state, still have some text describing what it is doing 13999 // even though the service no longer has an impact. 14000 if (adj > ProcessList.SERVICE_ADJ) { 14001 app.adjType = "started-bg-services"; 14002 } 14003 } 14004 // Don't kill this process because it is doing work; it 14005 // has said it is doing work. 14006 app.keeping = true; 14007 } 14008 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14009 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14010 Iterator<ArrayList<ConnectionRecord>> kt 14011 = s.connections.values().iterator(); 14012 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { 14013 ArrayList<ConnectionRecord> clist = kt.next(); 14014 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) { 14015 // XXX should compute this based on the max of 14016 // all connected clients. 14017 ConnectionRecord cr = clist.get(i); 14018 if (cr.binding.client == app) { 14019 // Binding to ourself is not interesting. 14020 continue; 14021 } 14022 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14023 ProcessRecord client = cr.binding.client; 14024 int clientAdj = adj; 14025 int myHiddenAdj = hiddenAdj; 14026 if (myHiddenAdj > client.hiddenAdj) { 14027 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) { 14028 myHiddenAdj = client.hiddenAdj; 14029 } else { 14030 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ; 14031 } 14032 } 14033 clientAdj = computeOomAdjLocked( 14034 client, myHiddenAdj, TOP_APP, true, doingAll); 14035 String adjType = null; 14036 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14037 // Not doing bind OOM management, so treat 14038 // this guy more like a started service. 14039 if (app.hasShownUi && app != mHomeProcess) { 14040 // If this process has shown some UI, let it immediately 14041 // go to the LRU list because it may be pretty heavy with 14042 // UI stuff. We'll tag it with a label just to help 14043 // debug and understand what is going on. 14044 if (adj > clientAdj) { 14045 adjType = "bound-bg-ui-services"; 14046 } 14047 app.hidden = false; 14048 clientAdj = adj; 14049 } else { 14050 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 14051 // This service has not seen activity within 14052 // recent memory, so allow it to drop to the 14053 // LRU list if there is no other reason to keep 14054 // it around. We'll also tag it with a label just 14055 // to help debug and undertand what is going on. 14056 if (adj > clientAdj) { 14057 adjType = "bound-bg-services"; 14058 } 14059 clientAdj = adj; 14060 } 14061 } 14062 } 14063 if (adj > clientAdj) { 14064 // If this process has recently shown UI, and 14065 // the process that is binding to it is less 14066 // important than being visible, then we don't 14067 // care about the binding as much as we care 14068 // about letting this process get into the LRU 14069 // list to be killed and restarted if needed for 14070 // memory. 14071 if (app.hasShownUi && app != mHomeProcess 14072 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14073 adjType = "bound-bg-ui-services"; 14074 } else { 14075 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14076 |Context.BIND_IMPORTANT)) != 0) { 14077 adj = clientAdj; 14078 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14079 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14080 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14081 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14082 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14083 adj = clientAdj; 14084 } else { 14085 app.pendingUiClean = true; 14086 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14087 adj = ProcessList.VISIBLE_APP_ADJ; 14088 } 14089 } 14090 if (!client.hidden) { 14091 app.hidden = false; 14092 } 14093 if (client.keeping) { 14094 app.keeping = true; 14095 } 14096 adjType = "service"; 14097 } 14098 } 14099 if (adjType != null) { 14100 app.adjType = adjType; 14101 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14102 .REASON_SERVICE_IN_USE; 14103 app.adjSource = cr.binding.client; 14104 app.adjSourceOom = clientAdj; 14105 app.adjTarget = s.name; 14106 } 14107 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14108 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14109 schedGroup = Process.THREAD_GROUP_DEFAULT; 14110 } 14111 } 14112 } 14113 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14114 ActivityRecord a = cr.activity; 14115 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14116 (a.visible || a.state == ActivityState.RESUMED 14117 || a.state == ActivityState.PAUSING)) { 14118 adj = ProcessList.FOREGROUND_APP_ADJ; 14119 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14120 schedGroup = Process.THREAD_GROUP_DEFAULT; 14121 } 14122 app.hidden = false; 14123 app.adjType = "service"; 14124 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14125 .REASON_SERVICE_IN_USE; 14126 app.adjSource = a; 14127 app.adjSourceOom = adj; 14128 app.adjTarget = s.name; 14129 } 14130 } 14131 } 14132 } 14133 } 14134 } 14135 14136 // Finally, if this process has active services running in it, we 14137 // would like to avoid killing it unless it would prevent the current 14138 // application from running. By default we put the process in 14139 // with the rest of the background processes; as we scan through 14140 // its services we may bump it up from there. 14141 if (adj > hiddenAdj) { 14142 adj = hiddenAdj; 14143 app.hidden = false; 14144 app.adjType = "bg-services"; 14145 } 14146 } 14147 14148 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14149 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14150 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator(); 14151 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ 14152 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14153 ContentProviderRecord cpr = jt.next(); 14154 for (int i = cpr.connections.size()-1; 14155 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14156 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE); 14157 i--) { 14158 ContentProviderConnection conn = cpr.connections.get(i); 14159 ProcessRecord client = conn.client; 14160 if (client == app) { 14161 // Being our own client is not interesting. 14162 continue; 14163 } 14164 int myHiddenAdj = hiddenAdj; 14165 if (myHiddenAdj > client.hiddenAdj) { 14166 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) { 14167 myHiddenAdj = client.hiddenAdj; 14168 } else { 14169 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ; 14170 } 14171 } 14172 int clientAdj = computeOomAdjLocked( 14173 client, myHiddenAdj, TOP_APP, true, doingAll); 14174 if (adj > clientAdj) { 14175 if (app.hasShownUi && app != mHomeProcess 14176 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14177 app.adjType = "bg-ui-provider"; 14178 } else { 14179 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14180 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14181 app.adjType = "provider"; 14182 } 14183 if (!client.hidden) { 14184 app.hidden = false; 14185 } 14186 if (client.keeping) { 14187 app.keeping = true; 14188 } 14189 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14190 .REASON_PROVIDER_IN_USE; 14191 app.adjSource = client; 14192 app.adjSourceOom = clientAdj; 14193 app.adjTarget = cpr.name; 14194 } 14195 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14196 schedGroup = Process.THREAD_GROUP_DEFAULT; 14197 } 14198 } 14199 // If the provider has external (non-framework) process 14200 // dependencies, ensure that its adjustment is at least 14201 // FOREGROUND_APP_ADJ. 14202 if (cpr.hasExternalProcessHandles()) { 14203 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14204 adj = ProcessList.FOREGROUND_APP_ADJ; 14205 schedGroup = Process.THREAD_GROUP_DEFAULT; 14206 app.hidden = false; 14207 app.keeping = true; 14208 app.adjType = "provider"; 14209 app.adjTarget = cpr.name; 14210 } 14211 } 14212 } 14213 } 14214 14215 if (adj == ProcessList.SERVICE_ADJ) { 14216 if (doingAll) { 14217 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3); 14218 mNewNumServiceProcs++; 14219 } 14220 if (app.serviceb) { 14221 adj = ProcessList.SERVICE_B_ADJ; 14222 } 14223 } else { 14224 app.serviceb = false; 14225 } 14226 14227 app.nonStoppingAdj = adj; 14228 14229 if (hasStoppingActivities) { 14230 // Only upgrade adjustment. 14231 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14232 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14233 app.adjType = "stopping"; 14234 } 14235 } 14236 14237 app.curRawAdj = adj; 14238 14239 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14240 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14241 if (adj > app.maxAdj) { 14242 adj = app.maxAdj; 14243 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14244 schedGroup = Process.THREAD_GROUP_DEFAULT; 14245 } 14246 } 14247 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14248 app.keeping = true; 14249 } 14250 14251 if (app.hasAboveClient) { 14252 // If this process has bound to any services with BIND_ABOVE_CLIENT, 14253 // then we need to drop its adjustment to be lower than the service's 14254 // in order to honor the request. We want to drop it by one adjustment 14255 // level... but there is special meaning applied to various levels so 14256 // we will skip some of them. 14257 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 14258 // System process will not get dropped, ever 14259 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 14260 adj = ProcessList.VISIBLE_APP_ADJ; 14261 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 14262 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14263 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) { 14264 adj = ProcessList.HIDDEN_APP_MIN_ADJ; 14265 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) { 14266 adj++; 14267 } 14268 } 14269 14270 int importance = app.memImportance; 14271 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14272 app.curAdj = adj; 14273 app.curSchedGroup = schedGroup; 14274 if (!interesting) { 14275 // For this reporting, if there is not something explicitly 14276 // interesting in this process then we will push it to the 14277 // background importance. 14278 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14279 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14280 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14281 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14282 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14283 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14284 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14285 } else if (adj >= ProcessList.SERVICE_ADJ) { 14286 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14287 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14288 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14289 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14290 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14291 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14292 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14293 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14294 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14295 } else { 14296 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14297 } 14298 } 14299 14300 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14301 if (foregroundActivities != app.foregroundActivities) { 14302 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14303 } 14304 if (changes != 0) { 14305 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14306 app.memImportance = importance; 14307 app.foregroundActivities = foregroundActivities; 14308 int i = mPendingProcessChanges.size()-1; 14309 ProcessChangeItem item = null; 14310 while (i >= 0) { 14311 item = mPendingProcessChanges.get(i); 14312 if (item.pid == app.pid) { 14313 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14314 break; 14315 } 14316 i--; 14317 } 14318 if (i < 0) { 14319 // No existing item in pending changes; need a new one. 14320 final int NA = mAvailProcessChanges.size(); 14321 if (NA > 0) { 14322 item = mAvailProcessChanges.remove(NA-1); 14323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14324 } else { 14325 item = new ProcessChangeItem(); 14326 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14327 } 14328 item.changes = 0; 14329 item.pid = app.pid; 14330 item.uid = app.info.uid; 14331 if (mPendingProcessChanges.size() == 0) { 14332 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14333 "*** Enqueueing dispatch processes changed!"); 14334 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14335 } 14336 mPendingProcessChanges.add(item); 14337 } 14338 item.changes |= changes; 14339 item.importance = importance; 14340 item.foregroundActivities = foregroundActivities; 14341 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14342 + Integer.toHexString(System.identityHashCode(item)) 14343 + " " + app.toShortString() + ": changes=" + item.changes 14344 + " importance=" + item.importance 14345 + " foreground=" + item.foregroundActivities 14346 + " type=" + app.adjType + " source=" + app.adjSource 14347 + " target=" + app.adjTarget); 14348 } 14349 14350 return app.curRawAdj; 14351 } 14352 14353 /** 14354 * Ask a given process to GC right now. 14355 */ 14356 final void performAppGcLocked(ProcessRecord app) { 14357 try { 14358 app.lastRequestedGc = SystemClock.uptimeMillis(); 14359 if (app.thread != null) { 14360 if (app.reportLowMemory) { 14361 app.reportLowMemory = false; 14362 app.thread.scheduleLowMemory(); 14363 } else { 14364 app.thread.processInBackground(); 14365 } 14366 } 14367 } catch (Exception e) { 14368 // whatever. 14369 } 14370 } 14371 14372 /** 14373 * Returns true if things are idle enough to perform GCs. 14374 */ 14375 private final boolean canGcNowLocked() { 14376 boolean processingBroadcasts = false; 14377 for (BroadcastQueue q : mBroadcastQueues) { 14378 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14379 processingBroadcasts = true; 14380 } 14381 } 14382 return !processingBroadcasts 14383 && (mSleeping || (mMainStack.mResumedActivity != null && 14384 mMainStack.mResumedActivity.idle)); 14385 } 14386 14387 /** 14388 * Perform GCs on all processes that are waiting for it, but only 14389 * if things are idle. 14390 */ 14391 final void performAppGcsLocked() { 14392 final int N = mProcessesToGc.size(); 14393 if (N <= 0) { 14394 return; 14395 } 14396 if (canGcNowLocked()) { 14397 while (mProcessesToGc.size() > 0) { 14398 ProcessRecord proc = mProcessesToGc.remove(0); 14399 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14400 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14401 <= SystemClock.uptimeMillis()) { 14402 // To avoid spamming the system, we will GC processes one 14403 // at a time, waiting a few seconds between each. 14404 performAppGcLocked(proc); 14405 scheduleAppGcsLocked(); 14406 return; 14407 } else { 14408 // It hasn't been long enough since we last GCed this 14409 // process... put it in the list to wait for its time. 14410 addProcessToGcListLocked(proc); 14411 break; 14412 } 14413 } 14414 } 14415 14416 scheduleAppGcsLocked(); 14417 } 14418 } 14419 14420 /** 14421 * If all looks good, perform GCs on all processes waiting for them. 14422 */ 14423 final void performAppGcsIfAppropriateLocked() { 14424 if (canGcNowLocked()) { 14425 performAppGcsLocked(); 14426 return; 14427 } 14428 // Still not idle, wait some more. 14429 scheduleAppGcsLocked(); 14430 } 14431 14432 /** 14433 * Schedule the execution of all pending app GCs. 14434 */ 14435 final void scheduleAppGcsLocked() { 14436 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14437 14438 if (mProcessesToGc.size() > 0) { 14439 // Schedule a GC for the time to the next process. 14440 ProcessRecord proc = mProcessesToGc.get(0); 14441 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14442 14443 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14444 long now = SystemClock.uptimeMillis(); 14445 if (when < (now+GC_TIMEOUT)) { 14446 when = now + GC_TIMEOUT; 14447 } 14448 mHandler.sendMessageAtTime(msg, when); 14449 } 14450 } 14451 14452 /** 14453 * Add a process to the array of processes waiting to be GCed. Keeps the 14454 * list in sorted order by the last GC time. The process can't already be 14455 * on the list. 14456 */ 14457 final void addProcessToGcListLocked(ProcessRecord proc) { 14458 boolean added = false; 14459 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14460 if (mProcessesToGc.get(i).lastRequestedGc < 14461 proc.lastRequestedGc) { 14462 added = true; 14463 mProcessesToGc.add(i+1, proc); 14464 break; 14465 } 14466 } 14467 if (!added) { 14468 mProcessesToGc.add(0, proc); 14469 } 14470 } 14471 14472 /** 14473 * Set up to ask a process to GC itself. This will either do it 14474 * immediately, or put it on the list of processes to gc the next 14475 * time things are idle. 14476 */ 14477 final void scheduleAppGcLocked(ProcessRecord app) { 14478 long now = SystemClock.uptimeMillis(); 14479 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14480 return; 14481 } 14482 if (!mProcessesToGc.contains(app)) { 14483 addProcessToGcListLocked(app); 14484 scheduleAppGcsLocked(); 14485 } 14486 } 14487 14488 final void checkExcessivePowerUsageLocked(boolean doKills) { 14489 updateCpuStatsNow(); 14490 14491 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14492 boolean doWakeKills = doKills; 14493 boolean doCpuKills = doKills; 14494 if (mLastPowerCheckRealtime == 0) { 14495 doWakeKills = false; 14496 } 14497 if (mLastPowerCheckUptime == 0) { 14498 doCpuKills = false; 14499 } 14500 if (stats.isScreenOn()) { 14501 doWakeKills = false; 14502 } 14503 final long curRealtime = SystemClock.elapsedRealtime(); 14504 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14505 final long curUptime = SystemClock.uptimeMillis(); 14506 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14507 mLastPowerCheckRealtime = curRealtime; 14508 mLastPowerCheckUptime = curUptime; 14509 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14510 doWakeKills = false; 14511 } 14512 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14513 doCpuKills = false; 14514 } 14515 int i = mLruProcesses.size(); 14516 while (i > 0) { 14517 i--; 14518 ProcessRecord app = mLruProcesses.get(i); 14519 if (!app.keeping) { 14520 long wtime; 14521 synchronized (stats) { 14522 wtime = stats.getProcessWakeTime(app.info.uid, 14523 app.pid, curRealtime); 14524 } 14525 long wtimeUsed = wtime - app.lastWakeTime; 14526 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14527 if (DEBUG_POWER) { 14528 StringBuilder sb = new StringBuilder(128); 14529 sb.append("Wake for "); 14530 app.toShortString(sb); 14531 sb.append(": over "); 14532 TimeUtils.formatDuration(realtimeSince, sb); 14533 sb.append(" used "); 14534 TimeUtils.formatDuration(wtimeUsed, sb); 14535 sb.append(" ("); 14536 sb.append((wtimeUsed*100)/realtimeSince); 14537 sb.append("%)"); 14538 Slog.i(TAG, sb.toString()); 14539 sb.setLength(0); 14540 sb.append("CPU for "); 14541 app.toShortString(sb); 14542 sb.append(": over "); 14543 TimeUtils.formatDuration(uptimeSince, sb); 14544 sb.append(" used "); 14545 TimeUtils.formatDuration(cputimeUsed, sb); 14546 sb.append(" ("); 14547 sb.append((cputimeUsed*100)/uptimeSince); 14548 sb.append("%)"); 14549 Slog.i(TAG, sb.toString()); 14550 } 14551 // If a process has held a wake lock for more 14552 // than 50% of the time during this period, 14553 // that sounds bad. Kill! 14554 if (doWakeKills && realtimeSince > 0 14555 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14556 synchronized (stats) { 14557 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14558 realtimeSince, wtimeUsed); 14559 } 14560 Slog.w(TAG, "Excessive wake lock in " + app.processName 14561 + " (pid " + app.pid + "): held " + wtimeUsed 14562 + " during " + realtimeSince); 14563 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14564 app.processName, app.setAdj, "excessive wake lock"); 14565 Process.killProcessQuiet(app.pid); 14566 } else if (doCpuKills && uptimeSince > 0 14567 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14568 synchronized (stats) { 14569 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 14570 uptimeSince, cputimeUsed); 14571 } 14572 Slog.w(TAG, "Excessive CPU in " + app.processName 14573 + " (pid " + app.pid + "): used " + cputimeUsed 14574 + " during " + uptimeSince); 14575 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14576 app.processName, app.setAdj, "excessive cpu"); 14577 Process.killProcessQuiet(app.pid); 14578 } else { 14579 app.lastWakeTime = wtime; 14580 app.lastCpuTime = app.curCpuTime; 14581 } 14582 } 14583 } 14584 } 14585 14586 private final boolean updateOomAdjLocked( 14587 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) { 14588 app.hiddenAdj = hiddenAdj; 14589 14590 if (app.thread == null) { 14591 return false; 14592 } 14593 14594 final boolean wasKeeping = app.keeping; 14595 14596 boolean success = true; 14597 14598 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll); 14599 14600 if (app.curRawAdj != app.setRawAdj) { 14601 if (wasKeeping && !app.keeping) { 14602 // This app is no longer something we want to keep. Note 14603 // its current wake lock time to later know to kill it if 14604 // it is not behaving well. 14605 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14606 synchronized (stats) { 14607 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 14608 app.pid, SystemClock.elapsedRealtime()); 14609 } 14610 app.lastCpuTime = app.curCpuTime; 14611 } 14612 14613 app.setRawAdj = app.curRawAdj; 14614 } 14615 14616 if (app.curAdj != app.setAdj) { 14617 if (Process.setOomAdj(app.pid, app.curAdj)) { 14618 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 14619 TAG, "Set " + app.pid + " " + app.processName + 14620 " adj " + app.curAdj + ": " + app.adjType); 14621 app.setAdj = app.curAdj; 14622 } else { 14623 success = false; 14624 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 14625 } 14626 } 14627 if (app.setSchedGroup != app.curSchedGroup) { 14628 app.setSchedGroup = app.curSchedGroup; 14629 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 14630 "Setting process group of " + app.processName 14631 + " to " + app.curSchedGroup); 14632 if (app.waitingToKill != null && 14633 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 14634 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill); 14635 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14636 app.processName, app.setAdj, app.waitingToKill); 14637 Process.killProcessQuiet(app.pid); 14638 success = false; 14639 } else { 14640 if (true) { 14641 long oldId = Binder.clearCallingIdentity(); 14642 try { 14643 Process.setProcessGroup(app.pid, app.curSchedGroup); 14644 } catch (Exception e) { 14645 Slog.w(TAG, "Failed setting process group of " + app.pid 14646 + " to " + app.curSchedGroup); 14647 e.printStackTrace(); 14648 } finally { 14649 Binder.restoreCallingIdentity(oldId); 14650 } 14651 } else { 14652 if (app.thread != null) { 14653 try { 14654 app.thread.setSchedulingGroup(app.curSchedGroup); 14655 } catch (RemoteException e) { 14656 } 14657 } 14658 } 14659 } 14660 } 14661 return success; 14662 } 14663 14664 private final ActivityRecord resumedAppLocked() { 14665 ActivityRecord resumedActivity = mMainStack.mResumedActivity; 14666 if (resumedActivity == null || resumedActivity.app == null) { 14667 resumedActivity = mMainStack.mPausingActivity; 14668 if (resumedActivity == null || resumedActivity.app == null) { 14669 resumedActivity = mMainStack.topRunningActivityLocked(null); 14670 } 14671 } 14672 return resumedActivity; 14673 } 14674 14675 private final boolean updateOomAdjLocked(ProcessRecord app) { 14676 final ActivityRecord TOP_ACT = resumedAppLocked(); 14677 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14678 int curAdj = app.curAdj; 14679 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14680 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14681 14682 mAdjSeq++; 14683 14684 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false); 14685 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ 14686 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ; 14687 if (nowHidden != wasHidden) { 14688 // Changed to/from hidden state, so apps after it in the LRU 14689 // list may also be changed. 14690 updateOomAdjLocked(); 14691 } 14692 return success; 14693 } 14694 14695 final void updateOomAdjLocked() { 14696 final ActivityRecord TOP_ACT = resumedAppLocked(); 14697 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 14698 14699 if (false) { 14700 RuntimeException e = new RuntimeException(); 14701 e.fillInStackTrace(); 14702 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 14703 } 14704 14705 mAdjSeq++; 14706 mNewNumServiceProcs = 0; 14707 14708 // Let's determine how many processes we have running vs. 14709 // how many slots we have for background processes; we may want 14710 // to put multiple processes in a slot of there are enough of 14711 // them. 14712 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; 14713 int factor = (mLruProcesses.size()-4)/numSlots; 14714 if (factor < 1) factor = 1; 14715 int step = 0; 14716 int numHidden = 0; 14717 int numTrimming = 0; 14718 14719 // First update the OOM adjustment for each of the 14720 // application processes based on their current state. 14721 int i = mLruProcesses.size(); 14722 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; 14723 while (i > 0) { 14724 i--; 14725 ProcessRecord app = mLruProcesses.get(i); 14726 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 14727 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true); 14728 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ 14729 && app.curAdj == curHiddenAdj) { 14730 step++; 14731 if (step >= factor) { 14732 step = 0; 14733 curHiddenAdj++; 14734 } 14735 } 14736 if (!app.killedBackground) { 14737 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { 14738 numHidden++; 14739 if (numHidden > mProcessLimit) { 14740 Slog.i(TAG, "No longer want " + app.processName 14741 + " (pid " + app.pid + "): hidden #" + numHidden); 14742 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14743 app.processName, app.setAdj, "too many background"); 14744 app.killedBackground = true; 14745 Process.killProcessQuiet(app.pid); 14746 } 14747 } 14748 if (!app.killedBackground && app.isolated && app.services.size() <= 0) { 14749 // If this is an isolated process, and there are no 14750 // services running in it, then the process is no longer 14751 // needed. We agressively kill these because we can by 14752 // definition not re-use the same process again, and it is 14753 // good to avoid having whatever code was running in them 14754 // left sitting around after no longer needed. 14755 Slog.i(TAG, "Isolated process " + app.processName 14756 + " (pid " + app.pid + ") no longer needed"); 14757 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14758 app.processName, app.setAdj, "isolated not needed"); 14759 app.killedBackground = true; 14760 Process.killProcessQuiet(app.pid); 14761 } 14762 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14763 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14764 && !app.killedBackground) { 14765 numTrimming++; 14766 } 14767 } 14768 } 14769 14770 mNumServiceProcs = mNewNumServiceProcs; 14771 14772 // Now determine the memory trimming level of background processes. 14773 // Unfortunately we need to start at the back of the list to do this 14774 // properly. We only do this if the number of background apps we 14775 // are managing to keep around is less than half the maximum we desire; 14776 // if we are keeping a good number around, we'll let them use whatever 14777 // memory they want. 14778 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { 14779 final int N = mLruProcesses.size(); 14780 factor = numTrimming/3; 14781 int minFactor = 2; 14782 if (mHomeProcess != null) minFactor++; 14783 if (mPreviousProcess != null) minFactor++; 14784 if (factor < minFactor) factor = minFactor; 14785 step = 0; 14786 int fgTrimLevel; 14787 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) { 14788 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 14789 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) { 14790 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 14791 } else { 14792 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 14793 } 14794 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 14795 for (i=0; i<N; i++) { 14796 ProcessRecord app = mLruProcesses.get(i); 14797 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ 14798 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ 14799 && !app.killedBackground) { 14800 if (app.trimMemoryLevel < curLevel && app.thread != null) { 14801 try { 14802 app.thread.scheduleTrimMemory(curLevel); 14803 } catch (RemoteException e) { 14804 } 14805 if (false) { 14806 // For now we won't do this; our memory trimming seems 14807 // to be good enough at this point that destroying 14808 // activities causes more harm than good. 14809 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 14810 && app != mHomeProcess && app != mPreviousProcess) { 14811 // Need to do this on its own message because the stack may not 14812 // be in a consistent state at this point. 14813 // For these apps we will also finish their activities 14814 // to help them free memory. 14815 mMainStack.scheduleDestroyActivities(app, false, "trim"); 14816 } 14817 } 14818 } 14819 app.trimMemoryLevel = curLevel; 14820 step++; 14821 if (step >= factor) { 14822 step = 0; 14823 switch (curLevel) { 14824 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 14825 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 14826 break; 14827 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 14828 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14829 break; 14830 } 14831 } 14832 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14833 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 14834 && app.thread != null) { 14835 try { 14836 app.thread.scheduleTrimMemory( 14837 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 14838 } catch (RemoteException e) { 14839 } 14840 } 14841 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 14842 } else { 14843 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14844 && app.pendingUiClean) { 14845 // If this application is now in the background and it 14846 // had done UI, then give it the special trim level to 14847 // have it free UI resources. 14848 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 14849 if (app.trimMemoryLevel < level && app.thread != null) { 14850 try { 14851 app.thread.scheduleTrimMemory(level); 14852 } catch (RemoteException e) { 14853 } 14854 } 14855 app.pendingUiClean = false; 14856 } 14857 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 14858 try { 14859 app.thread.scheduleTrimMemory(fgTrimLevel); 14860 } catch (RemoteException e) { 14861 } 14862 } 14863 app.trimMemoryLevel = fgTrimLevel; 14864 } 14865 } 14866 } else { 14867 final int N = mLruProcesses.size(); 14868 for (i=0; i<N; i++) { 14869 ProcessRecord app = mLruProcesses.get(i); 14870 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi) 14871 && app.pendingUiClean) { 14872 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 14873 && app.thread != null) { 14874 try { 14875 app.thread.scheduleTrimMemory( 14876 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 14877 } catch (RemoteException e) { 14878 } 14879 } 14880 app.pendingUiClean = false; 14881 } 14882 app.trimMemoryLevel = 0; 14883 } 14884 } 14885 14886 if (mAlwaysFinishActivities) { 14887 // Need to do this on its own message because the stack may not 14888 // be in a consistent state at this point. 14889 mMainStack.scheduleDestroyActivities(null, false, "always-finish"); 14890 } 14891 } 14892 14893 final void trimApplications() { 14894 synchronized (this) { 14895 int i; 14896 14897 // First remove any unused application processes whose package 14898 // has been removed. 14899 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 14900 final ProcessRecord app = mRemovedProcesses.get(i); 14901 if (app.activities.size() == 0 14902 && app.curReceiver == null && app.services.size() == 0) { 14903 Slog.i( 14904 TAG, "Exiting empty application process " 14905 + app.processName + " (" 14906 + (app.thread != null ? app.thread.asBinder() : null) 14907 + ")\n"); 14908 if (app.pid > 0 && app.pid != MY_PID) { 14909 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 14910 app.processName, app.setAdj, "empty"); 14911 Process.killProcessQuiet(app.pid); 14912 } else { 14913 try { 14914 app.thread.scheduleExit(); 14915 } catch (Exception e) { 14916 // Ignore exceptions. 14917 } 14918 } 14919 cleanUpApplicationRecordLocked(app, false, true, -1); 14920 mRemovedProcesses.remove(i); 14921 14922 if (app.persistent) { 14923 if (app.persistent) { 14924 addAppLocked(app.info, false); 14925 } 14926 } 14927 } 14928 } 14929 14930 // Now update the oom adj for all processes. 14931 updateOomAdjLocked(); 14932 } 14933 } 14934 14935 /** This method sends the specified signal to each of the persistent apps */ 14936 public void signalPersistentProcesses(int sig) throws RemoteException { 14937 if (sig != Process.SIGNAL_USR1) { 14938 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14939 } 14940 14941 synchronized (this) { 14942 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14943 != PackageManager.PERMISSION_GRANTED) { 14944 throw new SecurityException("Requires permission " 14945 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14946 } 14947 14948 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14949 ProcessRecord r = mLruProcesses.get(i); 14950 if (r.thread != null && r.persistent) { 14951 Process.sendSignal(r.pid, sig); 14952 } 14953 } 14954 } 14955 } 14956 14957 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 14958 if (proc == null || proc == mProfileProc) { 14959 proc = mProfileProc; 14960 path = mProfileFile; 14961 profileType = mProfileType; 14962 clearProfilerLocked(); 14963 } 14964 if (proc == null) { 14965 return; 14966 } 14967 try { 14968 proc.thread.profilerControl(false, path, null, profileType); 14969 } catch (RemoteException e) { 14970 throw new IllegalStateException("Process disappeared"); 14971 } 14972 } 14973 14974 private void clearProfilerLocked() { 14975 if (mProfileFd != null) { 14976 try { 14977 mProfileFd.close(); 14978 } catch (IOException e) { 14979 } 14980 } 14981 mProfileApp = null; 14982 mProfileProc = null; 14983 mProfileFile = null; 14984 mProfileType = 0; 14985 mAutoStopProfiler = false; 14986 } 14987 14988 public boolean profileControl(String process, boolean start, 14989 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 14990 14991 try { 14992 synchronized (this) { 14993 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14994 // its own permission. 14995 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14996 != PackageManager.PERMISSION_GRANTED) { 14997 throw new SecurityException("Requires permission " 14998 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14999 } 15000 15001 if (start && fd == null) { 15002 throw new IllegalArgumentException("null fd"); 15003 } 15004 15005 ProcessRecord proc = null; 15006 if (process != null) { 15007 try { 15008 int pid = Integer.parseInt(process); 15009 synchronized (mPidsSelfLocked) { 15010 proc = mPidsSelfLocked.get(pid); 15011 } 15012 } catch (NumberFormatException e) { 15013 } 15014 15015 if (proc == null) { 15016 HashMap<String, SparseArray<ProcessRecord>> all 15017 = mProcessNames.getMap(); 15018 SparseArray<ProcessRecord> procs = all.get(process); 15019 if (procs != null && procs.size() > 0) { 15020 proc = procs.valueAt(0); 15021 } 15022 } 15023 } 15024 15025 if (start && (proc == null || proc.thread == null)) { 15026 throw new IllegalArgumentException("Unknown process: " + process); 15027 } 15028 15029 if (start) { 15030 stopProfilerLocked(null, null, 0); 15031 setProfileApp(proc.info, proc.processName, path, fd, false); 15032 mProfileProc = proc; 15033 mProfileType = profileType; 15034 try { 15035 fd = fd.dup(); 15036 } catch (IOException e) { 15037 fd = null; 15038 } 15039 proc.thread.profilerControl(start, path, fd, profileType); 15040 fd = null; 15041 mProfileFd = null; 15042 } else { 15043 stopProfilerLocked(proc, path, profileType); 15044 if (fd != null) { 15045 try { 15046 fd.close(); 15047 } catch (IOException e) { 15048 } 15049 } 15050 } 15051 15052 return true; 15053 } 15054 } catch (RemoteException e) { 15055 throw new IllegalStateException("Process disappeared"); 15056 } finally { 15057 if (fd != null) { 15058 try { 15059 fd.close(); 15060 } catch (IOException e) { 15061 } 15062 } 15063 } 15064 } 15065 15066 public boolean dumpHeap(String process, boolean managed, 15067 String path, ParcelFileDescriptor fd) throws RemoteException { 15068 15069 try { 15070 synchronized (this) { 15071 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15072 // its own permission (same as profileControl). 15073 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15074 != PackageManager.PERMISSION_GRANTED) { 15075 throw new SecurityException("Requires permission " 15076 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15077 } 15078 15079 if (fd == null) { 15080 throw new IllegalArgumentException("null fd"); 15081 } 15082 15083 ProcessRecord proc = null; 15084 try { 15085 int pid = Integer.parseInt(process); 15086 synchronized (mPidsSelfLocked) { 15087 proc = mPidsSelfLocked.get(pid); 15088 } 15089 } catch (NumberFormatException e) { 15090 } 15091 15092 if (proc == null) { 15093 HashMap<String, SparseArray<ProcessRecord>> all 15094 = mProcessNames.getMap(); 15095 SparseArray<ProcessRecord> procs = all.get(process); 15096 if (procs != null && procs.size() > 0) { 15097 proc = procs.valueAt(0); 15098 } 15099 } 15100 15101 if (proc == null || proc.thread == null) { 15102 throw new IllegalArgumentException("Unknown process: " + process); 15103 } 15104 15105 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15106 if (!isDebuggable) { 15107 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15108 throw new SecurityException("Process not debuggable: " + proc); 15109 } 15110 } 15111 15112 proc.thread.dumpHeap(managed, path, fd); 15113 fd = null; 15114 return true; 15115 } 15116 } catch (RemoteException e) { 15117 throw new IllegalStateException("Process disappeared"); 15118 } finally { 15119 if (fd != null) { 15120 try { 15121 fd.close(); 15122 } catch (IOException e) { 15123 } 15124 } 15125 } 15126 } 15127 15128 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15129 public void monitor() { 15130 synchronized (this) { } 15131 } 15132 15133 void onCoreSettingsChange(Bundle settings) { 15134 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15135 ProcessRecord processRecord = mLruProcesses.get(i); 15136 try { 15137 if (processRecord.thread != null) { 15138 processRecord.thread.setCoreSettings(settings); 15139 } 15140 } catch (RemoteException re) { 15141 /* ignore */ 15142 } 15143 } 15144 } 15145 15146 // Multi-user methods 15147 15148 private int mCurrentUserId; 15149 private SparseIntArray mLoggedInUsers = new SparseIntArray(5); 15150 15151 public boolean switchUser(int userId) { 15152 final int callingUid = Binder.getCallingUid(); 15153 if (callingUid != 0 && callingUid != Process.myUid()) { 15154 Slog.e(TAG, "Trying to switch user from unauthorized app"); 15155 return false; 15156 } 15157 if (mCurrentUserId == userId) 15158 return true; 15159 15160 synchronized (this) { 15161 // Check if user is already logged in, otherwise check if user exists first before 15162 // adding to the list of logged in users. 15163 if (mLoggedInUsers.indexOfKey(userId) < 0) { 15164 if (!userExists(userId)) { 15165 return false; 15166 } 15167 mLoggedInUsers.append(userId, userId); 15168 } 15169 15170 mCurrentUserId = userId; 15171 boolean haveActivities = mMainStack.switchUser(userId); 15172 if (!haveActivities) { 15173 startHomeActivityLocked(userId); 15174 } 15175 15176 } 15177 15178 // Inform of user switch 15179 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED); 15180 addedIntent.putExtra(Intent.EXTRA_USERID, userId); 15181 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS); 15182 15183 return true; 15184 } 15185 15186 @Override 15187 public UserInfo getCurrentUser() throws RemoteException { 15188 final int callingUid = Binder.getCallingUid(); 15189 if (callingUid != 0 && callingUid != Process.myUid()) { 15190 Slog.e(TAG, "Trying to get user from unauthorized app"); 15191 return null; 15192 } 15193 return AppGlobals.getPackageManager().getUser(mCurrentUserId); 15194 } 15195 15196 private void onUserRemoved(Intent intent) { 15197 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1); 15198 if (extraUserId < 1) return; 15199 15200 // Kill all the processes for the user 15201 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>(); 15202 synchronized (this) { 15203 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap(); 15204 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) { 15205 SparseArray<ProcessRecord> uids = uidMap.getValue(); 15206 for (int i = 0; i < uids.size(); i++) { 15207 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) { 15208 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i))); 15209 } 15210 } 15211 } 15212 15213 for (Pair<String,Integer> pkgAndUid : pkgAndUids) { 15214 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second, 15215 false, false, true, true, extraUserId); 15216 } 15217 } 15218 } 15219 15220 private boolean userExists(int userId) { 15221 try { 15222 UserInfo user = AppGlobals.getPackageManager().getUser(userId); 15223 return user != null; 15224 } catch (RemoteException re) { 15225 // Won't happen, in same process 15226 } 15227 15228 return false; 15229 } 15230 15231 private void checkValidCaller(int uid, int userId) { 15232 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 15233 15234 throw new SecurityException("Caller uid=" + uid 15235 + " is not privileged to communicate with user=" + userId); 15236 } 15237 15238 private int applyUserId(int uid, int userId) { 15239 return UserId.getUid(userId, uid); 15240 } 15241 15242 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 15243 if (info == null) return null; 15244 ApplicationInfo newInfo = new ApplicationInfo(info); 15245 newInfo.uid = applyUserId(info.uid, userId); 15246 newInfo.dataDir = USER_DATA_DIR + userId + "/" 15247 + info.packageName; 15248 return newInfo; 15249 } 15250 15251 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 15252 if (aInfo == null 15253 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) { 15254 return aInfo; 15255 } 15256 15257 ActivityInfo info = new ActivityInfo(aInfo); 15258 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 15259 return info; 15260 } 15261 15262 static class ServiceMap { 15263 15264 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser 15265 = new SparseArray<HashMap<ComponentName, ServiceRecord>>(); 15266 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>> 15267 mServicesByIntentPerUser = new SparseArray< 15268 HashMap<Intent.FilterComparison, ServiceRecord>>(); 15269 15270 ServiceRecord getServiceByName(ComponentName name, int callingUser) { 15271 // TODO: Deal with global services 15272 if (DEBUG_MU) 15273 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser); 15274 return getServices(callingUser).get(name); 15275 } 15276 15277 ServiceRecord getServiceByName(ComponentName name) { 15278 return getServiceByName(name, -1); 15279 } 15280 15281 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15282 // TODO: Deal with global services 15283 if (DEBUG_MU) 15284 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser); 15285 return getServicesByIntent(callingUser).get(filter); 15286 } 15287 15288 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) { 15289 return getServiceByIntent(filter, -1); 15290 } 15291 15292 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) { 15293 // TODO: Deal with global services 15294 getServices(callingUser).put(name, value); 15295 } 15296 15297 void putServiceByIntent(Intent.FilterComparison filter, int callingUser, 15298 ServiceRecord value) { 15299 // TODO: Deal with global services 15300 getServicesByIntent(callingUser).put(filter, value); 15301 } 15302 15303 void removeServiceByName(ComponentName name, int callingUser) { 15304 // TODO: Deal with global services 15305 ServiceRecord removed = getServices(callingUser).remove(name); 15306 if (DEBUG_MU) 15307 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name 15308 + " removed=" + removed); 15309 } 15310 15311 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) { 15312 // TODO: Deal with global services 15313 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter); 15314 if (DEBUG_MU) 15315 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter 15316 + " removed=" + removed); 15317 } 15318 15319 Collection<ServiceRecord> getAllServices(int callingUser) { 15320 // TODO: Deal with global services 15321 return getServices(callingUser).values(); 15322 } 15323 15324 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) { 15325 HashMap map = mServicesByNamePerUser.get(callingUser); 15326 if (map == null) { 15327 map = new HashMap<ComponentName, ServiceRecord>(); 15328 mServicesByNamePerUser.put(callingUser, map); 15329 } 15330 return map; 15331 } 15332 15333 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent( 15334 int callingUser) { 15335 HashMap map = mServicesByIntentPerUser.get(callingUser); 15336 if (map == null) { 15337 map = new HashMap<Intent.FilterComparison, ServiceRecord>(); 15338 mServicesByIntentPerUser.put(callingUser, map); 15339 } 15340 return map; 15341 } 15342 } 15343} 15344