ActivityManagerService.java revision 42dc85a848285b021d03179131efe416e804cc6b
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.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.UserManagerService; 85import com.android.server.wm.AppTransition; 86import com.android.server.wm.WindowManagerService; 87import com.google.android.collect.Lists; 88import com.google.android.collect.Maps; 89 90import libcore.io.IoUtils; 91 92import org.xmlpull.v1.XmlPullParser; 93import org.xmlpull.v1.XmlPullParserException; 94import org.xmlpull.v1.XmlSerializer; 95 96import android.app.Activity; 97import android.app.ActivityManager; 98import android.app.ActivityManager.RunningTaskInfo; 99import android.app.ActivityManager.StackInfo; 100import android.app.ActivityManagerInternal; 101import android.app.ActivityManagerNative; 102import android.app.ActivityOptions; 103import android.app.ActivityThread; 104import android.app.AlertDialog; 105import android.app.AppGlobals; 106import android.app.ApplicationErrorReport; 107import android.app.Dialog; 108import android.app.IActivityController; 109import android.app.IApplicationThread; 110import android.app.IInstrumentationWatcher; 111import android.app.INotificationManager; 112import android.app.IProcessObserver; 113import android.app.IServiceConnection; 114import android.app.IStopUserCallback; 115import android.app.IUiAutomationConnection; 116import android.app.IUserSwitchObserver; 117import android.app.Instrumentation; 118import android.app.Notification; 119import android.app.NotificationManager; 120import android.app.PendingIntent; 121import android.app.backup.IBackupManager; 122import android.content.ActivityNotFoundException; 123import android.content.BroadcastReceiver; 124import android.content.ClipData; 125import android.content.ComponentCallbacks2; 126import android.content.ComponentName; 127import android.content.ContentProvider; 128import android.content.ContentResolver; 129import android.content.Context; 130import android.content.DialogInterface; 131import android.content.IContentProvider; 132import android.content.IIntentReceiver; 133import android.content.IIntentSender; 134import android.content.Intent; 135import android.content.IntentFilter; 136import android.content.IntentSender; 137import android.content.pm.ActivityInfo; 138import android.content.pm.ApplicationInfo; 139import android.content.pm.ConfigurationInfo; 140import android.content.pm.IPackageDataObserver; 141import android.content.pm.IPackageManager; 142import android.content.pm.InstrumentationInfo; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageManager; 145import android.content.pm.ParceledListSlice; 146import android.content.pm.UserInfo; 147import android.content.pm.PackageManager.NameNotFoundException; 148import android.content.pm.PathPermission; 149import android.content.pm.ProviderInfo; 150import android.content.pm.ResolveInfo; 151import android.content.pm.ServiceInfo; 152import android.content.res.CompatibilityInfo; 153import android.content.res.Configuration; 154import android.net.Proxy; 155import android.net.ProxyInfo; 156import android.net.Uri; 157import android.os.Binder; 158import android.os.Build; 159import android.os.Bundle; 160import android.os.Debug; 161import android.os.DropBoxManager; 162import android.os.Environment; 163import android.os.FactoryTest; 164import android.os.FileObserver; 165import android.os.FileUtils; 166import android.os.Handler; 167import android.os.IBinder; 168import android.os.IPermissionController; 169import android.os.IRemoteCallback; 170import android.os.IUserManager; 171import android.os.Looper; 172import android.os.Message; 173import android.os.Parcel; 174import android.os.ParcelFileDescriptor; 175import android.os.Process; 176import android.os.RemoteCallbackList; 177import android.os.RemoteException; 178import android.os.SELinux; 179import android.os.ServiceManager; 180import android.os.StrictMode; 181import android.os.SystemClock; 182import android.os.SystemProperties; 183import android.os.UpdateLock; 184import android.os.UserHandle; 185import android.os.UserManager; 186import android.provider.Settings; 187import android.text.format.DateUtils; 188import android.text.format.Time; 189import android.util.AtomicFile; 190import android.util.EventLog; 191import android.util.Log; 192import android.util.Pair; 193import android.util.PrintWriterPrinter; 194import android.util.Slog; 195import android.util.SparseArray; 196import android.util.TimeUtils; 197import android.util.Xml; 198import android.view.Gravity; 199import android.view.LayoutInflater; 200import android.view.View; 201import android.view.WindowManager; 202import dalvik.system.VMRuntime; 203 204import java.io.BufferedInputStream; 205import java.io.BufferedOutputStream; 206import java.io.DataInputStream; 207import java.io.DataOutputStream; 208import java.io.File; 209import java.io.FileDescriptor; 210import java.io.FileInputStream; 211import java.io.FileNotFoundException; 212import java.io.FileOutputStream; 213import java.io.IOException; 214import java.io.InputStreamReader; 215import java.io.PrintWriter; 216import java.io.StringWriter; 217import java.lang.ref.WeakReference; 218import java.util.ArrayList; 219import java.util.Arrays; 220import java.util.Collections; 221import java.util.Comparator; 222import java.util.HashMap; 223import java.util.HashSet; 224import java.util.Iterator; 225import java.util.List; 226import java.util.Locale; 227import java.util.Map; 228import java.util.Set; 229import java.util.concurrent.atomic.AtomicBoolean; 230import java.util.concurrent.atomic.AtomicLong; 231 232public final class ActivityManagerService extends ActivityManagerNative 233 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 234 235 private static final String USER_DATA_DIR = "/data/user/"; 236 // File that stores last updated system version and called preboot receivers 237 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 238 239 static final String TAG = "ActivityManager"; 240 static final String TAG_MU = "ActivityManagerServiceMU"; 241 static final boolean DEBUG = false; 242 static final boolean localLOGV = DEBUG; 243 static final boolean DEBUG_BACKUP = localLOGV || false; 244 static final boolean DEBUG_BROADCAST = localLOGV || false; 245 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 246 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_CLEANUP = localLOGV || false; 248 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 249 static final boolean DEBUG_FOCUS = false; 250 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 251 static final boolean DEBUG_MU = localLOGV || false; 252 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 253 static final boolean DEBUG_LRU = localLOGV || false; 254 static final boolean DEBUG_PAUSE = localLOGV || false; 255 static final boolean DEBUG_POWER = localLOGV || false; 256 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 257 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 258 static final boolean DEBUG_PROCESSES = localLOGV || false; 259 static final boolean DEBUG_PROVIDER = localLOGV || false; 260 static final boolean DEBUG_RESULTS = localLOGV || false; 261 static final boolean DEBUG_SERVICE = localLOGV || false; 262 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 263 static final boolean DEBUG_STACK = localLOGV || false; 264 static final boolean DEBUG_SWITCH = localLOGV || false; 265 static final boolean DEBUG_TASKS = localLOGV || false; 266 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 267 static final boolean DEBUG_TRANSITION = localLOGV || false; 268 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 269 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 270 static final boolean DEBUG_VISBILITY = localLOGV || false; 271 static final boolean DEBUG_PSS = localLOGV || false; 272 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 273 static final boolean DEBUG_RECENTS = localLOGV || false; 274 static final boolean VALIDATE_TOKENS = false; 275 static final boolean SHOW_ACTIVITY_START_TIME = true; 276 277 // Control over CPU and battery monitoring. 278 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 279 static final boolean MONITOR_CPU_USAGE = true; 280 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 281 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 282 static final boolean MONITOR_THREAD_CPU_USAGE = false; 283 284 // The flags that are set for all calls we make to the package manager. 285 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 286 287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 288 289 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 290 291 // Maximum number recent bitmaps to keep in memory. 292 static final int MAX_RECENT_BITMAPS = 5; 293 294 // Amount of time after a call to stopAppSwitches() during which we will 295 // prevent further untrusted switches from happening. 296 static final long APP_SWITCH_DELAY_TIME = 5*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real. 300 static final int PROC_START_TIMEOUT = 10*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real, when the process was 304 // started with a wrapper for instrumentation (such as Valgrind) because it 305 // could take much longer than usual. 306 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 307 308 // How long to wait after going idle before forcing apps to GC. 309 static final int GC_TIMEOUT = 5*1000; 310 311 // The minimum amount of time between successive GC requests for a process. 312 static final int GC_MIN_INTERVAL = 60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process. 315 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process 318 // when the request is due to the memory state being lowered. 319 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 320 321 // The rate at which we check for apps using excessive power -- 15 mins. 322 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on wake locks to start killing things. 326 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on CPU usage to start killing things. 330 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // How long we allow a receiver to run before giving up on it. 333 static final int BROADCAST_FG_TIMEOUT = 10*1000; 334 static final int BROADCAST_BG_TIMEOUT = 60*1000; 335 336 // How long we wait until we timeout on key dispatching. 337 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 338 339 // How long we wait until we timeout on key dispatching during instrumentation. 340 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 341 342 // Amount of time we wait for observers to handle a user switch before 343 // giving up on them and unfreezing the screen. 344 static final int USER_SWITCH_TIMEOUT = 2*1000; 345 346 // Maximum number of users we allow to be running at a time. 347 static final int MAX_RUNNING_USERS = 3; 348 349 // How long to wait in getAssistContextExtras for the activity and foreground services 350 // to respond with the result. 351 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 352 353 // Maximum number of persisted Uri grants a package is allowed 354 static final int MAX_PERSISTED_URI_GRANTS = 128; 355 356 static final int MY_PID = Process.myPid(); 357 358 static final String[] EMPTY_STRING_ARRAY = new String[0]; 359 360 // How many bytes to write into the dropbox log before truncating 361 static final int DROPBOX_MAX_SIZE = 256 * 1024; 362 363 // Access modes for handleIncomingUser. 364 static final int ALLOW_NON_FULL = 0; 365 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 366 static final int ALLOW_FULL_ONLY = 2; 367 368 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 369 370 /** All system services */ 371 SystemServiceManager mSystemServiceManager; 372 373 /** Run all ActivityStacks through this */ 374 ActivityStackSupervisor mStackSupervisor; 375 376 public IntentFirewall mIntentFirewall; 377 378 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 379 // default actuion automatically. Important for devices without direct input 380 // devices. 381 private boolean mShowDialogs = true; 382 383 BroadcastQueue mFgBroadcastQueue; 384 BroadcastQueue mBgBroadcastQueue; 385 // Convenient for easy iteration over the queues. Foreground is first 386 // so that dispatch of foreground broadcasts gets precedence. 387 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 388 389 BroadcastQueue broadcastQueueForIntent(Intent intent) { 390 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 391 if (DEBUG_BACKGROUND_BROADCAST) { 392 Slog.i(TAG, "Broadcast intent " + intent + " on " 393 + (isFg ? "foreground" : "background") 394 + " queue"); 395 } 396 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 397 } 398 399 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 400 for (BroadcastQueue queue : mBroadcastQueues) { 401 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 402 if (r != null) { 403 return r; 404 } 405 } 406 return null; 407 } 408 409 /** 410 * Activity we have told the window manager to have key focus. 411 */ 412 ActivityRecord mFocusedActivity = null; 413 414 /** 415 * List of intents that were used to start the most recent tasks. 416 */ 417 ArrayList<TaskRecord> mRecentTasks; 418 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 419 420 /** 421 * For addAppTask: cached of the last activity component that was added. 422 */ 423 ComponentName mLastAddedTaskComponent; 424 425 /** 426 * For addAppTask: cached of the last activity uid that was added. 427 */ 428 int mLastAddedTaskUid; 429 430 /** 431 * For addAppTask: cached of the last ActivityInfo that was added. 432 */ 433 ActivityInfo mLastAddedTaskActivity; 434 435 public class PendingAssistExtras extends Binder implements Runnable { 436 public final ActivityRecord activity; 437 public final Bundle extras; 438 public final Intent intent; 439 public final String hint; 440 public final int userHandle; 441 public boolean haveResult = false; 442 public Bundle result = null; 443 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 444 String _hint, int _userHandle) { 445 activity = _activity; 446 extras = _extras; 447 intent = _intent; 448 hint = _hint; 449 userHandle = _userHandle; 450 } 451 @Override 452 public void run() { 453 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 454 synchronized (this) { 455 haveResult = true; 456 notifyAll(); 457 } 458 } 459 } 460 461 final ArrayList<PendingAssistExtras> mPendingAssistExtras 462 = new ArrayList<PendingAssistExtras>(); 463 464 /** 465 * Process management. 466 */ 467 final ProcessList mProcessList = new ProcessList(); 468 469 /** 470 * All of the applications we currently have running organized by name. 471 * The keys are strings of the application package name (as 472 * returned by the package manager), and the keys are ApplicationRecord 473 * objects. 474 */ 475 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 476 477 /** 478 * Tracking long-term execution of processes to look for abuse and other 479 * bad app behavior. 480 */ 481 final ProcessStatsService mProcessStats; 482 483 /** 484 * The currently running isolated processes. 485 */ 486 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 487 488 /** 489 * Counter for assigning isolated process uids, to avoid frequently reusing the 490 * same ones. 491 */ 492 int mNextIsolatedProcessUid = 0; 493 494 /** 495 * The currently running heavy-weight process, if any. 496 */ 497 ProcessRecord mHeavyWeightProcess = null; 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Information about a process that is currently marked as bad. 506 */ 507 static final class BadProcessInfo { 508 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 509 this.time = time; 510 this.shortMsg = shortMsg; 511 this.longMsg = longMsg; 512 this.stack = stack; 513 } 514 515 final long time; 516 final String shortMsg; 517 final String longMsg; 518 final String stack; 519 } 520 521 /** 522 * Set of applications that we consider to be bad, and will reject 523 * incoming broadcasts from (which the user has no control over). 524 * Processes are added to this set when they have crashed twice within 525 * a minimum amount of time; they are removed from it when they are 526 * later restarted (hopefully due to some user action). The value is the 527 * time it was added to the list. 528 */ 529 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 530 531 /** 532 * All of the processes we currently have running organized by pid. 533 * The keys are the pid running the application. 534 * 535 * <p>NOTE: This object is protected by its own lock, NOT the global 536 * activity manager lock! 537 */ 538 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 550 551 /** 552 * List of records for processes that someone had tried to start before the 553 * system was ready. We don't start them at that point, but ensure they 554 * are started by the time booting is complete. 555 */ 556 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of persistent applications that are in the process 560 * of being started. 561 */ 562 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes that are being forcibly torn down. 566 */ 567 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of running applications, sorted by recent usage. 571 * The first entry in the list is the least recently used. 572 */ 573 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Where in mLruProcesses that the processes hosting activities start. 577 */ 578 int mLruProcessActivityStart = 0; 579 580 /** 581 * Where in mLruProcesses that the processes hosting services start. 582 * This is after (lower index) than mLruProcessesActivityStart. 583 */ 584 int mLruProcessServiceStart = 0; 585 586 /** 587 * List of processes that should gc as soon as things are idle. 588 */ 589 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 590 591 /** 592 * Processes we want to collect PSS data from. 593 */ 594 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Last time we requested PSS data of all processes. 598 */ 599 long mLastFullPssTime = SystemClock.uptimeMillis(); 600 601 /** 602 * If set, the next time we collect PSS data we should do a full collection 603 * with data from native processes and the kernel. 604 */ 605 boolean mFullPssPending = false; 606 607 /** 608 * This is the process holding what we currently consider to be 609 * the "home" activity. 610 */ 611 ProcessRecord mHomeProcess; 612 613 /** 614 * This is the process holding the activity the user last visited that 615 * is in a different process from the one they are currently in. 616 */ 617 ProcessRecord mPreviousProcess; 618 619 /** 620 * The time at which the previous process was last visible. 621 */ 622 long mPreviousProcessVisibleTime; 623 624 /** 625 * Which uses have been started, so are allowed to run code. 626 */ 627 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 628 629 /** 630 * LRU list of history of current users. Most recently current is at the end. 631 */ 632 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 633 634 /** 635 * Constant array of the users that are currently started. 636 */ 637 int[] mStartedUserArray = new int[] { 0 }; 638 639 /** 640 * Registered observers of the user switching mechanics. 641 */ 642 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 643 = new RemoteCallbackList<IUserSwitchObserver>(); 644 645 /** 646 * Currently active user switch. 647 */ 648 Object mCurUserSwitchCallback; 649 650 /** 651 * Packages that the user has asked to have run in screen size 652 * compatibility mode instead of filling the screen. 653 */ 654 final CompatModePackages mCompatModePackages; 655 656 /** 657 * Set of IntentSenderRecord objects that are currently active. 658 */ 659 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 660 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 661 662 /** 663 * Fingerprints (hashCode()) of stack traces that we've 664 * already logged DropBox entries for. Guarded by itself. If 665 * something (rogue user app) forces this over 666 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 667 */ 668 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 669 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 670 671 /** 672 * Strict Mode background batched logging state. 673 * 674 * The string buffer is guarded by itself, and its lock is also 675 * used to determine if another batched write is already 676 * in-flight. 677 */ 678 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 679 680 /** 681 * Keeps track of all IIntentReceivers that have been registered for 682 * broadcasts. Hash keys are the receiver IBinder, hash value is 683 * a ReceiverList. 684 */ 685 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 686 new HashMap<IBinder, ReceiverList>(); 687 688 /** 689 * Resolver for broadcast intents to registered receivers. 690 * Holds BroadcastFilter (subclass of IntentFilter). 691 */ 692 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 693 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 694 @Override 695 protected boolean allowFilterResult( 696 BroadcastFilter filter, List<BroadcastFilter> dest) { 697 IBinder target = filter.receiverList.receiver.asBinder(); 698 for (int i=dest.size()-1; i>=0; i--) { 699 if (dest.get(i).receiverList.receiver.asBinder() == target) { 700 return false; 701 } 702 } 703 return true; 704 } 705 706 @Override 707 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 708 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 709 || userId == filter.owningUserId) { 710 return super.newResult(filter, match, userId); 711 } 712 return null; 713 } 714 715 @Override 716 protected BroadcastFilter[] newArray(int size) { 717 return new BroadcastFilter[size]; 718 } 719 720 @Override 721 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 722 return packageName.equals(filter.packageName); 723 } 724 }; 725 726 /** 727 * State of all active sticky broadcasts per user. Keys are the action of the 728 * sticky Intent, values are an ArrayList of all broadcasted intents with 729 * that action (which should usually be one). The SparseArray is keyed 730 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 731 * for stickies that are sent to all users. 732 */ 733 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 734 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 735 736 final ActiveServices mServices; 737 738 /** 739 * Backup/restore process management 740 */ 741 String mBackupAppName = null; 742 BackupRecord mBackupTarget = null; 743 744 final ProviderMap mProviderMap; 745 746 /** 747 * List of content providers who have clients waiting for them. The 748 * application is currently being launched and the provider will be 749 * removed from this list once it is published. 750 */ 751 final ArrayList<ContentProviderRecord> mLaunchingProviders 752 = new ArrayList<ContentProviderRecord>(); 753 754 /** 755 * File storing persisted {@link #mGrantedUriPermissions}. 756 */ 757 private final AtomicFile mGrantFile; 758 759 /** XML constants used in {@link #mGrantFile} */ 760 private static final String TAG_URI_GRANTS = "uri-grants"; 761 private static final String TAG_URI_GRANT = "uri-grant"; 762 private static final String ATTR_USER_HANDLE = "userHandle"; 763 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 764 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 765 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 766 private static final String ATTR_TARGET_PKG = "targetPkg"; 767 private static final String ATTR_URI = "uri"; 768 private static final String ATTR_MODE_FLAGS = "modeFlags"; 769 private static final String ATTR_CREATED_TIME = "createdTime"; 770 private static final String ATTR_PREFIX = "prefix"; 771 772 /** 773 * Global set of specific {@link Uri} permissions that have been granted. 774 * This optimized lookup structure maps from {@link UriPermission#targetUid} 775 * to {@link UriPermission#uri} to {@link UriPermission}. 776 */ 777 @GuardedBy("this") 778 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 779 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 780 781 public static class GrantUri { 782 public final int sourceUserId; 783 public final Uri uri; 784 public boolean prefix; 785 786 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 787 this.sourceUserId = sourceUserId; 788 this.uri = uri; 789 this.prefix = prefix; 790 } 791 792 @Override 793 public int hashCode() { 794 return toString().hashCode(); 795 } 796 797 @Override 798 public boolean equals(Object o) { 799 if (o instanceof GrantUri) { 800 GrantUri other = (GrantUri) o; 801 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 802 && prefix == other.prefix; 803 } 804 return false; 805 } 806 807 @Override 808 public String toString() { 809 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 810 if (prefix) result += " [prefix]"; 811 return result; 812 } 813 814 public String toSafeString() { 815 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 816 if (prefix) result += " [prefix]"; 817 return result; 818 } 819 820 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 821 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 822 ContentProvider.getUriWithoutUserId(uri), false); 823 } 824 } 825 826 CoreSettingsObserver mCoreSettingsObserver; 827 828 /** 829 * Thread-local storage used to carry caller permissions over through 830 * indirect content-provider access. 831 */ 832 private class Identity { 833 public int pid; 834 public int uid; 835 836 Identity(int _pid, int _uid) { 837 pid = _pid; 838 uid = _uid; 839 } 840 } 841 842 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 843 844 /** 845 * All information we have collected about the runtime performance of 846 * any user id that can impact battery performance. 847 */ 848 final BatteryStatsService mBatteryStatsService; 849 850 /** 851 * Information about component usage 852 */ 853 UsageStatsManagerInternal mUsageStatsService; 854 855 /** 856 * Information about and control over application operations 857 */ 858 final AppOpsService mAppOpsService; 859 860 /** 861 * Save recent tasks information across reboots. 862 */ 863 final TaskPersister mTaskPersister; 864 865 /** 866 * Current configuration information. HistoryRecord objects are given 867 * a reference to this object to indicate which configuration they are 868 * currently running in, so this object must be kept immutable. 869 */ 870 Configuration mConfiguration = new Configuration(); 871 872 /** 873 * Current sequencing integer of the configuration, for skipping old 874 * configurations. 875 */ 876 int mConfigurationSeq = 0; 877 878 /** 879 * Hardware-reported OpenGLES version. 880 */ 881 final int GL_ES_VERSION; 882 883 /** 884 * List of initialization arguments to pass to all processes when binding applications to them. 885 * For example, references to the commonly used services. 886 */ 887 HashMap<String, IBinder> mAppBindArgs; 888 889 /** 890 * Temporary to avoid allocations. Protected by main lock. 891 */ 892 final StringBuilder mStringBuilder = new StringBuilder(256); 893 894 /** 895 * Used to control how we initialize the service. 896 */ 897 ComponentName mTopComponent; 898 String mTopAction = Intent.ACTION_MAIN; 899 String mTopData; 900 boolean mProcessesReady = false; 901 boolean mSystemReady = false; 902 boolean mBooting = false; 903 boolean mCallFinishBooting = false; 904 boolean mBootAnimationComplete = false; 905 boolean mWaitingUpdate = false; 906 boolean mDidUpdate = false; 907 boolean mOnBattery = false; 908 boolean mLaunchWarningShown = false; 909 910 Context mContext; 911 912 int mFactoryTest; 913 914 boolean mCheckedForSetup; 915 916 /** 917 * The time at which we will allow normal application switches again, 918 * after a call to {@link #stopAppSwitches()}. 919 */ 920 long mAppSwitchesAllowedTime; 921 922 /** 923 * This is set to true after the first switch after mAppSwitchesAllowedTime 924 * is set; any switches after that will clear the time. 925 */ 926 boolean mDidAppSwitch; 927 928 /** 929 * Last time (in realtime) at which we checked for power usage. 930 */ 931 long mLastPowerCheckRealtime; 932 933 /** 934 * Last time (in uptime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckUptime; 937 938 /** 939 * Set while we are wanting to sleep, to prevent any 940 * activities from being started/resumed. 941 */ 942 private boolean mSleeping = false; 943 944 /** 945 * Set while we are running a voice interaction. This overrides 946 * sleeping while it is active. 947 */ 948 private boolean mRunningVoice = false; 949 950 /** 951 * State of external calls telling us if the device is asleep. 952 */ 953 private boolean mWentToSleep = false; 954 955 /** 956 * State of external call telling us if the lock screen is shown. 957 */ 958 private boolean mLockScreenShown = false; 959 960 /** 961 * Set if we are shutting down the system, similar to sleeping. 962 */ 963 boolean mShuttingDown = false; 964 965 /** 966 * Current sequence id for oom_adj computation traversal. 967 */ 968 int mAdjSeq = 0; 969 970 /** 971 * Current sequence id for process LRU updating. 972 */ 973 int mLruSeq = 0; 974 975 /** 976 * Keep track of the non-cached/empty process we last found, to help 977 * determine how to distribute cached/empty processes next time. 978 */ 979 int mNumNonCachedProcs = 0; 980 981 /** 982 * Keep track of the number of cached hidden procs, to balance oom adj 983 * distribution between those and empty procs. 984 */ 985 int mNumCachedHiddenProcs = 0; 986 987 /** 988 * Keep track of the number of service processes we last found, to 989 * determine on the next iteration which should be B services. 990 */ 991 int mNumServiceProcs = 0; 992 int mNewNumAServiceProcs = 0; 993 int mNewNumServiceProcs = 0; 994 995 /** 996 * Allow the current computed overall memory level of the system to go down? 997 * This is set to false when we are killing processes for reasons other than 998 * memory management, so that the now smaller process list will not be taken as 999 * an indication that memory is tighter. 1000 */ 1001 boolean mAllowLowerMemLevel = false; 1002 1003 /** 1004 * The last computed memory level, for holding when we are in a state that 1005 * processes are going away for other reasons. 1006 */ 1007 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1008 1009 /** 1010 * The last total number of process we have, to determine if changes actually look 1011 * like a shrinking number of process due to lower RAM. 1012 */ 1013 int mLastNumProcesses; 1014 1015 /** 1016 * The uptime of the last time we performed idle maintenance. 1017 */ 1018 long mLastIdleTime = SystemClock.uptimeMillis(); 1019 1020 /** 1021 * Total time spent with RAM that has been added in the past since the last idle time. 1022 */ 1023 long mLowRamTimeSinceLastIdle = 0; 1024 1025 /** 1026 * If RAM is currently low, when that horrible situation started. 1027 */ 1028 long mLowRamStartTime = 0; 1029 1030 /** 1031 * For reporting to battery stats the current top application. 1032 */ 1033 private String mCurResumedPackage = null; 1034 private int mCurResumedUid = -1; 1035 1036 /** 1037 * For reporting to battery stats the apps currently running foreground 1038 * service. The ProcessMap is package/uid tuples; each of these contain 1039 * an array of the currently foreground processes. 1040 */ 1041 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1042 = new ProcessMap<ArrayList<ProcessRecord>>(); 1043 1044 /** 1045 * This is set if we had to do a delayed dexopt of an app before launching 1046 * it, to increase the ANR timeouts in that case. 1047 */ 1048 boolean mDidDexOpt; 1049 1050 /** 1051 * Set if the systemServer made a call to enterSafeMode. 1052 */ 1053 boolean mSafeMode; 1054 1055 String mDebugApp = null; 1056 boolean mWaitForDebugger = false; 1057 boolean mDebugTransient = false; 1058 String mOrigDebugApp = null; 1059 boolean mOrigWaitForDebugger = false; 1060 boolean mAlwaysFinishActivities = false; 1061 IActivityController mController = null; 1062 String mProfileApp = null; 1063 ProcessRecord mProfileProc = null; 1064 String mProfileFile; 1065 ParcelFileDescriptor mProfileFd; 1066 int mSamplingInterval = 0; 1067 boolean mAutoStopProfiler = false; 1068 int mProfileType = 0; 1069 String mOpenGlTraceApp = null; 1070 1071 static class ProcessChangeItem { 1072 static final int CHANGE_ACTIVITIES = 1<<0; 1073 static final int CHANGE_PROCESS_STATE = 1<<1; 1074 int changes; 1075 int uid; 1076 int pid; 1077 int processState; 1078 boolean foregroundActivities; 1079 } 1080 1081 final RemoteCallbackList<IProcessObserver> mProcessObservers 1082 = new RemoteCallbackList<IProcessObserver>(); 1083 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1084 1085 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1086 = new ArrayList<ProcessChangeItem>(); 1087 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1088 = new ArrayList<ProcessChangeItem>(); 1089 1090 /** 1091 * Runtime CPU use collection thread. This object's lock is used to 1092 * perform synchronization with the thread (notifying it to run). 1093 */ 1094 final Thread mProcessCpuThread; 1095 1096 /** 1097 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1098 * Must acquire this object's lock when accessing it. 1099 * NOTE: this lock will be held while doing long operations (trawling 1100 * through all processes in /proc), so it should never be acquired by 1101 * any critical paths such as when holding the main activity manager lock. 1102 */ 1103 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1104 MONITOR_THREAD_CPU_USAGE); 1105 final AtomicLong mLastCpuTime = new AtomicLong(0); 1106 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1107 1108 long mLastWriteTime = 0; 1109 1110 /** 1111 * Used to retain an update lock when the foreground activity is in 1112 * immersive mode. 1113 */ 1114 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1115 1116 /** 1117 * Set to true after the system has finished booting. 1118 */ 1119 boolean mBooted = false; 1120 1121 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1122 int mProcessLimitOverride = -1; 1123 1124 WindowManagerService mWindowManager; 1125 1126 final ActivityThread mSystemThread; 1127 1128 // Holds the current foreground user's id 1129 int mCurrentUserId = 0; 1130 // Holds the target user's id during a user switch 1131 int mTargetUserId = UserHandle.USER_NULL; 1132 // If there are multiple profiles for the current user, their ids are here 1133 // Currently only the primary user can have managed profiles 1134 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1135 1136 /** 1137 * Mapping from each known user ID to the profile group ID it is associated with. 1138 */ 1139 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1140 1141 private UserManagerService mUserManager; 1142 1143 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1144 final ProcessRecord mApp; 1145 final int mPid; 1146 final IApplicationThread mAppThread; 1147 1148 AppDeathRecipient(ProcessRecord app, int pid, 1149 IApplicationThread thread) { 1150 if (localLOGV) Slog.v( 1151 TAG, "New death recipient " + this 1152 + " for thread " + thread.asBinder()); 1153 mApp = app; 1154 mPid = pid; 1155 mAppThread = thread; 1156 } 1157 1158 @Override 1159 public void binderDied() { 1160 if (localLOGV) Slog.v( 1161 TAG, "Death received in " + this 1162 + " for thread " + mAppThread.asBinder()); 1163 synchronized(ActivityManagerService.this) { 1164 appDiedLocked(mApp, mPid, mAppThread); 1165 } 1166 } 1167 } 1168 1169 static final int SHOW_ERROR_MSG = 1; 1170 static final int SHOW_NOT_RESPONDING_MSG = 2; 1171 static final int SHOW_FACTORY_ERROR_MSG = 3; 1172 static final int UPDATE_CONFIGURATION_MSG = 4; 1173 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1174 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1175 static final int SERVICE_TIMEOUT_MSG = 12; 1176 static final int UPDATE_TIME_ZONE = 13; 1177 static final int SHOW_UID_ERROR_MSG = 14; 1178 static final int IM_FEELING_LUCKY_MSG = 15; 1179 static final int PROC_START_TIMEOUT_MSG = 20; 1180 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1181 static final int KILL_APPLICATION_MSG = 22; 1182 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1183 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1184 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1185 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1186 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1187 static final int CLEAR_DNS_CACHE_MSG = 28; 1188 static final int UPDATE_HTTP_PROXY_MSG = 29; 1189 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1190 static final int DISPATCH_PROCESSES_CHANGED = 31; 1191 static final int DISPATCH_PROCESS_DIED = 32; 1192 static final int REPORT_MEM_USAGE_MSG = 33; 1193 static final int REPORT_USER_SWITCH_MSG = 34; 1194 static final int CONTINUE_USER_SWITCH_MSG = 35; 1195 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1196 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1197 static final int PERSIST_URI_GRANTS_MSG = 38; 1198 static final int REQUEST_ALL_PSS_MSG = 39; 1199 static final int START_PROFILES_MSG = 40; 1200 static final int UPDATE_TIME = 41; 1201 static final int SYSTEM_USER_START_MSG = 42; 1202 static final int SYSTEM_USER_CURRENT_MSG = 43; 1203 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1204 static final int FINISH_BOOTING_MSG = 45; 1205 static final int START_USER_SWITCH_MSG = 46; 1206 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1207 1208 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1209 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1210 static final int FIRST_COMPAT_MODE_MSG = 300; 1211 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1212 1213 AlertDialog mUidAlert; 1214 CompatModeDialog mCompatModeDialog; 1215 long mLastMemUsageReportTime = 0; 1216 1217 private LockToAppRequestDialog mLockToAppRequest; 1218 1219 /** 1220 * Flag whether the current user is a "monkey", i.e. whether 1221 * the UI is driven by a UI automation tool. 1222 */ 1223 private boolean mUserIsMonkey; 1224 1225 /** Flag whether the device has a Recents UI */ 1226 boolean mHasRecents; 1227 1228 /** The dimensions of the thumbnails in the Recents UI. */ 1229 int mThumbnailWidth; 1230 int mThumbnailHeight; 1231 1232 final ServiceThread mHandlerThread; 1233 final MainHandler mHandler; 1234 1235 final class MainHandler extends Handler { 1236 public MainHandler(Looper looper) { 1237 super(looper, null, true); 1238 } 1239 1240 @Override 1241 public void handleMessage(Message msg) { 1242 switch (msg.what) { 1243 case SHOW_ERROR_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1246 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1247 synchronized (ActivityManagerService.this) { 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 AppErrorResult res = (AppErrorResult) data.get("result"); 1250 if (proc != null && proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has crash dialog: " + proc); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 boolean isBackground = (UserHandle.getAppId(proc.uid) 1258 >= Process.FIRST_APPLICATION_UID 1259 && proc.pid != MY_PID); 1260 for (int userId : mCurrentProfileIds) { 1261 isBackground &= (proc.userId != userId); 1262 } 1263 if (isBackground && !showBackground) { 1264 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 return; 1269 } 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new AppErrorDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 if (res != null) { 1279 res.set(0); 1280 } 1281 } 1282 } 1283 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_NOT_RESPONDING_MSG: { 1287 synchronized (ActivityManagerService.this) { 1288 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1289 ProcessRecord proc = (ProcessRecord)data.get("app"); 1290 if (proc != null && proc.anrDialog != null) { 1291 Slog.e(TAG, "App already has anr dialog: " + proc); 1292 return; 1293 } 1294 1295 Intent intent = new Intent("android.intent.action.ANR"); 1296 if (!mProcessesReady) { 1297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1298 | Intent.FLAG_RECEIVER_FOREGROUND); 1299 } 1300 broadcastIntentLocked(null, null, intent, 1301 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1302 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1303 1304 if (mShowDialogs) { 1305 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1306 mContext, proc, (ActivityRecord)data.get("activity"), 1307 msg.arg1 != 0); 1308 d.show(); 1309 proc.anrDialog = d; 1310 } else { 1311 // Just kill the app if there is no dialog to be shown. 1312 killAppAtUsersRequest(proc, null); 1313 } 1314 } 1315 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 ProcessRecord proc = (ProcessRecord) data.get("app"); 1322 if (proc == null) { 1323 Slog.e(TAG, "App not found when showing strict mode dialog."); 1324 break; 1325 } 1326 if (proc.crashDialog != null) { 1327 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1328 return; 1329 } 1330 AppErrorResult res = (AppErrorResult) data.get("result"); 1331 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1332 Dialog d = new StrictModeViolationDialog(mContext, 1333 ActivityManagerService.this, res, proc); 1334 d.show(); 1335 proc.crashDialog = d; 1336 } else { 1337 // The device is asleep, so just pretend that the user 1338 // saw a crash dialog and hit "force quit". 1339 res.set(0); 1340 } 1341 } 1342 ensureBootCompleted(); 1343 } break; 1344 case SHOW_FACTORY_ERROR_MSG: { 1345 Dialog d = new FactoryErrorDialog( 1346 mContext, msg.getData().getCharSequence("msg")); 1347 d.show(); 1348 ensureBootCompleted(); 1349 } break; 1350 case UPDATE_CONFIGURATION_MSG: { 1351 final ContentResolver resolver = mContext.getContentResolver(); 1352 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1353 } break; 1354 case GC_BACKGROUND_PROCESSES_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 performAppGcsIfAppropriateLocked(); 1357 } 1358 } break; 1359 case WAIT_FOR_DEBUGGER_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 ProcessRecord app = (ProcessRecord)msg.obj; 1362 if (msg.arg1 != 0) { 1363 if (!app.waitedForDebugger) { 1364 Dialog d = new AppWaitingForDebuggerDialog( 1365 ActivityManagerService.this, 1366 mContext, app); 1367 app.waitDialog = d; 1368 app.waitedForDebugger = true; 1369 d.show(); 1370 } 1371 } else { 1372 if (app.waitDialog != null) { 1373 app.waitDialog.dismiss(); 1374 app.waitDialog = null; 1375 } 1376 } 1377 } 1378 } break; 1379 case SERVICE_TIMEOUT_MSG: { 1380 if (mDidDexOpt) { 1381 mDidDexOpt = false; 1382 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1383 nmsg.obj = msg.obj; 1384 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1385 return; 1386 } 1387 mServices.serviceTimeout((ProcessRecord)msg.obj); 1388 } break; 1389 case UPDATE_TIME_ZONE: { 1390 synchronized (ActivityManagerService.this) { 1391 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1392 ProcessRecord r = mLruProcesses.get(i); 1393 if (r.thread != null) { 1394 try { 1395 r.thread.updateTimeZone(); 1396 } catch (RemoteException ex) { 1397 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1398 } 1399 } 1400 } 1401 } 1402 } break; 1403 case CLEAR_DNS_CACHE_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.clearDnsCache(); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case UPDATE_HTTP_PROXY_MSG: { 1418 ProxyInfo proxy = (ProxyInfo)msg.obj; 1419 String host = ""; 1420 String port = ""; 1421 String exclList = ""; 1422 Uri pacFileUrl = Uri.EMPTY; 1423 if (proxy != null) { 1424 host = proxy.getHost(); 1425 port = Integer.toString(proxy.getPort()); 1426 exclList = proxy.getExclusionListAsString(); 1427 pacFileUrl = proxy.getPacFileUrl(); 1428 } 1429 synchronized (ActivityManagerService.this) { 1430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1431 ProcessRecord r = mLruProcesses.get(i); 1432 if (r.thread != null) { 1433 try { 1434 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1435 } catch (RemoteException ex) { 1436 Slog.w(TAG, "Failed to update http proxy for: " + 1437 r.info.processName); 1438 } 1439 } 1440 } 1441 } 1442 } break; 1443 case SHOW_UID_ERROR_MSG: { 1444 String title = "System UIDs Inconsistent"; 1445 String text = "UIDs on the system are inconsistent, you need to wipe your" 1446 + " data partition or your device will be unstable."; 1447 Log.e(TAG, title + ": " + text); 1448 if (mShowDialogs) { 1449 // XXX This is a temporary dialog, no need to localize. 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(title); 1454 d.setMessage(text); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1456 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1457 mUidAlert = d; 1458 d.show(); 1459 } 1460 } break; 1461 case IM_FEELING_LUCKY_MSG: { 1462 if (mUidAlert != null) { 1463 mUidAlert.dismiss(); 1464 mUidAlert = null; 1465 } 1466 } break; 1467 case PROC_START_TIMEOUT_MSG: { 1468 if (mDidDexOpt) { 1469 mDidDexOpt = false; 1470 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1471 nmsg.obj = msg.obj; 1472 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1473 return; 1474 } 1475 ProcessRecord app = (ProcessRecord)msg.obj; 1476 synchronized (ActivityManagerService.this) { 1477 processStartTimedOutLocked(app); 1478 } 1479 } break; 1480 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1483 } 1484 } break; 1485 case KILL_APPLICATION_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 int appid = msg.arg1; 1488 boolean restart = (msg.arg2 == 1); 1489 Bundle bundle = (Bundle)msg.obj; 1490 String pkg = bundle.getString("pkg"); 1491 String reason = bundle.getString("reason"); 1492 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1493 false, UserHandle.USER_ALL, reason); 1494 } 1495 } break; 1496 case FINALIZE_PENDING_INTENT_MSG: { 1497 ((PendingIntentRecord)msg.obj).completeFinalize(); 1498 } break; 1499 case POST_HEAVY_NOTIFICATION_MSG: { 1500 INotificationManager inm = NotificationManager.getService(); 1501 if (inm == null) { 1502 return; 1503 } 1504 1505 ActivityRecord root = (ActivityRecord)msg.obj; 1506 ProcessRecord process = root.app; 1507 if (process == null) { 1508 return; 1509 } 1510 1511 try { 1512 Context context = mContext.createPackageContext(process.info.packageName, 0); 1513 String text = mContext.getString(R.string.heavy_weight_notification, 1514 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1515 Notification notification = new Notification(); 1516 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1517 notification.when = 0; 1518 notification.flags = Notification.FLAG_ONGOING_EVENT; 1519 notification.tickerText = text; 1520 notification.defaults = 0; // please be quiet 1521 notification.sound = null; 1522 notification.vibrate = null; 1523 notification.color = mContext.getResources().getColor( 1524 com.android.internal.R.color.system_notification_accent_color); 1525 notification.setLatestEventInfo(context, text, 1526 mContext.getText(R.string.heavy_weight_notification_detail), 1527 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1528 PendingIntent.FLAG_CANCEL_CURRENT, null, 1529 new UserHandle(root.userId))); 1530 1531 try { 1532 int[] outId = new int[1]; 1533 inm.enqueueNotificationWithTag("android", "android", null, 1534 R.string.heavy_weight_notification, 1535 notification, outId, root.userId); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error showing notification for heavy-weight app", e); 1539 } catch (RemoteException e) { 1540 } 1541 } catch (NameNotFoundException e) { 1542 Slog.w(TAG, "Unable to create context for heavy notification", e); 1543 } 1544 } break; 1545 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1546 INotificationManager inm = NotificationManager.getService(); 1547 if (inm == null) { 1548 return; 1549 } 1550 try { 1551 inm.cancelNotificationWithTag("android", null, 1552 R.string.heavy_weight_notification, msg.arg1); 1553 } catch (RuntimeException e) { 1554 Slog.w(ActivityManagerService.TAG, 1555 "Error canceling notification for service", e); 1556 } catch (RemoteException e) { 1557 } 1558 } break; 1559 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1560 synchronized (ActivityManagerService.this) { 1561 checkExcessivePowerUsageLocked(true); 1562 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1563 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1565 } 1566 } break; 1567 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1568 synchronized (ActivityManagerService.this) { 1569 ActivityRecord ar = (ActivityRecord)msg.obj; 1570 if (mCompatModeDialog != null) { 1571 if (mCompatModeDialog.mAppInfo.packageName.equals( 1572 ar.info.applicationInfo.packageName)) { 1573 return; 1574 } 1575 mCompatModeDialog.dismiss(); 1576 mCompatModeDialog = null; 1577 } 1578 if (ar != null && false) { 1579 if (mCompatModePackages.getPackageAskCompatModeLocked( 1580 ar.packageName)) { 1581 int mode = mCompatModePackages.computeCompatModeLocked( 1582 ar.info.applicationInfo); 1583 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1584 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1585 mCompatModeDialog = new CompatModeDialog( 1586 ActivityManagerService.this, mContext, 1587 ar.info.applicationInfo); 1588 mCompatModeDialog.show(); 1589 } 1590 } 1591 } 1592 } 1593 break; 1594 } 1595 case DISPATCH_PROCESSES_CHANGED: { 1596 dispatchProcessesChanged(); 1597 break; 1598 } 1599 case DISPATCH_PROCESS_DIED: { 1600 final int pid = msg.arg1; 1601 final int uid = msg.arg2; 1602 dispatchProcessDied(pid, uid); 1603 break; 1604 } 1605 case REPORT_MEM_USAGE_MSG: { 1606 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1607 Thread thread = new Thread() { 1608 @Override public void run() { 1609 final SparseArray<ProcessMemInfo> infoMap 1610 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 infoMap.put(mi.pid, mi); 1614 } 1615 updateCpuStatsNow(); 1616 synchronized (mProcessCpuTracker) { 1617 final int N = mProcessCpuTracker.countStats(); 1618 for (int i=0; i<N; i++) { 1619 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1620 if (st.vsize > 0) { 1621 long pss = Debug.getPss(st.pid, null); 1622 if (pss > 0) { 1623 if (infoMap.indexOfKey(st.pid) < 0) { 1624 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1625 ProcessList.NATIVE_ADJ, -1, "native", null); 1626 mi.pss = pss; 1627 memInfos.add(mi); 1628 } 1629 } 1630 } 1631 } 1632 } 1633 1634 long totalPss = 0; 1635 for (int i=0, N=memInfos.size(); i<N; i++) { 1636 ProcessMemInfo mi = memInfos.get(i); 1637 if (mi.pss == 0) { 1638 mi.pss = Debug.getPss(mi.pid, null); 1639 } 1640 totalPss += mi.pss; 1641 } 1642 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1643 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1644 if (lhs.oomAdj != rhs.oomAdj) { 1645 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1646 } 1647 if (lhs.pss != rhs.pss) { 1648 return lhs.pss < rhs.pss ? 1 : -1; 1649 } 1650 return 0; 1651 } 1652 }); 1653 1654 StringBuilder tag = new StringBuilder(128); 1655 StringBuilder stack = new StringBuilder(128); 1656 tag.append("Low on memory -- "); 1657 appendMemBucket(tag, totalPss, "total", false); 1658 appendMemBucket(stack, totalPss, "total", true); 1659 1660 StringBuilder logBuilder = new StringBuilder(1024); 1661 logBuilder.append("Low on memory:\n"); 1662 1663 boolean firstLine = true; 1664 int lastOomAdj = Integer.MIN_VALUE; 1665 for (int i=0, N=memInfos.size(); i<N; i++) { 1666 ProcessMemInfo mi = memInfos.get(i); 1667 1668 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1669 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1670 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1671 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1672 if (lastOomAdj != mi.oomAdj) { 1673 lastOomAdj = mi.oomAdj; 1674 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1675 tag.append(" / "); 1676 } 1677 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1678 if (firstLine) { 1679 stack.append(":"); 1680 firstLine = false; 1681 } 1682 stack.append("\n\t at "); 1683 } else { 1684 stack.append("$"); 1685 } 1686 } else { 1687 tag.append(" "); 1688 stack.append("$"); 1689 } 1690 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1691 appendMemBucket(tag, mi.pss, mi.name, false); 1692 } 1693 appendMemBucket(stack, mi.pss, mi.name, true); 1694 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1695 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1696 stack.append("("); 1697 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1698 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1699 stack.append(DUMP_MEM_OOM_LABEL[k]); 1700 stack.append(":"); 1701 stack.append(DUMP_MEM_OOM_ADJ[k]); 1702 } 1703 } 1704 stack.append(")"); 1705 } 1706 } 1707 1708 logBuilder.append(" "); 1709 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1710 logBuilder.append(' '); 1711 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1712 logBuilder.append(' '); 1713 ProcessList.appendRamKb(logBuilder, mi.pss); 1714 logBuilder.append(" kB: "); 1715 logBuilder.append(mi.name); 1716 logBuilder.append(" ("); 1717 logBuilder.append(mi.pid); 1718 logBuilder.append(") "); 1719 logBuilder.append(mi.adjType); 1720 logBuilder.append('\n'); 1721 if (mi.adjReason != null) { 1722 logBuilder.append(" "); 1723 logBuilder.append(mi.adjReason); 1724 logBuilder.append('\n'); 1725 } 1726 } 1727 1728 logBuilder.append(" "); 1729 ProcessList.appendRamKb(logBuilder, totalPss); 1730 logBuilder.append(" kB: TOTAL\n"); 1731 1732 long[] infos = new long[Debug.MEMINFO_COUNT]; 1733 Debug.getMemInfo(infos); 1734 logBuilder.append(" MemInfo: "); 1735 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1736 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1737 logBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 1738 logBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 1739 logBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 1740 logBuilder.append(" "); 1741 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1742 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1743 logBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 1744 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1745 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1746 logBuilder.append(" ZRAM: "); 1747 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1748 logBuilder.append(" kB RAM, "); 1749 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1750 logBuilder.append(" kB swap total, "); 1751 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1752 logBuilder.append(" kB swap free\n"); 1753 } 1754 Slog.i(TAG, logBuilder.toString()); 1755 1756 StringBuilder dropBuilder = new StringBuilder(1024); 1757 /* 1758 StringWriter oomSw = new StringWriter(); 1759 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1760 StringWriter catSw = new StringWriter(); 1761 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1762 String[] emptyArgs = new String[] { }; 1763 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1764 oomPw.flush(); 1765 String oomString = oomSw.toString(); 1766 */ 1767 dropBuilder.append(stack); 1768 dropBuilder.append('\n'); 1769 dropBuilder.append('\n'); 1770 dropBuilder.append(logBuilder); 1771 dropBuilder.append('\n'); 1772 /* 1773 dropBuilder.append(oomString); 1774 dropBuilder.append('\n'); 1775 */ 1776 StringWriter catSw = new StringWriter(); 1777 synchronized (ActivityManagerService.this) { 1778 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1779 String[] emptyArgs = new String[] { }; 1780 catPw.println(); 1781 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1782 catPw.println(); 1783 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1784 false, false, null); 1785 catPw.println(); 1786 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1787 catPw.flush(); 1788 } 1789 dropBuilder.append(catSw.toString()); 1790 addErrorToDropBox("lowmem", null, "system_server", null, 1791 null, tag.toString(), dropBuilder.toString(), null, null); 1792 //Slog.i(TAG, "Sent to dropbox:"); 1793 //Slog.i(TAG, dropBuilder.toString()); 1794 synchronized (ActivityManagerService.this) { 1795 long now = SystemClock.uptimeMillis(); 1796 if (mLastMemUsageReportTime < now) { 1797 mLastMemUsageReportTime = now; 1798 } 1799 } 1800 } 1801 }; 1802 thread.start(); 1803 break; 1804 } 1805 case START_USER_SWITCH_MSG: { 1806 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1807 break; 1808 } 1809 case REPORT_USER_SWITCH_MSG: { 1810 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1811 break; 1812 } 1813 case CONTINUE_USER_SWITCH_MSG: { 1814 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1815 break; 1816 } 1817 case USER_SWITCH_TIMEOUT_MSG: { 1818 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1819 break; 1820 } 1821 case IMMERSIVE_MODE_LOCK_MSG: { 1822 final boolean nextState = (msg.arg1 != 0); 1823 if (mUpdateLock.isHeld() != nextState) { 1824 if (DEBUG_IMMERSIVE) { 1825 final ActivityRecord r = (ActivityRecord) msg.obj; 1826 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1827 } 1828 if (nextState) { 1829 mUpdateLock.acquire(); 1830 } else { 1831 mUpdateLock.release(); 1832 } 1833 } 1834 break; 1835 } 1836 case PERSIST_URI_GRANTS_MSG: { 1837 writeGrantedUriPermissions(); 1838 break; 1839 } 1840 case REQUEST_ALL_PSS_MSG: { 1841 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1842 break; 1843 } 1844 case START_PROFILES_MSG: { 1845 synchronized (ActivityManagerService.this) { 1846 startProfilesLocked(); 1847 } 1848 break; 1849 } 1850 case UPDATE_TIME: { 1851 synchronized (ActivityManagerService.this) { 1852 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1853 ProcessRecord r = mLruProcesses.get(i); 1854 if (r.thread != null) { 1855 try { 1856 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1857 } catch (RemoteException ex) { 1858 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1859 } 1860 } 1861 } 1862 } 1863 break; 1864 } 1865 case SYSTEM_USER_START_MSG: { 1866 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1867 Integer.toString(msg.arg1), msg.arg1); 1868 mSystemServiceManager.startUser(msg.arg1); 1869 break; 1870 } 1871 case SYSTEM_USER_CURRENT_MSG: { 1872 mBatteryStatsService.noteEvent( 1873 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1874 Integer.toString(msg.arg2), msg.arg2); 1875 mBatteryStatsService.noteEvent( 1876 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1877 Integer.toString(msg.arg1), msg.arg1); 1878 mSystemServiceManager.switchUser(msg.arg1); 1879 mLockToAppRequest.clearPrompt(); 1880 break; 1881 } 1882 case ENTER_ANIMATION_COMPLETE_MSG: { 1883 synchronized (ActivityManagerService.this) { 1884 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1885 if (r != null && r.app != null && r.app.thread != null) { 1886 try { 1887 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1888 } catch (RemoteException e) { 1889 } 1890 } 1891 } 1892 break; 1893 } 1894 case FINISH_BOOTING_MSG: { 1895 if (msg.arg1 != 0) { 1896 finishBooting(); 1897 } 1898 if (msg.arg2 != 0) { 1899 enableScreenAfterBoot(); 1900 } 1901 break; 1902 } 1903 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1904 try { 1905 Locale l = (Locale) msg.obj; 1906 IBinder service = ServiceManager.getService("mount"); 1907 IMountService mountService = IMountService.Stub.asInterface(service); 1908 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1909 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1910 } catch (RemoteException e) { 1911 Log.e(TAG, "Error storing locale for decryption UI", e); 1912 } 1913 break; 1914 } 1915 } 1916 } 1917 }; 1918 1919 static final int COLLECT_PSS_BG_MSG = 1; 1920 1921 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1922 @Override 1923 public void handleMessage(Message msg) { 1924 switch (msg.what) { 1925 case COLLECT_PSS_BG_MSG: { 1926 long start = SystemClock.uptimeMillis(); 1927 MemInfoReader memInfo = null; 1928 synchronized (ActivityManagerService.this) { 1929 if (mFullPssPending) { 1930 mFullPssPending = false; 1931 memInfo = new MemInfoReader(); 1932 } 1933 } 1934 if (memInfo != null) { 1935 updateCpuStatsNow(); 1936 long nativeTotalPss = 0; 1937 synchronized (mProcessCpuTracker) { 1938 final int N = mProcessCpuTracker.countStats(); 1939 for (int j=0; j<N; j++) { 1940 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1941 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1942 // This is definitely an application process; skip it. 1943 continue; 1944 } 1945 synchronized (mPidsSelfLocked) { 1946 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1947 // This is one of our own processes; skip it. 1948 continue; 1949 } 1950 } 1951 nativeTotalPss += Debug.getPss(st.pid, null); 1952 } 1953 } 1954 memInfo.readMemInfo(); 1955 synchronized (ActivityManagerService.this) { 1956 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1957 + (SystemClock.uptimeMillis()-start) + "ms"); 1958 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1959 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1960 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1961 } 1962 } 1963 1964 int i=0, num=0; 1965 long[] tmp = new long[1]; 1966 do { 1967 ProcessRecord proc; 1968 int procState; 1969 int pid; 1970 synchronized (ActivityManagerService.this) { 1971 if (i >= mPendingPssProcesses.size()) { 1972 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1973 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1974 mPendingPssProcesses.clear(); 1975 return; 1976 } 1977 proc = mPendingPssProcesses.get(i); 1978 procState = proc.pssProcState; 1979 if (proc.thread != null && procState == proc.setProcState) { 1980 pid = proc.pid; 1981 } else { 1982 proc = null; 1983 pid = 0; 1984 } 1985 i++; 1986 } 1987 if (proc != null) { 1988 long pss = Debug.getPss(pid, tmp); 1989 synchronized (ActivityManagerService.this) { 1990 if (proc.thread != null && proc.setProcState == procState 1991 && proc.pid == pid) { 1992 num++; 1993 proc.lastPssTime = SystemClock.uptimeMillis(); 1994 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1995 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1996 + ": " + pss + " lastPss=" + proc.lastPss 1997 + " state=" + ProcessList.makeProcStateString(procState)); 1998 if (proc.initialIdlePss == 0) { 1999 proc.initialIdlePss = pss; 2000 } 2001 proc.lastPss = pss; 2002 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2003 proc.lastCachedPss = pss; 2004 } 2005 } 2006 } 2007 } 2008 } while (true); 2009 } 2010 } 2011 } 2012 }; 2013 2014 /** 2015 * Monitor for package changes and update our internal state. 2016 */ 2017 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2018 @Override 2019 public void onPackageRemoved(String packageName, int uid) { 2020 // Remove all tasks with activities in the specified package from the list of recent tasks 2021 final int eventUserId = getChangingUserId(); 2022 synchronized (ActivityManagerService.this) { 2023 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2024 TaskRecord tr = mRecentTasks.get(i); 2025 if (tr.userId != eventUserId) continue; 2026 2027 ComponentName cn = tr.intent.getComponent(); 2028 if (cn != null && cn.getPackageName().equals(packageName)) { 2029 // If the package name matches, remove the task and kill the process 2030 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2031 } 2032 } 2033 } 2034 } 2035 2036 @Override 2037 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2038 onPackageModified(packageName); 2039 return true; 2040 } 2041 2042 @Override 2043 public void onPackageModified(String packageName) { 2044 final int eventUserId = getChangingUserId(); 2045 final IPackageManager pm = AppGlobals.getPackageManager(); 2046 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2047 new ArrayList<Pair<Intent, Integer>>(); 2048 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2049 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2050 // Copy the list of recent tasks so that we don't hold onto the lock on 2051 // ActivityManagerService for long periods while checking if components exist. 2052 synchronized (ActivityManagerService.this) { 2053 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2054 TaskRecord tr = mRecentTasks.get(i); 2055 if (tr.userId != eventUserId) continue; 2056 2057 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2058 } 2059 } 2060 // Check the recent tasks and filter out all tasks with components that no longer exist. 2061 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2062 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2063 ComponentName cn = p.first.getComponent(); 2064 if (cn != null && cn.getPackageName().equals(packageName)) { 2065 if (componentsKnownToExist.contains(cn)) { 2066 // If we know that the component still exists in the package, then skip 2067 continue; 2068 } 2069 try { 2070 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2071 if (info != null) { 2072 componentsKnownToExist.add(cn); 2073 } else { 2074 tasksToRemove.add(p.second); 2075 } 2076 } catch (RemoteException e) { 2077 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2078 } 2079 } 2080 } 2081 // Prune all the tasks with removed components from the list of recent tasks 2082 synchronized (ActivityManagerService.this) { 2083 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2084 // Remove the task but don't kill the process (since other components in that 2085 // package may still be running and in the background) 2086 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2087 } 2088 } 2089 } 2090 2091 @Override 2092 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2093 // Force stop the specified packages 2094 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2095 if (packages != null) { 2096 for (String pkg : packages) { 2097 synchronized (ActivityManagerService.this) { 2098 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2099 userId, "finished booting")) { 2100 return true; 2101 } 2102 } 2103 } 2104 } 2105 return false; 2106 } 2107 }; 2108 2109 public void setSystemProcess() { 2110 try { 2111 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2112 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2113 ServiceManager.addService("meminfo", new MemBinder(this)); 2114 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2115 ServiceManager.addService("dbinfo", new DbBinder(this)); 2116 if (MONITOR_CPU_USAGE) { 2117 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2118 } 2119 ServiceManager.addService("permission", new PermissionController(this)); 2120 2121 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2122 "android", STOCK_PM_FLAGS); 2123 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2124 2125 synchronized (this) { 2126 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2127 app.persistent = true; 2128 app.pid = MY_PID; 2129 app.maxAdj = ProcessList.SYSTEM_ADJ; 2130 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2131 mProcessNames.put(app.processName, app.uid, app); 2132 synchronized (mPidsSelfLocked) { 2133 mPidsSelfLocked.put(app.pid, app); 2134 } 2135 updateLruProcessLocked(app, false, null); 2136 updateOomAdjLocked(); 2137 } 2138 } catch (PackageManager.NameNotFoundException e) { 2139 throw new RuntimeException( 2140 "Unable to find android system package", e); 2141 } 2142 } 2143 2144 public void setWindowManager(WindowManagerService wm) { 2145 mWindowManager = wm; 2146 mStackSupervisor.setWindowManager(wm); 2147 } 2148 2149 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2150 mUsageStatsService = usageStatsManager; 2151 } 2152 2153 public void startObservingNativeCrashes() { 2154 final NativeCrashListener ncl = new NativeCrashListener(this); 2155 ncl.start(); 2156 } 2157 2158 public IAppOpsService getAppOpsService() { 2159 return mAppOpsService; 2160 } 2161 2162 static class MemBinder extends Binder { 2163 ActivityManagerService mActivityManagerService; 2164 MemBinder(ActivityManagerService activityManagerService) { 2165 mActivityManagerService = activityManagerService; 2166 } 2167 2168 @Override 2169 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2170 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2171 != PackageManager.PERMISSION_GRANTED) { 2172 pw.println("Permission Denial: can't dump meminfo from from pid=" 2173 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2174 + " without permission " + android.Manifest.permission.DUMP); 2175 return; 2176 } 2177 2178 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2179 } 2180 } 2181 2182 static class GraphicsBinder extends Binder { 2183 ActivityManagerService mActivityManagerService; 2184 GraphicsBinder(ActivityManagerService activityManagerService) { 2185 mActivityManagerService = activityManagerService; 2186 } 2187 2188 @Override 2189 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2190 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2191 != PackageManager.PERMISSION_GRANTED) { 2192 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2193 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2194 + " without permission " + android.Manifest.permission.DUMP); 2195 return; 2196 } 2197 2198 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2199 } 2200 } 2201 2202 static class DbBinder extends Binder { 2203 ActivityManagerService mActivityManagerService; 2204 DbBinder(ActivityManagerService activityManagerService) { 2205 mActivityManagerService = activityManagerService; 2206 } 2207 2208 @Override 2209 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2210 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2211 != PackageManager.PERMISSION_GRANTED) { 2212 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2213 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2214 + " without permission " + android.Manifest.permission.DUMP); 2215 return; 2216 } 2217 2218 mActivityManagerService.dumpDbInfo(fd, pw, args); 2219 } 2220 } 2221 2222 static class CpuBinder extends Binder { 2223 ActivityManagerService mActivityManagerService; 2224 CpuBinder(ActivityManagerService activityManagerService) { 2225 mActivityManagerService = activityManagerService; 2226 } 2227 2228 @Override 2229 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2230 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2231 != PackageManager.PERMISSION_GRANTED) { 2232 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2233 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2234 + " without permission " + android.Manifest.permission.DUMP); 2235 return; 2236 } 2237 2238 synchronized (mActivityManagerService.mProcessCpuTracker) { 2239 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2240 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2241 SystemClock.uptimeMillis())); 2242 } 2243 } 2244 } 2245 2246 public static final class Lifecycle extends SystemService { 2247 private final ActivityManagerService mService; 2248 2249 public Lifecycle(Context context) { 2250 super(context); 2251 mService = new ActivityManagerService(context); 2252 } 2253 2254 @Override 2255 public void onStart() { 2256 mService.start(); 2257 } 2258 2259 public ActivityManagerService getService() { 2260 return mService; 2261 } 2262 } 2263 2264 // Note: This method is invoked on the main thread but may need to attach various 2265 // handlers to other threads. So take care to be explicit about the looper. 2266 public ActivityManagerService(Context systemContext) { 2267 mContext = systemContext; 2268 mFactoryTest = FactoryTest.getMode(); 2269 mSystemThread = ActivityThread.currentActivityThread(); 2270 2271 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2272 2273 mHandlerThread = new ServiceThread(TAG, 2274 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2275 mHandlerThread.start(); 2276 mHandler = new MainHandler(mHandlerThread.getLooper()); 2277 2278 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2279 "foreground", BROADCAST_FG_TIMEOUT, false); 2280 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2281 "background", BROADCAST_BG_TIMEOUT, true); 2282 mBroadcastQueues[0] = mFgBroadcastQueue; 2283 mBroadcastQueues[1] = mBgBroadcastQueue; 2284 2285 mServices = new ActiveServices(this); 2286 mProviderMap = new ProviderMap(this); 2287 2288 // TODO: Move creation of battery stats service outside of activity manager service. 2289 File dataDir = Environment.getDataDirectory(); 2290 File systemDir = new File(dataDir, "system"); 2291 systemDir.mkdirs(); 2292 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2293 mBatteryStatsService.getActiveStatistics().readLocked(); 2294 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2295 mOnBattery = DEBUG_POWER ? true 2296 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2297 mBatteryStatsService.getActiveStatistics().setCallback(this); 2298 2299 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2300 2301 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2302 2303 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2304 2305 // User 0 is the first and only user that runs at boot. 2306 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2307 mUserLru.add(Integer.valueOf(0)); 2308 updateStartedUserArrayLocked(); 2309 2310 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2311 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2312 2313 mConfiguration.setToDefaults(); 2314 mConfiguration.setLocale(Locale.getDefault()); 2315 2316 mConfigurationSeq = mConfiguration.seq = 1; 2317 mProcessCpuTracker.init(); 2318 2319 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2320 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2321 mStackSupervisor = new ActivityStackSupervisor(this); 2322 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2323 2324 mProcessCpuThread = new Thread("CpuTracker") { 2325 @Override 2326 public void run() { 2327 while (true) { 2328 try { 2329 try { 2330 synchronized(this) { 2331 final long now = SystemClock.uptimeMillis(); 2332 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2333 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2334 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2335 // + ", write delay=" + nextWriteDelay); 2336 if (nextWriteDelay < nextCpuDelay) { 2337 nextCpuDelay = nextWriteDelay; 2338 } 2339 if (nextCpuDelay > 0) { 2340 mProcessCpuMutexFree.set(true); 2341 this.wait(nextCpuDelay); 2342 } 2343 } 2344 } catch (InterruptedException e) { 2345 } 2346 updateCpuStatsNow(); 2347 } catch (Exception e) { 2348 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2349 } 2350 } 2351 } 2352 }; 2353 2354 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2355 2356 Watchdog.getInstance().addMonitor(this); 2357 Watchdog.getInstance().addThread(mHandler); 2358 } 2359 2360 public void setSystemServiceManager(SystemServiceManager mgr) { 2361 mSystemServiceManager = mgr; 2362 } 2363 2364 private void start() { 2365 Process.removeAllProcessGroups(); 2366 mProcessCpuThread.start(); 2367 2368 mBatteryStatsService.publish(mContext); 2369 mAppOpsService.publish(mContext); 2370 Slog.d("AppOps", "AppOpsService published"); 2371 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2372 } 2373 2374 public void initPowerManagement() { 2375 mStackSupervisor.initPowerManagement(); 2376 mBatteryStatsService.initPowerManagement(); 2377 } 2378 2379 @Override 2380 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2381 throws RemoteException { 2382 if (code == SYSPROPS_TRANSACTION) { 2383 // We need to tell all apps about the system property change. 2384 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2385 synchronized(this) { 2386 final int NP = mProcessNames.getMap().size(); 2387 for (int ip=0; ip<NP; ip++) { 2388 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2389 final int NA = apps.size(); 2390 for (int ia=0; ia<NA; ia++) { 2391 ProcessRecord app = apps.valueAt(ia); 2392 if (app.thread != null) { 2393 procs.add(app.thread.asBinder()); 2394 } 2395 } 2396 } 2397 } 2398 2399 int N = procs.size(); 2400 for (int i=0; i<N; i++) { 2401 Parcel data2 = Parcel.obtain(); 2402 try { 2403 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2404 } catch (RemoteException e) { 2405 } 2406 data2.recycle(); 2407 } 2408 } 2409 try { 2410 return super.onTransact(code, data, reply, flags); 2411 } catch (RuntimeException e) { 2412 // The activity manager only throws security exceptions, so let's 2413 // log all others. 2414 if (!(e instanceof SecurityException)) { 2415 Slog.wtf(TAG, "Activity Manager Crash", e); 2416 } 2417 throw e; 2418 } 2419 } 2420 2421 void updateCpuStats() { 2422 final long now = SystemClock.uptimeMillis(); 2423 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2424 return; 2425 } 2426 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2427 synchronized (mProcessCpuThread) { 2428 mProcessCpuThread.notify(); 2429 } 2430 } 2431 } 2432 2433 void updateCpuStatsNow() { 2434 synchronized (mProcessCpuTracker) { 2435 mProcessCpuMutexFree.set(false); 2436 final long now = SystemClock.uptimeMillis(); 2437 boolean haveNewCpuStats = false; 2438 2439 if (MONITOR_CPU_USAGE && 2440 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2441 mLastCpuTime.set(now); 2442 haveNewCpuStats = true; 2443 mProcessCpuTracker.update(); 2444 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2445 //Slog.i(TAG, "Total CPU usage: " 2446 // + mProcessCpu.getTotalCpuPercent() + "%"); 2447 2448 // Slog the cpu usage if the property is set. 2449 if ("true".equals(SystemProperties.get("events.cpu"))) { 2450 int user = mProcessCpuTracker.getLastUserTime(); 2451 int system = mProcessCpuTracker.getLastSystemTime(); 2452 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2453 int irq = mProcessCpuTracker.getLastIrqTime(); 2454 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2455 int idle = mProcessCpuTracker.getLastIdleTime(); 2456 2457 int total = user + system + iowait + irq + softIrq + idle; 2458 if (total == 0) total = 1; 2459 2460 EventLog.writeEvent(EventLogTags.CPU, 2461 ((user+system+iowait+irq+softIrq) * 100) / total, 2462 (user * 100) / total, 2463 (system * 100) / total, 2464 (iowait * 100) / total, 2465 (irq * 100) / total, 2466 (softIrq * 100) / total); 2467 } 2468 } 2469 2470 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2471 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2472 synchronized(bstats) { 2473 synchronized(mPidsSelfLocked) { 2474 if (haveNewCpuStats) { 2475 if (mOnBattery) { 2476 int perc = bstats.startAddingCpuLocked(); 2477 int totalUTime = 0; 2478 int totalSTime = 0; 2479 final int N = mProcessCpuTracker.countStats(); 2480 for (int i=0; i<N; i++) { 2481 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2482 if (!st.working) { 2483 continue; 2484 } 2485 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2486 int otherUTime = (st.rel_utime*perc)/100; 2487 int otherSTime = (st.rel_stime*perc)/100; 2488 totalUTime += otherUTime; 2489 totalSTime += otherSTime; 2490 if (pr != null) { 2491 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2492 if (ps == null || !ps.isActive()) { 2493 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2494 pr.info.uid, pr.processName); 2495 } 2496 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2497 st.rel_stime-otherSTime); 2498 ps.addSpeedStepTimes(cpuSpeedTimes); 2499 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2500 } else { 2501 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2502 if (ps == null || !ps.isActive()) { 2503 st.batteryStats = ps = bstats.getProcessStatsLocked( 2504 bstats.mapUid(st.uid), st.name); 2505 } 2506 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2507 st.rel_stime-otherSTime); 2508 ps.addSpeedStepTimes(cpuSpeedTimes); 2509 } 2510 } 2511 bstats.finishAddingCpuLocked(perc, totalUTime, 2512 totalSTime, cpuSpeedTimes); 2513 } 2514 } 2515 } 2516 2517 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2518 mLastWriteTime = now; 2519 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2520 } 2521 } 2522 } 2523 } 2524 2525 @Override 2526 public void batteryNeedsCpuUpdate() { 2527 updateCpuStatsNow(); 2528 } 2529 2530 @Override 2531 public void batteryPowerChanged(boolean onBattery) { 2532 // When plugging in, update the CPU stats first before changing 2533 // the plug state. 2534 updateCpuStatsNow(); 2535 synchronized (this) { 2536 synchronized(mPidsSelfLocked) { 2537 mOnBattery = DEBUG_POWER ? true : onBattery; 2538 } 2539 } 2540 } 2541 2542 /** 2543 * Initialize the application bind args. These are passed to each 2544 * process when the bindApplication() IPC is sent to the process. They're 2545 * lazily setup to make sure the services are running when they're asked for. 2546 */ 2547 private HashMap<String, IBinder> getCommonServicesLocked() { 2548 if (mAppBindArgs == null) { 2549 mAppBindArgs = new HashMap<String, IBinder>(); 2550 2551 // Setup the application init args 2552 mAppBindArgs.put("package", ServiceManager.getService("package")); 2553 mAppBindArgs.put("window", ServiceManager.getService("window")); 2554 mAppBindArgs.put(Context.ALARM_SERVICE, 2555 ServiceManager.getService(Context.ALARM_SERVICE)); 2556 } 2557 return mAppBindArgs; 2558 } 2559 2560 final void setFocusedActivityLocked(ActivityRecord r) { 2561 if (mFocusedActivity != r) { 2562 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2563 mFocusedActivity = r; 2564 if (r.task != null && r.task.voiceInteractor != null) { 2565 startRunningVoiceLocked(); 2566 } else { 2567 finishRunningVoiceLocked(); 2568 } 2569 mStackSupervisor.setFocusedStack(r); 2570 if (r != null) { 2571 mWindowManager.setFocusedApp(r.appToken, true); 2572 } 2573 applyUpdateLockStateLocked(r); 2574 } 2575 } 2576 2577 final void clearFocusedActivity(ActivityRecord r) { 2578 if (mFocusedActivity == r) { 2579 mFocusedActivity = null; 2580 } 2581 } 2582 2583 @Override 2584 public void setFocusedStack(int stackId) { 2585 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2586 synchronized (ActivityManagerService.this) { 2587 ActivityStack stack = mStackSupervisor.getStack(stackId); 2588 if (stack != null) { 2589 ActivityRecord r = stack.topRunningActivityLocked(null); 2590 if (r != null) { 2591 setFocusedActivityLocked(r); 2592 } 2593 } 2594 } 2595 } 2596 2597 @Override 2598 public void notifyActivityDrawn(IBinder token) { 2599 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2600 synchronized (this) { 2601 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2602 if (r != null) { 2603 r.task.stack.notifyActivityDrawnLocked(r); 2604 } 2605 } 2606 } 2607 2608 final void applyUpdateLockStateLocked(ActivityRecord r) { 2609 // Modifications to the UpdateLock state are done on our handler, outside 2610 // the activity manager's locks. The new state is determined based on the 2611 // state *now* of the relevant activity record. The object is passed to 2612 // the handler solely for logging detail, not to be consulted/modified. 2613 final boolean nextState = r != null && r.immersive; 2614 mHandler.sendMessage( 2615 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2616 } 2617 2618 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2619 Message msg = Message.obtain(); 2620 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2621 msg.obj = r.task.askedCompatMode ? null : r; 2622 mHandler.sendMessage(msg); 2623 } 2624 2625 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2626 String what, Object obj, ProcessRecord srcApp) { 2627 app.lastActivityTime = now; 2628 2629 if (app.activities.size() > 0) { 2630 // Don't want to touch dependent processes that are hosting activities. 2631 return index; 2632 } 2633 2634 int lrui = mLruProcesses.lastIndexOf(app); 2635 if (lrui < 0) { 2636 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2637 + what + " " + obj + " from " + srcApp); 2638 return index; 2639 } 2640 2641 if (lrui >= index) { 2642 // Don't want to cause this to move dependent processes *back* in the 2643 // list as if they were less frequently used. 2644 return index; 2645 } 2646 2647 if (lrui >= mLruProcessActivityStart) { 2648 // Don't want to touch dependent processes that are hosting activities. 2649 return index; 2650 } 2651 2652 mLruProcesses.remove(lrui); 2653 if (index > 0) { 2654 index--; 2655 } 2656 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2657 + " in LRU list: " + app); 2658 mLruProcesses.add(index, app); 2659 return index; 2660 } 2661 2662 final void removeLruProcessLocked(ProcessRecord app) { 2663 int lrui = mLruProcesses.lastIndexOf(app); 2664 if (lrui >= 0) { 2665 if (!app.killed) { 2666 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2667 Process.killProcessQuiet(app.pid); 2668 Process.killProcessGroup(app.info.uid, app.pid); 2669 } 2670 if (lrui <= mLruProcessActivityStart) { 2671 mLruProcessActivityStart--; 2672 } 2673 if (lrui <= mLruProcessServiceStart) { 2674 mLruProcessServiceStart--; 2675 } 2676 mLruProcesses.remove(lrui); 2677 } 2678 } 2679 2680 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2681 ProcessRecord client) { 2682 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2683 || app.treatLikeActivity; 2684 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2685 if (!activityChange && hasActivity) { 2686 // The process has activities, so we are only allowing activity-based adjustments 2687 // to move it. It should be kept in the front of the list with other 2688 // processes that have activities, and we don't want those to change their 2689 // order except due to activity operations. 2690 return; 2691 } 2692 2693 mLruSeq++; 2694 final long now = SystemClock.uptimeMillis(); 2695 app.lastActivityTime = now; 2696 2697 // First a quick reject: if the app is already at the position we will 2698 // put it, then there is nothing to do. 2699 if (hasActivity) { 2700 final int N = mLruProcesses.size(); 2701 if (N > 0 && mLruProcesses.get(N-1) == app) { 2702 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2703 return; 2704 } 2705 } else { 2706 if (mLruProcessServiceStart > 0 2707 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2708 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2709 return; 2710 } 2711 } 2712 2713 int lrui = mLruProcesses.lastIndexOf(app); 2714 2715 if (app.persistent && lrui >= 0) { 2716 // We don't care about the position of persistent processes, as long as 2717 // they are in the list. 2718 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2719 return; 2720 } 2721 2722 /* In progress: compute new position first, so we can avoid doing work 2723 if the process is not actually going to move. Not yet working. 2724 int addIndex; 2725 int nextIndex; 2726 boolean inActivity = false, inService = false; 2727 if (hasActivity) { 2728 // Process has activities, put it at the very tipsy-top. 2729 addIndex = mLruProcesses.size(); 2730 nextIndex = mLruProcessServiceStart; 2731 inActivity = true; 2732 } else if (hasService) { 2733 // Process has services, put it at the top of the service list. 2734 addIndex = mLruProcessActivityStart; 2735 nextIndex = mLruProcessServiceStart; 2736 inActivity = true; 2737 inService = true; 2738 } else { 2739 // Process not otherwise of interest, it goes to the top of the non-service area. 2740 addIndex = mLruProcessServiceStart; 2741 if (client != null) { 2742 int clientIndex = mLruProcesses.lastIndexOf(client); 2743 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2744 + app); 2745 if (clientIndex >= 0 && addIndex > clientIndex) { 2746 addIndex = clientIndex; 2747 } 2748 } 2749 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2750 } 2751 2752 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2753 + mLruProcessActivityStart + "): " + app); 2754 */ 2755 2756 if (lrui >= 0) { 2757 if (lrui < mLruProcessActivityStart) { 2758 mLruProcessActivityStart--; 2759 } 2760 if (lrui < mLruProcessServiceStart) { 2761 mLruProcessServiceStart--; 2762 } 2763 /* 2764 if (addIndex > lrui) { 2765 addIndex--; 2766 } 2767 if (nextIndex > lrui) { 2768 nextIndex--; 2769 } 2770 */ 2771 mLruProcesses.remove(lrui); 2772 } 2773 2774 /* 2775 mLruProcesses.add(addIndex, app); 2776 if (inActivity) { 2777 mLruProcessActivityStart++; 2778 } 2779 if (inService) { 2780 mLruProcessActivityStart++; 2781 } 2782 */ 2783 2784 int nextIndex; 2785 if (hasActivity) { 2786 final int N = mLruProcesses.size(); 2787 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2788 // Process doesn't have activities, but has clients with 2789 // activities... move it up, but one below the top (the top 2790 // should always have a real activity). 2791 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2792 mLruProcesses.add(N-1, app); 2793 // To keep it from spamming the LRU list (by making a bunch of clients), 2794 // we will push down any other entries owned by the app. 2795 final int uid = app.info.uid; 2796 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2797 ProcessRecord subProc = mLruProcesses.get(i); 2798 if (subProc.info.uid == uid) { 2799 // We want to push this one down the list. If the process after 2800 // it is for the same uid, however, don't do so, because we don't 2801 // want them internally to be re-ordered. 2802 if (mLruProcesses.get(i-1).info.uid != uid) { 2803 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2804 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2805 ProcessRecord tmp = mLruProcesses.get(i); 2806 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2807 mLruProcesses.set(i-1, tmp); 2808 i--; 2809 } 2810 } else { 2811 // A gap, we can stop here. 2812 break; 2813 } 2814 } 2815 } else { 2816 // Process has activities, put it at the very tipsy-top. 2817 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2818 mLruProcesses.add(app); 2819 } 2820 nextIndex = mLruProcessServiceStart; 2821 } else if (hasService) { 2822 // Process has services, put it at the top of the service list. 2823 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2824 mLruProcesses.add(mLruProcessActivityStart, app); 2825 nextIndex = mLruProcessServiceStart; 2826 mLruProcessActivityStart++; 2827 } else { 2828 // Process not otherwise of interest, it goes to the top of the non-service area. 2829 int index = mLruProcessServiceStart; 2830 if (client != null) { 2831 // If there is a client, don't allow the process to be moved up higher 2832 // in the list than that client. 2833 int clientIndex = mLruProcesses.lastIndexOf(client); 2834 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2835 + " when updating " + app); 2836 if (clientIndex <= lrui) { 2837 // Don't allow the client index restriction to push it down farther in the 2838 // list than it already is. 2839 clientIndex = lrui; 2840 } 2841 if (clientIndex >= 0 && index > clientIndex) { 2842 index = clientIndex; 2843 } 2844 } 2845 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2846 mLruProcesses.add(index, app); 2847 nextIndex = index-1; 2848 mLruProcessActivityStart++; 2849 mLruProcessServiceStart++; 2850 } 2851 2852 // If the app is currently using a content provider or service, 2853 // bump those processes as well. 2854 for (int j=app.connections.size()-1; j>=0; j--) { 2855 ConnectionRecord cr = app.connections.valueAt(j); 2856 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2857 && cr.binding.service.app != null 2858 && cr.binding.service.app.lruSeq != mLruSeq 2859 && !cr.binding.service.app.persistent) { 2860 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2861 "service connection", cr, app); 2862 } 2863 } 2864 for (int j=app.conProviders.size()-1; j>=0; j--) { 2865 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2866 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2867 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2868 "provider reference", cpr, app); 2869 } 2870 } 2871 } 2872 2873 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2874 if (uid == Process.SYSTEM_UID) { 2875 // The system gets to run in any process. If there are multiple 2876 // processes with the same uid, just pick the first (this 2877 // should never happen). 2878 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2879 if (procs == null) return null; 2880 final int N = procs.size(); 2881 for (int i = 0; i < N; i++) { 2882 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2883 } 2884 } 2885 ProcessRecord proc = mProcessNames.get(processName, uid); 2886 if (false && proc != null && !keepIfLarge 2887 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2888 && proc.lastCachedPss >= 4000) { 2889 // Turn this condition on to cause killing to happen regularly, for testing. 2890 if (proc.baseProcessTracker != null) { 2891 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2892 } 2893 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2894 } else if (proc != null && !keepIfLarge 2895 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2896 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2897 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2898 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2899 if (proc.baseProcessTracker != null) { 2900 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2901 } 2902 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2903 } 2904 } 2905 return proc; 2906 } 2907 2908 void ensurePackageDexOpt(String packageName) { 2909 IPackageManager pm = AppGlobals.getPackageManager(); 2910 try { 2911 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2912 mDidDexOpt = true; 2913 } 2914 } catch (RemoteException e) { 2915 } 2916 } 2917 2918 boolean isNextTransitionForward() { 2919 int transit = mWindowManager.getPendingAppTransition(); 2920 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2921 || transit == AppTransition.TRANSIT_TASK_OPEN 2922 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2923 } 2924 2925 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2926 String processName, String abiOverride, int uid, Runnable crashHandler) { 2927 synchronized(this) { 2928 ApplicationInfo info = new ApplicationInfo(); 2929 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2930 // For isolated processes, the former contains the parent's uid and the latter the 2931 // actual uid of the isolated process. 2932 // In the special case introduced by this method (which is, starting an isolated 2933 // process directly from the SystemServer without an actual parent app process) the 2934 // closest thing to a parent's uid is SYSTEM_UID. 2935 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2936 // the |isolated| logic in the ProcessRecord constructor. 2937 info.uid = Process.SYSTEM_UID; 2938 info.processName = processName; 2939 info.className = entryPoint; 2940 info.packageName = "android"; 2941 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2942 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2943 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2944 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2945 crashHandler); 2946 return proc != null ? proc.pid : 0; 2947 } 2948 } 2949 2950 final ProcessRecord startProcessLocked(String processName, 2951 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2952 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2953 boolean isolated, boolean keepIfLarge) { 2954 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2955 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2956 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2957 null /* crashHandler */); 2958 } 2959 2960 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2961 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2962 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2963 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2964 long startTime = SystemClock.elapsedRealtime(); 2965 ProcessRecord app; 2966 if (!isolated) { 2967 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2968 checkTime(startTime, "startProcess: after getProcessRecord"); 2969 } else { 2970 // If this is an isolated process, it can't re-use an existing process. 2971 app = null; 2972 } 2973 // We don't have to do anything more if: 2974 // (1) There is an existing application record; and 2975 // (2) The caller doesn't think it is dead, OR there is no thread 2976 // object attached to it so we know it couldn't have crashed; and 2977 // (3) There is a pid assigned to it, so it is either starting or 2978 // already running. 2979 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2980 + " app=" + app + " knownToBeDead=" + knownToBeDead 2981 + " thread=" + (app != null ? app.thread : null) 2982 + " pid=" + (app != null ? app.pid : -1)); 2983 if (app != null && app.pid > 0) { 2984 if (!knownToBeDead || app.thread == null) { 2985 // We already have the app running, or are waiting for it to 2986 // come up (we have a pid but not yet its thread), so keep it. 2987 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2988 // If this is a new package in the process, add the package to the list 2989 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2990 checkTime(startTime, "startProcess: done, added package to proc"); 2991 return app; 2992 } 2993 2994 // An application record is attached to a previous process, 2995 // clean it up now. 2996 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2997 checkTime(startTime, "startProcess: bad proc running, killing"); 2998 Process.killProcessGroup(app.info.uid, app.pid); 2999 handleAppDiedLocked(app, true, true); 3000 checkTime(startTime, "startProcess: done killing old proc"); 3001 } 3002 3003 String hostingNameStr = hostingName != null 3004 ? hostingName.flattenToShortString() : null; 3005 3006 if (!isolated) { 3007 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3008 // If we are in the background, then check to see if this process 3009 // is bad. If so, we will just silently fail. 3010 if (mBadProcesses.get(info.processName, info.uid) != null) { 3011 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3012 + "/" + info.processName); 3013 return null; 3014 } 3015 } else { 3016 // When the user is explicitly starting a process, then clear its 3017 // crash count so that we won't make it bad until they see at 3018 // least one crash dialog again, and make the process good again 3019 // if it had been bad. 3020 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3021 + "/" + info.processName); 3022 mProcessCrashTimes.remove(info.processName, info.uid); 3023 if (mBadProcesses.get(info.processName, info.uid) != null) { 3024 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3025 UserHandle.getUserId(info.uid), info.uid, 3026 info.processName); 3027 mBadProcesses.remove(info.processName, info.uid); 3028 if (app != null) { 3029 app.bad = false; 3030 } 3031 } 3032 } 3033 } 3034 3035 if (app == null) { 3036 checkTime(startTime, "startProcess: creating new process record"); 3037 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3038 app.crashHandler = crashHandler; 3039 if (app == null) { 3040 Slog.w(TAG, "Failed making new process record for " 3041 + processName + "/" + info.uid + " isolated=" + isolated); 3042 return null; 3043 } 3044 mProcessNames.put(processName, app.uid, app); 3045 if (isolated) { 3046 mIsolatedProcesses.put(app.uid, app); 3047 } 3048 checkTime(startTime, "startProcess: done creating new process record"); 3049 } else { 3050 // If this is a new package in the process, add the package to the list 3051 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3052 checkTime(startTime, "startProcess: added package to existing proc"); 3053 } 3054 3055 // If the system is not ready yet, then hold off on starting this 3056 // process until it is. 3057 if (!mProcessesReady 3058 && !isAllowedWhileBooting(info) 3059 && !allowWhileBooting) { 3060 if (!mProcessesOnHold.contains(app)) { 3061 mProcessesOnHold.add(app); 3062 } 3063 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3064 checkTime(startTime, "startProcess: returning with proc on hold"); 3065 return app; 3066 } 3067 3068 checkTime(startTime, "startProcess: stepping in to startProcess"); 3069 startProcessLocked( 3070 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3071 checkTime(startTime, "startProcess: done starting proc!"); 3072 return (app.pid != 0) ? app : null; 3073 } 3074 3075 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3076 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3077 } 3078 3079 private final void startProcessLocked(ProcessRecord app, 3080 String hostingType, String hostingNameStr) { 3081 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3082 null /* entryPoint */, null /* entryPointArgs */); 3083 } 3084 3085 private final void startProcessLocked(ProcessRecord app, String hostingType, 3086 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3087 long startTime = SystemClock.elapsedRealtime(); 3088 if (app.pid > 0 && app.pid != MY_PID) { 3089 checkTime(startTime, "startProcess: removing from pids map"); 3090 synchronized (mPidsSelfLocked) { 3091 mPidsSelfLocked.remove(app.pid); 3092 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3093 } 3094 checkTime(startTime, "startProcess: done removing from pids map"); 3095 app.setPid(0); 3096 } 3097 3098 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3099 "startProcessLocked removing on hold: " + app); 3100 mProcessesOnHold.remove(app); 3101 3102 checkTime(startTime, "startProcess: starting to update cpu stats"); 3103 updateCpuStats(); 3104 checkTime(startTime, "startProcess: done updating cpu stats"); 3105 3106 try { 3107 int uid = app.uid; 3108 3109 int[] gids = null; 3110 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3111 if (!app.isolated) { 3112 int[] permGids = null; 3113 try { 3114 checkTime(startTime, "startProcess: getting gids from package manager"); 3115 final PackageManager pm = mContext.getPackageManager(); 3116 permGids = pm.getPackageGids(app.info.packageName); 3117 3118 if (Environment.isExternalStorageEmulated()) { 3119 checkTime(startTime, "startProcess: checking external storage perm"); 3120 if (pm.checkPermission( 3121 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3122 app.info.packageName) == PERMISSION_GRANTED) { 3123 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3124 } else { 3125 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3126 } 3127 } 3128 } catch (PackageManager.NameNotFoundException e) { 3129 Slog.w(TAG, "Unable to retrieve gids", e); 3130 } 3131 3132 /* 3133 * Add shared application and profile GIDs so applications can share some 3134 * resources like shared libraries and access user-wide resources 3135 */ 3136 if (permGids == null) { 3137 gids = new int[2]; 3138 } else { 3139 gids = new int[permGids.length + 2]; 3140 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3141 } 3142 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3143 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3144 } 3145 checkTime(startTime, "startProcess: building args"); 3146 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3147 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3148 && mTopComponent != null 3149 && app.processName.equals(mTopComponent.getPackageName())) { 3150 uid = 0; 3151 } 3152 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3153 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3154 uid = 0; 3155 } 3156 } 3157 int debugFlags = 0; 3158 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3159 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3160 // Also turn on CheckJNI for debuggable apps. It's quite 3161 // awkward to turn on otherwise. 3162 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3163 } 3164 // Run the app in safe mode if its manifest requests so or the 3165 // system is booted in safe mode. 3166 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3167 mSafeMode == true) { 3168 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3169 } 3170 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3171 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3172 } 3173 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3174 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3175 } 3176 if ("1".equals(SystemProperties.get("debug.assert"))) { 3177 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3178 } 3179 3180 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3181 if (requiredAbi == null) { 3182 requiredAbi = Build.SUPPORTED_ABIS[0]; 3183 } 3184 3185 String instructionSet = null; 3186 if (app.info.primaryCpuAbi != null) { 3187 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3188 } 3189 3190 // Start the process. It will either succeed and return a result containing 3191 // the PID of the new process, or else throw a RuntimeException. 3192 boolean isActivityProcess = (entryPoint == null); 3193 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3194 checkTime(startTime, "startProcess: asking zygote to start proc"); 3195 Process.ProcessStartResult startResult = Process.start(entryPoint, 3196 app.processName, uid, uid, gids, debugFlags, mountExternal, 3197 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3198 app.info.dataDir, entryPointArgs); 3199 checkTime(startTime, "startProcess: returned from zygote!"); 3200 3201 if (app.isolated) { 3202 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3203 } 3204 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3205 checkTime(startTime, "startProcess: done updating battery stats"); 3206 3207 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3208 UserHandle.getUserId(uid), startResult.pid, uid, 3209 app.processName, hostingType, 3210 hostingNameStr != null ? hostingNameStr : ""); 3211 3212 if (app.persistent) { 3213 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3214 } 3215 3216 checkTime(startTime, "startProcess: building log message"); 3217 StringBuilder buf = mStringBuilder; 3218 buf.setLength(0); 3219 buf.append("Start proc "); 3220 buf.append(app.processName); 3221 if (!isActivityProcess) { 3222 buf.append(" ["); 3223 buf.append(entryPoint); 3224 buf.append("]"); 3225 } 3226 buf.append(" for "); 3227 buf.append(hostingType); 3228 if (hostingNameStr != null) { 3229 buf.append(" "); 3230 buf.append(hostingNameStr); 3231 } 3232 buf.append(": pid="); 3233 buf.append(startResult.pid); 3234 buf.append(" uid="); 3235 buf.append(uid); 3236 buf.append(" gids={"); 3237 if (gids != null) { 3238 for (int gi=0; gi<gids.length; gi++) { 3239 if (gi != 0) buf.append(", "); 3240 buf.append(gids[gi]); 3241 3242 } 3243 } 3244 buf.append("}"); 3245 if (requiredAbi != null) { 3246 buf.append(" abi="); 3247 buf.append(requiredAbi); 3248 } 3249 Slog.i(TAG, buf.toString()); 3250 app.setPid(startResult.pid); 3251 app.usingWrapper = startResult.usingWrapper; 3252 app.removed = false; 3253 app.killed = false; 3254 app.killedByAm = false; 3255 checkTime(startTime, "startProcess: starting to update pids map"); 3256 synchronized (mPidsSelfLocked) { 3257 this.mPidsSelfLocked.put(startResult.pid, app); 3258 if (isActivityProcess) { 3259 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3260 msg.obj = app; 3261 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3262 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3263 } 3264 } 3265 checkTime(startTime, "startProcess: done updating pids map"); 3266 } catch (RuntimeException e) { 3267 // XXX do better error recovery. 3268 app.setPid(0); 3269 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3270 if (app.isolated) { 3271 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3272 } 3273 Slog.e(TAG, "Failure starting process " + app.processName, e); 3274 } 3275 } 3276 3277 void updateUsageStats(ActivityRecord component, boolean resumed) { 3278 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3279 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3280 if (resumed) { 3281 if (mUsageStatsService != null) { 3282 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3283 UsageEvents.Event.MOVE_TO_FOREGROUND); 3284 } 3285 synchronized (stats) { 3286 stats.noteActivityResumedLocked(component.app.uid); 3287 } 3288 } else { 3289 if (mUsageStatsService != null) { 3290 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3291 UsageEvents.Event.MOVE_TO_BACKGROUND); 3292 } 3293 synchronized (stats) { 3294 stats.noteActivityPausedLocked(component.app.uid); 3295 } 3296 } 3297 } 3298 3299 Intent getHomeIntent() { 3300 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3301 intent.setComponent(mTopComponent); 3302 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3303 intent.addCategory(Intent.CATEGORY_HOME); 3304 } 3305 return intent; 3306 } 3307 3308 boolean startHomeActivityLocked(int userId) { 3309 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3310 && mTopAction == null) { 3311 // We are running in factory test mode, but unable to find 3312 // the factory test app, so just sit around displaying the 3313 // error message and don't try to start anything. 3314 return false; 3315 } 3316 Intent intent = getHomeIntent(); 3317 ActivityInfo aInfo = 3318 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3319 if (aInfo != null) { 3320 intent.setComponent(new ComponentName( 3321 aInfo.applicationInfo.packageName, aInfo.name)); 3322 // Don't do this if the home app is currently being 3323 // instrumented. 3324 aInfo = new ActivityInfo(aInfo); 3325 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3326 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3327 aInfo.applicationInfo.uid, true); 3328 if (app == null || app.instrumentationClass == null) { 3329 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3330 mStackSupervisor.startHomeActivity(intent, aInfo); 3331 } 3332 } 3333 3334 return true; 3335 } 3336 3337 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3338 ActivityInfo ai = null; 3339 ComponentName comp = intent.getComponent(); 3340 try { 3341 if (comp != null) { 3342 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3343 } else { 3344 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3345 intent, 3346 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3347 flags, userId); 3348 3349 if (info != null) { 3350 ai = info.activityInfo; 3351 } 3352 } 3353 } catch (RemoteException e) { 3354 // ignore 3355 } 3356 3357 return ai; 3358 } 3359 3360 /** 3361 * Starts the "new version setup screen" if appropriate. 3362 */ 3363 void startSetupActivityLocked() { 3364 // Only do this once per boot. 3365 if (mCheckedForSetup) { 3366 return; 3367 } 3368 3369 // We will show this screen if the current one is a different 3370 // version than the last one shown, and we are not running in 3371 // low-level factory test mode. 3372 final ContentResolver resolver = mContext.getContentResolver(); 3373 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3374 Settings.Global.getInt(resolver, 3375 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3376 mCheckedForSetup = true; 3377 3378 // See if we should be showing the platform update setup UI. 3379 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3380 List<ResolveInfo> ris = mContext.getPackageManager() 3381 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3382 3383 // We don't allow third party apps to replace this. 3384 ResolveInfo ri = null; 3385 for (int i=0; ris != null && i<ris.size(); i++) { 3386 if ((ris.get(i).activityInfo.applicationInfo.flags 3387 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3388 ri = ris.get(i); 3389 break; 3390 } 3391 } 3392 3393 if (ri != null) { 3394 String vers = ri.activityInfo.metaData != null 3395 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3396 : null; 3397 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3398 vers = ri.activityInfo.applicationInfo.metaData.getString( 3399 Intent.METADATA_SETUP_VERSION); 3400 } 3401 String lastVers = Settings.Secure.getString( 3402 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3403 if (vers != null && !vers.equals(lastVers)) { 3404 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3405 intent.setComponent(new ComponentName( 3406 ri.activityInfo.packageName, ri.activityInfo.name)); 3407 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3408 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3409 null); 3410 } 3411 } 3412 } 3413 } 3414 3415 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3416 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3417 } 3418 3419 void enforceNotIsolatedCaller(String caller) { 3420 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3421 throw new SecurityException("Isolated process not allowed to call " + caller); 3422 } 3423 } 3424 3425 void enforceShellRestriction(String restriction, int userHandle) { 3426 if (Binder.getCallingUid() == Process.SHELL_UID) { 3427 if (userHandle < 0 3428 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3429 throw new SecurityException("Shell does not have permission to access user " 3430 + userHandle); 3431 } 3432 } 3433 } 3434 3435 @Override 3436 public int getFrontActivityScreenCompatMode() { 3437 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3438 synchronized (this) { 3439 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3440 } 3441 } 3442 3443 @Override 3444 public void setFrontActivityScreenCompatMode(int mode) { 3445 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3446 "setFrontActivityScreenCompatMode"); 3447 synchronized (this) { 3448 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3449 } 3450 } 3451 3452 @Override 3453 public int getPackageScreenCompatMode(String packageName) { 3454 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3455 synchronized (this) { 3456 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3457 } 3458 } 3459 3460 @Override 3461 public void setPackageScreenCompatMode(String packageName, int mode) { 3462 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3463 "setPackageScreenCompatMode"); 3464 synchronized (this) { 3465 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3466 } 3467 } 3468 3469 @Override 3470 public boolean getPackageAskScreenCompat(String packageName) { 3471 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3472 synchronized (this) { 3473 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3474 } 3475 } 3476 3477 @Override 3478 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3479 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3480 "setPackageAskScreenCompat"); 3481 synchronized (this) { 3482 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3483 } 3484 } 3485 3486 private void dispatchProcessesChanged() { 3487 int N; 3488 synchronized (this) { 3489 N = mPendingProcessChanges.size(); 3490 if (mActiveProcessChanges.length < N) { 3491 mActiveProcessChanges = new ProcessChangeItem[N]; 3492 } 3493 mPendingProcessChanges.toArray(mActiveProcessChanges); 3494 mAvailProcessChanges.addAll(mPendingProcessChanges); 3495 mPendingProcessChanges.clear(); 3496 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3497 } 3498 3499 int i = mProcessObservers.beginBroadcast(); 3500 while (i > 0) { 3501 i--; 3502 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3503 if (observer != null) { 3504 try { 3505 for (int j=0; j<N; j++) { 3506 ProcessChangeItem item = mActiveProcessChanges[j]; 3507 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3508 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3509 + item.pid + " uid=" + item.uid + ": " 3510 + item.foregroundActivities); 3511 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3512 item.foregroundActivities); 3513 } 3514 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3515 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3516 + item.pid + " uid=" + item.uid + ": " + item.processState); 3517 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3518 } 3519 } 3520 } catch (RemoteException e) { 3521 } 3522 } 3523 } 3524 mProcessObservers.finishBroadcast(); 3525 } 3526 3527 private void dispatchProcessDied(int pid, int uid) { 3528 int i = mProcessObservers.beginBroadcast(); 3529 while (i > 0) { 3530 i--; 3531 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3532 if (observer != null) { 3533 try { 3534 observer.onProcessDied(pid, uid); 3535 } catch (RemoteException e) { 3536 } 3537 } 3538 } 3539 mProcessObservers.finishBroadcast(); 3540 } 3541 3542 @Override 3543 public final int startActivity(IApplicationThread caller, String callingPackage, 3544 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3545 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3546 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3547 resultWho, requestCode, startFlags, profilerInfo, options, 3548 UserHandle.getCallingUserId()); 3549 } 3550 3551 @Override 3552 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3553 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3554 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3555 enforceNotIsolatedCaller("startActivity"); 3556 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3557 false, ALLOW_FULL_ONLY, "startActivity", null); 3558 // TODO: Switch to user app stacks here. 3559 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3560 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3561 profilerInfo, null, null, options, userId, null, null); 3562 } 3563 3564 @Override 3565 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3566 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3567 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3568 3569 // This is very dangerous -- it allows you to perform a start activity (including 3570 // permission grants) as any app that may launch one of your own activities. So 3571 // we will only allow this to be done from activities that are part of the core framework, 3572 // and then only when they are running as the system. 3573 final ActivityRecord sourceRecord; 3574 final int targetUid; 3575 final String targetPackage; 3576 synchronized (this) { 3577 if (resultTo == null) { 3578 throw new SecurityException("Must be called from an activity"); 3579 } 3580 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3581 if (sourceRecord == null) { 3582 throw new SecurityException("Called with bad activity token: " + resultTo); 3583 } 3584 if (!sourceRecord.info.packageName.equals("android")) { 3585 throw new SecurityException( 3586 "Must be called from an activity that is declared in the android package"); 3587 } 3588 if (sourceRecord.app == null) { 3589 throw new SecurityException("Called without a process attached to activity"); 3590 } 3591 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3592 // This is still okay, as long as this activity is running under the 3593 // uid of the original calling activity. 3594 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3595 throw new SecurityException( 3596 "Calling activity in uid " + sourceRecord.app.uid 3597 + " must be system uid or original calling uid " 3598 + sourceRecord.launchedFromUid); 3599 } 3600 } 3601 targetUid = sourceRecord.launchedFromUid; 3602 targetPackage = sourceRecord.launchedFromPackage; 3603 } 3604 3605 if (userId == UserHandle.USER_NULL) { 3606 userId = UserHandle.getUserId(sourceRecord.app.uid); 3607 } 3608 3609 // TODO: Switch to user app stacks here. 3610 try { 3611 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3612 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3613 null, null, options, userId, null, null); 3614 return ret; 3615 } catch (SecurityException e) { 3616 // XXX need to figure out how to propagate to original app. 3617 // A SecurityException here is generally actually a fault of the original 3618 // calling activity (such as a fairly granting permissions), so propagate it 3619 // back to them. 3620 /* 3621 StringBuilder msg = new StringBuilder(); 3622 msg.append("While launching"); 3623 msg.append(intent.toString()); 3624 msg.append(": "); 3625 msg.append(e.getMessage()); 3626 */ 3627 throw e; 3628 } 3629 } 3630 3631 @Override 3632 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3633 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3634 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3635 enforceNotIsolatedCaller("startActivityAndWait"); 3636 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3637 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3638 WaitResult res = new WaitResult(); 3639 // TODO: Switch to user app stacks here. 3640 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3641 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3642 options, userId, null, null); 3643 return res; 3644 } 3645 3646 @Override 3647 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3648 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3649 int startFlags, Configuration config, Bundle options, int userId) { 3650 enforceNotIsolatedCaller("startActivityWithConfig"); 3651 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3652 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3653 // TODO: Switch to user app stacks here. 3654 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3655 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3656 null, null, config, options, userId, null, null); 3657 return ret; 3658 } 3659 3660 @Override 3661 public int startActivityIntentSender(IApplicationThread caller, 3662 IntentSender intent, Intent fillInIntent, String resolvedType, 3663 IBinder resultTo, String resultWho, int requestCode, 3664 int flagsMask, int flagsValues, Bundle options) { 3665 enforceNotIsolatedCaller("startActivityIntentSender"); 3666 // Refuse possible leaked file descriptors 3667 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3668 throw new IllegalArgumentException("File descriptors passed in Intent"); 3669 } 3670 3671 IIntentSender sender = intent.getTarget(); 3672 if (!(sender instanceof PendingIntentRecord)) { 3673 throw new IllegalArgumentException("Bad PendingIntent object"); 3674 } 3675 3676 PendingIntentRecord pir = (PendingIntentRecord)sender; 3677 3678 synchronized (this) { 3679 // If this is coming from the currently resumed activity, it is 3680 // effectively saying that app switches are allowed at this point. 3681 final ActivityStack stack = getFocusedStack(); 3682 if (stack.mResumedActivity != null && 3683 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3684 mAppSwitchesAllowedTime = 0; 3685 } 3686 } 3687 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3688 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3689 return ret; 3690 } 3691 3692 @Override 3693 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3694 Intent intent, String resolvedType, IVoiceInteractionSession session, 3695 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3696 Bundle options, int userId) { 3697 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3698 != PackageManager.PERMISSION_GRANTED) { 3699 String msg = "Permission Denial: startVoiceActivity() from pid=" 3700 + Binder.getCallingPid() 3701 + ", uid=" + Binder.getCallingUid() 3702 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3703 Slog.w(TAG, msg); 3704 throw new SecurityException(msg); 3705 } 3706 if (session == null || interactor == null) { 3707 throw new NullPointerException("null session or interactor"); 3708 } 3709 userId = handleIncomingUser(callingPid, callingUid, userId, 3710 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3711 // TODO: Switch to user app stacks here. 3712 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3713 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3714 null, options, userId, null, null); 3715 } 3716 3717 @Override 3718 public boolean startNextMatchingActivity(IBinder callingActivity, 3719 Intent intent, Bundle options) { 3720 // Refuse possible leaked file descriptors 3721 if (intent != null && intent.hasFileDescriptors() == true) { 3722 throw new IllegalArgumentException("File descriptors passed in Intent"); 3723 } 3724 3725 synchronized (this) { 3726 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3727 if (r == null) { 3728 ActivityOptions.abort(options); 3729 return false; 3730 } 3731 if (r.app == null || r.app.thread == null) { 3732 // The caller is not running... d'oh! 3733 ActivityOptions.abort(options); 3734 return false; 3735 } 3736 intent = new Intent(intent); 3737 // The caller is not allowed to change the data. 3738 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3739 // And we are resetting to find the next component... 3740 intent.setComponent(null); 3741 3742 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3743 3744 ActivityInfo aInfo = null; 3745 try { 3746 List<ResolveInfo> resolves = 3747 AppGlobals.getPackageManager().queryIntentActivities( 3748 intent, r.resolvedType, 3749 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3750 UserHandle.getCallingUserId()); 3751 3752 // Look for the original activity in the list... 3753 final int N = resolves != null ? resolves.size() : 0; 3754 for (int i=0; i<N; i++) { 3755 ResolveInfo rInfo = resolves.get(i); 3756 if (rInfo.activityInfo.packageName.equals(r.packageName) 3757 && rInfo.activityInfo.name.equals(r.info.name)) { 3758 // We found the current one... the next matching is 3759 // after it. 3760 i++; 3761 if (i<N) { 3762 aInfo = resolves.get(i).activityInfo; 3763 } 3764 if (debug) { 3765 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3766 + "/" + r.info.name); 3767 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3768 + "/" + aInfo.name); 3769 } 3770 break; 3771 } 3772 } 3773 } catch (RemoteException e) { 3774 } 3775 3776 if (aInfo == null) { 3777 // Nobody who is next! 3778 ActivityOptions.abort(options); 3779 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3780 return false; 3781 } 3782 3783 intent.setComponent(new ComponentName( 3784 aInfo.applicationInfo.packageName, aInfo.name)); 3785 intent.setFlags(intent.getFlags()&~( 3786 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3787 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3788 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3789 Intent.FLAG_ACTIVITY_NEW_TASK)); 3790 3791 // Okay now we need to start the new activity, replacing the 3792 // currently running activity. This is a little tricky because 3793 // we want to start the new one as if the current one is finished, 3794 // but not finish the current one first so that there is no flicker. 3795 // And thus... 3796 final boolean wasFinishing = r.finishing; 3797 r.finishing = true; 3798 3799 // Propagate reply information over to the new activity. 3800 final ActivityRecord resultTo = r.resultTo; 3801 final String resultWho = r.resultWho; 3802 final int requestCode = r.requestCode; 3803 r.resultTo = null; 3804 if (resultTo != null) { 3805 resultTo.removeResultsLocked(r, resultWho, requestCode); 3806 } 3807 3808 final long origId = Binder.clearCallingIdentity(); 3809 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3810 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3811 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3812 -1, r.launchedFromUid, 0, options, false, null, null, null); 3813 Binder.restoreCallingIdentity(origId); 3814 3815 r.finishing = wasFinishing; 3816 if (res != ActivityManager.START_SUCCESS) { 3817 return false; 3818 } 3819 return true; 3820 } 3821 } 3822 3823 @Override 3824 public final int startActivityFromRecents(int taskId, Bundle options) { 3825 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3826 String msg = "Permission Denial: startActivityFromRecents called without " + 3827 START_TASKS_FROM_RECENTS; 3828 Slog.w(TAG, msg); 3829 throw new SecurityException(msg); 3830 } 3831 return startActivityFromRecentsInner(taskId, options); 3832 } 3833 3834 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3835 final TaskRecord task; 3836 final int callingUid; 3837 final String callingPackage; 3838 final Intent intent; 3839 final int userId; 3840 synchronized (this) { 3841 task = recentTaskForIdLocked(taskId); 3842 if (task == null) { 3843 throw new IllegalArgumentException("Task " + taskId + " not found."); 3844 } 3845 callingUid = task.mCallingUid; 3846 callingPackage = task.mCallingPackage; 3847 intent = task.intent; 3848 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3849 userId = task.userId; 3850 } 3851 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3852 options, userId, null, task); 3853 } 3854 3855 final int startActivityInPackage(int uid, String callingPackage, 3856 Intent intent, String resolvedType, IBinder resultTo, 3857 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3858 IActivityContainer container, TaskRecord inTask) { 3859 3860 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3861 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3862 3863 // TODO: Switch to user app stacks here. 3864 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3865 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3866 null, null, null, options, userId, container, inTask); 3867 return ret; 3868 } 3869 3870 @Override 3871 public final int startActivities(IApplicationThread caller, String callingPackage, 3872 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3873 int userId) { 3874 enforceNotIsolatedCaller("startActivities"); 3875 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3876 false, ALLOW_FULL_ONLY, "startActivity", null); 3877 // TODO: Switch to user app stacks here. 3878 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3879 resolvedTypes, resultTo, options, userId); 3880 return ret; 3881 } 3882 3883 final int startActivitiesInPackage(int uid, String callingPackage, 3884 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3885 Bundle options, int userId) { 3886 3887 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3888 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3889 // TODO: Switch to user app stacks here. 3890 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3891 resultTo, options, userId); 3892 return ret; 3893 } 3894 3895 //explicitly remove thd old information in mRecentTasks when removing existing user. 3896 private void removeRecentTasksForUserLocked(int userId) { 3897 if(userId <= 0) { 3898 Slog.i(TAG, "Can't remove recent task on user " + userId); 3899 return; 3900 } 3901 3902 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3903 TaskRecord tr = mRecentTasks.get(i); 3904 if (tr.userId == userId) { 3905 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3906 + " when finishing user" + userId); 3907 mRecentTasks.remove(i); 3908 tr.removedFromRecents(mTaskPersister); 3909 } 3910 } 3911 3912 // Remove tasks from persistent storage. 3913 mTaskPersister.wakeup(null, true); 3914 } 3915 3916 // Sort by taskId 3917 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3918 @Override 3919 public int compare(TaskRecord lhs, TaskRecord rhs) { 3920 return rhs.taskId - lhs.taskId; 3921 } 3922 }; 3923 3924 // Extract the affiliates of the chain containing mRecentTasks[start]. 3925 private int processNextAffiliateChain(int start) { 3926 final TaskRecord startTask = mRecentTasks.get(start); 3927 final int affiliateId = startTask.mAffiliatedTaskId; 3928 3929 // Quick identification of isolated tasks. I.e. those not launched behind. 3930 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3931 startTask.mNextAffiliate == null) { 3932 // There is still a slim chance that there are other tasks that point to this task 3933 // and that the chain is so messed up that this task no longer points to them but 3934 // the gain of this optimization outweighs the risk. 3935 startTask.inRecents = true; 3936 return start + 1; 3937 } 3938 3939 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3940 mTmpRecents.clear(); 3941 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3942 final TaskRecord task = mRecentTasks.get(i); 3943 if (task.mAffiliatedTaskId == affiliateId) { 3944 mRecentTasks.remove(i); 3945 mTmpRecents.add(task); 3946 } 3947 } 3948 3949 // Sort them all by taskId. That is the order they were create in and that order will 3950 // always be correct. 3951 Collections.sort(mTmpRecents, mTaskRecordComparator); 3952 3953 // Go through and fix up the linked list. 3954 // The first one is the end of the chain and has no next. 3955 final TaskRecord first = mTmpRecents.get(0); 3956 first.inRecents = true; 3957 if (first.mNextAffiliate != null) { 3958 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3959 first.setNextAffiliate(null); 3960 mTaskPersister.wakeup(first, false); 3961 } 3962 // Everything in the middle is doubly linked from next to prev. 3963 final int tmpSize = mTmpRecents.size(); 3964 for (int i = 0; i < tmpSize - 1; ++i) { 3965 final TaskRecord next = mTmpRecents.get(i); 3966 final TaskRecord prev = mTmpRecents.get(i + 1); 3967 if (next.mPrevAffiliate != prev) { 3968 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3969 " setting prev=" + prev); 3970 next.setPrevAffiliate(prev); 3971 mTaskPersister.wakeup(next, false); 3972 } 3973 if (prev.mNextAffiliate != next) { 3974 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3975 " setting next=" + next); 3976 prev.setNextAffiliate(next); 3977 mTaskPersister.wakeup(prev, false); 3978 } 3979 prev.inRecents = true; 3980 } 3981 // The last one is the beginning of the list and has no prev. 3982 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3983 if (last.mPrevAffiliate != null) { 3984 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3985 last.setPrevAffiliate(null); 3986 mTaskPersister.wakeup(last, false); 3987 } 3988 3989 // Insert the group back into mRecentTasks at start. 3990 mRecentTasks.addAll(start, mTmpRecents); 3991 3992 // Let the caller know where we left off. 3993 return start + tmpSize; 3994 } 3995 3996 /** 3997 * Update the recent tasks lists: make sure tasks should still be here (their 3998 * applications / activities still exist), update their availability, fixup ordering 3999 * of affiliations. 4000 */ 4001 void cleanupRecentTasksLocked(int userId) { 4002 if (mRecentTasks == null) { 4003 // Happens when called from the packagemanager broadcast before boot. 4004 return; 4005 } 4006 4007 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4008 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4009 final IPackageManager pm = AppGlobals.getPackageManager(); 4010 final ActivityInfo dummyAct = new ActivityInfo(); 4011 final ApplicationInfo dummyApp = new ApplicationInfo(); 4012 4013 int N = mRecentTasks.size(); 4014 4015 int[] users = userId == UserHandle.USER_ALL 4016 ? getUsersLocked() : new int[] { userId }; 4017 for (int user : users) { 4018 for (int i = 0; i < N; i++) { 4019 TaskRecord task = mRecentTasks.get(i); 4020 if (task.userId != user) { 4021 // Only look at tasks for the user ID of interest. 4022 continue; 4023 } 4024 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4025 // This situation is broken, and we should just get rid of it now. 4026 mRecentTasks.remove(i); 4027 task.removedFromRecents(mTaskPersister); 4028 i--; 4029 N--; 4030 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4031 continue; 4032 } 4033 // Check whether this activity is currently available. 4034 if (task.realActivity != null) { 4035 ActivityInfo ai = availActCache.get(task.realActivity); 4036 if (ai == null) { 4037 try { 4038 ai = pm.getActivityInfo(task.realActivity, 4039 PackageManager.GET_UNINSTALLED_PACKAGES 4040 | PackageManager.GET_DISABLED_COMPONENTS, user); 4041 } catch (RemoteException e) { 4042 // Will never happen. 4043 continue; 4044 } 4045 if (ai == null) { 4046 ai = dummyAct; 4047 } 4048 availActCache.put(task.realActivity, ai); 4049 } 4050 if (ai == dummyAct) { 4051 // This could be either because the activity no longer exists, or the 4052 // app is temporarily gone. For the former we want to remove the recents 4053 // entry; for the latter we want to mark it as unavailable. 4054 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4055 if (app == null) { 4056 try { 4057 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4058 PackageManager.GET_UNINSTALLED_PACKAGES 4059 | PackageManager.GET_DISABLED_COMPONENTS, user); 4060 } catch (RemoteException e) { 4061 // Will never happen. 4062 continue; 4063 } 4064 if (app == null) { 4065 app = dummyApp; 4066 } 4067 availAppCache.put(task.realActivity.getPackageName(), app); 4068 } 4069 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4070 // Doesn't exist any more! Good-bye. 4071 mRecentTasks.remove(i); 4072 task.removedFromRecents(mTaskPersister); 4073 i--; 4074 N--; 4075 Slog.w(TAG, "Removing no longer valid recent: " + task); 4076 continue; 4077 } else { 4078 // Otherwise just not available for now. 4079 if (task.isAvailable) { 4080 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4081 + task); 4082 } 4083 task.isAvailable = false; 4084 } 4085 } else { 4086 if (!ai.enabled || !ai.applicationInfo.enabled 4087 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4088 if (task.isAvailable) { 4089 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4090 + task + " (enabled=" + ai.enabled + "/" 4091 + ai.applicationInfo.enabled + " flags=" 4092 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4093 } 4094 task.isAvailable = false; 4095 } else { 4096 if (!task.isAvailable) { 4097 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4098 + task); 4099 } 4100 task.isAvailable = true; 4101 } 4102 } 4103 } 4104 } 4105 } 4106 4107 // Verify the affiliate chain for each task. 4108 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4109 } 4110 4111 mTmpRecents.clear(); 4112 // mRecentTasks is now in sorted, affiliated order. 4113 } 4114 4115 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4116 int N = mRecentTasks.size(); 4117 TaskRecord top = task; 4118 int topIndex = taskIndex; 4119 while (top.mNextAffiliate != null && topIndex > 0) { 4120 top = top.mNextAffiliate; 4121 topIndex--; 4122 } 4123 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4124 + topIndex + " from intial " + taskIndex); 4125 // Find the end of the chain, doing a sanity check along the way. 4126 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4127 int endIndex = topIndex; 4128 TaskRecord prev = top; 4129 while (endIndex < N) { 4130 TaskRecord cur = mRecentTasks.get(endIndex); 4131 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4132 + endIndex + " " + cur); 4133 if (cur == top) { 4134 // Verify start of the chain. 4135 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4136 Slog.wtf(TAG, "Bad chain @" + endIndex 4137 + ": first task has next affiliate: " + prev); 4138 sane = false; 4139 break; 4140 } 4141 } else { 4142 // Verify middle of the chain's next points back to the one before. 4143 if (cur.mNextAffiliate != prev 4144 || cur.mNextAffiliateTaskId != prev.taskId) { 4145 Slog.wtf(TAG, "Bad chain @" + endIndex 4146 + ": middle task " + cur + " @" + endIndex 4147 + " has bad next affiliate " 4148 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4149 + ", expected " + prev); 4150 sane = false; 4151 break; 4152 } 4153 } 4154 if (cur.mPrevAffiliateTaskId == -1) { 4155 // Chain ends here. 4156 if (cur.mPrevAffiliate != null) { 4157 Slog.wtf(TAG, "Bad chain @" + endIndex 4158 + ": last task " + cur + " has previous affiliate " 4159 + cur.mPrevAffiliate); 4160 sane = false; 4161 } 4162 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4163 break; 4164 } else { 4165 // Verify middle of the chain's prev points to a valid item. 4166 if (cur.mPrevAffiliate == null) { 4167 Slog.wtf(TAG, "Bad chain @" + endIndex 4168 + ": task " + cur + " has previous affiliate " 4169 + cur.mPrevAffiliate + " but should be id " 4170 + cur.mPrevAffiliate); 4171 sane = false; 4172 break; 4173 } 4174 } 4175 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4176 Slog.wtf(TAG, "Bad chain @" + endIndex 4177 + ": task " + cur + " has affiliated id " 4178 + cur.mAffiliatedTaskId + " but should be " 4179 + task.mAffiliatedTaskId); 4180 sane = false; 4181 break; 4182 } 4183 prev = cur; 4184 endIndex++; 4185 if (endIndex >= N) { 4186 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4187 + ": last task " + prev); 4188 sane = false; 4189 break; 4190 } 4191 } 4192 if (sane) { 4193 if (endIndex < taskIndex) { 4194 Slog.wtf(TAG, "Bad chain @" + endIndex 4195 + ": did not extend to task " + task + " @" + taskIndex); 4196 sane = false; 4197 } 4198 } 4199 if (sane) { 4200 // All looks good, we can just move all of the affiliated tasks 4201 // to the top. 4202 for (int i=topIndex; i<=endIndex; i++) { 4203 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4204 + " from " + i + " to " + (i-topIndex)); 4205 TaskRecord cur = mRecentTasks.remove(i); 4206 mRecentTasks.add(i-topIndex, cur); 4207 } 4208 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4209 + " to " + endIndex); 4210 return true; 4211 } 4212 4213 // Whoops, couldn't do it. 4214 return false; 4215 } 4216 4217 final void addRecentTaskLocked(TaskRecord task) { 4218 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4219 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4220 4221 int N = mRecentTasks.size(); 4222 // Quick case: check if the top-most recent task is the same. 4223 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4224 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4225 return; 4226 } 4227 // Another quick case: check if this is part of a set of affiliated 4228 // tasks that are at the top. 4229 if (isAffiliated && N > 0 && task.inRecents 4230 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4231 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4232 + " at top when adding " + task); 4233 return; 4234 } 4235 // Another quick case: never add voice sessions. 4236 if (task.voiceSession != null) { 4237 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4238 return; 4239 } 4240 4241 boolean needAffiliationFix = false; 4242 4243 // Slightly less quick case: the task is already in recents, so all we need 4244 // to do is move it. 4245 if (task.inRecents) { 4246 int taskIndex = mRecentTasks.indexOf(task); 4247 if (taskIndex >= 0) { 4248 if (!isAffiliated) { 4249 // Simple case: this is not an affiliated task, so we just move it to the front. 4250 mRecentTasks.remove(taskIndex); 4251 mRecentTasks.add(0, task); 4252 notifyTaskPersisterLocked(task, false); 4253 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4254 + " from " + taskIndex); 4255 return; 4256 } else { 4257 // More complicated: need to keep all affiliated tasks together. 4258 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4259 // All went well. 4260 return; 4261 } 4262 4263 // Uh oh... something bad in the affiliation chain, try to rebuild 4264 // everything and then go through our general path of adding a new task. 4265 needAffiliationFix = true; 4266 } 4267 } else { 4268 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4269 needAffiliationFix = true; 4270 } 4271 } 4272 4273 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4274 trimRecentsForTask(task, true); 4275 4276 N = mRecentTasks.size(); 4277 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4278 final TaskRecord tr = mRecentTasks.remove(N - 1); 4279 tr.removedFromRecents(mTaskPersister); 4280 N--; 4281 } 4282 task.inRecents = true; 4283 if (!isAffiliated || needAffiliationFix) { 4284 // If this is a simple non-affiliated task, or we had some failure trying to 4285 // handle it as part of an affilated task, then just place it at the top. 4286 mRecentTasks.add(0, task); 4287 } else if (isAffiliated) { 4288 // If this is a new affiliated task, then move all of the affiliated tasks 4289 // to the front and insert this new one. 4290 TaskRecord other = task.mNextAffiliate; 4291 if (other == null) { 4292 other = task.mPrevAffiliate; 4293 } 4294 if (other != null) { 4295 int otherIndex = mRecentTasks.indexOf(other); 4296 if (otherIndex >= 0) { 4297 // Insert new task at appropriate location. 4298 int taskIndex; 4299 if (other == task.mNextAffiliate) { 4300 // We found the index of our next affiliation, which is who is 4301 // before us in the list, so add after that point. 4302 taskIndex = otherIndex+1; 4303 } else { 4304 // We found the index of our previous affiliation, which is who is 4305 // after us in the list, so add at their position. 4306 taskIndex = otherIndex; 4307 } 4308 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4309 + taskIndex + ": " + task); 4310 mRecentTasks.add(taskIndex, task); 4311 4312 // Now move everything to the front. 4313 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4314 // All went well. 4315 return; 4316 } 4317 4318 // Uh oh... something bad in the affiliation chain, try to rebuild 4319 // everything and then go through our general path of adding a new task. 4320 needAffiliationFix = true; 4321 } else { 4322 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4323 + other); 4324 needAffiliationFix = true; 4325 } 4326 } else { 4327 if (DEBUG_RECENTS) Slog.d(TAG, 4328 "addRecent: adding affiliated task without next/prev:" + task); 4329 needAffiliationFix = true; 4330 } 4331 } 4332 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4333 4334 if (needAffiliationFix) { 4335 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4336 cleanupRecentTasksLocked(task.userId); 4337 } 4338 } 4339 4340 /** 4341 * If needed, remove oldest existing entries in recents that are for the same kind 4342 * of task as the given one. 4343 */ 4344 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4345 int N = mRecentTasks.size(); 4346 final Intent intent = task.intent; 4347 final boolean document = intent != null && intent.isDocument(); 4348 4349 int maxRecents = task.maxRecents - 1; 4350 for (int i=0; i<N; i++) { 4351 final TaskRecord tr = mRecentTasks.get(i); 4352 if (task != tr) { 4353 if (task.userId != tr.userId) { 4354 continue; 4355 } 4356 if (i > MAX_RECENT_BITMAPS) { 4357 tr.freeLastThumbnail(); 4358 } 4359 final Intent trIntent = tr.intent; 4360 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4361 (intent == null || !intent.filterEquals(trIntent))) { 4362 continue; 4363 } 4364 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4365 if (document && trIsDocument) { 4366 // These are the same document activity (not necessarily the same doc). 4367 if (maxRecents > 0) { 4368 --maxRecents; 4369 continue; 4370 } 4371 // Hit the maximum number of documents for this task. Fall through 4372 // and remove this document from recents. 4373 } else if (document || trIsDocument) { 4374 // Only one of these is a document. Not the droid we're looking for. 4375 continue; 4376 } 4377 } 4378 4379 if (!doTrim) { 4380 // If the caller is not actually asking for a trim, just tell them we reached 4381 // a point where the trim would happen. 4382 return i; 4383 } 4384 4385 // Either task and tr are the same or, their affinities match or their intents match 4386 // and neither of them is a document, or they are documents using the same activity 4387 // and their maxRecents has been reached. 4388 tr.disposeThumbnail(); 4389 mRecentTasks.remove(i); 4390 if (task != tr) { 4391 tr.removedFromRecents(mTaskPersister); 4392 } 4393 i--; 4394 N--; 4395 if (task.intent == null) { 4396 // If the new recent task we are adding is not fully 4397 // specified, then replace it with the existing recent task. 4398 task = tr; 4399 } 4400 notifyTaskPersisterLocked(tr, false); 4401 } 4402 4403 return -1; 4404 } 4405 4406 @Override 4407 public void reportActivityFullyDrawn(IBinder token) { 4408 synchronized (this) { 4409 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4410 if (r == null) { 4411 return; 4412 } 4413 r.reportFullyDrawnLocked(); 4414 } 4415 } 4416 4417 @Override 4418 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4419 synchronized (this) { 4420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4421 if (r == null) { 4422 return; 4423 } 4424 final long origId = Binder.clearCallingIdentity(); 4425 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4426 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4427 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4428 if (config != null) { 4429 r.frozenBeforeDestroy = true; 4430 if (!updateConfigurationLocked(config, r, false, false)) { 4431 mStackSupervisor.resumeTopActivitiesLocked(); 4432 } 4433 } 4434 Binder.restoreCallingIdentity(origId); 4435 } 4436 } 4437 4438 @Override 4439 public int getRequestedOrientation(IBinder token) { 4440 synchronized (this) { 4441 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4442 if (r == null) { 4443 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4444 } 4445 return mWindowManager.getAppOrientation(r.appToken); 4446 } 4447 } 4448 4449 /** 4450 * This is the internal entry point for handling Activity.finish(). 4451 * 4452 * @param token The Binder token referencing the Activity we want to finish. 4453 * @param resultCode Result code, if any, from this Activity. 4454 * @param resultData Result data (Intent), if any, from this Activity. 4455 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4456 * the root Activity in the task. 4457 * 4458 * @return Returns true if the activity successfully finished, or false if it is still running. 4459 */ 4460 @Override 4461 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4462 boolean finishTask) { 4463 // Refuse possible leaked file descriptors 4464 if (resultData != null && resultData.hasFileDescriptors() == true) { 4465 throw new IllegalArgumentException("File descriptors passed in Intent"); 4466 } 4467 4468 synchronized(this) { 4469 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4470 if (r == null) { 4471 return true; 4472 } 4473 // Keep track of the root activity of the task before we finish it 4474 TaskRecord tr = r.task; 4475 ActivityRecord rootR = tr.getRootActivity(); 4476 // Do not allow task to finish in Lock Task mode. 4477 if (tr == mStackSupervisor.mLockTaskModeTask) { 4478 if (rootR == r) { 4479 mStackSupervisor.showLockTaskToast(); 4480 return false; 4481 } 4482 } 4483 if (mController != null) { 4484 // Find the first activity that is not finishing. 4485 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4486 if (next != null) { 4487 // ask watcher if this is allowed 4488 boolean resumeOK = true; 4489 try { 4490 resumeOK = mController.activityResuming(next.packageName); 4491 } catch (RemoteException e) { 4492 mController = null; 4493 Watchdog.getInstance().setActivityController(null); 4494 } 4495 4496 if (!resumeOK) { 4497 return false; 4498 } 4499 } 4500 } 4501 final long origId = Binder.clearCallingIdentity(); 4502 try { 4503 boolean res; 4504 if (finishTask && r == rootR) { 4505 // If requested, remove the task that is associated to this activity only if it 4506 // was the root activity in the task. The result code and data is ignored because 4507 // we don't support returning them across task boundaries. 4508 res = removeTaskByIdLocked(tr.taskId, 0); 4509 } else { 4510 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4511 resultData, "app-request", true); 4512 } 4513 return res; 4514 } finally { 4515 Binder.restoreCallingIdentity(origId); 4516 } 4517 } 4518 } 4519 4520 @Override 4521 public final void finishHeavyWeightApp() { 4522 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4523 != PackageManager.PERMISSION_GRANTED) { 4524 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4525 + Binder.getCallingPid() 4526 + ", uid=" + Binder.getCallingUid() 4527 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4528 Slog.w(TAG, msg); 4529 throw new SecurityException(msg); 4530 } 4531 4532 synchronized(this) { 4533 if (mHeavyWeightProcess == null) { 4534 return; 4535 } 4536 4537 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4538 mHeavyWeightProcess.activities); 4539 for (int i=0; i<activities.size(); i++) { 4540 ActivityRecord r = activities.get(i); 4541 if (!r.finishing) { 4542 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4543 null, "finish-heavy", true); 4544 } 4545 } 4546 4547 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4548 mHeavyWeightProcess.userId, 0)); 4549 mHeavyWeightProcess = null; 4550 } 4551 } 4552 4553 @Override 4554 public void crashApplication(int uid, int initialPid, String packageName, 4555 String message) { 4556 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4557 != PackageManager.PERMISSION_GRANTED) { 4558 String msg = "Permission Denial: crashApplication() from pid=" 4559 + Binder.getCallingPid() 4560 + ", uid=" + Binder.getCallingUid() 4561 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4562 Slog.w(TAG, msg); 4563 throw new SecurityException(msg); 4564 } 4565 4566 synchronized(this) { 4567 ProcessRecord proc = null; 4568 4569 // Figure out which process to kill. We don't trust that initialPid 4570 // still has any relation to current pids, so must scan through the 4571 // list. 4572 synchronized (mPidsSelfLocked) { 4573 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4574 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4575 if (p.uid != uid) { 4576 continue; 4577 } 4578 if (p.pid == initialPid) { 4579 proc = p; 4580 break; 4581 } 4582 if (p.pkgList.containsKey(packageName)) { 4583 proc = p; 4584 } 4585 } 4586 } 4587 4588 if (proc == null) { 4589 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4590 + " initialPid=" + initialPid 4591 + " packageName=" + packageName); 4592 return; 4593 } 4594 4595 if (proc.thread != null) { 4596 if (proc.pid == Process.myPid()) { 4597 Log.w(TAG, "crashApplication: trying to crash self!"); 4598 return; 4599 } 4600 long ident = Binder.clearCallingIdentity(); 4601 try { 4602 proc.thread.scheduleCrash(message); 4603 } catch (RemoteException e) { 4604 } 4605 Binder.restoreCallingIdentity(ident); 4606 } 4607 } 4608 } 4609 4610 @Override 4611 public final void finishSubActivity(IBinder token, String resultWho, 4612 int requestCode) { 4613 synchronized(this) { 4614 final long origId = Binder.clearCallingIdentity(); 4615 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4616 if (r != null) { 4617 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4618 } 4619 Binder.restoreCallingIdentity(origId); 4620 } 4621 } 4622 4623 @Override 4624 public boolean finishActivityAffinity(IBinder token) { 4625 synchronized(this) { 4626 final long origId = Binder.clearCallingIdentity(); 4627 try { 4628 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4629 4630 ActivityRecord rootR = r.task.getRootActivity(); 4631 // Do not allow task to finish in Lock Task mode. 4632 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4633 if (rootR == r) { 4634 mStackSupervisor.showLockTaskToast(); 4635 return false; 4636 } 4637 } 4638 boolean res = false; 4639 if (r != null) { 4640 res = r.task.stack.finishActivityAffinityLocked(r); 4641 } 4642 return res; 4643 } finally { 4644 Binder.restoreCallingIdentity(origId); 4645 } 4646 } 4647 } 4648 4649 @Override 4650 public void finishVoiceTask(IVoiceInteractionSession session) { 4651 synchronized(this) { 4652 final long origId = Binder.clearCallingIdentity(); 4653 try { 4654 mStackSupervisor.finishVoiceTask(session); 4655 } finally { 4656 Binder.restoreCallingIdentity(origId); 4657 } 4658 } 4659 4660 } 4661 4662 @Override 4663 public boolean releaseActivityInstance(IBinder token) { 4664 synchronized(this) { 4665 final long origId = Binder.clearCallingIdentity(); 4666 try { 4667 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4668 if (r.task == null || r.task.stack == null) { 4669 return false; 4670 } 4671 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4672 } finally { 4673 Binder.restoreCallingIdentity(origId); 4674 } 4675 } 4676 } 4677 4678 @Override 4679 public void releaseSomeActivities(IApplicationThread appInt) { 4680 synchronized(this) { 4681 final long origId = Binder.clearCallingIdentity(); 4682 try { 4683 ProcessRecord app = getRecordForAppLocked(appInt); 4684 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4685 } finally { 4686 Binder.restoreCallingIdentity(origId); 4687 } 4688 } 4689 } 4690 4691 @Override 4692 public boolean willActivityBeVisible(IBinder token) { 4693 synchronized(this) { 4694 ActivityStack stack = ActivityRecord.getStackLocked(token); 4695 if (stack != null) { 4696 return stack.willActivityBeVisibleLocked(token); 4697 } 4698 return false; 4699 } 4700 } 4701 4702 @Override 4703 public void overridePendingTransition(IBinder token, String packageName, 4704 int enterAnim, int exitAnim) { 4705 synchronized(this) { 4706 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4707 if (self == null) { 4708 return; 4709 } 4710 4711 final long origId = Binder.clearCallingIdentity(); 4712 4713 if (self.state == ActivityState.RESUMED 4714 || self.state == ActivityState.PAUSING) { 4715 mWindowManager.overridePendingAppTransition(packageName, 4716 enterAnim, exitAnim, null); 4717 } 4718 4719 Binder.restoreCallingIdentity(origId); 4720 } 4721 } 4722 4723 /** 4724 * Main function for removing an existing process from the activity manager 4725 * as a result of that process going away. Clears out all connections 4726 * to the process. 4727 */ 4728 private final void handleAppDiedLocked(ProcessRecord app, 4729 boolean restarting, boolean allowRestart) { 4730 int pid = app.pid; 4731 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4732 if (!kept && !restarting) { 4733 removeLruProcessLocked(app); 4734 if (pid > 0) { 4735 ProcessList.remove(pid); 4736 } 4737 } 4738 4739 if (mProfileProc == app) { 4740 clearProfilerLocked(); 4741 } 4742 4743 // Remove this application's activities from active lists. 4744 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4745 4746 app.activities.clear(); 4747 4748 if (app.instrumentationClass != null) { 4749 Slog.w(TAG, "Crash of app " + app.processName 4750 + " running instrumentation " + app.instrumentationClass); 4751 Bundle info = new Bundle(); 4752 info.putString("shortMsg", "Process crashed."); 4753 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4754 } 4755 4756 if (!restarting) { 4757 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4758 // If there was nothing to resume, and we are not already 4759 // restarting this process, but there is a visible activity that 4760 // is hosted by the process... then make sure all visible 4761 // activities are running, taking care of restarting this 4762 // process. 4763 if (hasVisibleActivities) { 4764 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4765 } 4766 } 4767 } 4768 } 4769 4770 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4771 IBinder threadBinder = thread.asBinder(); 4772 // Find the application record. 4773 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4774 ProcessRecord rec = mLruProcesses.get(i); 4775 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4776 return i; 4777 } 4778 } 4779 return -1; 4780 } 4781 4782 final ProcessRecord getRecordForAppLocked( 4783 IApplicationThread thread) { 4784 if (thread == null) { 4785 return null; 4786 } 4787 4788 int appIndex = getLRURecordIndexForAppLocked(thread); 4789 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4790 } 4791 4792 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4793 // If there are no longer any background processes running, 4794 // and the app that died was not running instrumentation, 4795 // then tell everyone we are now low on memory. 4796 boolean haveBg = false; 4797 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4798 ProcessRecord rec = mLruProcesses.get(i); 4799 if (rec.thread != null 4800 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4801 haveBg = true; 4802 break; 4803 } 4804 } 4805 4806 if (!haveBg) { 4807 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4808 if (doReport) { 4809 long now = SystemClock.uptimeMillis(); 4810 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4811 doReport = false; 4812 } else { 4813 mLastMemUsageReportTime = now; 4814 } 4815 } 4816 final ArrayList<ProcessMemInfo> memInfos 4817 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4818 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4819 long now = SystemClock.uptimeMillis(); 4820 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4821 ProcessRecord rec = mLruProcesses.get(i); 4822 if (rec == dyingProc || rec.thread == null) { 4823 continue; 4824 } 4825 if (doReport) { 4826 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4827 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4828 } 4829 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4830 // The low memory report is overriding any current 4831 // state for a GC request. Make sure to do 4832 // heavy/important/visible/foreground processes first. 4833 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4834 rec.lastRequestedGc = 0; 4835 } else { 4836 rec.lastRequestedGc = rec.lastLowMemory; 4837 } 4838 rec.reportLowMemory = true; 4839 rec.lastLowMemory = now; 4840 mProcessesToGc.remove(rec); 4841 addProcessToGcListLocked(rec); 4842 } 4843 } 4844 if (doReport) { 4845 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4846 mHandler.sendMessage(msg); 4847 } 4848 scheduleAppGcsLocked(); 4849 } 4850 } 4851 4852 final void appDiedLocked(ProcessRecord app) { 4853 appDiedLocked(app, app.pid, app.thread); 4854 } 4855 4856 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4857 // First check if this ProcessRecord is actually active for the pid. 4858 synchronized (mPidsSelfLocked) { 4859 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4860 if (curProc != app) { 4861 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4862 return; 4863 } 4864 } 4865 4866 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4867 synchronized (stats) { 4868 stats.noteProcessDiedLocked(app.info.uid, pid); 4869 } 4870 4871 Process.killProcessQuiet(pid); 4872 Process.killProcessGroup(app.info.uid, pid); 4873 app.killed = true; 4874 4875 // Clean up already done if the process has been re-started. 4876 if (app.pid == pid && app.thread != null && 4877 app.thread.asBinder() == thread.asBinder()) { 4878 boolean doLowMem = app.instrumentationClass == null; 4879 boolean doOomAdj = doLowMem; 4880 if (!app.killedByAm) { 4881 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4882 + ") has died"); 4883 mAllowLowerMemLevel = true; 4884 } else { 4885 // Note that we always want to do oom adj to update our state with the 4886 // new number of procs. 4887 mAllowLowerMemLevel = false; 4888 doLowMem = false; 4889 } 4890 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4891 if (DEBUG_CLEANUP) Slog.v( 4892 TAG, "Dying app: " + app + ", pid: " + pid 4893 + ", thread: " + thread.asBinder()); 4894 handleAppDiedLocked(app, false, true); 4895 4896 if (doOomAdj) { 4897 updateOomAdjLocked(); 4898 } 4899 if (doLowMem) { 4900 doLowMemReportIfNeededLocked(app); 4901 } 4902 } else if (app.pid != pid) { 4903 // A new process has already been started. 4904 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4905 + ") has died and restarted (pid " + app.pid + ")."); 4906 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4907 } else if (DEBUG_PROCESSES) { 4908 Slog.d(TAG, "Received spurious death notification for thread " 4909 + thread.asBinder()); 4910 } 4911 } 4912 4913 /** 4914 * If a stack trace dump file is configured, dump process stack traces. 4915 * @param clearTraces causes the dump file to be erased prior to the new 4916 * traces being written, if true; when false, the new traces will be 4917 * appended to any existing file content. 4918 * @param firstPids of dalvik VM processes to dump stack traces for first 4919 * @param lastPids of dalvik VM processes to dump stack traces for last 4920 * @param nativeProcs optional list of native process names to dump stack crawls 4921 * @return file containing stack traces, or null if no dump file is configured 4922 */ 4923 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4924 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4925 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4926 if (tracesPath == null || tracesPath.length() == 0) { 4927 return null; 4928 } 4929 4930 File tracesFile = new File(tracesPath); 4931 try { 4932 File tracesDir = tracesFile.getParentFile(); 4933 if (!tracesDir.exists()) { 4934 tracesDir.mkdirs(); 4935 if (!SELinux.restorecon(tracesDir)) { 4936 return null; 4937 } 4938 } 4939 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4940 4941 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4942 tracesFile.createNewFile(); 4943 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4944 } catch (IOException e) { 4945 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4946 return null; 4947 } 4948 4949 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4950 return tracesFile; 4951 } 4952 4953 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4954 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4955 // Use a FileObserver to detect when traces finish writing. 4956 // The order of traces is considered important to maintain for legibility. 4957 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4958 @Override 4959 public synchronized void onEvent(int event, String path) { notify(); } 4960 }; 4961 4962 try { 4963 observer.startWatching(); 4964 4965 // First collect all of the stacks of the most important pids. 4966 if (firstPids != null) { 4967 try { 4968 int num = firstPids.size(); 4969 for (int i = 0; i < num; i++) { 4970 synchronized (observer) { 4971 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4972 observer.wait(200); // Wait for write-close, give up after 200msec 4973 } 4974 } 4975 } catch (InterruptedException e) { 4976 Slog.wtf(TAG, e); 4977 } 4978 } 4979 4980 // Next collect the stacks of the native pids 4981 if (nativeProcs != null) { 4982 int[] pids = Process.getPidsForCommands(nativeProcs); 4983 if (pids != null) { 4984 for (int pid : pids) { 4985 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4986 } 4987 } 4988 } 4989 4990 // Lastly, measure CPU usage. 4991 if (processCpuTracker != null) { 4992 processCpuTracker.init(); 4993 System.gc(); 4994 processCpuTracker.update(); 4995 try { 4996 synchronized (processCpuTracker) { 4997 processCpuTracker.wait(500); // measure over 1/2 second. 4998 } 4999 } catch (InterruptedException e) { 5000 } 5001 processCpuTracker.update(); 5002 5003 // We'll take the stack crawls of just the top apps using CPU. 5004 final int N = processCpuTracker.countWorkingStats(); 5005 int numProcs = 0; 5006 for (int i=0; i<N && numProcs<5; i++) { 5007 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5008 if (lastPids.indexOfKey(stats.pid) >= 0) { 5009 numProcs++; 5010 try { 5011 synchronized (observer) { 5012 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5013 observer.wait(200); // Wait for write-close, give up after 200msec 5014 } 5015 } catch (InterruptedException e) { 5016 Slog.wtf(TAG, e); 5017 } 5018 5019 } 5020 } 5021 } 5022 } finally { 5023 observer.stopWatching(); 5024 } 5025 } 5026 5027 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5028 if (true || IS_USER_BUILD) { 5029 return; 5030 } 5031 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5032 if (tracesPath == null || tracesPath.length() == 0) { 5033 return; 5034 } 5035 5036 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5037 StrictMode.allowThreadDiskWrites(); 5038 try { 5039 final File tracesFile = new File(tracesPath); 5040 final File tracesDir = tracesFile.getParentFile(); 5041 final File tracesTmp = new File(tracesDir, "__tmp__"); 5042 try { 5043 if (!tracesDir.exists()) { 5044 tracesDir.mkdirs(); 5045 if (!SELinux.restorecon(tracesDir.getPath())) { 5046 return; 5047 } 5048 } 5049 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5050 5051 if (tracesFile.exists()) { 5052 tracesTmp.delete(); 5053 tracesFile.renameTo(tracesTmp); 5054 } 5055 StringBuilder sb = new StringBuilder(); 5056 Time tobj = new Time(); 5057 tobj.set(System.currentTimeMillis()); 5058 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5059 sb.append(": "); 5060 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5061 sb.append(" since "); 5062 sb.append(msg); 5063 FileOutputStream fos = new FileOutputStream(tracesFile); 5064 fos.write(sb.toString().getBytes()); 5065 if (app == null) { 5066 fos.write("\n*** No application process!".getBytes()); 5067 } 5068 fos.close(); 5069 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5070 } catch (IOException e) { 5071 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5072 return; 5073 } 5074 5075 if (app != null) { 5076 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5077 firstPids.add(app.pid); 5078 dumpStackTraces(tracesPath, firstPids, null, null, null); 5079 } 5080 5081 File lastTracesFile = null; 5082 File curTracesFile = null; 5083 for (int i=9; i>=0; i--) { 5084 String name = String.format(Locale.US, "slow%02d.txt", i); 5085 curTracesFile = new File(tracesDir, name); 5086 if (curTracesFile.exists()) { 5087 if (lastTracesFile != null) { 5088 curTracesFile.renameTo(lastTracesFile); 5089 } else { 5090 curTracesFile.delete(); 5091 } 5092 } 5093 lastTracesFile = curTracesFile; 5094 } 5095 tracesFile.renameTo(curTracesFile); 5096 if (tracesTmp.exists()) { 5097 tracesTmp.renameTo(tracesFile); 5098 } 5099 } finally { 5100 StrictMode.setThreadPolicy(oldPolicy); 5101 } 5102 } 5103 5104 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5105 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5106 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5107 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5108 5109 if (mController != null) { 5110 try { 5111 // 0 == continue, -1 = kill process immediately 5112 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5113 if (res < 0 && app.pid != MY_PID) { 5114 app.kill("anr", true); 5115 } 5116 } catch (RemoteException e) { 5117 mController = null; 5118 Watchdog.getInstance().setActivityController(null); 5119 } 5120 } 5121 5122 long anrTime = SystemClock.uptimeMillis(); 5123 if (MONITOR_CPU_USAGE) { 5124 updateCpuStatsNow(); 5125 } 5126 5127 synchronized (this) { 5128 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5129 if (mShuttingDown) { 5130 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5131 return; 5132 } else if (app.notResponding) { 5133 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5134 return; 5135 } else if (app.crashing) { 5136 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5137 return; 5138 } 5139 5140 // In case we come through here for the same app before completing 5141 // this one, mark as anring now so we will bail out. 5142 app.notResponding = true; 5143 5144 // Log the ANR to the event log. 5145 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5146 app.processName, app.info.flags, annotation); 5147 5148 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5149 firstPids.add(app.pid); 5150 5151 int parentPid = app.pid; 5152 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5153 if (parentPid != app.pid) firstPids.add(parentPid); 5154 5155 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5156 5157 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5158 ProcessRecord r = mLruProcesses.get(i); 5159 if (r != null && r.thread != null) { 5160 int pid = r.pid; 5161 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5162 if (r.persistent) { 5163 firstPids.add(pid); 5164 } else { 5165 lastPids.put(pid, Boolean.TRUE); 5166 } 5167 } 5168 } 5169 } 5170 } 5171 5172 // Log the ANR to the main log. 5173 StringBuilder info = new StringBuilder(); 5174 info.setLength(0); 5175 info.append("ANR in ").append(app.processName); 5176 if (activity != null && activity.shortComponentName != null) { 5177 info.append(" (").append(activity.shortComponentName).append(")"); 5178 } 5179 info.append("\n"); 5180 info.append("PID: ").append(app.pid).append("\n"); 5181 if (annotation != null) { 5182 info.append("Reason: ").append(annotation).append("\n"); 5183 } 5184 if (parent != null && parent != activity) { 5185 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5186 } 5187 5188 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5189 5190 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5191 NATIVE_STACKS_OF_INTEREST); 5192 5193 String cpuInfo = null; 5194 if (MONITOR_CPU_USAGE) { 5195 updateCpuStatsNow(); 5196 synchronized (mProcessCpuTracker) { 5197 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5198 } 5199 info.append(processCpuTracker.printCurrentLoad()); 5200 info.append(cpuInfo); 5201 } 5202 5203 info.append(processCpuTracker.printCurrentState(anrTime)); 5204 5205 Slog.e(TAG, info.toString()); 5206 if (tracesFile == null) { 5207 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5208 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5209 } 5210 5211 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5212 cpuInfo, tracesFile, null); 5213 5214 if (mController != null) { 5215 try { 5216 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5217 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5218 if (res != 0) { 5219 if (res < 0 && app.pid != MY_PID) { 5220 app.kill("anr", true); 5221 } else { 5222 synchronized (this) { 5223 mServices.scheduleServiceTimeoutLocked(app); 5224 } 5225 } 5226 return; 5227 } 5228 } catch (RemoteException e) { 5229 mController = null; 5230 Watchdog.getInstance().setActivityController(null); 5231 } 5232 } 5233 5234 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5235 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5236 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5237 5238 synchronized (this) { 5239 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5240 app.kill("bg anr", true); 5241 return; 5242 } 5243 5244 // Set the app's notResponding state, and look up the errorReportReceiver 5245 makeAppNotRespondingLocked(app, 5246 activity != null ? activity.shortComponentName : null, 5247 annotation != null ? "ANR " + annotation : "ANR", 5248 info.toString()); 5249 5250 // Bring up the infamous App Not Responding dialog 5251 Message msg = Message.obtain(); 5252 HashMap<String, Object> map = new HashMap<String, Object>(); 5253 msg.what = SHOW_NOT_RESPONDING_MSG; 5254 msg.obj = map; 5255 msg.arg1 = aboveSystem ? 1 : 0; 5256 map.put("app", app); 5257 if (activity != null) { 5258 map.put("activity", activity); 5259 } 5260 5261 mHandler.sendMessage(msg); 5262 } 5263 } 5264 5265 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5266 if (!mLaunchWarningShown) { 5267 mLaunchWarningShown = true; 5268 mHandler.post(new Runnable() { 5269 @Override 5270 public void run() { 5271 synchronized (ActivityManagerService.this) { 5272 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5273 d.show(); 5274 mHandler.postDelayed(new Runnable() { 5275 @Override 5276 public void run() { 5277 synchronized (ActivityManagerService.this) { 5278 d.dismiss(); 5279 mLaunchWarningShown = false; 5280 } 5281 } 5282 }, 4000); 5283 } 5284 } 5285 }); 5286 } 5287 } 5288 5289 @Override 5290 public boolean clearApplicationUserData(final String packageName, 5291 final IPackageDataObserver observer, int userId) { 5292 enforceNotIsolatedCaller("clearApplicationUserData"); 5293 int uid = Binder.getCallingUid(); 5294 int pid = Binder.getCallingPid(); 5295 userId = handleIncomingUser(pid, uid, 5296 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5297 long callingId = Binder.clearCallingIdentity(); 5298 try { 5299 IPackageManager pm = AppGlobals.getPackageManager(); 5300 int pkgUid = -1; 5301 synchronized(this) { 5302 try { 5303 pkgUid = pm.getPackageUid(packageName, userId); 5304 } catch (RemoteException e) { 5305 } 5306 if (pkgUid == -1) { 5307 Slog.w(TAG, "Invalid packageName: " + packageName); 5308 if (observer != null) { 5309 try { 5310 observer.onRemoveCompleted(packageName, false); 5311 } catch (RemoteException e) { 5312 Slog.i(TAG, "Observer no longer exists."); 5313 } 5314 } 5315 return false; 5316 } 5317 if (uid == pkgUid || checkComponentPermission( 5318 android.Manifest.permission.CLEAR_APP_USER_DATA, 5319 pid, uid, -1, true) 5320 == PackageManager.PERMISSION_GRANTED) { 5321 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5322 } else { 5323 throw new SecurityException("PID " + pid + " does not have permission " 5324 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5325 + " of package " + packageName); 5326 } 5327 5328 // Remove all tasks match the cleared application package and user 5329 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5330 final TaskRecord tr = mRecentTasks.get(i); 5331 final String taskPackageName = 5332 tr.getBaseIntent().getComponent().getPackageName(); 5333 if (tr.userId != userId) continue; 5334 if (!taskPackageName.equals(packageName)) continue; 5335 removeTaskByIdLocked(tr.taskId, 0); 5336 } 5337 } 5338 5339 try { 5340 // Clear application user data 5341 pm.clearApplicationUserData(packageName, observer, userId); 5342 5343 synchronized(this) { 5344 // Remove all permissions granted from/to this package 5345 removeUriPermissionsForPackageLocked(packageName, userId, true); 5346 } 5347 5348 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5349 Uri.fromParts("package", packageName, null)); 5350 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5351 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5352 null, null, 0, null, null, null, false, false, userId); 5353 } catch (RemoteException e) { 5354 } 5355 } finally { 5356 Binder.restoreCallingIdentity(callingId); 5357 } 5358 return true; 5359 } 5360 5361 @Override 5362 public void killBackgroundProcesses(final String packageName, int userId) { 5363 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5364 != PackageManager.PERMISSION_GRANTED && 5365 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5366 != PackageManager.PERMISSION_GRANTED) { 5367 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5368 + Binder.getCallingPid() 5369 + ", uid=" + Binder.getCallingUid() 5370 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5371 Slog.w(TAG, msg); 5372 throw new SecurityException(msg); 5373 } 5374 5375 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5376 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5377 long callingId = Binder.clearCallingIdentity(); 5378 try { 5379 IPackageManager pm = AppGlobals.getPackageManager(); 5380 synchronized(this) { 5381 int appId = -1; 5382 try { 5383 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5384 } catch (RemoteException e) { 5385 } 5386 if (appId == -1) { 5387 Slog.w(TAG, "Invalid packageName: " + packageName); 5388 return; 5389 } 5390 killPackageProcessesLocked(packageName, appId, userId, 5391 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5392 } 5393 } finally { 5394 Binder.restoreCallingIdentity(callingId); 5395 } 5396 } 5397 5398 @Override 5399 public void killAllBackgroundProcesses() { 5400 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5401 != PackageManager.PERMISSION_GRANTED) { 5402 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5403 + Binder.getCallingPid() 5404 + ", uid=" + Binder.getCallingUid() 5405 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5406 Slog.w(TAG, msg); 5407 throw new SecurityException(msg); 5408 } 5409 5410 long callingId = Binder.clearCallingIdentity(); 5411 try { 5412 synchronized(this) { 5413 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5414 final int NP = mProcessNames.getMap().size(); 5415 for (int ip=0; ip<NP; ip++) { 5416 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5417 final int NA = apps.size(); 5418 for (int ia=0; ia<NA; ia++) { 5419 ProcessRecord app = apps.valueAt(ia); 5420 if (app.persistent) { 5421 // we don't kill persistent processes 5422 continue; 5423 } 5424 if (app.removed) { 5425 procs.add(app); 5426 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5427 app.removed = true; 5428 procs.add(app); 5429 } 5430 } 5431 } 5432 5433 int N = procs.size(); 5434 for (int i=0; i<N; i++) { 5435 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5436 } 5437 mAllowLowerMemLevel = true; 5438 updateOomAdjLocked(); 5439 doLowMemReportIfNeededLocked(null); 5440 } 5441 } finally { 5442 Binder.restoreCallingIdentity(callingId); 5443 } 5444 } 5445 5446 @Override 5447 public void forceStopPackage(final String packageName, int userId) { 5448 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5449 != PackageManager.PERMISSION_GRANTED) { 5450 String msg = "Permission Denial: forceStopPackage() from pid=" 5451 + Binder.getCallingPid() 5452 + ", uid=" + Binder.getCallingUid() 5453 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5454 Slog.w(TAG, msg); 5455 throw new SecurityException(msg); 5456 } 5457 final int callingPid = Binder.getCallingPid(); 5458 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5459 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5460 long callingId = Binder.clearCallingIdentity(); 5461 try { 5462 IPackageManager pm = AppGlobals.getPackageManager(); 5463 synchronized(this) { 5464 int[] users = userId == UserHandle.USER_ALL 5465 ? getUsersLocked() : new int[] { userId }; 5466 for (int user : users) { 5467 int pkgUid = -1; 5468 try { 5469 pkgUid = pm.getPackageUid(packageName, user); 5470 } catch (RemoteException e) { 5471 } 5472 if (pkgUid == -1) { 5473 Slog.w(TAG, "Invalid packageName: " + packageName); 5474 continue; 5475 } 5476 try { 5477 pm.setPackageStoppedState(packageName, true, user); 5478 } catch (RemoteException e) { 5479 } catch (IllegalArgumentException e) { 5480 Slog.w(TAG, "Failed trying to unstop package " 5481 + packageName + ": " + e); 5482 } 5483 if (isUserRunningLocked(user, false)) { 5484 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5485 } 5486 } 5487 } 5488 } finally { 5489 Binder.restoreCallingIdentity(callingId); 5490 } 5491 } 5492 5493 @Override 5494 public void addPackageDependency(String packageName) { 5495 synchronized (this) { 5496 int callingPid = Binder.getCallingPid(); 5497 if (callingPid == Process.myPid()) { 5498 // Yeah, um, no. 5499 Slog.w(TAG, "Can't addPackageDependency on system process"); 5500 return; 5501 } 5502 ProcessRecord proc; 5503 synchronized (mPidsSelfLocked) { 5504 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5505 } 5506 if (proc != null) { 5507 if (proc.pkgDeps == null) { 5508 proc.pkgDeps = new ArraySet<String>(1); 5509 } 5510 proc.pkgDeps.add(packageName); 5511 } 5512 } 5513 } 5514 5515 /* 5516 * The pkg name and app id have to be specified. 5517 */ 5518 @Override 5519 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5520 if (pkg == null) { 5521 return; 5522 } 5523 // Make sure the uid is valid. 5524 if (appid < 0) { 5525 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5526 return; 5527 } 5528 int callerUid = Binder.getCallingUid(); 5529 // Only the system server can kill an application 5530 if (callerUid == Process.SYSTEM_UID) { 5531 // Post an aysnc message to kill the application 5532 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5533 msg.arg1 = appid; 5534 msg.arg2 = 0; 5535 Bundle bundle = new Bundle(); 5536 bundle.putString("pkg", pkg); 5537 bundle.putString("reason", reason); 5538 msg.obj = bundle; 5539 mHandler.sendMessage(msg); 5540 } else { 5541 throw new SecurityException(callerUid + " cannot kill pkg: " + 5542 pkg); 5543 } 5544 } 5545 5546 @Override 5547 public void closeSystemDialogs(String reason) { 5548 enforceNotIsolatedCaller("closeSystemDialogs"); 5549 5550 final int pid = Binder.getCallingPid(); 5551 final int uid = Binder.getCallingUid(); 5552 final long origId = Binder.clearCallingIdentity(); 5553 try { 5554 synchronized (this) { 5555 // Only allow this from foreground processes, so that background 5556 // applications can't abuse it to prevent system UI from being shown. 5557 if (uid >= Process.FIRST_APPLICATION_UID) { 5558 ProcessRecord proc; 5559 synchronized (mPidsSelfLocked) { 5560 proc = mPidsSelfLocked.get(pid); 5561 } 5562 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5563 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5564 + " from background process " + proc); 5565 return; 5566 } 5567 } 5568 closeSystemDialogsLocked(reason); 5569 } 5570 } finally { 5571 Binder.restoreCallingIdentity(origId); 5572 } 5573 } 5574 5575 void closeSystemDialogsLocked(String reason) { 5576 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5577 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5578 | Intent.FLAG_RECEIVER_FOREGROUND); 5579 if (reason != null) { 5580 intent.putExtra("reason", reason); 5581 } 5582 mWindowManager.closeSystemDialogs(reason); 5583 5584 mStackSupervisor.closeSystemDialogsLocked(); 5585 5586 broadcastIntentLocked(null, null, intent, null, 5587 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5588 Process.SYSTEM_UID, UserHandle.USER_ALL); 5589 } 5590 5591 @Override 5592 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5593 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5594 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5595 for (int i=pids.length-1; i>=0; i--) { 5596 ProcessRecord proc; 5597 int oomAdj; 5598 synchronized (this) { 5599 synchronized (mPidsSelfLocked) { 5600 proc = mPidsSelfLocked.get(pids[i]); 5601 oomAdj = proc != null ? proc.setAdj : 0; 5602 } 5603 } 5604 infos[i] = new Debug.MemoryInfo(); 5605 Debug.getMemoryInfo(pids[i], infos[i]); 5606 if (proc != null) { 5607 synchronized (this) { 5608 if (proc.thread != null && proc.setAdj == oomAdj) { 5609 // Record this for posterity if the process has been stable. 5610 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5611 infos[i].getTotalUss(), false, proc.pkgList); 5612 } 5613 } 5614 } 5615 } 5616 return infos; 5617 } 5618 5619 @Override 5620 public long[] getProcessPss(int[] pids) { 5621 enforceNotIsolatedCaller("getProcessPss"); 5622 long[] pss = new long[pids.length]; 5623 for (int i=pids.length-1; i>=0; i--) { 5624 ProcessRecord proc; 5625 int oomAdj; 5626 synchronized (this) { 5627 synchronized (mPidsSelfLocked) { 5628 proc = mPidsSelfLocked.get(pids[i]); 5629 oomAdj = proc != null ? proc.setAdj : 0; 5630 } 5631 } 5632 long[] tmpUss = new long[1]; 5633 pss[i] = Debug.getPss(pids[i], tmpUss); 5634 if (proc != null) { 5635 synchronized (this) { 5636 if (proc.thread != null && proc.setAdj == oomAdj) { 5637 // Record this for posterity if the process has been stable. 5638 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5639 } 5640 } 5641 } 5642 } 5643 return pss; 5644 } 5645 5646 @Override 5647 public void killApplicationProcess(String processName, int uid) { 5648 if (processName == null) { 5649 return; 5650 } 5651 5652 int callerUid = Binder.getCallingUid(); 5653 // Only the system server can kill an application 5654 if (callerUid == Process.SYSTEM_UID) { 5655 synchronized (this) { 5656 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5657 if (app != null && app.thread != null) { 5658 try { 5659 app.thread.scheduleSuicide(); 5660 } catch (RemoteException e) { 5661 // If the other end already died, then our work here is done. 5662 } 5663 } else { 5664 Slog.w(TAG, "Process/uid not found attempting kill of " 5665 + processName + " / " + uid); 5666 } 5667 } 5668 } else { 5669 throw new SecurityException(callerUid + " cannot kill app process: " + 5670 processName); 5671 } 5672 } 5673 5674 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5675 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5676 false, true, false, false, UserHandle.getUserId(uid), reason); 5677 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5678 Uri.fromParts("package", packageName, null)); 5679 if (!mProcessesReady) { 5680 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5681 | Intent.FLAG_RECEIVER_FOREGROUND); 5682 } 5683 intent.putExtra(Intent.EXTRA_UID, uid); 5684 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5685 broadcastIntentLocked(null, null, intent, 5686 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5687 false, false, 5688 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5689 } 5690 5691 private void forceStopUserLocked(int userId, String reason) { 5692 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5693 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5694 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5695 | Intent.FLAG_RECEIVER_FOREGROUND); 5696 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5697 broadcastIntentLocked(null, null, intent, 5698 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5699 false, false, 5700 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5701 } 5702 5703 private final boolean killPackageProcessesLocked(String packageName, int appId, 5704 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5705 boolean doit, boolean evenPersistent, String reason) { 5706 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5707 5708 // Remove all processes this package may have touched: all with the 5709 // same UID (except for the system or root user), and all whose name 5710 // matches the package name. 5711 final int NP = mProcessNames.getMap().size(); 5712 for (int ip=0; ip<NP; ip++) { 5713 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5714 final int NA = apps.size(); 5715 for (int ia=0; ia<NA; ia++) { 5716 ProcessRecord app = apps.valueAt(ia); 5717 if (app.persistent && !evenPersistent) { 5718 // we don't kill persistent processes 5719 continue; 5720 } 5721 if (app.removed) { 5722 if (doit) { 5723 procs.add(app); 5724 } 5725 continue; 5726 } 5727 5728 // Skip process if it doesn't meet our oom adj requirement. 5729 if (app.setAdj < minOomAdj) { 5730 continue; 5731 } 5732 5733 // If no package is specified, we call all processes under the 5734 // give user id. 5735 if (packageName == null) { 5736 if (app.userId != userId) { 5737 continue; 5738 } 5739 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5740 continue; 5741 } 5742 // Package has been specified, we want to hit all processes 5743 // that match it. We need to qualify this by the processes 5744 // that are running under the specified app and user ID. 5745 } else { 5746 final boolean isDep = app.pkgDeps != null 5747 && app.pkgDeps.contains(packageName); 5748 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5749 continue; 5750 } 5751 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5752 continue; 5753 } 5754 if (!app.pkgList.containsKey(packageName) && !isDep) { 5755 continue; 5756 } 5757 } 5758 5759 // Process has passed all conditions, kill it! 5760 if (!doit) { 5761 return true; 5762 } 5763 app.removed = true; 5764 procs.add(app); 5765 } 5766 } 5767 5768 int N = procs.size(); 5769 for (int i=0; i<N; i++) { 5770 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5771 } 5772 updateOomAdjLocked(); 5773 return N > 0; 5774 } 5775 5776 private final boolean forceStopPackageLocked(String name, int appId, 5777 boolean callerWillRestart, boolean purgeCache, boolean doit, 5778 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5779 int i; 5780 int N; 5781 5782 if (userId == UserHandle.USER_ALL && name == null) { 5783 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5784 } 5785 5786 if (appId < 0 && name != null) { 5787 try { 5788 appId = UserHandle.getAppId( 5789 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5790 } catch (RemoteException e) { 5791 } 5792 } 5793 5794 if (doit) { 5795 if (name != null) { 5796 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5797 + " user=" + userId + ": " + reason); 5798 } else { 5799 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5800 } 5801 5802 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5803 for (int ip=pmap.size()-1; ip>=0; ip--) { 5804 SparseArray<Long> ba = pmap.valueAt(ip); 5805 for (i=ba.size()-1; i>=0; i--) { 5806 boolean remove = false; 5807 final int entUid = ba.keyAt(i); 5808 if (name != null) { 5809 if (userId == UserHandle.USER_ALL) { 5810 if (UserHandle.getAppId(entUid) == appId) { 5811 remove = true; 5812 } 5813 } else { 5814 if (entUid == UserHandle.getUid(userId, appId)) { 5815 remove = true; 5816 } 5817 } 5818 } else if (UserHandle.getUserId(entUid) == userId) { 5819 remove = true; 5820 } 5821 if (remove) { 5822 ba.removeAt(i); 5823 } 5824 } 5825 if (ba.size() == 0) { 5826 pmap.removeAt(ip); 5827 } 5828 } 5829 } 5830 5831 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5832 -100, callerWillRestart, true, doit, evenPersistent, 5833 name == null ? ("stop user " + userId) : ("stop " + name)); 5834 5835 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5836 if (!doit) { 5837 return true; 5838 } 5839 didSomething = true; 5840 } 5841 5842 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5843 if (!doit) { 5844 return true; 5845 } 5846 didSomething = true; 5847 } 5848 5849 if (name == null) { 5850 // Remove all sticky broadcasts from this user. 5851 mStickyBroadcasts.remove(userId); 5852 } 5853 5854 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5855 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5856 userId, providers)) { 5857 if (!doit) { 5858 return true; 5859 } 5860 didSomething = true; 5861 } 5862 N = providers.size(); 5863 for (i=0; i<N; i++) { 5864 removeDyingProviderLocked(null, providers.get(i), true); 5865 } 5866 5867 // Remove transient permissions granted from/to this package/user 5868 removeUriPermissionsForPackageLocked(name, userId, false); 5869 5870 if (name == null || uninstalling) { 5871 // Remove pending intents. For now we only do this when force 5872 // stopping users, because we have some problems when doing this 5873 // for packages -- app widgets are not currently cleaned up for 5874 // such packages, so they can be left with bad pending intents. 5875 if (mIntentSenderRecords.size() > 0) { 5876 Iterator<WeakReference<PendingIntentRecord>> it 5877 = mIntentSenderRecords.values().iterator(); 5878 while (it.hasNext()) { 5879 WeakReference<PendingIntentRecord> wpir = it.next(); 5880 if (wpir == null) { 5881 it.remove(); 5882 continue; 5883 } 5884 PendingIntentRecord pir = wpir.get(); 5885 if (pir == null) { 5886 it.remove(); 5887 continue; 5888 } 5889 if (name == null) { 5890 // Stopping user, remove all objects for the user. 5891 if (pir.key.userId != userId) { 5892 // Not the same user, skip it. 5893 continue; 5894 } 5895 } else { 5896 if (UserHandle.getAppId(pir.uid) != appId) { 5897 // Different app id, skip it. 5898 continue; 5899 } 5900 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5901 // Different user, skip it. 5902 continue; 5903 } 5904 if (!pir.key.packageName.equals(name)) { 5905 // Different package, skip it. 5906 continue; 5907 } 5908 } 5909 if (!doit) { 5910 return true; 5911 } 5912 didSomething = true; 5913 it.remove(); 5914 pir.canceled = true; 5915 if (pir.key.activity != null) { 5916 pir.key.activity.pendingResults.remove(pir.ref); 5917 } 5918 } 5919 } 5920 } 5921 5922 if (doit) { 5923 if (purgeCache && name != null) { 5924 AttributeCache ac = AttributeCache.instance(); 5925 if (ac != null) { 5926 ac.removePackage(name); 5927 } 5928 } 5929 if (mBooted) { 5930 mStackSupervisor.resumeTopActivitiesLocked(); 5931 mStackSupervisor.scheduleIdleLocked(); 5932 } 5933 } 5934 5935 return didSomething; 5936 } 5937 5938 private final boolean removeProcessLocked(ProcessRecord app, 5939 boolean callerWillRestart, boolean allowRestart, String reason) { 5940 final String name = app.processName; 5941 final int uid = app.uid; 5942 if (DEBUG_PROCESSES) Slog.d( 5943 TAG, "Force removing proc " + app.toShortString() + " (" + name 5944 + "/" + uid + ")"); 5945 5946 mProcessNames.remove(name, uid); 5947 mIsolatedProcesses.remove(app.uid); 5948 if (mHeavyWeightProcess == app) { 5949 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5950 mHeavyWeightProcess.userId, 0)); 5951 mHeavyWeightProcess = null; 5952 } 5953 boolean needRestart = false; 5954 if (app.pid > 0 && app.pid != MY_PID) { 5955 int pid = app.pid; 5956 synchronized (mPidsSelfLocked) { 5957 mPidsSelfLocked.remove(pid); 5958 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5959 } 5960 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5961 if (app.isolated) { 5962 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5963 } 5964 app.kill(reason, true); 5965 handleAppDiedLocked(app, true, allowRestart); 5966 removeLruProcessLocked(app); 5967 5968 if (app.persistent && !app.isolated) { 5969 if (!callerWillRestart) { 5970 addAppLocked(app.info, false, null /* ABI override */); 5971 } else { 5972 needRestart = true; 5973 } 5974 } 5975 } else { 5976 mRemovedProcesses.add(app); 5977 } 5978 5979 return needRestart; 5980 } 5981 5982 private final void processStartTimedOutLocked(ProcessRecord app) { 5983 final int pid = app.pid; 5984 boolean gone = false; 5985 synchronized (mPidsSelfLocked) { 5986 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5987 if (knownApp != null && knownApp.thread == null) { 5988 mPidsSelfLocked.remove(pid); 5989 gone = true; 5990 } 5991 } 5992 5993 if (gone) { 5994 Slog.w(TAG, "Process " + app + " failed to attach"); 5995 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5996 pid, app.uid, app.processName); 5997 mProcessNames.remove(app.processName, app.uid); 5998 mIsolatedProcesses.remove(app.uid); 5999 if (mHeavyWeightProcess == app) { 6000 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6001 mHeavyWeightProcess.userId, 0)); 6002 mHeavyWeightProcess = null; 6003 } 6004 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6005 if (app.isolated) { 6006 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6007 } 6008 // Take care of any launching providers waiting for this process. 6009 checkAppInLaunchingProvidersLocked(app, true); 6010 // Take care of any services that are waiting for the process. 6011 mServices.processStartTimedOutLocked(app); 6012 app.kill("start timeout", true); 6013 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6014 Slog.w(TAG, "Unattached app died before backup, skipping"); 6015 try { 6016 IBackupManager bm = IBackupManager.Stub.asInterface( 6017 ServiceManager.getService(Context.BACKUP_SERVICE)); 6018 bm.agentDisconnected(app.info.packageName); 6019 } catch (RemoteException e) { 6020 // Can't happen; the backup manager is local 6021 } 6022 } 6023 if (isPendingBroadcastProcessLocked(pid)) { 6024 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6025 skipPendingBroadcastLocked(pid); 6026 } 6027 } else { 6028 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6029 } 6030 } 6031 6032 private final boolean attachApplicationLocked(IApplicationThread thread, 6033 int pid) { 6034 6035 // Find the application record that is being attached... either via 6036 // the pid if we are running in multiple processes, or just pull the 6037 // next app record if we are emulating process with anonymous threads. 6038 ProcessRecord app; 6039 if (pid != MY_PID && pid >= 0) { 6040 synchronized (mPidsSelfLocked) { 6041 app = mPidsSelfLocked.get(pid); 6042 } 6043 } else { 6044 app = null; 6045 } 6046 6047 if (app == null) { 6048 Slog.w(TAG, "No pending application record for pid " + pid 6049 + " (IApplicationThread " + thread + "); dropping process"); 6050 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6051 if (pid > 0 && pid != MY_PID) { 6052 Process.killProcessQuiet(pid); 6053 //TODO: Process.killProcessGroup(app.info.uid, pid); 6054 } else { 6055 try { 6056 thread.scheduleExit(); 6057 } catch (Exception e) { 6058 // Ignore exceptions. 6059 } 6060 } 6061 return false; 6062 } 6063 6064 // If this application record is still attached to a previous 6065 // process, clean it up now. 6066 if (app.thread != null) { 6067 handleAppDiedLocked(app, true, true); 6068 } 6069 6070 // Tell the process all about itself. 6071 6072 if (localLOGV) Slog.v( 6073 TAG, "Binding process pid " + pid + " to record " + app); 6074 6075 final String processName = app.processName; 6076 try { 6077 AppDeathRecipient adr = new AppDeathRecipient( 6078 app, pid, thread); 6079 thread.asBinder().linkToDeath(adr, 0); 6080 app.deathRecipient = adr; 6081 } catch (RemoteException e) { 6082 app.resetPackageList(mProcessStats); 6083 startProcessLocked(app, "link fail", processName); 6084 return false; 6085 } 6086 6087 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6088 6089 app.makeActive(thread, mProcessStats); 6090 app.curAdj = app.setAdj = -100; 6091 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6092 app.forcingToForeground = null; 6093 updateProcessForegroundLocked(app, false, false); 6094 app.hasShownUi = false; 6095 app.debugging = false; 6096 app.cached = false; 6097 6098 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6099 6100 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6101 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6102 6103 if (!normalMode) { 6104 Slog.i(TAG, "Launching preboot mode app: " + app); 6105 } 6106 6107 if (localLOGV) Slog.v( 6108 TAG, "New app record " + app 6109 + " thread=" + thread.asBinder() + " pid=" + pid); 6110 try { 6111 int testMode = IApplicationThread.DEBUG_OFF; 6112 if (mDebugApp != null && mDebugApp.equals(processName)) { 6113 testMode = mWaitForDebugger 6114 ? IApplicationThread.DEBUG_WAIT 6115 : IApplicationThread.DEBUG_ON; 6116 app.debugging = true; 6117 if (mDebugTransient) { 6118 mDebugApp = mOrigDebugApp; 6119 mWaitForDebugger = mOrigWaitForDebugger; 6120 } 6121 } 6122 String profileFile = app.instrumentationProfileFile; 6123 ParcelFileDescriptor profileFd = null; 6124 int samplingInterval = 0; 6125 boolean profileAutoStop = false; 6126 if (mProfileApp != null && mProfileApp.equals(processName)) { 6127 mProfileProc = app; 6128 profileFile = mProfileFile; 6129 profileFd = mProfileFd; 6130 samplingInterval = mSamplingInterval; 6131 profileAutoStop = mAutoStopProfiler; 6132 } 6133 boolean enableOpenGlTrace = false; 6134 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6135 enableOpenGlTrace = true; 6136 mOpenGlTraceApp = null; 6137 } 6138 6139 // If the app is being launched for restore or full backup, set it up specially 6140 boolean isRestrictedBackupMode = false; 6141 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6142 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6143 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6144 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6145 } 6146 6147 ensurePackageDexOpt(app.instrumentationInfo != null 6148 ? app.instrumentationInfo.packageName 6149 : app.info.packageName); 6150 if (app.instrumentationClass != null) { 6151 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6152 } 6153 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6154 + processName + " with config " + mConfiguration); 6155 ApplicationInfo appInfo = app.instrumentationInfo != null 6156 ? app.instrumentationInfo : app.info; 6157 app.compat = compatibilityInfoForPackageLocked(appInfo); 6158 if (profileFd != null) { 6159 profileFd = profileFd.dup(); 6160 } 6161 ProfilerInfo profilerInfo = profileFile == null ? null 6162 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6163 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6164 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6165 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6166 isRestrictedBackupMode || !normalMode, app.persistent, 6167 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6168 mCoreSettingsObserver.getCoreSettingsLocked()); 6169 updateLruProcessLocked(app, false, null); 6170 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6171 } catch (Exception e) { 6172 // todo: Yikes! What should we do? For now we will try to 6173 // start another process, but that could easily get us in 6174 // an infinite loop of restarting processes... 6175 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6176 6177 app.resetPackageList(mProcessStats); 6178 app.unlinkDeathRecipient(); 6179 startProcessLocked(app, "bind fail", processName); 6180 return false; 6181 } 6182 6183 // Remove this record from the list of starting applications. 6184 mPersistentStartingProcesses.remove(app); 6185 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6186 "Attach application locked removing on hold: " + app); 6187 mProcessesOnHold.remove(app); 6188 6189 boolean badApp = false; 6190 boolean didSomething = false; 6191 6192 // See if the top visible activity is waiting to run in this process... 6193 if (normalMode) { 6194 try { 6195 if (mStackSupervisor.attachApplicationLocked(app)) { 6196 didSomething = true; 6197 } 6198 } catch (Exception e) { 6199 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6200 badApp = true; 6201 } 6202 } 6203 6204 // Find any services that should be running in this process... 6205 if (!badApp) { 6206 try { 6207 didSomething |= mServices.attachApplicationLocked(app, processName); 6208 } catch (Exception e) { 6209 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6210 badApp = true; 6211 } 6212 } 6213 6214 // Check if a next-broadcast receiver is in this process... 6215 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6216 try { 6217 didSomething |= sendPendingBroadcastsLocked(app); 6218 } catch (Exception e) { 6219 // If the app died trying to launch the receiver we declare it 'bad' 6220 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6221 badApp = true; 6222 } 6223 } 6224 6225 // Check whether the next backup agent is in this process... 6226 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6227 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6228 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6229 try { 6230 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6231 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6232 mBackupTarget.backupMode); 6233 } catch (Exception e) { 6234 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6235 badApp = true; 6236 } 6237 } 6238 6239 if (badApp) { 6240 app.kill("error during init", true); 6241 handleAppDiedLocked(app, false, true); 6242 return false; 6243 } 6244 6245 if (!didSomething) { 6246 updateOomAdjLocked(); 6247 } 6248 6249 return true; 6250 } 6251 6252 @Override 6253 public final void attachApplication(IApplicationThread thread) { 6254 synchronized (this) { 6255 int callingPid = Binder.getCallingPid(); 6256 final long origId = Binder.clearCallingIdentity(); 6257 attachApplicationLocked(thread, callingPid); 6258 Binder.restoreCallingIdentity(origId); 6259 } 6260 } 6261 6262 @Override 6263 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6264 final long origId = Binder.clearCallingIdentity(); 6265 synchronized (this) { 6266 ActivityStack stack = ActivityRecord.getStackLocked(token); 6267 if (stack != null) { 6268 ActivityRecord r = 6269 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6270 if (stopProfiling) { 6271 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6272 try { 6273 mProfileFd.close(); 6274 } catch (IOException e) { 6275 } 6276 clearProfilerLocked(); 6277 } 6278 } 6279 } 6280 } 6281 Binder.restoreCallingIdentity(origId); 6282 } 6283 6284 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6285 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6286 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6287 } 6288 6289 void enableScreenAfterBoot() { 6290 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6291 SystemClock.uptimeMillis()); 6292 mWindowManager.enableScreenAfterBoot(); 6293 6294 synchronized (this) { 6295 updateEventDispatchingLocked(); 6296 } 6297 } 6298 6299 @Override 6300 public void showBootMessage(final CharSequence msg, final boolean always) { 6301 enforceNotIsolatedCaller("showBootMessage"); 6302 mWindowManager.showBootMessage(msg, always); 6303 } 6304 6305 @Override 6306 public void keyguardWaitingForActivityDrawn() { 6307 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6308 final long token = Binder.clearCallingIdentity(); 6309 try { 6310 synchronized (this) { 6311 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6312 mWindowManager.keyguardWaitingForActivityDrawn(); 6313 if (mLockScreenShown) { 6314 mLockScreenShown = false; 6315 comeOutOfSleepIfNeededLocked(); 6316 } 6317 } 6318 } finally { 6319 Binder.restoreCallingIdentity(token); 6320 } 6321 } 6322 6323 final void finishBooting() { 6324 synchronized (this) { 6325 if (!mBootAnimationComplete) { 6326 mCallFinishBooting = true; 6327 return; 6328 } 6329 mCallFinishBooting = false; 6330 } 6331 6332 // Register receivers to handle package update events 6333 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6334 6335 // Let system services know. 6336 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6337 6338 synchronized (this) { 6339 // Ensure that any processes we had put on hold are now started 6340 // up. 6341 final int NP = mProcessesOnHold.size(); 6342 if (NP > 0) { 6343 ArrayList<ProcessRecord> procs = 6344 new ArrayList<ProcessRecord>(mProcessesOnHold); 6345 for (int ip=0; ip<NP; ip++) { 6346 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6347 + procs.get(ip)); 6348 startProcessLocked(procs.get(ip), "on-hold", null); 6349 } 6350 } 6351 6352 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6353 // Start looking for apps that are abusing wake locks. 6354 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6355 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6356 // Tell anyone interested that we are done booting! 6357 SystemProperties.set("sys.boot_completed", "1"); 6358 6359 // And trigger dev.bootcomplete if we are not showing encryption progress 6360 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6361 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6362 SystemProperties.set("dev.bootcomplete", "1"); 6363 } 6364 for (int i=0; i<mStartedUsers.size(); i++) { 6365 UserStartedState uss = mStartedUsers.valueAt(i); 6366 if (uss.mState == UserStartedState.STATE_BOOTING) { 6367 uss.mState = UserStartedState.STATE_RUNNING; 6368 final int userId = mStartedUsers.keyAt(i); 6369 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6370 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6371 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6372 broadcastIntentLocked(null, null, intent, null, 6373 new IIntentReceiver.Stub() { 6374 @Override 6375 public void performReceive(Intent intent, int resultCode, 6376 String data, Bundle extras, boolean ordered, 6377 boolean sticky, int sendingUser) { 6378 synchronized (ActivityManagerService.this) { 6379 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6380 true, false); 6381 } 6382 } 6383 }, 6384 0, null, null, 6385 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6386 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6387 userId); 6388 } 6389 } 6390 scheduleStartProfilesLocked(); 6391 } 6392 } 6393 } 6394 6395 @Override 6396 public void bootAnimationComplete() { 6397 final boolean callFinishBooting; 6398 synchronized (this) { 6399 callFinishBooting = mCallFinishBooting; 6400 mBootAnimationComplete = true; 6401 } 6402 if (callFinishBooting) { 6403 finishBooting(); 6404 } 6405 } 6406 6407 final void ensureBootCompleted() { 6408 boolean booting; 6409 boolean enableScreen; 6410 synchronized (this) { 6411 booting = mBooting; 6412 mBooting = false; 6413 enableScreen = !mBooted; 6414 mBooted = true; 6415 } 6416 6417 if (booting) { 6418 finishBooting(); 6419 } 6420 6421 if (enableScreen) { 6422 enableScreenAfterBoot(); 6423 } 6424 } 6425 6426 @Override 6427 public final void activityResumed(IBinder token) { 6428 final long origId = Binder.clearCallingIdentity(); 6429 synchronized(this) { 6430 ActivityStack stack = ActivityRecord.getStackLocked(token); 6431 if (stack != null) { 6432 ActivityRecord.activityResumedLocked(token); 6433 } 6434 } 6435 Binder.restoreCallingIdentity(origId); 6436 } 6437 6438 @Override 6439 public final void activityPaused(IBinder token) { 6440 final long origId = Binder.clearCallingIdentity(); 6441 synchronized(this) { 6442 ActivityStack stack = ActivityRecord.getStackLocked(token); 6443 if (stack != null) { 6444 stack.activityPausedLocked(token, false); 6445 } 6446 } 6447 Binder.restoreCallingIdentity(origId); 6448 } 6449 6450 @Override 6451 public final void activityStopped(IBinder token, Bundle icicle, 6452 PersistableBundle persistentState, CharSequence description) { 6453 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6454 6455 // Refuse possible leaked file descriptors 6456 if (icicle != null && icicle.hasFileDescriptors()) { 6457 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6458 } 6459 6460 final long origId = Binder.clearCallingIdentity(); 6461 6462 synchronized (this) { 6463 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6464 if (r != null) { 6465 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6466 } 6467 } 6468 6469 trimApplications(); 6470 6471 Binder.restoreCallingIdentity(origId); 6472 } 6473 6474 @Override 6475 public final void activityDestroyed(IBinder token) { 6476 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6477 synchronized (this) { 6478 ActivityStack stack = ActivityRecord.getStackLocked(token); 6479 if (stack != null) { 6480 stack.activityDestroyedLocked(token); 6481 } 6482 } 6483 } 6484 6485 @Override 6486 public final void backgroundResourcesReleased(IBinder token) { 6487 final long origId = Binder.clearCallingIdentity(); 6488 try { 6489 synchronized (this) { 6490 ActivityStack stack = ActivityRecord.getStackLocked(token); 6491 if (stack != null) { 6492 stack.backgroundResourcesReleased(token); 6493 } 6494 } 6495 } finally { 6496 Binder.restoreCallingIdentity(origId); 6497 } 6498 } 6499 6500 @Override 6501 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6502 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6503 } 6504 6505 @Override 6506 public final void notifyEnterAnimationComplete(IBinder token) { 6507 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6508 } 6509 6510 @Override 6511 public String getCallingPackage(IBinder token) { 6512 synchronized (this) { 6513 ActivityRecord r = getCallingRecordLocked(token); 6514 return r != null ? r.info.packageName : null; 6515 } 6516 } 6517 6518 @Override 6519 public ComponentName getCallingActivity(IBinder token) { 6520 synchronized (this) { 6521 ActivityRecord r = getCallingRecordLocked(token); 6522 return r != null ? r.intent.getComponent() : null; 6523 } 6524 } 6525 6526 private ActivityRecord getCallingRecordLocked(IBinder token) { 6527 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6528 if (r == null) { 6529 return null; 6530 } 6531 return r.resultTo; 6532 } 6533 6534 @Override 6535 public ComponentName getActivityClassForToken(IBinder token) { 6536 synchronized(this) { 6537 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6538 if (r == null) { 6539 return null; 6540 } 6541 return r.intent.getComponent(); 6542 } 6543 } 6544 6545 @Override 6546 public String getPackageForToken(IBinder token) { 6547 synchronized(this) { 6548 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6549 if (r == null) { 6550 return null; 6551 } 6552 return r.packageName; 6553 } 6554 } 6555 6556 @Override 6557 public IIntentSender getIntentSender(int type, 6558 String packageName, IBinder token, String resultWho, 6559 int requestCode, Intent[] intents, String[] resolvedTypes, 6560 int flags, Bundle options, int userId) { 6561 enforceNotIsolatedCaller("getIntentSender"); 6562 // Refuse possible leaked file descriptors 6563 if (intents != null) { 6564 if (intents.length < 1) { 6565 throw new IllegalArgumentException("Intents array length must be >= 1"); 6566 } 6567 for (int i=0; i<intents.length; i++) { 6568 Intent intent = intents[i]; 6569 if (intent != null) { 6570 if (intent.hasFileDescriptors()) { 6571 throw new IllegalArgumentException("File descriptors passed in Intent"); 6572 } 6573 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6574 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6575 throw new IllegalArgumentException( 6576 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6577 } 6578 intents[i] = new Intent(intent); 6579 } 6580 } 6581 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6582 throw new IllegalArgumentException( 6583 "Intent array length does not match resolvedTypes length"); 6584 } 6585 } 6586 if (options != null) { 6587 if (options.hasFileDescriptors()) { 6588 throw new IllegalArgumentException("File descriptors passed in options"); 6589 } 6590 } 6591 6592 synchronized(this) { 6593 int callingUid = Binder.getCallingUid(); 6594 int origUserId = userId; 6595 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6596 type == ActivityManager.INTENT_SENDER_BROADCAST, 6597 ALLOW_NON_FULL, "getIntentSender", null); 6598 if (origUserId == UserHandle.USER_CURRENT) { 6599 // We don't want to evaluate this until the pending intent is 6600 // actually executed. However, we do want to always do the 6601 // security checking for it above. 6602 userId = UserHandle.USER_CURRENT; 6603 } 6604 try { 6605 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6606 int uid = AppGlobals.getPackageManager() 6607 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6608 if (!UserHandle.isSameApp(callingUid, uid)) { 6609 String msg = "Permission Denial: getIntentSender() from pid=" 6610 + Binder.getCallingPid() 6611 + ", uid=" + Binder.getCallingUid() 6612 + ", (need uid=" + uid + ")" 6613 + " is not allowed to send as package " + packageName; 6614 Slog.w(TAG, msg); 6615 throw new SecurityException(msg); 6616 } 6617 } 6618 6619 return getIntentSenderLocked(type, packageName, callingUid, userId, 6620 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6621 6622 } catch (RemoteException e) { 6623 throw new SecurityException(e); 6624 } 6625 } 6626 } 6627 6628 IIntentSender getIntentSenderLocked(int type, String packageName, 6629 int callingUid, int userId, IBinder token, String resultWho, 6630 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6631 Bundle options) { 6632 if (DEBUG_MU) 6633 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6634 ActivityRecord activity = null; 6635 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6636 activity = ActivityRecord.isInStackLocked(token); 6637 if (activity == null) { 6638 return null; 6639 } 6640 if (activity.finishing) { 6641 return null; 6642 } 6643 } 6644 6645 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6646 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6647 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6648 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6649 |PendingIntent.FLAG_UPDATE_CURRENT); 6650 6651 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6652 type, packageName, activity, resultWho, 6653 requestCode, intents, resolvedTypes, flags, options, userId); 6654 WeakReference<PendingIntentRecord> ref; 6655 ref = mIntentSenderRecords.get(key); 6656 PendingIntentRecord rec = ref != null ? ref.get() : null; 6657 if (rec != null) { 6658 if (!cancelCurrent) { 6659 if (updateCurrent) { 6660 if (rec.key.requestIntent != null) { 6661 rec.key.requestIntent.replaceExtras(intents != null ? 6662 intents[intents.length - 1] : null); 6663 } 6664 if (intents != null) { 6665 intents[intents.length-1] = rec.key.requestIntent; 6666 rec.key.allIntents = intents; 6667 rec.key.allResolvedTypes = resolvedTypes; 6668 } else { 6669 rec.key.allIntents = null; 6670 rec.key.allResolvedTypes = null; 6671 } 6672 } 6673 return rec; 6674 } 6675 rec.canceled = true; 6676 mIntentSenderRecords.remove(key); 6677 } 6678 if (noCreate) { 6679 return rec; 6680 } 6681 rec = new PendingIntentRecord(this, key, callingUid); 6682 mIntentSenderRecords.put(key, rec.ref); 6683 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6684 if (activity.pendingResults == null) { 6685 activity.pendingResults 6686 = new HashSet<WeakReference<PendingIntentRecord>>(); 6687 } 6688 activity.pendingResults.add(rec.ref); 6689 } 6690 return rec; 6691 } 6692 6693 @Override 6694 public void cancelIntentSender(IIntentSender sender) { 6695 if (!(sender instanceof PendingIntentRecord)) { 6696 return; 6697 } 6698 synchronized(this) { 6699 PendingIntentRecord rec = (PendingIntentRecord)sender; 6700 try { 6701 int uid = AppGlobals.getPackageManager() 6702 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6703 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6704 String msg = "Permission Denial: cancelIntentSender() from pid=" 6705 + Binder.getCallingPid() 6706 + ", uid=" + Binder.getCallingUid() 6707 + " is not allowed to cancel packges " 6708 + rec.key.packageName; 6709 Slog.w(TAG, msg); 6710 throw new SecurityException(msg); 6711 } 6712 } catch (RemoteException e) { 6713 throw new SecurityException(e); 6714 } 6715 cancelIntentSenderLocked(rec, true); 6716 } 6717 } 6718 6719 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6720 rec.canceled = true; 6721 mIntentSenderRecords.remove(rec.key); 6722 if (cleanActivity && rec.key.activity != null) { 6723 rec.key.activity.pendingResults.remove(rec.ref); 6724 } 6725 } 6726 6727 @Override 6728 public String getPackageForIntentSender(IIntentSender pendingResult) { 6729 if (!(pendingResult instanceof PendingIntentRecord)) { 6730 return null; 6731 } 6732 try { 6733 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6734 return res.key.packageName; 6735 } catch (ClassCastException e) { 6736 } 6737 return null; 6738 } 6739 6740 @Override 6741 public int getUidForIntentSender(IIntentSender sender) { 6742 if (sender instanceof PendingIntentRecord) { 6743 try { 6744 PendingIntentRecord res = (PendingIntentRecord)sender; 6745 return res.uid; 6746 } catch (ClassCastException e) { 6747 } 6748 } 6749 return -1; 6750 } 6751 6752 @Override 6753 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6754 if (!(pendingResult instanceof PendingIntentRecord)) { 6755 return false; 6756 } 6757 try { 6758 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6759 if (res.key.allIntents == null) { 6760 return false; 6761 } 6762 for (int i=0; i<res.key.allIntents.length; i++) { 6763 Intent intent = res.key.allIntents[i]; 6764 if (intent.getPackage() != null && intent.getComponent() != null) { 6765 return false; 6766 } 6767 } 6768 return true; 6769 } catch (ClassCastException e) { 6770 } 6771 return false; 6772 } 6773 6774 @Override 6775 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6776 if (!(pendingResult instanceof PendingIntentRecord)) { 6777 return false; 6778 } 6779 try { 6780 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6781 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6782 return true; 6783 } 6784 return false; 6785 } catch (ClassCastException e) { 6786 } 6787 return false; 6788 } 6789 6790 @Override 6791 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6792 if (!(pendingResult instanceof PendingIntentRecord)) { 6793 return null; 6794 } 6795 try { 6796 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6797 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6798 } catch (ClassCastException e) { 6799 } 6800 return null; 6801 } 6802 6803 @Override 6804 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6805 if (!(pendingResult instanceof PendingIntentRecord)) { 6806 return null; 6807 } 6808 try { 6809 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6810 Intent intent = res.key.requestIntent; 6811 if (intent != null) { 6812 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6813 || res.lastTagPrefix.equals(prefix))) { 6814 return res.lastTag; 6815 } 6816 res.lastTagPrefix = prefix; 6817 StringBuilder sb = new StringBuilder(128); 6818 if (prefix != null) { 6819 sb.append(prefix); 6820 } 6821 if (intent.getAction() != null) { 6822 sb.append(intent.getAction()); 6823 } else if (intent.getComponent() != null) { 6824 intent.getComponent().appendShortString(sb); 6825 } else { 6826 sb.append("?"); 6827 } 6828 return res.lastTag = sb.toString(); 6829 } 6830 } catch (ClassCastException e) { 6831 } 6832 return null; 6833 } 6834 6835 @Override 6836 public void setProcessLimit(int max) { 6837 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6838 "setProcessLimit()"); 6839 synchronized (this) { 6840 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6841 mProcessLimitOverride = max; 6842 } 6843 trimApplications(); 6844 } 6845 6846 @Override 6847 public int getProcessLimit() { 6848 synchronized (this) { 6849 return mProcessLimitOverride; 6850 } 6851 } 6852 6853 void foregroundTokenDied(ForegroundToken token) { 6854 synchronized (ActivityManagerService.this) { 6855 synchronized (mPidsSelfLocked) { 6856 ForegroundToken cur 6857 = mForegroundProcesses.get(token.pid); 6858 if (cur != token) { 6859 return; 6860 } 6861 mForegroundProcesses.remove(token.pid); 6862 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6863 if (pr == null) { 6864 return; 6865 } 6866 pr.forcingToForeground = null; 6867 updateProcessForegroundLocked(pr, false, false); 6868 } 6869 updateOomAdjLocked(); 6870 } 6871 } 6872 6873 @Override 6874 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6875 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6876 "setProcessForeground()"); 6877 synchronized(this) { 6878 boolean changed = false; 6879 6880 synchronized (mPidsSelfLocked) { 6881 ProcessRecord pr = mPidsSelfLocked.get(pid); 6882 if (pr == null && isForeground) { 6883 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6884 return; 6885 } 6886 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6887 if (oldToken != null) { 6888 oldToken.token.unlinkToDeath(oldToken, 0); 6889 mForegroundProcesses.remove(pid); 6890 if (pr != null) { 6891 pr.forcingToForeground = null; 6892 } 6893 changed = true; 6894 } 6895 if (isForeground && token != null) { 6896 ForegroundToken newToken = new ForegroundToken() { 6897 @Override 6898 public void binderDied() { 6899 foregroundTokenDied(this); 6900 } 6901 }; 6902 newToken.pid = pid; 6903 newToken.token = token; 6904 try { 6905 token.linkToDeath(newToken, 0); 6906 mForegroundProcesses.put(pid, newToken); 6907 pr.forcingToForeground = token; 6908 changed = true; 6909 } catch (RemoteException e) { 6910 // If the process died while doing this, we will later 6911 // do the cleanup with the process death link. 6912 } 6913 } 6914 } 6915 6916 if (changed) { 6917 updateOomAdjLocked(); 6918 } 6919 } 6920 } 6921 6922 // ========================================================= 6923 // PERMISSIONS 6924 // ========================================================= 6925 6926 static class PermissionController extends IPermissionController.Stub { 6927 ActivityManagerService mActivityManagerService; 6928 PermissionController(ActivityManagerService activityManagerService) { 6929 mActivityManagerService = activityManagerService; 6930 } 6931 6932 @Override 6933 public boolean checkPermission(String permission, int pid, int uid) { 6934 return mActivityManagerService.checkPermission(permission, pid, 6935 uid) == PackageManager.PERMISSION_GRANTED; 6936 } 6937 } 6938 6939 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6940 @Override 6941 public int checkComponentPermission(String permission, int pid, int uid, 6942 int owningUid, boolean exported) { 6943 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6944 owningUid, exported); 6945 } 6946 6947 @Override 6948 public Object getAMSLock() { 6949 return ActivityManagerService.this; 6950 } 6951 } 6952 6953 /** 6954 * This can be called with or without the global lock held. 6955 */ 6956 int checkComponentPermission(String permission, int pid, int uid, 6957 int owningUid, boolean exported) { 6958 // We might be performing an operation on behalf of an indirect binder 6959 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6960 // client identity accordingly before proceeding. 6961 Identity tlsIdentity = sCallerIdentity.get(); 6962 if (tlsIdentity != null) { 6963 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6964 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6965 uid = tlsIdentity.uid; 6966 pid = tlsIdentity.pid; 6967 } 6968 6969 if (pid == MY_PID) { 6970 return PackageManager.PERMISSION_GRANTED; 6971 } 6972 6973 return ActivityManager.checkComponentPermission(permission, uid, 6974 owningUid, exported); 6975 } 6976 6977 /** 6978 * As the only public entry point for permissions checking, this method 6979 * can enforce the semantic that requesting a check on a null global 6980 * permission is automatically denied. (Internally a null permission 6981 * string is used when calling {@link #checkComponentPermission} in cases 6982 * when only uid-based security is needed.) 6983 * 6984 * This can be called with or without the global lock held. 6985 */ 6986 @Override 6987 public int checkPermission(String permission, int pid, int uid) { 6988 if (permission == null) { 6989 return PackageManager.PERMISSION_DENIED; 6990 } 6991 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6992 } 6993 6994 /** 6995 * Binder IPC calls go through the public entry point. 6996 * This can be called with or without the global lock held. 6997 */ 6998 int checkCallingPermission(String permission) { 6999 return checkPermission(permission, 7000 Binder.getCallingPid(), 7001 UserHandle.getAppId(Binder.getCallingUid())); 7002 } 7003 7004 /** 7005 * This can be called with or without the global lock held. 7006 */ 7007 void enforceCallingPermission(String permission, String func) { 7008 if (checkCallingPermission(permission) 7009 == PackageManager.PERMISSION_GRANTED) { 7010 return; 7011 } 7012 7013 String msg = "Permission Denial: " + func + " from pid=" 7014 + Binder.getCallingPid() 7015 + ", uid=" + Binder.getCallingUid() 7016 + " requires " + permission; 7017 Slog.w(TAG, msg); 7018 throw new SecurityException(msg); 7019 } 7020 7021 /** 7022 * Determine if UID is holding permissions required to access {@link Uri} in 7023 * the given {@link ProviderInfo}. Final permission checking is always done 7024 * in {@link ContentProvider}. 7025 */ 7026 private final boolean checkHoldingPermissionsLocked( 7027 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7028 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7029 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7030 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7031 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7032 != PERMISSION_GRANTED) { 7033 return false; 7034 } 7035 } 7036 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7037 } 7038 7039 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7040 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7041 if (pi.applicationInfo.uid == uid) { 7042 return true; 7043 } else if (!pi.exported) { 7044 return false; 7045 } 7046 7047 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7048 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7049 try { 7050 // check if target holds top-level <provider> permissions 7051 if (!readMet && pi.readPermission != null && considerUidPermissions 7052 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7053 readMet = true; 7054 } 7055 if (!writeMet && pi.writePermission != null && considerUidPermissions 7056 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7057 writeMet = true; 7058 } 7059 7060 // track if unprotected read/write is allowed; any denied 7061 // <path-permission> below removes this ability 7062 boolean allowDefaultRead = pi.readPermission == null; 7063 boolean allowDefaultWrite = pi.writePermission == null; 7064 7065 // check if target holds any <path-permission> that match uri 7066 final PathPermission[] pps = pi.pathPermissions; 7067 if (pps != null) { 7068 final String path = grantUri.uri.getPath(); 7069 int i = pps.length; 7070 while (i > 0 && (!readMet || !writeMet)) { 7071 i--; 7072 PathPermission pp = pps[i]; 7073 if (pp.match(path)) { 7074 if (!readMet) { 7075 final String pprperm = pp.getReadPermission(); 7076 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7077 + pprperm + " for " + pp.getPath() 7078 + ": match=" + pp.match(path) 7079 + " check=" + pm.checkUidPermission(pprperm, uid)); 7080 if (pprperm != null) { 7081 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7082 == PERMISSION_GRANTED) { 7083 readMet = true; 7084 } else { 7085 allowDefaultRead = false; 7086 } 7087 } 7088 } 7089 if (!writeMet) { 7090 final String ppwperm = pp.getWritePermission(); 7091 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7092 + ppwperm + " for " + pp.getPath() 7093 + ": match=" + pp.match(path) 7094 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7095 if (ppwperm != null) { 7096 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7097 == PERMISSION_GRANTED) { 7098 writeMet = true; 7099 } else { 7100 allowDefaultWrite = false; 7101 } 7102 } 7103 } 7104 } 7105 } 7106 } 7107 7108 // grant unprotected <provider> read/write, if not blocked by 7109 // <path-permission> above 7110 if (allowDefaultRead) readMet = true; 7111 if (allowDefaultWrite) writeMet = true; 7112 7113 } catch (RemoteException e) { 7114 return false; 7115 } 7116 7117 return readMet && writeMet; 7118 } 7119 7120 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7121 ProviderInfo pi = null; 7122 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7123 if (cpr != null) { 7124 pi = cpr.info; 7125 } else { 7126 try { 7127 pi = AppGlobals.getPackageManager().resolveContentProvider( 7128 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7129 } catch (RemoteException ex) { 7130 } 7131 } 7132 return pi; 7133 } 7134 7135 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7136 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7137 if (targetUris != null) { 7138 return targetUris.get(grantUri); 7139 } 7140 return null; 7141 } 7142 7143 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7144 String targetPkg, int targetUid, GrantUri grantUri) { 7145 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7146 if (targetUris == null) { 7147 targetUris = Maps.newArrayMap(); 7148 mGrantedUriPermissions.put(targetUid, targetUris); 7149 } 7150 7151 UriPermission perm = targetUris.get(grantUri); 7152 if (perm == null) { 7153 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7154 targetUris.put(grantUri, perm); 7155 } 7156 7157 return perm; 7158 } 7159 7160 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7161 final int modeFlags) { 7162 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7163 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7164 : UriPermission.STRENGTH_OWNED; 7165 7166 // Root gets to do everything. 7167 if (uid == 0) { 7168 return true; 7169 } 7170 7171 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7172 if (perms == null) return false; 7173 7174 // First look for exact match 7175 final UriPermission exactPerm = perms.get(grantUri); 7176 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7177 return true; 7178 } 7179 7180 // No exact match, look for prefixes 7181 final int N = perms.size(); 7182 for (int i = 0; i < N; i++) { 7183 final UriPermission perm = perms.valueAt(i); 7184 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7185 && perm.getStrength(modeFlags) >= minStrength) { 7186 return true; 7187 } 7188 } 7189 7190 return false; 7191 } 7192 7193 /** 7194 * @param uri This uri must NOT contain an embedded userId. 7195 * @param userId The userId in which the uri is to be resolved. 7196 */ 7197 @Override 7198 public int checkUriPermission(Uri uri, int pid, int uid, 7199 final int modeFlags, int userId) { 7200 enforceNotIsolatedCaller("checkUriPermission"); 7201 7202 // Another redirected-binder-call permissions check as in 7203 // {@link checkComponentPermission}. 7204 Identity tlsIdentity = sCallerIdentity.get(); 7205 if (tlsIdentity != null) { 7206 uid = tlsIdentity.uid; 7207 pid = tlsIdentity.pid; 7208 } 7209 7210 // Our own process gets to do everything. 7211 if (pid == MY_PID) { 7212 return PackageManager.PERMISSION_GRANTED; 7213 } 7214 synchronized (this) { 7215 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7216 ? PackageManager.PERMISSION_GRANTED 7217 : PackageManager.PERMISSION_DENIED; 7218 } 7219 } 7220 7221 /** 7222 * Check if the targetPkg can be granted permission to access uri by 7223 * the callingUid using the given modeFlags. Throws a security exception 7224 * if callingUid is not allowed to do this. Returns the uid of the target 7225 * if the URI permission grant should be performed; returns -1 if it is not 7226 * needed (for example targetPkg already has permission to access the URI). 7227 * If you already know the uid of the target, you can supply it in 7228 * lastTargetUid else set that to -1. 7229 */ 7230 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7231 final int modeFlags, int lastTargetUid) { 7232 if (!Intent.isAccessUriMode(modeFlags)) { 7233 return -1; 7234 } 7235 7236 if (targetPkg != null) { 7237 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7238 "Checking grant " + targetPkg + " permission to " + grantUri); 7239 } 7240 7241 final IPackageManager pm = AppGlobals.getPackageManager(); 7242 7243 // If this is not a content: uri, we can't do anything with it. 7244 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7245 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7246 "Can't grant URI permission for non-content URI: " + grantUri); 7247 return -1; 7248 } 7249 7250 final String authority = grantUri.uri.getAuthority(); 7251 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7252 if (pi == null) { 7253 Slog.w(TAG, "No content provider found for permission check: " + 7254 grantUri.uri.toSafeString()); 7255 return -1; 7256 } 7257 7258 int targetUid = lastTargetUid; 7259 if (targetUid < 0 && targetPkg != null) { 7260 try { 7261 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7262 if (targetUid < 0) { 7263 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7264 "Can't grant URI permission no uid for: " + targetPkg); 7265 return -1; 7266 } 7267 } catch (RemoteException ex) { 7268 return -1; 7269 } 7270 } 7271 7272 if (targetUid >= 0) { 7273 // First... does the target actually need this permission? 7274 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7275 // No need to grant the target this permission. 7276 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7277 "Target " + targetPkg + " already has full permission to " + grantUri); 7278 return -1; 7279 } 7280 } else { 7281 // First... there is no target package, so can anyone access it? 7282 boolean allowed = pi.exported; 7283 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7284 if (pi.readPermission != null) { 7285 allowed = false; 7286 } 7287 } 7288 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7289 if (pi.writePermission != null) { 7290 allowed = false; 7291 } 7292 } 7293 if (allowed) { 7294 return -1; 7295 } 7296 } 7297 7298 /* There is a special cross user grant if: 7299 * - The target is on another user. 7300 * - Apps on the current user can access the uri without any uid permissions. 7301 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7302 * grant uri permissions. 7303 */ 7304 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7305 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7306 modeFlags, false /*without considering the uid permissions*/); 7307 7308 // Second... is the provider allowing granting of URI permissions? 7309 if (!specialCrossUserGrant) { 7310 if (!pi.grantUriPermissions) { 7311 throw new SecurityException("Provider " + pi.packageName 7312 + "/" + pi.name 7313 + " does not allow granting of Uri permissions (uri " 7314 + grantUri + ")"); 7315 } 7316 if (pi.uriPermissionPatterns != null) { 7317 final int N = pi.uriPermissionPatterns.length; 7318 boolean allowed = false; 7319 for (int i=0; i<N; i++) { 7320 if (pi.uriPermissionPatterns[i] != null 7321 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7322 allowed = true; 7323 break; 7324 } 7325 } 7326 if (!allowed) { 7327 throw new SecurityException("Provider " + pi.packageName 7328 + "/" + pi.name 7329 + " does not allow granting of permission to path of Uri " 7330 + grantUri); 7331 } 7332 } 7333 } 7334 7335 // Third... does the caller itself have permission to access 7336 // this uri? 7337 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7338 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7339 // Require they hold a strong enough Uri permission 7340 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7341 throw new SecurityException("Uid " + callingUid 7342 + " does not have permission to uri " + grantUri); 7343 } 7344 } 7345 } 7346 return targetUid; 7347 } 7348 7349 /** 7350 * @param uri This uri must NOT contain an embedded userId. 7351 * @param userId The userId in which the uri is to be resolved. 7352 */ 7353 @Override 7354 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7355 final int modeFlags, int userId) { 7356 enforceNotIsolatedCaller("checkGrantUriPermission"); 7357 synchronized(this) { 7358 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7359 new GrantUri(userId, uri, false), modeFlags, -1); 7360 } 7361 } 7362 7363 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7364 final int modeFlags, UriPermissionOwner owner) { 7365 if (!Intent.isAccessUriMode(modeFlags)) { 7366 return; 7367 } 7368 7369 // So here we are: the caller has the assumed permission 7370 // to the uri, and the target doesn't. Let's now give this to 7371 // the target. 7372 7373 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7374 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7375 7376 final String authority = grantUri.uri.getAuthority(); 7377 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7378 if (pi == null) { 7379 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7380 return; 7381 } 7382 7383 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7384 grantUri.prefix = true; 7385 } 7386 final UriPermission perm = findOrCreateUriPermissionLocked( 7387 pi.packageName, targetPkg, targetUid, grantUri); 7388 perm.grantModes(modeFlags, owner); 7389 } 7390 7391 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7392 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7393 if (targetPkg == null) { 7394 throw new NullPointerException("targetPkg"); 7395 } 7396 int targetUid; 7397 final IPackageManager pm = AppGlobals.getPackageManager(); 7398 try { 7399 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7400 } catch (RemoteException ex) { 7401 return; 7402 } 7403 7404 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7405 targetUid); 7406 if (targetUid < 0) { 7407 return; 7408 } 7409 7410 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7411 owner); 7412 } 7413 7414 static class NeededUriGrants extends ArrayList<GrantUri> { 7415 final String targetPkg; 7416 final int targetUid; 7417 final int flags; 7418 7419 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7420 this.targetPkg = targetPkg; 7421 this.targetUid = targetUid; 7422 this.flags = flags; 7423 } 7424 } 7425 7426 /** 7427 * Like checkGrantUriPermissionLocked, but takes an Intent. 7428 */ 7429 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7430 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7431 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7432 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7433 + " clip=" + (intent != null ? intent.getClipData() : null) 7434 + " from " + intent + "; flags=0x" 7435 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7436 7437 if (targetPkg == null) { 7438 throw new NullPointerException("targetPkg"); 7439 } 7440 7441 if (intent == null) { 7442 return null; 7443 } 7444 Uri data = intent.getData(); 7445 ClipData clip = intent.getClipData(); 7446 if (data == null && clip == null) { 7447 return null; 7448 } 7449 // Default userId for uris in the intent (if they don't specify it themselves) 7450 int contentUserHint = intent.getContentUserHint(); 7451 if (contentUserHint == UserHandle.USER_CURRENT) { 7452 contentUserHint = UserHandle.getUserId(callingUid); 7453 } 7454 final IPackageManager pm = AppGlobals.getPackageManager(); 7455 int targetUid; 7456 if (needed != null) { 7457 targetUid = needed.targetUid; 7458 } else { 7459 try { 7460 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7461 } catch (RemoteException ex) { 7462 return null; 7463 } 7464 if (targetUid < 0) { 7465 if (DEBUG_URI_PERMISSION) { 7466 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7467 + " on user " + targetUserId); 7468 } 7469 return null; 7470 } 7471 } 7472 if (data != null) { 7473 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7474 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7475 targetUid); 7476 if (targetUid > 0) { 7477 if (needed == null) { 7478 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7479 } 7480 needed.add(grantUri); 7481 } 7482 } 7483 if (clip != null) { 7484 for (int i=0; i<clip.getItemCount(); i++) { 7485 Uri uri = clip.getItemAt(i).getUri(); 7486 if (uri != null) { 7487 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7488 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7489 targetUid); 7490 if (targetUid > 0) { 7491 if (needed == null) { 7492 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7493 } 7494 needed.add(grantUri); 7495 } 7496 } else { 7497 Intent clipIntent = clip.getItemAt(i).getIntent(); 7498 if (clipIntent != null) { 7499 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7500 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7501 if (newNeeded != null) { 7502 needed = newNeeded; 7503 } 7504 } 7505 } 7506 } 7507 } 7508 7509 return needed; 7510 } 7511 7512 /** 7513 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7514 */ 7515 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7516 UriPermissionOwner owner) { 7517 if (needed != null) { 7518 for (int i=0; i<needed.size(); i++) { 7519 GrantUri grantUri = needed.get(i); 7520 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7521 grantUri, needed.flags, owner); 7522 } 7523 } 7524 } 7525 7526 void grantUriPermissionFromIntentLocked(int callingUid, 7527 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7528 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7529 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7530 if (needed == null) { 7531 return; 7532 } 7533 7534 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7535 } 7536 7537 /** 7538 * @param uri This uri must NOT contain an embedded userId. 7539 * @param userId The userId in which the uri is to be resolved. 7540 */ 7541 @Override 7542 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7543 final int modeFlags, int userId) { 7544 enforceNotIsolatedCaller("grantUriPermission"); 7545 GrantUri grantUri = new GrantUri(userId, uri, false); 7546 synchronized(this) { 7547 final ProcessRecord r = getRecordForAppLocked(caller); 7548 if (r == null) { 7549 throw new SecurityException("Unable to find app for caller " 7550 + caller 7551 + " when granting permission to uri " + grantUri); 7552 } 7553 if (targetPkg == null) { 7554 throw new IllegalArgumentException("null target"); 7555 } 7556 if (grantUri == null) { 7557 throw new IllegalArgumentException("null uri"); 7558 } 7559 7560 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7561 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7562 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7563 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7564 7565 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7566 UserHandle.getUserId(r.uid)); 7567 } 7568 } 7569 7570 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7571 if (perm.modeFlags == 0) { 7572 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7573 perm.targetUid); 7574 if (perms != null) { 7575 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7576 "Removing " + perm.targetUid + " permission to " + perm.uri); 7577 7578 perms.remove(perm.uri); 7579 if (perms.isEmpty()) { 7580 mGrantedUriPermissions.remove(perm.targetUid); 7581 } 7582 } 7583 } 7584 } 7585 7586 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7587 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7588 7589 final IPackageManager pm = AppGlobals.getPackageManager(); 7590 final String authority = grantUri.uri.getAuthority(); 7591 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7592 if (pi == null) { 7593 Slog.w(TAG, "No content provider found for permission revoke: " 7594 + grantUri.toSafeString()); 7595 return; 7596 } 7597 7598 // Does the caller have this permission on the URI? 7599 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7600 // If they don't have direct access to the URI, then revoke any 7601 // ownerless URI permissions that have been granted to them. 7602 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7603 if (perms != null) { 7604 boolean persistChanged = false; 7605 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7606 final UriPermission perm = it.next(); 7607 if (perm.uri.sourceUserId == grantUri.sourceUserId 7608 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7609 if (DEBUG_URI_PERMISSION) 7610 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7611 " permission to " + perm.uri); 7612 persistChanged |= perm.revokeModes( 7613 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7614 if (perm.modeFlags == 0) { 7615 it.remove(); 7616 } 7617 } 7618 } 7619 if (perms.isEmpty()) { 7620 mGrantedUriPermissions.remove(callingUid); 7621 } 7622 if (persistChanged) { 7623 schedulePersistUriGrants(); 7624 } 7625 } 7626 return; 7627 } 7628 7629 boolean persistChanged = false; 7630 7631 // Go through all of the permissions and remove any that match. 7632 int N = mGrantedUriPermissions.size(); 7633 for (int i = 0; i < N; i++) { 7634 final int targetUid = mGrantedUriPermissions.keyAt(i); 7635 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7636 7637 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7638 final UriPermission perm = it.next(); 7639 if (perm.uri.sourceUserId == grantUri.sourceUserId 7640 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7641 if (DEBUG_URI_PERMISSION) 7642 Slog.v(TAG, 7643 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7644 persistChanged |= perm.revokeModes( 7645 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7646 if (perm.modeFlags == 0) { 7647 it.remove(); 7648 } 7649 } 7650 } 7651 7652 if (perms.isEmpty()) { 7653 mGrantedUriPermissions.remove(targetUid); 7654 N--; 7655 i--; 7656 } 7657 } 7658 7659 if (persistChanged) { 7660 schedulePersistUriGrants(); 7661 } 7662 } 7663 7664 /** 7665 * @param uri This uri must NOT contain an embedded userId. 7666 * @param userId The userId in which the uri is to be resolved. 7667 */ 7668 @Override 7669 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7670 int userId) { 7671 enforceNotIsolatedCaller("revokeUriPermission"); 7672 synchronized(this) { 7673 final ProcessRecord r = getRecordForAppLocked(caller); 7674 if (r == null) { 7675 throw new SecurityException("Unable to find app for caller " 7676 + caller 7677 + " when revoking permission to uri " + uri); 7678 } 7679 if (uri == null) { 7680 Slog.w(TAG, "revokeUriPermission: null uri"); 7681 return; 7682 } 7683 7684 if (!Intent.isAccessUriMode(modeFlags)) { 7685 return; 7686 } 7687 7688 final IPackageManager pm = AppGlobals.getPackageManager(); 7689 final String authority = uri.getAuthority(); 7690 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7691 if (pi == null) { 7692 Slog.w(TAG, "No content provider found for permission revoke: " 7693 + uri.toSafeString()); 7694 return; 7695 } 7696 7697 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7698 } 7699 } 7700 7701 /** 7702 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7703 * given package. 7704 * 7705 * @param packageName Package name to match, or {@code null} to apply to all 7706 * packages. 7707 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7708 * to all users. 7709 * @param persistable If persistable grants should be removed. 7710 */ 7711 private void removeUriPermissionsForPackageLocked( 7712 String packageName, int userHandle, boolean persistable) { 7713 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7714 throw new IllegalArgumentException("Must narrow by either package or user"); 7715 } 7716 7717 boolean persistChanged = false; 7718 7719 int N = mGrantedUriPermissions.size(); 7720 for (int i = 0; i < N; i++) { 7721 final int targetUid = mGrantedUriPermissions.keyAt(i); 7722 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7723 7724 // Only inspect grants matching user 7725 if (userHandle == UserHandle.USER_ALL 7726 || userHandle == UserHandle.getUserId(targetUid)) { 7727 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7728 final UriPermission perm = it.next(); 7729 7730 // Only inspect grants matching package 7731 if (packageName == null || perm.sourcePkg.equals(packageName) 7732 || perm.targetPkg.equals(packageName)) { 7733 persistChanged |= perm.revokeModes(persistable 7734 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7735 7736 // Only remove when no modes remain; any persisted grants 7737 // will keep this alive. 7738 if (perm.modeFlags == 0) { 7739 it.remove(); 7740 } 7741 } 7742 } 7743 7744 if (perms.isEmpty()) { 7745 mGrantedUriPermissions.remove(targetUid); 7746 N--; 7747 i--; 7748 } 7749 } 7750 } 7751 7752 if (persistChanged) { 7753 schedulePersistUriGrants(); 7754 } 7755 } 7756 7757 @Override 7758 public IBinder newUriPermissionOwner(String name) { 7759 enforceNotIsolatedCaller("newUriPermissionOwner"); 7760 synchronized(this) { 7761 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7762 return owner.getExternalTokenLocked(); 7763 } 7764 } 7765 7766 /** 7767 * @param uri This uri must NOT contain an embedded userId. 7768 * @param sourceUserId The userId in which the uri is to be resolved. 7769 * @param targetUserId The userId of the app that receives the grant. 7770 */ 7771 @Override 7772 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7773 final int modeFlags, int sourceUserId, int targetUserId) { 7774 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7775 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7776 synchronized(this) { 7777 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7778 if (owner == null) { 7779 throw new IllegalArgumentException("Unknown owner: " + token); 7780 } 7781 if (fromUid != Binder.getCallingUid()) { 7782 if (Binder.getCallingUid() != Process.myUid()) { 7783 // Only system code can grant URI permissions on behalf 7784 // of other users. 7785 throw new SecurityException("nice try"); 7786 } 7787 } 7788 if (targetPkg == null) { 7789 throw new IllegalArgumentException("null target"); 7790 } 7791 if (uri == null) { 7792 throw new IllegalArgumentException("null uri"); 7793 } 7794 7795 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7796 modeFlags, owner, targetUserId); 7797 } 7798 } 7799 7800 /** 7801 * @param uri This uri must NOT contain an embedded userId. 7802 * @param userId The userId in which the uri is to be resolved. 7803 */ 7804 @Override 7805 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7806 synchronized(this) { 7807 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7808 if (owner == null) { 7809 throw new IllegalArgumentException("Unknown owner: " + token); 7810 } 7811 7812 if (uri == null) { 7813 owner.removeUriPermissionsLocked(mode); 7814 } else { 7815 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7816 } 7817 } 7818 } 7819 7820 private void schedulePersistUriGrants() { 7821 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7822 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7823 10 * DateUtils.SECOND_IN_MILLIS); 7824 } 7825 } 7826 7827 private void writeGrantedUriPermissions() { 7828 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7829 7830 // Snapshot permissions so we can persist without lock 7831 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7832 synchronized (this) { 7833 final int size = mGrantedUriPermissions.size(); 7834 for (int i = 0; i < size; i++) { 7835 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7836 for (UriPermission perm : perms.values()) { 7837 if (perm.persistedModeFlags != 0) { 7838 persist.add(perm.snapshot()); 7839 } 7840 } 7841 } 7842 } 7843 7844 FileOutputStream fos = null; 7845 try { 7846 fos = mGrantFile.startWrite(); 7847 7848 XmlSerializer out = new FastXmlSerializer(); 7849 out.setOutput(fos, "utf-8"); 7850 out.startDocument(null, true); 7851 out.startTag(null, TAG_URI_GRANTS); 7852 for (UriPermission.Snapshot perm : persist) { 7853 out.startTag(null, TAG_URI_GRANT); 7854 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7855 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7856 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7857 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7858 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7859 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7860 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7861 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7862 out.endTag(null, TAG_URI_GRANT); 7863 } 7864 out.endTag(null, TAG_URI_GRANTS); 7865 out.endDocument(); 7866 7867 mGrantFile.finishWrite(fos); 7868 } catch (IOException e) { 7869 if (fos != null) { 7870 mGrantFile.failWrite(fos); 7871 } 7872 } 7873 } 7874 7875 private void readGrantedUriPermissionsLocked() { 7876 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7877 7878 final long now = System.currentTimeMillis(); 7879 7880 FileInputStream fis = null; 7881 try { 7882 fis = mGrantFile.openRead(); 7883 final XmlPullParser in = Xml.newPullParser(); 7884 in.setInput(fis, null); 7885 7886 int type; 7887 while ((type = in.next()) != END_DOCUMENT) { 7888 final String tag = in.getName(); 7889 if (type == START_TAG) { 7890 if (TAG_URI_GRANT.equals(tag)) { 7891 final int sourceUserId; 7892 final int targetUserId; 7893 final int userHandle = readIntAttribute(in, 7894 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7895 if (userHandle != UserHandle.USER_NULL) { 7896 // For backwards compatibility. 7897 sourceUserId = userHandle; 7898 targetUserId = userHandle; 7899 } else { 7900 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7901 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7902 } 7903 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7904 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7905 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7906 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7907 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7908 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7909 7910 // Sanity check that provider still belongs to source package 7911 final ProviderInfo pi = getProviderInfoLocked( 7912 uri.getAuthority(), sourceUserId); 7913 if (pi != null && sourcePkg.equals(pi.packageName)) { 7914 int targetUid = -1; 7915 try { 7916 targetUid = AppGlobals.getPackageManager() 7917 .getPackageUid(targetPkg, targetUserId); 7918 } catch (RemoteException e) { 7919 } 7920 if (targetUid != -1) { 7921 final UriPermission perm = findOrCreateUriPermissionLocked( 7922 sourcePkg, targetPkg, targetUid, 7923 new GrantUri(sourceUserId, uri, prefix)); 7924 perm.initPersistedModes(modeFlags, createdTime); 7925 } 7926 } else { 7927 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7928 + " but instead found " + pi); 7929 } 7930 } 7931 } 7932 } 7933 } catch (FileNotFoundException e) { 7934 // Missing grants is okay 7935 } catch (IOException e) { 7936 Slog.wtf(TAG, "Failed reading Uri grants", e); 7937 } catch (XmlPullParserException e) { 7938 Slog.wtf(TAG, "Failed reading Uri grants", e); 7939 } finally { 7940 IoUtils.closeQuietly(fis); 7941 } 7942 } 7943 7944 /** 7945 * @param uri This uri must NOT contain an embedded userId. 7946 * @param userId The userId in which the uri is to be resolved. 7947 */ 7948 @Override 7949 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7950 enforceNotIsolatedCaller("takePersistableUriPermission"); 7951 7952 Preconditions.checkFlagsArgument(modeFlags, 7953 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7954 7955 synchronized (this) { 7956 final int callingUid = Binder.getCallingUid(); 7957 boolean persistChanged = false; 7958 GrantUri grantUri = new GrantUri(userId, uri, false); 7959 7960 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7961 new GrantUri(userId, uri, false)); 7962 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7963 new GrantUri(userId, uri, true)); 7964 7965 final boolean exactValid = (exactPerm != null) 7966 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7967 final boolean prefixValid = (prefixPerm != null) 7968 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7969 7970 if (!(exactValid || prefixValid)) { 7971 throw new SecurityException("No persistable permission grants found for UID " 7972 + callingUid + " and Uri " + grantUri.toSafeString()); 7973 } 7974 7975 if (exactValid) { 7976 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7977 } 7978 if (prefixValid) { 7979 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7980 } 7981 7982 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7983 7984 if (persistChanged) { 7985 schedulePersistUriGrants(); 7986 } 7987 } 7988 } 7989 7990 /** 7991 * @param uri This uri must NOT contain an embedded userId. 7992 * @param userId The userId in which the uri is to be resolved. 7993 */ 7994 @Override 7995 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7996 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7997 7998 Preconditions.checkFlagsArgument(modeFlags, 7999 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 8000 8001 synchronized (this) { 8002 final int callingUid = Binder.getCallingUid(); 8003 boolean persistChanged = false; 8004 8005 UriPermission exactPerm = findUriPermissionLocked(callingUid, 8006 new GrantUri(userId, uri, false)); 8007 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8008 new GrantUri(userId, uri, true)); 8009 if (exactPerm == null && prefixPerm == null) { 8010 throw new SecurityException("No permission grants found for UID " + callingUid 8011 + " and Uri " + uri.toSafeString()); 8012 } 8013 8014 if (exactPerm != null) { 8015 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8016 removeUriPermissionIfNeededLocked(exactPerm); 8017 } 8018 if (prefixPerm != null) { 8019 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8020 removeUriPermissionIfNeededLocked(prefixPerm); 8021 } 8022 8023 if (persistChanged) { 8024 schedulePersistUriGrants(); 8025 } 8026 } 8027 } 8028 8029 /** 8030 * Prune any older {@link UriPermission} for the given UID until outstanding 8031 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8032 * 8033 * @return if any mutations occured that require persisting. 8034 */ 8035 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8036 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8037 if (perms == null) return false; 8038 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8039 8040 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8041 for (UriPermission perm : perms.values()) { 8042 if (perm.persistedModeFlags != 0) { 8043 persisted.add(perm); 8044 } 8045 } 8046 8047 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8048 if (trimCount <= 0) return false; 8049 8050 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8051 for (int i = 0; i < trimCount; i++) { 8052 final UriPermission perm = persisted.get(i); 8053 8054 if (DEBUG_URI_PERMISSION) { 8055 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8056 } 8057 8058 perm.releasePersistableModes(~0); 8059 removeUriPermissionIfNeededLocked(perm); 8060 } 8061 8062 return true; 8063 } 8064 8065 @Override 8066 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8067 String packageName, boolean incoming) { 8068 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8069 Preconditions.checkNotNull(packageName, "packageName"); 8070 8071 final int callingUid = Binder.getCallingUid(); 8072 final IPackageManager pm = AppGlobals.getPackageManager(); 8073 try { 8074 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8075 if (packageUid != callingUid) { 8076 throw new SecurityException( 8077 "Package " + packageName + " does not belong to calling UID " + callingUid); 8078 } 8079 } catch (RemoteException e) { 8080 throw new SecurityException("Failed to verify package name ownership"); 8081 } 8082 8083 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8084 synchronized (this) { 8085 if (incoming) { 8086 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8087 callingUid); 8088 if (perms == null) { 8089 Slog.w(TAG, "No permission grants found for " + packageName); 8090 } else { 8091 for (UriPermission perm : perms.values()) { 8092 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8093 result.add(perm.buildPersistedPublicApiObject()); 8094 } 8095 } 8096 } 8097 } else { 8098 final int size = mGrantedUriPermissions.size(); 8099 for (int i = 0; i < size; i++) { 8100 final ArrayMap<GrantUri, UriPermission> perms = 8101 mGrantedUriPermissions.valueAt(i); 8102 for (UriPermission perm : perms.values()) { 8103 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8104 result.add(perm.buildPersistedPublicApiObject()); 8105 } 8106 } 8107 } 8108 } 8109 } 8110 return new ParceledListSlice<android.content.UriPermission>(result); 8111 } 8112 8113 @Override 8114 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8115 synchronized (this) { 8116 ProcessRecord app = 8117 who != null ? getRecordForAppLocked(who) : null; 8118 if (app == null) return; 8119 8120 Message msg = Message.obtain(); 8121 msg.what = WAIT_FOR_DEBUGGER_MSG; 8122 msg.obj = app; 8123 msg.arg1 = waiting ? 1 : 0; 8124 mHandler.sendMessage(msg); 8125 } 8126 } 8127 8128 @Override 8129 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8130 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8131 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8132 outInfo.availMem = Process.getFreeMemory(); 8133 outInfo.totalMem = Process.getTotalMemory(); 8134 outInfo.threshold = homeAppMem; 8135 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8136 outInfo.hiddenAppThreshold = cachedAppMem; 8137 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8138 ProcessList.SERVICE_ADJ); 8139 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8140 ProcessList.VISIBLE_APP_ADJ); 8141 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8142 ProcessList.FOREGROUND_APP_ADJ); 8143 } 8144 8145 // ========================================================= 8146 // TASK MANAGEMENT 8147 // ========================================================= 8148 8149 @Override 8150 public List<IAppTask> getAppTasks(String callingPackage) { 8151 int callingUid = Binder.getCallingUid(); 8152 long ident = Binder.clearCallingIdentity(); 8153 8154 synchronized(this) { 8155 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8156 try { 8157 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8158 8159 final int N = mRecentTasks.size(); 8160 for (int i = 0; i < N; i++) { 8161 TaskRecord tr = mRecentTasks.get(i); 8162 // Skip tasks that do not match the caller. We don't need to verify 8163 // callingPackage, because we are also limiting to callingUid and know 8164 // that will limit to the correct security sandbox. 8165 if (tr.effectiveUid != callingUid) { 8166 continue; 8167 } 8168 Intent intent = tr.getBaseIntent(); 8169 if (intent == null || 8170 !callingPackage.equals(intent.getComponent().getPackageName())) { 8171 continue; 8172 } 8173 ActivityManager.RecentTaskInfo taskInfo = 8174 createRecentTaskInfoFromTaskRecord(tr); 8175 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8176 list.add(taskImpl); 8177 } 8178 } finally { 8179 Binder.restoreCallingIdentity(ident); 8180 } 8181 return list; 8182 } 8183 } 8184 8185 @Override 8186 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8187 final int callingUid = Binder.getCallingUid(); 8188 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8189 8190 synchronized(this) { 8191 if (localLOGV) Slog.v( 8192 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8193 8194 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8195 callingUid); 8196 8197 // TODO: Improve with MRU list from all ActivityStacks. 8198 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8199 } 8200 8201 return list; 8202 } 8203 8204 TaskRecord getMostRecentTask() { 8205 return mRecentTasks.get(0); 8206 } 8207 8208 /** 8209 * Creates a new RecentTaskInfo from a TaskRecord. 8210 */ 8211 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8212 // Update the task description to reflect any changes in the task stack 8213 tr.updateTaskDescription(); 8214 8215 // Compose the recent task info 8216 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8217 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8218 rti.persistentId = tr.taskId; 8219 rti.baseIntent = new Intent(tr.getBaseIntent()); 8220 rti.origActivity = tr.origActivity; 8221 rti.description = tr.lastDescription; 8222 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8223 rti.userId = tr.userId; 8224 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8225 rti.firstActiveTime = tr.firstActiveTime; 8226 rti.lastActiveTime = tr.lastActiveTime; 8227 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8228 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8229 return rti; 8230 } 8231 8232 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8233 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8234 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8235 if (!allowed) { 8236 if (checkPermission(android.Manifest.permission.GET_TASKS, 8237 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8238 // Temporary compatibility: some existing apps on the system image may 8239 // still be requesting the old permission and not switched to the new 8240 // one; if so, we'll still allow them full access. This means we need 8241 // to see if they are holding the old permission and are a system app. 8242 try { 8243 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8244 allowed = true; 8245 Slog.w(TAG, caller + ": caller " + callingUid 8246 + " is using old GET_TASKS but privileged; allowing"); 8247 } 8248 } catch (RemoteException e) { 8249 } 8250 } 8251 } 8252 if (!allowed) { 8253 Slog.w(TAG, caller + ": caller " + callingUid 8254 + " does not hold GET_TASKS; limiting output"); 8255 } 8256 return allowed; 8257 } 8258 8259 @Override 8260 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8261 final int callingUid = Binder.getCallingUid(); 8262 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8263 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8264 8265 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8266 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8267 synchronized (this) { 8268 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8269 callingUid); 8270 final boolean detailed = checkCallingPermission( 8271 android.Manifest.permission.GET_DETAILED_TASKS) 8272 == PackageManager.PERMISSION_GRANTED; 8273 8274 final int N = mRecentTasks.size(); 8275 ArrayList<ActivityManager.RecentTaskInfo> res 8276 = new ArrayList<ActivityManager.RecentTaskInfo>( 8277 maxNum < N ? maxNum : N); 8278 8279 final Set<Integer> includedUsers; 8280 if (includeProfiles) { 8281 includedUsers = getProfileIdsLocked(userId); 8282 } else { 8283 includedUsers = new HashSet<Integer>(); 8284 } 8285 includedUsers.add(Integer.valueOf(userId)); 8286 8287 for (int i=0; i<N && maxNum > 0; i++) { 8288 TaskRecord tr = mRecentTasks.get(i); 8289 // Only add calling user or related users recent tasks 8290 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8291 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8292 continue; 8293 } 8294 8295 // Return the entry if desired by the caller. We always return 8296 // the first entry, because callers always expect this to be the 8297 // foreground app. We may filter others if the caller has 8298 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8299 // we should exclude the entry. 8300 8301 if (i == 0 8302 || withExcluded 8303 || (tr.intent == null) 8304 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8305 == 0)) { 8306 if (!allowed) { 8307 // If the caller doesn't have the GET_TASKS permission, then only 8308 // allow them to see a small subset of tasks -- their own and home. 8309 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8310 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8311 continue; 8312 } 8313 } 8314 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8315 if (tr.stack != null && tr.stack.isHomeStack()) { 8316 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8317 continue; 8318 } 8319 } 8320 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8321 // Don't include auto remove tasks that are finished or finishing. 8322 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8323 + tr); 8324 continue; 8325 } 8326 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8327 && !tr.isAvailable) { 8328 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8329 continue; 8330 } 8331 8332 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8333 if (!detailed) { 8334 rti.baseIntent.replaceExtras((Bundle)null); 8335 } 8336 8337 res.add(rti); 8338 maxNum--; 8339 } 8340 } 8341 return res; 8342 } 8343 } 8344 8345 private TaskRecord recentTaskForIdLocked(int id) { 8346 final int N = mRecentTasks.size(); 8347 for (int i=0; i<N; i++) { 8348 TaskRecord tr = mRecentTasks.get(i); 8349 if (tr.taskId == id) { 8350 return tr; 8351 } 8352 } 8353 return null; 8354 } 8355 8356 @Override 8357 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8358 synchronized (this) { 8359 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8360 "getTaskThumbnail()"); 8361 TaskRecord tr = recentTaskForIdLocked(id); 8362 if (tr != null) { 8363 return tr.getTaskThumbnailLocked(); 8364 } 8365 } 8366 return null; 8367 } 8368 8369 @Override 8370 public int addAppTask(IBinder activityToken, Intent intent, 8371 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8372 final int callingUid = Binder.getCallingUid(); 8373 final long callingIdent = Binder.clearCallingIdentity(); 8374 8375 try { 8376 synchronized (this) { 8377 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8378 if (r == null) { 8379 throw new IllegalArgumentException("Activity does not exist; token=" 8380 + activityToken); 8381 } 8382 ComponentName comp = intent.getComponent(); 8383 if (comp == null) { 8384 throw new IllegalArgumentException("Intent " + intent 8385 + " must specify explicit component"); 8386 } 8387 if (thumbnail.getWidth() != mThumbnailWidth 8388 || thumbnail.getHeight() != mThumbnailHeight) { 8389 throw new IllegalArgumentException("Bad thumbnail size: got " 8390 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8391 + mThumbnailWidth + "x" + mThumbnailHeight); 8392 } 8393 if (intent.getSelector() != null) { 8394 intent.setSelector(null); 8395 } 8396 if (intent.getSourceBounds() != null) { 8397 intent.setSourceBounds(null); 8398 } 8399 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8400 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8401 // The caller has added this as an auto-remove task... that makes no 8402 // sense, so turn off auto-remove. 8403 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8404 } 8405 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8406 // Must be a new task. 8407 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8408 } 8409 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8410 mLastAddedTaskActivity = null; 8411 } 8412 ActivityInfo ainfo = mLastAddedTaskActivity; 8413 if (ainfo == null) { 8414 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8415 comp, 0, UserHandle.getUserId(callingUid)); 8416 if (ainfo.applicationInfo.uid != callingUid) { 8417 throw new SecurityException( 8418 "Can't add task for another application: target uid=" 8419 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8420 } 8421 } 8422 8423 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8424 intent, description); 8425 8426 int trimIdx = trimRecentsForTask(task, false); 8427 if (trimIdx >= 0) { 8428 // If this would have caused a trim, then we'll abort because that 8429 // means it would be added at the end of the list but then just removed. 8430 return -1; 8431 } 8432 8433 final int N = mRecentTasks.size(); 8434 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8435 final TaskRecord tr = mRecentTasks.remove(N - 1); 8436 tr.removedFromRecents(mTaskPersister); 8437 } 8438 8439 task.inRecents = true; 8440 mRecentTasks.add(task); 8441 r.task.stack.addTask(task, false, false); 8442 8443 task.setLastThumbnail(thumbnail); 8444 task.freeLastThumbnail(); 8445 8446 return task.taskId; 8447 } 8448 } finally { 8449 Binder.restoreCallingIdentity(callingIdent); 8450 } 8451 } 8452 8453 @Override 8454 public Point getAppTaskThumbnailSize() { 8455 synchronized (this) { 8456 return new Point(mThumbnailWidth, mThumbnailHeight); 8457 } 8458 } 8459 8460 @Override 8461 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8462 synchronized (this) { 8463 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8464 if (r != null) { 8465 r.setTaskDescription(td); 8466 r.task.updateTaskDescription(); 8467 } 8468 } 8469 } 8470 8471 @Override 8472 public Bitmap getTaskDescriptionIcon(String filename) { 8473 if (!FileUtils.isValidExtFilename(filename) 8474 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8475 throw new IllegalArgumentException("Bad filename: " + filename); 8476 } 8477 return mTaskPersister.getTaskDescriptionIcon(filename); 8478 } 8479 8480 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8481 mRecentTasks.remove(tr); 8482 tr.removedFromRecents(mTaskPersister); 8483 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8484 Intent baseIntent = new Intent( 8485 tr.intent != null ? tr.intent : tr.affinityIntent); 8486 ComponentName component = baseIntent.getComponent(); 8487 if (component == null) { 8488 Slog.w(TAG, "Now component for base intent of task: " + tr); 8489 return; 8490 } 8491 8492 // Find any running services associated with this app. 8493 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8494 8495 if (killProcesses) { 8496 // Find any running processes associated with this app. 8497 final String pkg = component.getPackageName(); 8498 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8499 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8500 for (int i=0; i<pmap.size(); i++) { 8501 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8502 for (int j=0; j<uids.size(); j++) { 8503 ProcessRecord proc = uids.valueAt(j); 8504 if (proc.userId != tr.userId) { 8505 continue; 8506 } 8507 if (!proc.pkgList.containsKey(pkg)) { 8508 continue; 8509 } 8510 procs.add(proc); 8511 } 8512 } 8513 8514 // Kill the running processes. 8515 for (int i=0; i<procs.size(); i++) { 8516 ProcessRecord pr = procs.get(i); 8517 if (pr == mHomeProcess) { 8518 // Don't kill the home process along with tasks from the same package. 8519 continue; 8520 } 8521 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8522 pr.kill("remove task", true); 8523 } else { 8524 pr.waitingToKill = "remove task"; 8525 } 8526 } 8527 } 8528 } 8529 8530 /** 8531 * Removes the task with the specified task id. 8532 * 8533 * @param taskId Identifier of the task to be removed. 8534 * @param flags Additional operational flags. May be 0 or 8535 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8536 * @return Returns true if the given task was found and removed. 8537 */ 8538 private boolean removeTaskByIdLocked(int taskId, int flags) { 8539 TaskRecord tr = recentTaskForIdLocked(taskId); 8540 if (tr != null) { 8541 tr.removeTaskActivitiesLocked(); 8542 cleanUpRemovedTaskLocked(tr, flags); 8543 if (tr.isPersistable) { 8544 notifyTaskPersisterLocked(null, true); 8545 } 8546 return true; 8547 } 8548 return false; 8549 } 8550 8551 @Override 8552 public boolean removeTask(int taskId, int flags) { 8553 synchronized (this) { 8554 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8555 "removeTask()"); 8556 long ident = Binder.clearCallingIdentity(); 8557 try { 8558 return removeTaskByIdLocked(taskId, flags); 8559 } finally { 8560 Binder.restoreCallingIdentity(ident); 8561 } 8562 } 8563 } 8564 8565 /** 8566 * TODO: Add mController hook 8567 */ 8568 @Override 8569 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8570 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8571 "moveTaskToFront()"); 8572 8573 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8574 synchronized(this) { 8575 moveTaskToFrontLocked(taskId, flags, options); 8576 } 8577 } 8578 8579 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8580 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8581 Binder.getCallingUid(), -1, -1, "Task to front")) { 8582 ActivityOptions.abort(options); 8583 return; 8584 } 8585 final long origId = Binder.clearCallingIdentity(); 8586 try { 8587 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8588 if (task == null) { 8589 return; 8590 } 8591 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8592 mStackSupervisor.showLockTaskToast(); 8593 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8594 return; 8595 } 8596 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8597 if (prev != null && prev.isRecentsActivity()) { 8598 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8599 } 8600 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8601 } finally { 8602 Binder.restoreCallingIdentity(origId); 8603 } 8604 ActivityOptions.abort(options); 8605 } 8606 8607 @Override 8608 public void moveTaskToBack(int taskId) { 8609 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8610 "moveTaskToBack()"); 8611 8612 synchronized(this) { 8613 TaskRecord tr = recentTaskForIdLocked(taskId); 8614 if (tr != null) { 8615 if (tr == mStackSupervisor.mLockTaskModeTask) { 8616 mStackSupervisor.showLockTaskToast(); 8617 return; 8618 } 8619 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8620 ActivityStack stack = tr.stack; 8621 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8622 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8623 Binder.getCallingUid(), -1, -1, "Task to back")) { 8624 return; 8625 } 8626 } 8627 final long origId = Binder.clearCallingIdentity(); 8628 try { 8629 stack.moveTaskToBackLocked(taskId, null); 8630 } finally { 8631 Binder.restoreCallingIdentity(origId); 8632 } 8633 } 8634 } 8635 } 8636 8637 /** 8638 * Moves an activity, and all of the other activities within the same task, to the bottom 8639 * of the history stack. The activity's order within the task is unchanged. 8640 * 8641 * @param token A reference to the activity we wish to move 8642 * @param nonRoot If false then this only works if the activity is the root 8643 * of a task; if true it will work for any activity in a task. 8644 * @return Returns true if the move completed, false if not. 8645 */ 8646 @Override 8647 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8648 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8649 synchronized(this) { 8650 final long origId = Binder.clearCallingIdentity(); 8651 try { 8652 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8653 if (taskId >= 0) { 8654 if ((mStackSupervisor.mLockTaskModeTask != null) 8655 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8656 mStackSupervisor.showLockTaskToast(); 8657 return false; 8658 } 8659 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8660 } 8661 } finally { 8662 Binder.restoreCallingIdentity(origId); 8663 } 8664 } 8665 return false; 8666 } 8667 8668 @Override 8669 public void moveTaskBackwards(int task) { 8670 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8671 "moveTaskBackwards()"); 8672 8673 synchronized(this) { 8674 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8675 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8676 return; 8677 } 8678 final long origId = Binder.clearCallingIdentity(); 8679 moveTaskBackwardsLocked(task); 8680 Binder.restoreCallingIdentity(origId); 8681 } 8682 } 8683 8684 private final void moveTaskBackwardsLocked(int task) { 8685 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8686 } 8687 8688 @Override 8689 public IBinder getHomeActivityToken() throws RemoteException { 8690 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8691 "getHomeActivityToken()"); 8692 synchronized (this) { 8693 return mStackSupervisor.getHomeActivityToken(); 8694 } 8695 } 8696 8697 @Override 8698 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8699 IActivityContainerCallback callback) throws RemoteException { 8700 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8701 "createActivityContainer()"); 8702 synchronized (this) { 8703 if (parentActivityToken == null) { 8704 throw new IllegalArgumentException("parent token must not be null"); 8705 } 8706 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8707 if (r == null) { 8708 return null; 8709 } 8710 if (callback == null) { 8711 throw new IllegalArgumentException("callback must not be null"); 8712 } 8713 return mStackSupervisor.createActivityContainer(r, callback); 8714 } 8715 } 8716 8717 @Override 8718 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8719 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8720 "deleteActivityContainer()"); 8721 synchronized (this) { 8722 mStackSupervisor.deleteActivityContainer(container); 8723 } 8724 } 8725 8726 @Override 8727 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8728 throws RemoteException { 8729 synchronized (this) { 8730 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8731 if (stack != null) { 8732 return stack.mActivityContainer; 8733 } 8734 return null; 8735 } 8736 } 8737 8738 @Override 8739 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8740 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8741 "moveTaskToStack()"); 8742 if (stackId == HOME_STACK_ID) { 8743 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8744 new RuntimeException("here").fillInStackTrace()); 8745 } 8746 synchronized (this) { 8747 long ident = Binder.clearCallingIdentity(); 8748 try { 8749 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8750 + stackId + " toTop=" + toTop); 8751 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8752 } finally { 8753 Binder.restoreCallingIdentity(ident); 8754 } 8755 } 8756 } 8757 8758 @Override 8759 public void resizeStack(int stackBoxId, Rect bounds) { 8760 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8761 "resizeStackBox()"); 8762 long ident = Binder.clearCallingIdentity(); 8763 try { 8764 mWindowManager.resizeStack(stackBoxId, bounds); 8765 } finally { 8766 Binder.restoreCallingIdentity(ident); 8767 } 8768 } 8769 8770 @Override 8771 public List<StackInfo> getAllStackInfos() { 8772 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8773 "getAllStackInfos()"); 8774 long ident = Binder.clearCallingIdentity(); 8775 try { 8776 synchronized (this) { 8777 return mStackSupervisor.getAllStackInfosLocked(); 8778 } 8779 } finally { 8780 Binder.restoreCallingIdentity(ident); 8781 } 8782 } 8783 8784 @Override 8785 public StackInfo getStackInfo(int stackId) { 8786 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8787 "getStackInfo()"); 8788 long ident = Binder.clearCallingIdentity(); 8789 try { 8790 synchronized (this) { 8791 return mStackSupervisor.getStackInfoLocked(stackId); 8792 } 8793 } finally { 8794 Binder.restoreCallingIdentity(ident); 8795 } 8796 } 8797 8798 @Override 8799 public boolean isInHomeStack(int taskId) { 8800 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8801 "getStackInfo()"); 8802 long ident = Binder.clearCallingIdentity(); 8803 try { 8804 synchronized (this) { 8805 TaskRecord tr = recentTaskForIdLocked(taskId); 8806 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8807 } 8808 } finally { 8809 Binder.restoreCallingIdentity(ident); 8810 } 8811 } 8812 8813 @Override 8814 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8815 synchronized(this) { 8816 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8817 } 8818 } 8819 8820 private boolean isLockTaskAuthorized(String pkg) { 8821 final DevicePolicyManager dpm = (DevicePolicyManager) 8822 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8823 try { 8824 int uid = mContext.getPackageManager().getPackageUid(pkg, 8825 Binder.getCallingUserHandle().getIdentifier()); 8826 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8827 } catch (NameNotFoundException e) { 8828 return false; 8829 } 8830 } 8831 8832 void startLockTaskMode(TaskRecord task) { 8833 final String pkg; 8834 synchronized (this) { 8835 pkg = task.intent.getComponent().getPackageName(); 8836 } 8837 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8838 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8839 final TaskRecord taskRecord = task; 8840 mHandler.post(new Runnable() { 8841 @Override 8842 public void run() { 8843 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8844 } 8845 }); 8846 return; 8847 } 8848 long ident = Binder.clearCallingIdentity(); 8849 try { 8850 synchronized (this) { 8851 // Since we lost lock on task, make sure it is still there. 8852 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8853 if (task != null) { 8854 if (!isSystemInitiated 8855 && ((mStackSupervisor.getFocusedStack() == null) 8856 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8857 throw new IllegalArgumentException("Invalid task, not in foreground"); 8858 } 8859 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8860 } 8861 } 8862 } finally { 8863 Binder.restoreCallingIdentity(ident); 8864 } 8865 } 8866 8867 @Override 8868 public void startLockTaskMode(int taskId) { 8869 final TaskRecord task; 8870 long ident = Binder.clearCallingIdentity(); 8871 try { 8872 synchronized (this) { 8873 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8874 } 8875 } finally { 8876 Binder.restoreCallingIdentity(ident); 8877 } 8878 if (task != null) { 8879 startLockTaskMode(task); 8880 } 8881 } 8882 8883 @Override 8884 public void startLockTaskMode(IBinder token) { 8885 final TaskRecord task; 8886 long ident = Binder.clearCallingIdentity(); 8887 try { 8888 synchronized (this) { 8889 final ActivityRecord r = ActivityRecord.forToken(token); 8890 if (r == null) { 8891 return; 8892 } 8893 task = r.task; 8894 } 8895 } finally { 8896 Binder.restoreCallingIdentity(ident); 8897 } 8898 if (task != null) { 8899 startLockTaskMode(task); 8900 } 8901 } 8902 8903 @Override 8904 public void startLockTaskModeOnCurrent() throws RemoteException { 8905 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8906 "startLockTaskModeOnCurrent"); 8907 ActivityRecord r = null; 8908 synchronized (this) { 8909 r = mStackSupervisor.topRunningActivityLocked(); 8910 } 8911 startLockTaskMode(r.task); 8912 } 8913 8914 @Override 8915 public void stopLockTaskMode() { 8916 // Verify that the user matches the package of the intent for the TaskRecord 8917 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8918 // and stopLockTaskMode. 8919 final int callingUid = Binder.getCallingUid(); 8920 if (callingUid != Process.SYSTEM_UID) { 8921 try { 8922 String pkg = 8923 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8924 int uid = mContext.getPackageManager().getPackageUid(pkg, 8925 Binder.getCallingUserHandle().getIdentifier()); 8926 if (uid != callingUid) { 8927 throw new SecurityException("Invalid uid, expected " + uid); 8928 } 8929 } catch (NameNotFoundException e) { 8930 Log.d(TAG, "stopLockTaskMode " + e); 8931 return; 8932 } 8933 } 8934 long ident = Binder.clearCallingIdentity(); 8935 try { 8936 Log.d(TAG, "stopLockTaskMode"); 8937 // Stop lock task 8938 synchronized (this) { 8939 mStackSupervisor.setLockTaskModeLocked(null, false); 8940 } 8941 } finally { 8942 Binder.restoreCallingIdentity(ident); 8943 } 8944 } 8945 8946 @Override 8947 public void stopLockTaskModeOnCurrent() throws RemoteException { 8948 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8949 "stopLockTaskModeOnCurrent"); 8950 long ident = Binder.clearCallingIdentity(); 8951 try { 8952 stopLockTaskMode(); 8953 } finally { 8954 Binder.restoreCallingIdentity(ident); 8955 } 8956 } 8957 8958 @Override 8959 public boolean isInLockTaskMode() { 8960 synchronized (this) { 8961 return mStackSupervisor.isInLockTaskMode(); 8962 } 8963 } 8964 8965 // ========================================================= 8966 // CONTENT PROVIDERS 8967 // ========================================================= 8968 8969 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8970 List<ProviderInfo> providers = null; 8971 try { 8972 providers = AppGlobals.getPackageManager(). 8973 queryContentProviders(app.processName, app.uid, 8974 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8975 } catch (RemoteException ex) { 8976 } 8977 if (DEBUG_MU) 8978 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8979 int userId = app.userId; 8980 if (providers != null) { 8981 int N = providers.size(); 8982 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8983 for (int i=0; i<N; i++) { 8984 ProviderInfo cpi = 8985 (ProviderInfo)providers.get(i); 8986 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8987 cpi.name, cpi.flags); 8988 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8989 // This is a singleton provider, but a user besides the 8990 // default user is asking to initialize a process it runs 8991 // in... well, no, it doesn't actually run in this process, 8992 // it runs in the process of the default user. Get rid of it. 8993 providers.remove(i); 8994 N--; 8995 i--; 8996 continue; 8997 } 8998 8999 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9000 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 9001 if (cpr == null) { 9002 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 9003 mProviderMap.putProviderByClass(comp, cpr); 9004 } 9005 if (DEBUG_MU) 9006 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9007 app.pubProviders.put(cpi.name, cpr); 9008 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9009 // Don't add this if it is a platform component that is marked 9010 // to run in multiple processes, because this is actually 9011 // part of the framework so doesn't make sense to track as a 9012 // separate apk in the process. 9013 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9014 mProcessStats); 9015 } 9016 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9017 } 9018 } 9019 return providers; 9020 } 9021 9022 /** 9023 * Check if {@link ProcessRecord} has a possible chance at accessing the 9024 * given {@link ProviderInfo}. Final permission checking is always done 9025 * in {@link ContentProvider}. 9026 */ 9027 private final String checkContentProviderPermissionLocked( 9028 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9029 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9030 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9031 boolean checkedGrants = false; 9032 if (checkUser) { 9033 // Looking for cross-user grants before enforcing the typical cross-users permissions 9034 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9035 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9036 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9037 return null; 9038 } 9039 checkedGrants = true; 9040 } 9041 userId = handleIncomingUser(callingPid, callingUid, userId, 9042 false, ALLOW_NON_FULL, 9043 "checkContentProviderPermissionLocked " + cpi.authority, null); 9044 if (userId != tmpTargetUserId) { 9045 // When we actually went to determine the final targer user ID, this ended 9046 // up different than our initial check for the authority. This is because 9047 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9048 // SELF. So we need to re-check the grants again. 9049 checkedGrants = false; 9050 } 9051 } 9052 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9053 cpi.applicationInfo.uid, cpi.exported) 9054 == PackageManager.PERMISSION_GRANTED) { 9055 return null; 9056 } 9057 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9058 cpi.applicationInfo.uid, cpi.exported) 9059 == PackageManager.PERMISSION_GRANTED) { 9060 return null; 9061 } 9062 9063 PathPermission[] pps = cpi.pathPermissions; 9064 if (pps != null) { 9065 int i = pps.length; 9066 while (i > 0) { 9067 i--; 9068 PathPermission pp = pps[i]; 9069 String pprperm = pp.getReadPermission(); 9070 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9071 cpi.applicationInfo.uid, cpi.exported) 9072 == PackageManager.PERMISSION_GRANTED) { 9073 return null; 9074 } 9075 String ppwperm = pp.getWritePermission(); 9076 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9077 cpi.applicationInfo.uid, cpi.exported) 9078 == PackageManager.PERMISSION_GRANTED) { 9079 return null; 9080 } 9081 } 9082 } 9083 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9084 return null; 9085 } 9086 9087 String msg; 9088 if (!cpi.exported) { 9089 msg = "Permission Denial: opening provider " + cpi.name 9090 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9091 + ", uid=" + callingUid + ") that is not exported from uid " 9092 + cpi.applicationInfo.uid; 9093 } else { 9094 msg = "Permission Denial: opening provider " + cpi.name 9095 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9096 + ", uid=" + callingUid + ") requires " 9097 + cpi.readPermission + " or " + cpi.writePermission; 9098 } 9099 Slog.w(TAG, msg); 9100 return msg; 9101 } 9102 9103 /** 9104 * Returns if the ContentProvider has granted a uri to callingUid 9105 */ 9106 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9107 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9108 if (perms != null) { 9109 for (int i=perms.size()-1; i>=0; i--) { 9110 GrantUri grantUri = perms.keyAt(i); 9111 if (grantUri.sourceUserId == userId || !checkUser) { 9112 if (matchesProvider(grantUri.uri, cpi)) { 9113 return true; 9114 } 9115 } 9116 } 9117 } 9118 return false; 9119 } 9120 9121 /** 9122 * Returns true if the uri authority is one of the authorities specified in the provider. 9123 */ 9124 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9125 String uriAuth = uri.getAuthority(); 9126 String cpiAuth = cpi.authority; 9127 if (cpiAuth.indexOf(';') == -1) { 9128 return cpiAuth.equals(uriAuth); 9129 } 9130 String[] cpiAuths = cpiAuth.split(";"); 9131 int length = cpiAuths.length; 9132 for (int i = 0; i < length; i++) { 9133 if (cpiAuths[i].equals(uriAuth)) return true; 9134 } 9135 return false; 9136 } 9137 9138 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9139 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9140 if (r != null) { 9141 for (int i=0; i<r.conProviders.size(); i++) { 9142 ContentProviderConnection conn = r.conProviders.get(i); 9143 if (conn.provider == cpr) { 9144 if (DEBUG_PROVIDER) Slog.v(TAG, 9145 "Adding provider requested by " 9146 + r.processName + " from process " 9147 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9148 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9149 if (stable) { 9150 conn.stableCount++; 9151 conn.numStableIncs++; 9152 } else { 9153 conn.unstableCount++; 9154 conn.numUnstableIncs++; 9155 } 9156 return conn; 9157 } 9158 } 9159 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9160 if (stable) { 9161 conn.stableCount = 1; 9162 conn.numStableIncs = 1; 9163 } else { 9164 conn.unstableCount = 1; 9165 conn.numUnstableIncs = 1; 9166 } 9167 cpr.connections.add(conn); 9168 r.conProviders.add(conn); 9169 return conn; 9170 } 9171 cpr.addExternalProcessHandleLocked(externalProcessToken); 9172 return null; 9173 } 9174 9175 boolean decProviderCountLocked(ContentProviderConnection conn, 9176 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9177 if (conn != null) { 9178 cpr = conn.provider; 9179 if (DEBUG_PROVIDER) Slog.v(TAG, 9180 "Removing provider requested by " 9181 + conn.client.processName + " from process " 9182 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9183 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9184 if (stable) { 9185 conn.stableCount--; 9186 } else { 9187 conn.unstableCount--; 9188 } 9189 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9190 cpr.connections.remove(conn); 9191 conn.client.conProviders.remove(conn); 9192 return true; 9193 } 9194 return false; 9195 } 9196 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9197 return false; 9198 } 9199 9200 private void checkTime(long startTime, String where) { 9201 long now = SystemClock.elapsedRealtime(); 9202 if ((now-startTime) > 1000) { 9203 // If we are taking more than a second, log about it. 9204 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9205 } 9206 } 9207 9208 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9209 String name, IBinder token, boolean stable, int userId) { 9210 ContentProviderRecord cpr; 9211 ContentProviderConnection conn = null; 9212 ProviderInfo cpi = null; 9213 9214 synchronized(this) { 9215 long startTime = SystemClock.elapsedRealtime(); 9216 9217 ProcessRecord r = null; 9218 if (caller != null) { 9219 r = getRecordForAppLocked(caller); 9220 if (r == null) { 9221 throw new SecurityException( 9222 "Unable to find app for caller " + caller 9223 + " (pid=" + Binder.getCallingPid() 9224 + ") when getting content provider " + name); 9225 } 9226 } 9227 9228 boolean checkCrossUser = true; 9229 9230 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9231 9232 // First check if this content provider has been published... 9233 cpr = mProviderMap.getProviderByName(name, userId); 9234 // If that didn't work, check if it exists for user 0 and then 9235 // verify that it's a singleton provider before using it. 9236 if (cpr == null && userId != UserHandle.USER_OWNER) { 9237 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9238 if (cpr != null) { 9239 cpi = cpr.info; 9240 if (isSingleton(cpi.processName, cpi.applicationInfo, 9241 cpi.name, cpi.flags) 9242 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9243 userId = UserHandle.USER_OWNER; 9244 checkCrossUser = false; 9245 } else { 9246 cpr = null; 9247 cpi = null; 9248 } 9249 } 9250 } 9251 9252 boolean providerRunning = cpr != null; 9253 if (providerRunning) { 9254 cpi = cpr.info; 9255 String msg; 9256 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9257 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9258 != null) { 9259 throw new SecurityException(msg); 9260 } 9261 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9262 9263 if (r != null && cpr.canRunHere(r)) { 9264 // This provider has been published or is in the process 9265 // of being published... but it is also allowed to run 9266 // in the caller's process, so don't make a connection 9267 // and just let the caller instantiate its own instance. 9268 ContentProviderHolder holder = cpr.newHolder(null); 9269 // don't give caller the provider object, it needs 9270 // to make its own. 9271 holder.provider = null; 9272 return holder; 9273 } 9274 9275 final long origId = Binder.clearCallingIdentity(); 9276 9277 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9278 9279 // In this case the provider instance already exists, so we can 9280 // return it right away. 9281 conn = incProviderCountLocked(r, cpr, token, stable); 9282 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9283 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9284 // If this is a perceptible app accessing the provider, 9285 // make sure to count it as being accessed and thus 9286 // back up on the LRU list. This is good because 9287 // content providers are often expensive to start. 9288 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9289 updateLruProcessLocked(cpr.proc, false, null); 9290 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9291 } 9292 } 9293 9294 if (cpr.proc != null) { 9295 if (false) { 9296 if (cpr.name.flattenToShortString().equals( 9297 "com.android.providers.calendar/.CalendarProvider2")) { 9298 Slog.v(TAG, "****************** KILLING " 9299 + cpr.name.flattenToShortString()); 9300 Process.killProcess(cpr.proc.pid); 9301 } 9302 } 9303 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9304 boolean success = updateOomAdjLocked(cpr.proc); 9305 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9306 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9307 // NOTE: there is still a race here where a signal could be 9308 // pending on the process even though we managed to update its 9309 // adj level. Not sure what to do about this, but at least 9310 // the race is now smaller. 9311 if (!success) { 9312 // Uh oh... it looks like the provider's process 9313 // has been killed on us. We need to wait for a new 9314 // process to be started, and make sure its death 9315 // doesn't kill our process. 9316 Slog.i(TAG, 9317 "Existing provider " + cpr.name.flattenToShortString() 9318 + " is crashing; detaching " + r); 9319 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9320 checkTime(startTime, "getContentProviderImpl: before appDied"); 9321 appDiedLocked(cpr.proc); 9322 checkTime(startTime, "getContentProviderImpl: after appDied"); 9323 if (!lastRef) { 9324 // This wasn't the last ref our process had on 9325 // the provider... we have now been killed, bail. 9326 return null; 9327 } 9328 providerRunning = false; 9329 conn = null; 9330 } 9331 } 9332 9333 Binder.restoreCallingIdentity(origId); 9334 } 9335 9336 boolean singleton; 9337 if (!providerRunning) { 9338 try { 9339 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9340 cpi = AppGlobals.getPackageManager(). 9341 resolveContentProvider(name, 9342 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9343 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9344 } catch (RemoteException ex) { 9345 } 9346 if (cpi == null) { 9347 return null; 9348 } 9349 // If the provider is a singleton AND 9350 // (it's a call within the same user || the provider is a 9351 // privileged app) 9352 // Then allow connecting to the singleton provider 9353 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9354 cpi.name, cpi.flags) 9355 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9356 if (singleton) { 9357 userId = UserHandle.USER_OWNER; 9358 } 9359 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9360 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9361 9362 String msg; 9363 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9364 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9365 != null) { 9366 throw new SecurityException(msg); 9367 } 9368 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9369 9370 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9371 && !cpi.processName.equals("system")) { 9372 // If this content provider does not run in the system 9373 // process, and the system is not yet ready to run other 9374 // processes, then fail fast instead of hanging. 9375 throw new IllegalArgumentException( 9376 "Attempt to launch content provider before system ready"); 9377 } 9378 9379 // Make sure that the user who owns this provider is started. If not, 9380 // we don't want to allow it to run. 9381 if (mStartedUsers.get(userId) == null) { 9382 Slog.w(TAG, "Unable to launch app " 9383 + cpi.applicationInfo.packageName + "/" 9384 + cpi.applicationInfo.uid + " for provider " 9385 + name + ": user " + userId + " is stopped"); 9386 return null; 9387 } 9388 9389 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9390 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9391 cpr = mProviderMap.getProviderByClass(comp, userId); 9392 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9393 final boolean firstClass = cpr == null; 9394 if (firstClass) { 9395 final long ident = Binder.clearCallingIdentity(); 9396 try { 9397 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9398 ApplicationInfo ai = 9399 AppGlobals.getPackageManager(). 9400 getApplicationInfo( 9401 cpi.applicationInfo.packageName, 9402 STOCK_PM_FLAGS, userId); 9403 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9404 if (ai == null) { 9405 Slog.w(TAG, "No package info for content provider " 9406 + cpi.name); 9407 return null; 9408 } 9409 ai = getAppInfoForUser(ai, userId); 9410 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9411 } catch (RemoteException ex) { 9412 // pm is in same process, this will never happen. 9413 } finally { 9414 Binder.restoreCallingIdentity(ident); 9415 } 9416 } 9417 9418 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9419 9420 if (r != null && cpr.canRunHere(r)) { 9421 // If this is a multiprocess provider, then just return its 9422 // info and allow the caller to instantiate it. Only do 9423 // this if the provider is the same user as the caller's 9424 // process, or can run as root (so can be in any process). 9425 return cpr.newHolder(null); 9426 } 9427 9428 if (DEBUG_PROVIDER) { 9429 RuntimeException e = new RuntimeException("here"); 9430 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9431 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9432 } 9433 9434 // This is single process, and our app is now connecting to it. 9435 // See if we are already in the process of launching this 9436 // provider. 9437 final int N = mLaunchingProviders.size(); 9438 int i; 9439 for (i=0; i<N; i++) { 9440 if (mLaunchingProviders.get(i) == cpr) { 9441 break; 9442 } 9443 } 9444 9445 // If the provider is not already being launched, then get it 9446 // started. 9447 if (i >= N) { 9448 final long origId = Binder.clearCallingIdentity(); 9449 9450 try { 9451 // Content provider is now in use, its package can't be stopped. 9452 try { 9453 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9454 AppGlobals.getPackageManager().setPackageStoppedState( 9455 cpr.appInfo.packageName, false, userId); 9456 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9457 } catch (RemoteException e) { 9458 } catch (IllegalArgumentException e) { 9459 Slog.w(TAG, "Failed trying to unstop package " 9460 + cpr.appInfo.packageName + ": " + e); 9461 } 9462 9463 // Use existing process if already started 9464 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9465 ProcessRecord proc = getProcessRecordLocked( 9466 cpi.processName, cpr.appInfo.uid, false); 9467 if (proc != null && proc.thread != null) { 9468 if (DEBUG_PROVIDER) { 9469 Slog.d(TAG, "Installing in existing process " + proc); 9470 } 9471 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9472 proc.pubProviders.put(cpi.name, cpr); 9473 try { 9474 proc.thread.scheduleInstallProvider(cpi); 9475 } catch (RemoteException e) { 9476 } 9477 } else { 9478 checkTime(startTime, "getContentProviderImpl: before start process"); 9479 proc = startProcessLocked(cpi.processName, 9480 cpr.appInfo, false, 0, "content provider", 9481 new ComponentName(cpi.applicationInfo.packageName, 9482 cpi.name), false, false, false); 9483 checkTime(startTime, "getContentProviderImpl: after start process"); 9484 if (proc == null) { 9485 Slog.w(TAG, "Unable to launch app " 9486 + cpi.applicationInfo.packageName + "/" 9487 + cpi.applicationInfo.uid + " for provider " 9488 + name + ": process is bad"); 9489 return null; 9490 } 9491 } 9492 cpr.launchingApp = proc; 9493 mLaunchingProviders.add(cpr); 9494 } finally { 9495 Binder.restoreCallingIdentity(origId); 9496 } 9497 } 9498 9499 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9500 9501 // Make sure the provider is published (the same provider class 9502 // may be published under multiple names). 9503 if (firstClass) { 9504 mProviderMap.putProviderByClass(comp, cpr); 9505 } 9506 9507 mProviderMap.putProviderByName(name, cpr); 9508 conn = incProviderCountLocked(r, cpr, token, stable); 9509 if (conn != null) { 9510 conn.waiting = true; 9511 } 9512 } 9513 checkTime(startTime, "getContentProviderImpl: done!"); 9514 } 9515 9516 // Wait for the provider to be published... 9517 synchronized (cpr) { 9518 while (cpr.provider == null) { 9519 if (cpr.launchingApp == null) { 9520 Slog.w(TAG, "Unable to launch app " 9521 + cpi.applicationInfo.packageName + "/" 9522 + cpi.applicationInfo.uid + " for provider " 9523 + name + ": launching app became null"); 9524 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9525 UserHandle.getUserId(cpi.applicationInfo.uid), 9526 cpi.applicationInfo.packageName, 9527 cpi.applicationInfo.uid, name); 9528 return null; 9529 } 9530 try { 9531 if (DEBUG_MU) { 9532 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9533 + cpr.launchingApp); 9534 } 9535 if (conn != null) { 9536 conn.waiting = true; 9537 } 9538 cpr.wait(); 9539 } catch (InterruptedException ex) { 9540 } finally { 9541 if (conn != null) { 9542 conn.waiting = false; 9543 } 9544 } 9545 } 9546 } 9547 return cpr != null ? cpr.newHolder(conn) : null; 9548 } 9549 9550 @Override 9551 public final ContentProviderHolder getContentProvider( 9552 IApplicationThread caller, String name, int userId, boolean stable) { 9553 enforceNotIsolatedCaller("getContentProvider"); 9554 if (caller == null) { 9555 String msg = "null IApplicationThread when getting content provider " 9556 + name; 9557 Slog.w(TAG, msg); 9558 throw new SecurityException(msg); 9559 } 9560 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9561 // with cross-user grant. 9562 return getContentProviderImpl(caller, name, null, stable, userId); 9563 } 9564 9565 public ContentProviderHolder getContentProviderExternal( 9566 String name, int userId, IBinder token) { 9567 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9568 "Do not have permission in call getContentProviderExternal()"); 9569 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9570 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9571 return getContentProviderExternalUnchecked(name, token, userId); 9572 } 9573 9574 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9575 IBinder token, int userId) { 9576 return getContentProviderImpl(null, name, token, true, userId); 9577 } 9578 9579 /** 9580 * Drop a content provider from a ProcessRecord's bookkeeping 9581 */ 9582 public void removeContentProvider(IBinder connection, boolean stable) { 9583 enforceNotIsolatedCaller("removeContentProvider"); 9584 long ident = Binder.clearCallingIdentity(); 9585 try { 9586 synchronized (this) { 9587 ContentProviderConnection conn; 9588 try { 9589 conn = (ContentProviderConnection)connection; 9590 } catch (ClassCastException e) { 9591 String msg ="removeContentProvider: " + connection 9592 + " not a ContentProviderConnection"; 9593 Slog.w(TAG, msg); 9594 throw new IllegalArgumentException(msg); 9595 } 9596 if (conn == null) { 9597 throw new NullPointerException("connection is null"); 9598 } 9599 if (decProviderCountLocked(conn, null, null, stable)) { 9600 updateOomAdjLocked(); 9601 } 9602 } 9603 } finally { 9604 Binder.restoreCallingIdentity(ident); 9605 } 9606 } 9607 9608 public void removeContentProviderExternal(String name, IBinder token) { 9609 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9610 "Do not have permission in call removeContentProviderExternal()"); 9611 int userId = UserHandle.getCallingUserId(); 9612 long ident = Binder.clearCallingIdentity(); 9613 try { 9614 removeContentProviderExternalUnchecked(name, token, userId); 9615 } finally { 9616 Binder.restoreCallingIdentity(ident); 9617 } 9618 } 9619 9620 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9621 synchronized (this) { 9622 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9623 if(cpr == null) { 9624 //remove from mProvidersByClass 9625 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9626 return; 9627 } 9628 9629 //update content provider record entry info 9630 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9631 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9632 if (localCpr.hasExternalProcessHandles()) { 9633 if (localCpr.removeExternalProcessHandleLocked(token)) { 9634 updateOomAdjLocked(); 9635 } else { 9636 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9637 + " with no external reference for token: " 9638 + token + "."); 9639 } 9640 } else { 9641 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9642 + " with no external references."); 9643 } 9644 } 9645 } 9646 9647 public final void publishContentProviders(IApplicationThread caller, 9648 List<ContentProviderHolder> providers) { 9649 if (providers == null) { 9650 return; 9651 } 9652 9653 enforceNotIsolatedCaller("publishContentProviders"); 9654 synchronized (this) { 9655 final ProcessRecord r = getRecordForAppLocked(caller); 9656 if (DEBUG_MU) 9657 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9658 if (r == null) { 9659 throw new SecurityException( 9660 "Unable to find app for caller " + caller 9661 + " (pid=" + Binder.getCallingPid() 9662 + ") when publishing content providers"); 9663 } 9664 9665 final long origId = Binder.clearCallingIdentity(); 9666 9667 final int N = providers.size(); 9668 for (int i=0; i<N; i++) { 9669 ContentProviderHolder src = providers.get(i); 9670 if (src == null || src.info == null || src.provider == null) { 9671 continue; 9672 } 9673 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9674 if (DEBUG_MU) 9675 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9676 if (dst != null) { 9677 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9678 mProviderMap.putProviderByClass(comp, dst); 9679 String names[] = dst.info.authority.split(";"); 9680 for (int j = 0; j < names.length; j++) { 9681 mProviderMap.putProviderByName(names[j], dst); 9682 } 9683 9684 int NL = mLaunchingProviders.size(); 9685 int j; 9686 for (j=0; j<NL; j++) { 9687 if (mLaunchingProviders.get(j) == dst) { 9688 mLaunchingProviders.remove(j); 9689 j--; 9690 NL--; 9691 } 9692 } 9693 synchronized (dst) { 9694 dst.provider = src.provider; 9695 dst.proc = r; 9696 dst.notifyAll(); 9697 } 9698 updateOomAdjLocked(r); 9699 } 9700 } 9701 9702 Binder.restoreCallingIdentity(origId); 9703 } 9704 } 9705 9706 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9707 ContentProviderConnection conn; 9708 try { 9709 conn = (ContentProviderConnection)connection; 9710 } catch (ClassCastException e) { 9711 String msg ="refContentProvider: " + connection 9712 + " not a ContentProviderConnection"; 9713 Slog.w(TAG, msg); 9714 throw new IllegalArgumentException(msg); 9715 } 9716 if (conn == null) { 9717 throw new NullPointerException("connection is null"); 9718 } 9719 9720 synchronized (this) { 9721 if (stable > 0) { 9722 conn.numStableIncs += stable; 9723 } 9724 stable = conn.stableCount + stable; 9725 if (stable < 0) { 9726 throw new IllegalStateException("stableCount < 0: " + stable); 9727 } 9728 9729 if (unstable > 0) { 9730 conn.numUnstableIncs += unstable; 9731 } 9732 unstable = conn.unstableCount + unstable; 9733 if (unstable < 0) { 9734 throw new IllegalStateException("unstableCount < 0: " + unstable); 9735 } 9736 9737 if ((stable+unstable) <= 0) { 9738 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9739 + stable + " unstable=" + unstable); 9740 } 9741 conn.stableCount = stable; 9742 conn.unstableCount = unstable; 9743 return !conn.dead; 9744 } 9745 } 9746 9747 public void unstableProviderDied(IBinder connection) { 9748 ContentProviderConnection conn; 9749 try { 9750 conn = (ContentProviderConnection)connection; 9751 } catch (ClassCastException e) { 9752 String msg ="refContentProvider: " + connection 9753 + " not a ContentProviderConnection"; 9754 Slog.w(TAG, msg); 9755 throw new IllegalArgumentException(msg); 9756 } 9757 if (conn == null) { 9758 throw new NullPointerException("connection is null"); 9759 } 9760 9761 // Safely retrieve the content provider associated with the connection. 9762 IContentProvider provider; 9763 synchronized (this) { 9764 provider = conn.provider.provider; 9765 } 9766 9767 if (provider == null) { 9768 // Um, yeah, we're way ahead of you. 9769 return; 9770 } 9771 9772 // Make sure the caller is being honest with us. 9773 if (provider.asBinder().pingBinder()) { 9774 // Er, no, still looks good to us. 9775 synchronized (this) { 9776 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9777 + " says " + conn + " died, but we don't agree"); 9778 return; 9779 } 9780 } 9781 9782 // Well look at that! It's dead! 9783 synchronized (this) { 9784 if (conn.provider.provider != provider) { 9785 // But something changed... good enough. 9786 return; 9787 } 9788 9789 ProcessRecord proc = conn.provider.proc; 9790 if (proc == null || proc.thread == null) { 9791 // Seems like the process is already cleaned up. 9792 return; 9793 } 9794 9795 // As far as we're concerned, this is just like receiving a 9796 // death notification... just a bit prematurely. 9797 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9798 + ") early provider death"); 9799 final long ident = Binder.clearCallingIdentity(); 9800 try { 9801 appDiedLocked(proc); 9802 } finally { 9803 Binder.restoreCallingIdentity(ident); 9804 } 9805 } 9806 } 9807 9808 @Override 9809 public void appNotRespondingViaProvider(IBinder connection) { 9810 enforceCallingPermission( 9811 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9812 9813 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9814 if (conn == null) { 9815 Slog.w(TAG, "ContentProviderConnection is null"); 9816 return; 9817 } 9818 9819 final ProcessRecord host = conn.provider.proc; 9820 if (host == null) { 9821 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9822 return; 9823 } 9824 9825 final long token = Binder.clearCallingIdentity(); 9826 try { 9827 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9828 } finally { 9829 Binder.restoreCallingIdentity(token); 9830 } 9831 } 9832 9833 public final void installSystemProviders() { 9834 List<ProviderInfo> providers; 9835 synchronized (this) { 9836 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9837 providers = generateApplicationProvidersLocked(app); 9838 if (providers != null) { 9839 for (int i=providers.size()-1; i>=0; i--) { 9840 ProviderInfo pi = (ProviderInfo)providers.get(i); 9841 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9842 Slog.w(TAG, "Not installing system proc provider " + pi.name 9843 + ": not system .apk"); 9844 providers.remove(i); 9845 } 9846 } 9847 } 9848 } 9849 if (providers != null) { 9850 mSystemThread.installSystemProviders(providers); 9851 } 9852 9853 mCoreSettingsObserver = new CoreSettingsObserver(this); 9854 9855 //mUsageStatsService.monitorPackages(); 9856 } 9857 9858 /** 9859 * Allows apps to retrieve the MIME type of a URI. 9860 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9861 * users, then it does not need permission to access the ContentProvider. 9862 * Either, it needs cross-user uri grants. 9863 * 9864 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9865 * 9866 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9867 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9868 */ 9869 public String getProviderMimeType(Uri uri, int userId) { 9870 enforceNotIsolatedCaller("getProviderMimeType"); 9871 final String name = uri.getAuthority(); 9872 int callingUid = Binder.getCallingUid(); 9873 int callingPid = Binder.getCallingPid(); 9874 long ident = 0; 9875 boolean clearedIdentity = false; 9876 userId = unsafeConvertIncomingUser(userId); 9877 if (canClearIdentity(callingPid, callingUid, userId)) { 9878 clearedIdentity = true; 9879 ident = Binder.clearCallingIdentity(); 9880 } 9881 ContentProviderHolder holder = null; 9882 try { 9883 holder = getContentProviderExternalUnchecked(name, null, userId); 9884 if (holder != null) { 9885 return holder.provider.getType(uri); 9886 } 9887 } catch (RemoteException e) { 9888 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9889 return null; 9890 } finally { 9891 // We need to clear the identity to call removeContentProviderExternalUnchecked 9892 if (!clearedIdentity) { 9893 ident = Binder.clearCallingIdentity(); 9894 } 9895 try { 9896 if (holder != null) { 9897 removeContentProviderExternalUnchecked(name, null, userId); 9898 } 9899 } finally { 9900 Binder.restoreCallingIdentity(ident); 9901 } 9902 } 9903 9904 return null; 9905 } 9906 9907 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9908 if (UserHandle.getUserId(callingUid) == userId) { 9909 return true; 9910 } 9911 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9912 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9913 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9914 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9915 return true; 9916 } 9917 return false; 9918 } 9919 9920 // ========================================================= 9921 // GLOBAL MANAGEMENT 9922 // ========================================================= 9923 9924 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9925 boolean isolated, int isolatedUid) { 9926 String proc = customProcess != null ? customProcess : info.processName; 9927 BatteryStatsImpl.Uid.Proc ps = null; 9928 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9929 int uid = info.uid; 9930 if (isolated) { 9931 if (isolatedUid == 0) { 9932 int userId = UserHandle.getUserId(uid); 9933 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9934 while (true) { 9935 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9936 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9937 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9938 } 9939 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9940 mNextIsolatedProcessUid++; 9941 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9942 // No process for this uid, use it. 9943 break; 9944 } 9945 stepsLeft--; 9946 if (stepsLeft <= 0) { 9947 return null; 9948 } 9949 } 9950 } else { 9951 // Special case for startIsolatedProcess (internal only), where 9952 // the uid of the isolated process is specified by the caller. 9953 uid = isolatedUid; 9954 } 9955 } 9956 return new ProcessRecord(stats, info, proc, uid); 9957 } 9958 9959 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9960 String abiOverride) { 9961 ProcessRecord app; 9962 if (!isolated) { 9963 app = getProcessRecordLocked(info.processName, info.uid, true); 9964 } else { 9965 app = null; 9966 } 9967 9968 if (app == null) { 9969 app = newProcessRecordLocked(info, null, isolated, 0); 9970 mProcessNames.put(info.processName, app.uid, app); 9971 if (isolated) { 9972 mIsolatedProcesses.put(app.uid, app); 9973 } 9974 updateLruProcessLocked(app, false, null); 9975 updateOomAdjLocked(); 9976 } 9977 9978 // This package really, really can not be stopped. 9979 try { 9980 AppGlobals.getPackageManager().setPackageStoppedState( 9981 info.packageName, false, UserHandle.getUserId(app.uid)); 9982 } catch (RemoteException e) { 9983 } catch (IllegalArgumentException e) { 9984 Slog.w(TAG, "Failed trying to unstop package " 9985 + info.packageName + ": " + e); 9986 } 9987 9988 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9989 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9990 app.persistent = true; 9991 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9992 } 9993 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9994 mPersistentStartingProcesses.add(app); 9995 startProcessLocked(app, "added application", app.processName, abiOverride, 9996 null /* entryPoint */, null /* entryPointArgs */); 9997 } 9998 9999 return app; 10000 } 10001 10002 public void unhandledBack() { 10003 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10004 "unhandledBack()"); 10005 10006 synchronized(this) { 10007 final long origId = Binder.clearCallingIdentity(); 10008 try { 10009 getFocusedStack().unhandledBackLocked(); 10010 } finally { 10011 Binder.restoreCallingIdentity(origId); 10012 } 10013 } 10014 } 10015 10016 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10017 enforceNotIsolatedCaller("openContentUri"); 10018 final int userId = UserHandle.getCallingUserId(); 10019 String name = uri.getAuthority(); 10020 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10021 ParcelFileDescriptor pfd = null; 10022 if (cph != null) { 10023 // We record the binder invoker's uid in thread-local storage before 10024 // going to the content provider to open the file. Later, in the code 10025 // that handles all permissions checks, we look for this uid and use 10026 // that rather than the Activity Manager's own uid. The effect is that 10027 // we do the check against the caller's permissions even though it looks 10028 // to the content provider like the Activity Manager itself is making 10029 // the request. 10030 sCallerIdentity.set(new Identity( 10031 Binder.getCallingPid(), Binder.getCallingUid())); 10032 try { 10033 pfd = cph.provider.openFile(null, uri, "r", null); 10034 } catch (FileNotFoundException e) { 10035 // do nothing; pfd will be returned null 10036 } finally { 10037 // Ensure that whatever happens, we clean up the identity state 10038 sCallerIdentity.remove(); 10039 } 10040 10041 // We've got the fd now, so we're done with the provider. 10042 removeContentProviderExternalUnchecked(name, null, userId); 10043 } else { 10044 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10045 } 10046 return pfd; 10047 } 10048 10049 // Actually is sleeping or shutting down or whatever else in the future 10050 // is an inactive state. 10051 public boolean isSleepingOrShuttingDown() { 10052 return isSleeping() || mShuttingDown; 10053 } 10054 10055 public boolean isSleeping() { 10056 return mSleeping; 10057 } 10058 10059 void goingToSleep() { 10060 synchronized(this) { 10061 mWentToSleep = true; 10062 goToSleepIfNeededLocked(); 10063 } 10064 } 10065 10066 void finishRunningVoiceLocked() { 10067 if (mRunningVoice) { 10068 mRunningVoice = false; 10069 goToSleepIfNeededLocked(); 10070 } 10071 } 10072 10073 void goToSleepIfNeededLocked() { 10074 if (mWentToSleep && !mRunningVoice) { 10075 if (!mSleeping) { 10076 mSleeping = true; 10077 mStackSupervisor.goingToSleepLocked(); 10078 10079 // Initialize the wake times of all processes. 10080 checkExcessivePowerUsageLocked(false); 10081 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10082 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10083 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10084 } 10085 } 10086 } 10087 10088 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10089 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10090 // Never persist the home stack. 10091 return; 10092 } 10093 mTaskPersister.wakeup(task, flush); 10094 } 10095 10096 @Override 10097 public boolean shutdown(int timeout) { 10098 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10099 != PackageManager.PERMISSION_GRANTED) { 10100 throw new SecurityException("Requires permission " 10101 + android.Manifest.permission.SHUTDOWN); 10102 } 10103 10104 boolean timedout = false; 10105 10106 synchronized(this) { 10107 mShuttingDown = true; 10108 updateEventDispatchingLocked(); 10109 timedout = mStackSupervisor.shutdownLocked(timeout); 10110 } 10111 10112 mAppOpsService.shutdown(); 10113 if (mUsageStatsService != null) { 10114 mUsageStatsService.prepareShutdown(); 10115 } 10116 mBatteryStatsService.shutdown(); 10117 synchronized (this) { 10118 mProcessStats.shutdownLocked(); 10119 } 10120 notifyTaskPersisterLocked(null, true); 10121 10122 return timedout; 10123 } 10124 10125 public final void activitySlept(IBinder token) { 10126 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10127 10128 final long origId = Binder.clearCallingIdentity(); 10129 10130 synchronized (this) { 10131 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10132 if (r != null) { 10133 mStackSupervisor.activitySleptLocked(r); 10134 } 10135 } 10136 10137 Binder.restoreCallingIdentity(origId); 10138 } 10139 10140 void logLockScreen(String msg) { 10141 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10142 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10143 mWentToSleep + " mSleeping=" + mSleeping); 10144 } 10145 10146 private void comeOutOfSleepIfNeededLocked() { 10147 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10148 if (mSleeping) { 10149 mSleeping = false; 10150 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10151 } 10152 } 10153 } 10154 10155 void wakingUp() { 10156 synchronized(this) { 10157 mWentToSleep = false; 10158 comeOutOfSleepIfNeededLocked(); 10159 } 10160 } 10161 10162 void startRunningVoiceLocked() { 10163 if (!mRunningVoice) { 10164 mRunningVoice = true; 10165 comeOutOfSleepIfNeededLocked(); 10166 } 10167 } 10168 10169 private void updateEventDispatchingLocked() { 10170 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10171 } 10172 10173 public void setLockScreenShown(boolean shown) { 10174 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10175 != PackageManager.PERMISSION_GRANTED) { 10176 throw new SecurityException("Requires permission " 10177 + android.Manifest.permission.DEVICE_POWER); 10178 } 10179 10180 synchronized(this) { 10181 long ident = Binder.clearCallingIdentity(); 10182 try { 10183 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10184 mLockScreenShown = shown; 10185 comeOutOfSleepIfNeededLocked(); 10186 } finally { 10187 Binder.restoreCallingIdentity(ident); 10188 } 10189 } 10190 } 10191 10192 @Override 10193 public void stopAppSwitches() { 10194 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10195 != PackageManager.PERMISSION_GRANTED) { 10196 throw new SecurityException("Requires permission " 10197 + android.Manifest.permission.STOP_APP_SWITCHES); 10198 } 10199 10200 synchronized(this) { 10201 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10202 + APP_SWITCH_DELAY_TIME; 10203 mDidAppSwitch = false; 10204 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10205 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10206 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10207 } 10208 } 10209 10210 public void resumeAppSwitches() { 10211 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10212 != PackageManager.PERMISSION_GRANTED) { 10213 throw new SecurityException("Requires permission " 10214 + android.Manifest.permission.STOP_APP_SWITCHES); 10215 } 10216 10217 synchronized(this) { 10218 // Note that we don't execute any pending app switches... we will 10219 // let those wait until either the timeout, or the next start 10220 // activity request. 10221 mAppSwitchesAllowedTime = 0; 10222 } 10223 } 10224 10225 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10226 int callingPid, int callingUid, String name) { 10227 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10228 return true; 10229 } 10230 10231 int perm = checkComponentPermission( 10232 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10233 sourceUid, -1, true); 10234 if (perm == PackageManager.PERMISSION_GRANTED) { 10235 return true; 10236 } 10237 10238 // If the actual IPC caller is different from the logical source, then 10239 // also see if they are allowed to control app switches. 10240 if (callingUid != -1 && callingUid != sourceUid) { 10241 perm = checkComponentPermission( 10242 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10243 callingUid, -1, true); 10244 if (perm == PackageManager.PERMISSION_GRANTED) { 10245 return true; 10246 } 10247 } 10248 10249 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10250 return false; 10251 } 10252 10253 public void setDebugApp(String packageName, boolean waitForDebugger, 10254 boolean persistent) { 10255 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10256 "setDebugApp()"); 10257 10258 long ident = Binder.clearCallingIdentity(); 10259 try { 10260 // Note that this is not really thread safe if there are multiple 10261 // callers into it at the same time, but that's not a situation we 10262 // care about. 10263 if (persistent) { 10264 final ContentResolver resolver = mContext.getContentResolver(); 10265 Settings.Global.putString( 10266 resolver, Settings.Global.DEBUG_APP, 10267 packageName); 10268 Settings.Global.putInt( 10269 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10270 waitForDebugger ? 1 : 0); 10271 } 10272 10273 synchronized (this) { 10274 if (!persistent) { 10275 mOrigDebugApp = mDebugApp; 10276 mOrigWaitForDebugger = mWaitForDebugger; 10277 } 10278 mDebugApp = packageName; 10279 mWaitForDebugger = waitForDebugger; 10280 mDebugTransient = !persistent; 10281 if (packageName != null) { 10282 forceStopPackageLocked(packageName, -1, false, false, true, true, 10283 false, UserHandle.USER_ALL, "set debug app"); 10284 } 10285 } 10286 } finally { 10287 Binder.restoreCallingIdentity(ident); 10288 } 10289 } 10290 10291 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10292 synchronized (this) { 10293 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10294 if (!isDebuggable) { 10295 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10296 throw new SecurityException("Process not debuggable: " + app.packageName); 10297 } 10298 } 10299 10300 mOpenGlTraceApp = processName; 10301 } 10302 } 10303 10304 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10305 synchronized (this) { 10306 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10307 if (!isDebuggable) { 10308 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10309 throw new SecurityException("Process not debuggable: " + app.packageName); 10310 } 10311 } 10312 mProfileApp = processName; 10313 mProfileFile = profilerInfo.profileFile; 10314 if (mProfileFd != null) { 10315 try { 10316 mProfileFd.close(); 10317 } catch (IOException e) { 10318 } 10319 mProfileFd = null; 10320 } 10321 mProfileFd = profilerInfo.profileFd; 10322 mSamplingInterval = profilerInfo.samplingInterval; 10323 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10324 mProfileType = 0; 10325 } 10326 } 10327 10328 @Override 10329 public void setAlwaysFinish(boolean enabled) { 10330 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10331 "setAlwaysFinish()"); 10332 10333 Settings.Global.putInt( 10334 mContext.getContentResolver(), 10335 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10336 10337 synchronized (this) { 10338 mAlwaysFinishActivities = enabled; 10339 } 10340 } 10341 10342 @Override 10343 public void setActivityController(IActivityController controller) { 10344 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10345 "setActivityController()"); 10346 synchronized (this) { 10347 mController = controller; 10348 Watchdog.getInstance().setActivityController(controller); 10349 } 10350 } 10351 10352 @Override 10353 public void setUserIsMonkey(boolean userIsMonkey) { 10354 synchronized (this) { 10355 synchronized (mPidsSelfLocked) { 10356 final int callingPid = Binder.getCallingPid(); 10357 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10358 if (precessRecord == null) { 10359 throw new SecurityException("Unknown process: " + callingPid); 10360 } 10361 if (precessRecord.instrumentationUiAutomationConnection == null) { 10362 throw new SecurityException("Only an instrumentation process " 10363 + "with a UiAutomation can call setUserIsMonkey"); 10364 } 10365 } 10366 mUserIsMonkey = userIsMonkey; 10367 } 10368 } 10369 10370 @Override 10371 public boolean isUserAMonkey() { 10372 synchronized (this) { 10373 // If there is a controller also implies the user is a monkey. 10374 return (mUserIsMonkey || mController != null); 10375 } 10376 } 10377 10378 public void requestBugReport() { 10379 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10380 SystemProperties.set("ctl.start", "bugreport"); 10381 } 10382 10383 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10384 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10385 } 10386 10387 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10388 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10389 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10390 } 10391 return KEY_DISPATCHING_TIMEOUT; 10392 } 10393 10394 @Override 10395 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10396 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10397 != PackageManager.PERMISSION_GRANTED) { 10398 throw new SecurityException("Requires permission " 10399 + android.Manifest.permission.FILTER_EVENTS); 10400 } 10401 ProcessRecord proc; 10402 long timeout; 10403 synchronized (this) { 10404 synchronized (mPidsSelfLocked) { 10405 proc = mPidsSelfLocked.get(pid); 10406 } 10407 timeout = getInputDispatchingTimeoutLocked(proc); 10408 } 10409 10410 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10411 return -1; 10412 } 10413 10414 return timeout; 10415 } 10416 10417 /** 10418 * Handle input dispatching timeouts. 10419 * Returns whether input dispatching should be aborted or not. 10420 */ 10421 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10422 final ActivityRecord activity, final ActivityRecord parent, 10423 final boolean aboveSystem, String reason) { 10424 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10425 != PackageManager.PERMISSION_GRANTED) { 10426 throw new SecurityException("Requires permission " 10427 + android.Manifest.permission.FILTER_EVENTS); 10428 } 10429 10430 final String annotation; 10431 if (reason == null) { 10432 annotation = "Input dispatching timed out"; 10433 } else { 10434 annotation = "Input dispatching timed out (" + reason + ")"; 10435 } 10436 10437 if (proc != null) { 10438 synchronized (this) { 10439 if (proc.debugging) { 10440 return false; 10441 } 10442 10443 if (mDidDexOpt) { 10444 // Give more time since we were dexopting. 10445 mDidDexOpt = false; 10446 return false; 10447 } 10448 10449 if (proc.instrumentationClass != null) { 10450 Bundle info = new Bundle(); 10451 info.putString("shortMsg", "keyDispatchingTimedOut"); 10452 info.putString("longMsg", annotation); 10453 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10454 return true; 10455 } 10456 } 10457 mHandler.post(new Runnable() { 10458 @Override 10459 public void run() { 10460 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10461 } 10462 }); 10463 } 10464 10465 return true; 10466 } 10467 10468 public Bundle getAssistContextExtras(int requestType) { 10469 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10470 UserHandle.getCallingUserId()); 10471 if (pae == null) { 10472 return null; 10473 } 10474 synchronized (pae) { 10475 while (!pae.haveResult) { 10476 try { 10477 pae.wait(); 10478 } catch (InterruptedException e) { 10479 } 10480 } 10481 if (pae.result != null) { 10482 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10483 } 10484 } 10485 synchronized (this) { 10486 mPendingAssistExtras.remove(pae); 10487 mHandler.removeCallbacks(pae); 10488 } 10489 return pae.extras; 10490 } 10491 10492 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10493 int userHandle) { 10494 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10495 "getAssistContextExtras()"); 10496 PendingAssistExtras pae; 10497 Bundle extras = new Bundle(); 10498 synchronized (this) { 10499 ActivityRecord activity = getFocusedStack().mResumedActivity; 10500 if (activity == null) { 10501 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10502 return null; 10503 } 10504 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10505 if (activity.app == null || activity.app.thread == null) { 10506 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10507 return null; 10508 } 10509 if (activity.app.pid == Binder.getCallingPid()) { 10510 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10511 return null; 10512 } 10513 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10514 try { 10515 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10516 requestType); 10517 mPendingAssistExtras.add(pae); 10518 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10519 } catch (RemoteException e) { 10520 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10521 return null; 10522 } 10523 return pae; 10524 } 10525 } 10526 10527 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10528 PendingAssistExtras pae = (PendingAssistExtras)token; 10529 synchronized (pae) { 10530 pae.result = extras; 10531 pae.haveResult = true; 10532 pae.notifyAll(); 10533 if (pae.intent == null) { 10534 // Caller is just waiting for the result. 10535 return; 10536 } 10537 } 10538 10539 // We are now ready to launch the assist activity. 10540 synchronized (this) { 10541 boolean exists = mPendingAssistExtras.remove(pae); 10542 mHandler.removeCallbacks(pae); 10543 if (!exists) { 10544 // Timed out. 10545 return; 10546 } 10547 } 10548 pae.intent.replaceExtras(extras); 10549 if (pae.hint != null) { 10550 pae.intent.putExtra(pae.hint, true); 10551 } 10552 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10553 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10554 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10555 closeSystemDialogs("assist"); 10556 try { 10557 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10558 } catch (ActivityNotFoundException e) { 10559 Slog.w(TAG, "No activity to handle assist action.", e); 10560 } 10561 } 10562 10563 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10564 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10565 } 10566 10567 public void registerProcessObserver(IProcessObserver observer) { 10568 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10569 "registerProcessObserver()"); 10570 synchronized (this) { 10571 mProcessObservers.register(observer); 10572 } 10573 } 10574 10575 @Override 10576 public void unregisterProcessObserver(IProcessObserver observer) { 10577 synchronized (this) { 10578 mProcessObservers.unregister(observer); 10579 } 10580 } 10581 10582 @Override 10583 public boolean convertFromTranslucent(IBinder token) { 10584 final long origId = Binder.clearCallingIdentity(); 10585 try { 10586 synchronized (this) { 10587 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10588 if (r == null) { 10589 return false; 10590 } 10591 final boolean translucentChanged = r.changeWindowTranslucency(true); 10592 if (translucentChanged) { 10593 r.task.stack.releaseBackgroundResources(); 10594 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10595 } 10596 mWindowManager.setAppFullscreen(token, true); 10597 return translucentChanged; 10598 } 10599 } finally { 10600 Binder.restoreCallingIdentity(origId); 10601 } 10602 } 10603 10604 @Override 10605 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10606 final long origId = Binder.clearCallingIdentity(); 10607 try { 10608 synchronized (this) { 10609 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10610 if (r == null) { 10611 return false; 10612 } 10613 int index = r.task.mActivities.lastIndexOf(r); 10614 if (index > 0) { 10615 ActivityRecord under = r.task.mActivities.get(index - 1); 10616 under.returningOptions = options; 10617 } 10618 final boolean translucentChanged = r.changeWindowTranslucency(false); 10619 if (translucentChanged) { 10620 r.task.stack.convertToTranslucent(r); 10621 } 10622 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10623 mWindowManager.setAppFullscreen(token, false); 10624 return translucentChanged; 10625 } 10626 } finally { 10627 Binder.restoreCallingIdentity(origId); 10628 } 10629 } 10630 10631 @Override 10632 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10633 final long origId = Binder.clearCallingIdentity(); 10634 try { 10635 synchronized (this) { 10636 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10637 if (r != null) { 10638 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10639 } 10640 } 10641 return false; 10642 } finally { 10643 Binder.restoreCallingIdentity(origId); 10644 } 10645 } 10646 10647 @Override 10648 public boolean isBackgroundVisibleBehind(IBinder token) { 10649 final long origId = Binder.clearCallingIdentity(); 10650 try { 10651 synchronized (this) { 10652 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10653 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10654 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10655 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10656 return visible; 10657 } 10658 } finally { 10659 Binder.restoreCallingIdentity(origId); 10660 } 10661 } 10662 10663 @Override 10664 public ActivityOptions getActivityOptions(IBinder token) { 10665 final long origId = Binder.clearCallingIdentity(); 10666 try { 10667 synchronized (this) { 10668 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10669 if (r != null) { 10670 final ActivityOptions activityOptions = r.pendingOptions; 10671 r.pendingOptions = null; 10672 return activityOptions; 10673 } 10674 return null; 10675 } 10676 } finally { 10677 Binder.restoreCallingIdentity(origId); 10678 } 10679 } 10680 10681 @Override 10682 public void setImmersive(IBinder token, boolean immersive) { 10683 synchronized(this) { 10684 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10685 if (r == null) { 10686 throw new IllegalArgumentException(); 10687 } 10688 r.immersive = immersive; 10689 10690 // update associated state if we're frontmost 10691 if (r == mFocusedActivity) { 10692 if (DEBUG_IMMERSIVE) { 10693 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10694 } 10695 applyUpdateLockStateLocked(r); 10696 } 10697 } 10698 } 10699 10700 @Override 10701 public boolean isImmersive(IBinder token) { 10702 synchronized (this) { 10703 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10704 if (r == null) { 10705 throw new IllegalArgumentException(); 10706 } 10707 return r.immersive; 10708 } 10709 } 10710 10711 public boolean isTopActivityImmersive() { 10712 enforceNotIsolatedCaller("startActivity"); 10713 synchronized (this) { 10714 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10715 return (r != null) ? r.immersive : false; 10716 } 10717 } 10718 10719 @Override 10720 public boolean isTopOfTask(IBinder token) { 10721 synchronized (this) { 10722 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10723 if (r == null) { 10724 throw new IllegalArgumentException(); 10725 } 10726 return r.task.getTopActivity() == r; 10727 } 10728 } 10729 10730 public final void enterSafeMode() { 10731 synchronized(this) { 10732 // It only makes sense to do this before the system is ready 10733 // and started launching other packages. 10734 if (!mSystemReady) { 10735 try { 10736 AppGlobals.getPackageManager().enterSafeMode(); 10737 } catch (RemoteException e) { 10738 } 10739 } 10740 10741 mSafeMode = true; 10742 } 10743 } 10744 10745 public final void showSafeModeOverlay() { 10746 View v = LayoutInflater.from(mContext).inflate( 10747 com.android.internal.R.layout.safe_mode, null); 10748 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10749 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10750 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10751 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10752 lp.gravity = Gravity.BOTTOM | Gravity.START; 10753 lp.format = v.getBackground().getOpacity(); 10754 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10755 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10756 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10757 ((WindowManager)mContext.getSystemService( 10758 Context.WINDOW_SERVICE)).addView(v, lp); 10759 } 10760 10761 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10762 if (!(sender instanceof PendingIntentRecord)) { 10763 return; 10764 } 10765 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10766 synchronized (stats) { 10767 if (mBatteryStatsService.isOnBattery()) { 10768 mBatteryStatsService.enforceCallingPermission(); 10769 PendingIntentRecord rec = (PendingIntentRecord)sender; 10770 int MY_UID = Binder.getCallingUid(); 10771 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10772 BatteryStatsImpl.Uid.Pkg pkg = 10773 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10774 sourcePkg != null ? sourcePkg : rec.key.packageName); 10775 pkg.incWakeupsLocked(); 10776 } 10777 } 10778 } 10779 10780 public boolean killPids(int[] pids, String pReason, boolean secure) { 10781 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10782 throw new SecurityException("killPids only available to the system"); 10783 } 10784 String reason = (pReason == null) ? "Unknown" : pReason; 10785 // XXX Note: don't acquire main activity lock here, because the window 10786 // manager calls in with its locks held. 10787 10788 boolean killed = false; 10789 synchronized (mPidsSelfLocked) { 10790 int[] types = new int[pids.length]; 10791 int worstType = 0; 10792 for (int i=0; i<pids.length; i++) { 10793 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10794 if (proc != null) { 10795 int type = proc.setAdj; 10796 types[i] = type; 10797 if (type > worstType) { 10798 worstType = type; 10799 } 10800 } 10801 } 10802 10803 // If the worst oom_adj is somewhere in the cached proc LRU range, 10804 // then constrain it so we will kill all cached procs. 10805 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10806 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10807 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10808 } 10809 10810 // If this is not a secure call, don't let it kill processes that 10811 // are important. 10812 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10813 worstType = ProcessList.SERVICE_ADJ; 10814 } 10815 10816 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10817 for (int i=0; i<pids.length; i++) { 10818 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10819 if (proc == null) { 10820 continue; 10821 } 10822 int adj = proc.setAdj; 10823 if (adj >= worstType && !proc.killedByAm) { 10824 proc.kill(reason, true); 10825 killed = true; 10826 } 10827 } 10828 } 10829 return killed; 10830 } 10831 10832 @Override 10833 public void killUid(int uid, String reason) { 10834 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10835 throw new SecurityException("killUid only available to the system"); 10836 } 10837 synchronized (this) { 10838 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10839 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10840 reason != null ? reason : "kill uid"); 10841 } 10842 } 10843 10844 @Override 10845 public boolean killProcessesBelowForeground(String reason) { 10846 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10847 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10848 } 10849 10850 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10851 } 10852 10853 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10854 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10855 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10856 } 10857 10858 boolean killed = false; 10859 synchronized (mPidsSelfLocked) { 10860 final int size = mPidsSelfLocked.size(); 10861 for (int i = 0; i < size; i++) { 10862 final int pid = mPidsSelfLocked.keyAt(i); 10863 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10864 if (proc == null) continue; 10865 10866 final int adj = proc.setAdj; 10867 if (adj > belowAdj && !proc.killedByAm) { 10868 proc.kill(reason, true); 10869 killed = true; 10870 } 10871 } 10872 } 10873 return killed; 10874 } 10875 10876 @Override 10877 public void hang(final IBinder who, boolean allowRestart) { 10878 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10879 != PackageManager.PERMISSION_GRANTED) { 10880 throw new SecurityException("Requires permission " 10881 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10882 } 10883 10884 final IBinder.DeathRecipient death = new DeathRecipient() { 10885 @Override 10886 public void binderDied() { 10887 synchronized (this) { 10888 notifyAll(); 10889 } 10890 } 10891 }; 10892 10893 try { 10894 who.linkToDeath(death, 0); 10895 } catch (RemoteException e) { 10896 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10897 return; 10898 } 10899 10900 synchronized (this) { 10901 Watchdog.getInstance().setAllowRestart(allowRestart); 10902 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10903 synchronized (death) { 10904 while (who.isBinderAlive()) { 10905 try { 10906 death.wait(); 10907 } catch (InterruptedException e) { 10908 } 10909 } 10910 } 10911 Watchdog.getInstance().setAllowRestart(true); 10912 } 10913 } 10914 10915 @Override 10916 public void restart() { 10917 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10918 != PackageManager.PERMISSION_GRANTED) { 10919 throw new SecurityException("Requires permission " 10920 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10921 } 10922 10923 Log.i(TAG, "Sending shutdown broadcast..."); 10924 10925 BroadcastReceiver br = new BroadcastReceiver() { 10926 @Override public void onReceive(Context context, Intent intent) { 10927 // Now the broadcast is done, finish up the low-level shutdown. 10928 Log.i(TAG, "Shutting down activity manager..."); 10929 shutdown(10000); 10930 Log.i(TAG, "Shutdown complete, restarting!"); 10931 Process.killProcess(Process.myPid()); 10932 System.exit(10); 10933 } 10934 }; 10935 10936 // First send the high-level shut down broadcast. 10937 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10938 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10939 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10940 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10941 mContext.sendOrderedBroadcastAsUser(intent, 10942 UserHandle.ALL, null, br, mHandler, 0, null, null); 10943 */ 10944 br.onReceive(mContext, intent); 10945 } 10946 10947 private long getLowRamTimeSinceIdle(long now) { 10948 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10949 } 10950 10951 @Override 10952 public void performIdleMaintenance() { 10953 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10954 != PackageManager.PERMISSION_GRANTED) { 10955 throw new SecurityException("Requires permission " 10956 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10957 } 10958 10959 synchronized (this) { 10960 final long now = SystemClock.uptimeMillis(); 10961 final long timeSinceLastIdle = now - mLastIdleTime; 10962 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10963 mLastIdleTime = now; 10964 mLowRamTimeSinceLastIdle = 0; 10965 if (mLowRamStartTime != 0) { 10966 mLowRamStartTime = now; 10967 } 10968 10969 StringBuilder sb = new StringBuilder(128); 10970 sb.append("Idle maintenance over "); 10971 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10972 sb.append(" low RAM for "); 10973 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10974 Slog.i(TAG, sb.toString()); 10975 10976 // If at least 1/3 of our time since the last idle period has been spent 10977 // with RAM low, then we want to kill processes. 10978 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10979 10980 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10981 ProcessRecord proc = mLruProcesses.get(i); 10982 if (proc.notCachedSinceIdle) { 10983 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10984 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10985 if (doKilling && proc.initialIdlePss != 0 10986 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10987 proc.kill("idle maint (pss " + proc.lastPss 10988 + " from " + proc.initialIdlePss + ")", true); 10989 } 10990 } 10991 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10992 proc.notCachedSinceIdle = true; 10993 proc.initialIdlePss = 0; 10994 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10995 isSleeping(), now); 10996 } 10997 } 10998 10999 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 11000 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11001 } 11002 } 11003 11004 private void retrieveSettings() { 11005 final ContentResolver resolver = mContext.getContentResolver(); 11006 String debugApp = Settings.Global.getString( 11007 resolver, Settings.Global.DEBUG_APP); 11008 boolean waitForDebugger = Settings.Global.getInt( 11009 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11010 boolean alwaysFinishActivities = Settings.Global.getInt( 11011 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11012 boolean forceRtl = Settings.Global.getInt( 11013 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11014 // Transfer any global setting for forcing RTL layout, into a System Property 11015 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11016 11017 Configuration configuration = new Configuration(); 11018 Settings.System.getConfiguration(resolver, configuration); 11019 if (forceRtl) { 11020 // This will take care of setting the correct layout direction flags 11021 configuration.setLayoutDirection(configuration.locale); 11022 } 11023 11024 synchronized (this) { 11025 mDebugApp = mOrigDebugApp = debugApp; 11026 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11027 mAlwaysFinishActivities = alwaysFinishActivities; 11028 // This happens before any activities are started, so we can 11029 // change mConfiguration in-place. 11030 updateConfigurationLocked(configuration, null, false, true); 11031 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11032 } 11033 } 11034 11035 /** Loads resources after the current configuration has been set. */ 11036 private void loadResourcesOnSystemReady() { 11037 final Resources res = mContext.getResources(); 11038 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11039 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11040 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11041 } 11042 11043 public boolean testIsSystemReady() { 11044 // no need to synchronize(this) just to read & return the value 11045 return mSystemReady; 11046 } 11047 11048 private static File getCalledPreBootReceiversFile() { 11049 File dataDir = Environment.getDataDirectory(); 11050 File systemDir = new File(dataDir, "system"); 11051 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11052 return fname; 11053 } 11054 11055 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11056 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11057 File file = getCalledPreBootReceiversFile(); 11058 FileInputStream fis = null; 11059 try { 11060 fis = new FileInputStream(file); 11061 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11062 int fvers = dis.readInt(); 11063 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11064 String vers = dis.readUTF(); 11065 String codename = dis.readUTF(); 11066 String build = dis.readUTF(); 11067 if (android.os.Build.VERSION.RELEASE.equals(vers) 11068 && android.os.Build.VERSION.CODENAME.equals(codename) 11069 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11070 int num = dis.readInt(); 11071 while (num > 0) { 11072 num--; 11073 String pkg = dis.readUTF(); 11074 String cls = dis.readUTF(); 11075 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11076 } 11077 } 11078 } 11079 } catch (FileNotFoundException e) { 11080 } catch (IOException e) { 11081 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11082 } finally { 11083 if (fis != null) { 11084 try { 11085 fis.close(); 11086 } catch (IOException e) { 11087 } 11088 } 11089 } 11090 return lastDoneReceivers; 11091 } 11092 11093 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11094 File file = getCalledPreBootReceiversFile(); 11095 FileOutputStream fos = null; 11096 DataOutputStream dos = null; 11097 try { 11098 fos = new FileOutputStream(file); 11099 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11100 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11101 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11102 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11103 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11104 dos.writeInt(list.size()); 11105 for (int i=0; i<list.size(); i++) { 11106 dos.writeUTF(list.get(i).getPackageName()); 11107 dos.writeUTF(list.get(i).getClassName()); 11108 } 11109 } catch (IOException e) { 11110 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11111 file.delete(); 11112 } finally { 11113 FileUtils.sync(fos); 11114 if (dos != null) { 11115 try { 11116 dos.close(); 11117 } catch (IOException e) { 11118 // TODO Auto-generated catch block 11119 e.printStackTrace(); 11120 } 11121 } 11122 } 11123 } 11124 11125 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11126 ArrayList<ComponentName> doneReceivers, int userId) { 11127 boolean waitingUpdate = false; 11128 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11129 List<ResolveInfo> ris = null; 11130 try { 11131 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11132 intent, null, 0, userId); 11133 } catch (RemoteException e) { 11134 } 11135 if (ris != null) { 11136 for (int i=ris.size()-1; i>=0; i--) { 11137 if ((ris.get(i).activityInfo.applicationInfo.flags 11138 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11139 ris.remove(i); 11140 } 11141 } 11142 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11143 11144 // For User 0, load the version number. When delivering to a new user, deliver 11145 // to all receivers. 11146 if (userId == UserHandle.USER_OWNER) { 11147 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11148 for (int i=0; i<ris.size(); i++) { 11149 ActivityInfo ai = ris.get(i).activityInfo; 11150 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11151 if (lastDoneReceivers.contains(comp)) { 11152 // We already did the pre boot receiver for this app with the current 11153 // platform version, so don't do it again... 11154 ris.remove(i); 11155 i--; 11156 // ...however, do keep it as one that has been done, so we don't 11157 // forget about it when rewriting the file of last done receivers. 11158 doneReceivers.add(comp); 11159 } 11160 } 11161 } 11162 11163 // If primary user, send broadcast to all available users, else just to userId 11164 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11165 : new int[] { userId }; 11166 for (int i = 0; i < ris.size(); i++) { 11167 ActivityInfo ai = ris.get(i).activityInfo; 11168 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11169 doneReceivers.add(comp); 11170 intent.setComponent(comp); 11171 for (int j=0; j<users.length; j++) { 11172 IIntentReceiver finisher = null; 11173 // On last receiver and user, set up a completion callback 11174 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11175 finisher = new IIntentReceiver.Stub() { 11176 public void performReceive(Intent intent, int resultCode, 11177 String data, Bundle extras, boolean ordered, 11178 boolean sticky, int sendingUser) { 11179 // The raw IIntentReceiver interface is called 11180 // with the AM lock held, so redispatch to 11181 // execute our code without the lock. 11182 mHandler.post(onFinishCallback); 11183 } 11184 }; 11185 } 11186 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11187 + " for user " + users[j]); 11188 broadcastIntentLocked(null, null, intent, null, finisher, 11189 0, null, null, null, AppOpsManager.OP_NONE, 11190 true, false, MY_PID, Process.SYSTEM_UID, 11191 users[j]); 11192 if (finisher != null) { 11193 waitingUpdate = true; 11194 } 11195 } 11196 } 11197 } 11198 11199 return waitingUpdate; 11200 } 11201 11202 public void systemReady(final Runnable goingCallback) { 11203 synchronized(this) { 11204 if (mSystemReady) { 11205 // If we're done calling all the receivers, run the next "boot phase" passed in 11206 // by the SystemServer 11207 if (goingCallback != null) { 11208 goingCallback.run(); 11209 } 11210 return; 11211 } 11212 11213 // Make sure we have the current profile info, since it is needed for 11214 // security checks. 11215 updateCurrentProfileIdsLocked(); 11216 11217 if (mRecentTasks == null) { 11218 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11219 if (!mRecentTasks.isEmpty()) { 11220 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11221 } 11222 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11223 mTaskPersister.startPersisting(); 11224 } 11225 11226 // Check to see if there are any update receivers to run. 11227 if (!mDidUpdate) { 11228 if (mWaitingUpdate) { 11229 return; 11230 } 11231 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11232 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11233 public void run() { 11234 synchronized (ActivityManagerService.this) { 11235 mDidUpdate = true; 11236 } 11237 writeLastDonePreBootReceivers(doneReceivers); 11238 showBootMessage(mContext.getText( 11239 R.string.android_upgrading_complete), 11240 false); 11241 systemReady(goingCallback); 11242 } 11243 }, doneReceivers, UserHandle.USER_OWNER); 11244 11245 if (mWaitingUpdate) { 11246 return; 11247 } 11248 mDidUpdate = true; 11249 } 11250 11251 mAppOpsService.systemReady(); 11252 mSystemReady = true; 11253 } 11254 11255 ArrayList<ProcessRecord> procsToKill = null; 11256 synchronized(mPidsSelfLocked) { 11257 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11258 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11259 if (!isAllowedWhileBooting(proc.info)){ 11260 if (procsToKill == null) { 11261 procsToKill = new ArrayList<ProcessRecord>(); 11262 } 11263 procsToKill.add(proc); 11264 } 11265 } 11266 } 11267 11268 synchronized(this) { 11269 if (procsToKill != null) { 11270 for (int i=procsToKill.size()-1; i>=0; i--) { 11271 ProcessRecord proc = procsToKill.get(i); 11272 Slog.i(TAG, "Removing system update proc: " + proc); 11273 removeProcessLocked(proc, true, false, "system update done"); 11274 } 11275 } 11276 11277 // Now that we have cleaned up any update processes, we 11278 // are ready to start launching real processes and know that 11279 // we won't trample on them any more. 11280 mProcessesReady = true; 11281 } 11282 11283 Slog.i(TAG, "System now ready"); 11284 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11285 SystemClock.uptimeMillis()); 11286 11287 synchronized(this) { 11288 // Make sure we have no pre-ready processes sitting around. 11289 11290 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11291 ResolveInfo ri = mContext.getPackageManager() 11292 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11293 STOCK_PM_FLAGS); 11294 CharSequence errorMsg = null; 11295 if (ri != null) { 11296 ActivityInfo ai = ri.activityInfo; 11297 ApplicationInfo app = ai.applicationInfo; 11298 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11299 mTopAction = Intent.ACTION_FACTORY_TEST; 11300 mTopData = null; 11301 mTopComponent = new ComponentName(app.packageName, 11302 ai.name); 11303 } else { 11304 errorMsg = mContext.getResources().getText( 11305 com.android.internal.R.string.factorytest_not_system); 11306 } 11307 } else { 11308 errorMsg = mContext.getResources().getText( 11309 com.android.internal.R.string.factorytest_no_action); 11310 } 11311 if (errorMsg != null) { 11312 mTopAction = null; 11313 mTopData = null; 11314 mTopComponent = null; 11315 Message msg = Message.obtain(); 11316 msg.what = SHOW_FACTORY_ERROR_MSG; 11317 msg.getData().putCharSequence("msg", errorMsg); 11318 mHandler.sendMessage(msg); 11319 } 11320 } 11321 } 11322 11323 retrieveSettings(); 11324 loadResourcesOnSystemReady(); 11325 11326 synchronized (this) { 11327 readGrantedUriPermissionsLocked(); 11328 } 11329 11330 if (goingCallback != null) goingCallback.run(); 11331 11332 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11333 Integer.toString(mCurrentUserId), mCurrentUserId); 11334 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11335 Integer.toString(mCurrentUserId), mCurrentUserId); 11336 mSystemServiceManager.startUser(mCurrentUserId); 11337 11338 synchronized (this) { 11339 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11340 try { 11341 List apps = AppGlobals.getPackageManager(). 11342 getPersistentApplications(STOCK_PM_FLAGS); 11343 if (apps != null) { 11344 int N = apps.size(); 11345 int i; 11346 for (i=0; i<N; i++) { 11347 ApplicationInfo info 11348 = (ApplicationInfo)apps.get(i); 11349 if (info != null && 11350 !info.packageName.equals("android")) { 11351 addAppLocked(info, false, null /* ABI override */); 11352 } 11353 } 11354 } 11355 } catch (RemoteException ex) { 11356 // pm is in same process, this will never happen. 11357 } 11358 } 11359 11360 // Start up initial activity. 11361 mBooting = true; 11362 startHomeActivityLocked(mCurrentUserId); 11363 11364 try { 11365 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11366 Message msg = Message.obtain(); 11367 msg.what = SHOW_UID_ERROR_MSG; 11368 mHandler.sendMessage(msg); 11369 } 11370 } catch (RemoteException e) { 11371 } 11372 11373 long ident = Binder.clearCallingIdentity(); 11374 try { 11375 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11376 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11377 | Intent.FLAG_RECEIVER_FOREGROUND); 11378 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11379 broadcastIntentLocked(null, null, intent, 11380 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11381 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11382 intent = new Intent(Intent.ACTION_USER_STARTING); 11383 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11384 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11385 broadcastIntentLocked(null, null, intent, 11386 null, new IIntentReceiver.Stub() { 11387 @Override 11388 public void performReceive(Intent intent, int resultCode, String data, 11389 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11390 throws RemoteException { 11391 } 11392 }, 0, null, null, 11393 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11394 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11395 } catch (Throwable t) { 11396 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11397 } finally { 11398 Binder.restoreCallingIdentity(ident); 11399 } 11400 mStackSupervisor.resumeTopActivitiesLocked(); 11401 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11402 } 11403 } 11404 11405 private boolean makeAppCrashingLocked(ProcessRecord app, 11406 String shortMsg, String longMsg, String stackTrace) { 11407 app.crashing = true; 11408 app.crashingReport = generateProcessError(app, 11409 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11410 startAppProblemLocked(app); 11411 app.stopFreezingAllLocked(); 11412 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11413 } 11414 11415 private void makeAppNotRespondingLocked(ProcessRecord app, 11416 String activity, String shortMsg, String longMsg) { 11417 app.notResponding = true; 11418 app.notRespondingReport = generateProcessError(app, 11419 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11420 activity, shortMsg, longMsg, null); 11421 startAppProblemLocked(app); 11422 app.stopFreezingAllLocked(); 11423 } 11424 11425 /** 11426 * Generate a process error record, suitable for attachment to a ProcessRecord. 11427 * 11428 * @param app The ProcessRecord in which the error occurred. 11429 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11430 * ActivityManager.AppErrorStateInfo 11431 * @param activity The activity associated with the crash, if known. 11432 * @param shortMsg Short message describing the crash. 11433 * @param longMsg Long message describing the crash. 11434 * @param stackTrace Full crash stack trace, may be null. 11435 * 11436 * @return Returns a fully-formed AppErrorStateInfo record. 11437 */ 11438 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11439 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11440 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11441 11442 report.condition = condition; 11443 report.processName = app.processName; 11444 report.pid = app.pid; 11445 report.uid = app.info.uid; 11446 report.tag = activity; 11447 report.shortMsg = shortMsg; 11448 report.longMsg = longMsg; 11449 report.stackTrace = stackTrace; 11450 11451 return report; 11452 } 11453 11454 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11455 synchronized (this) { 11456 app.crashing = false; 11457 app.crashingReport = null; 11458 app.notResponding = false; 11459 app.notRespondingReport = null; 11460 if (app.anrDialog == fromDialog) { 11461 app.anrDialog = null; 11462 } 11463 if (app.waitDialog == fromDialog) { 11464 app.waitDialog = null; 11465 } 11466 if (app.pid > 0 && app.pid != MY_PID) { 11467 handleAppCrashLocked(app, null, null, null); 11468 app.kill("user request after error", true); 11469 } 11470 } 11471 } 11472 11473 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11474 String stackTrace) { 11475 long now = SystemClock.uptimeMillis(); 11476 11477 Long crashTime; 11478 if (!app.isolated) { 11479 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11480 } else { 11481 crashTime = null; 11482 } 11483 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11484 // This process loses! 11485 Slog.w(TAG, "Process " + app.info.processName 11486 + " has crashed too many times: killing!"); 11487 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11488 app.userId, app.info.processName, app.uid); 11489 mStackSupervisor.handleAppCrashLocked(app); 11490 if (!app.persistent) { 11491 // We don't want to start this process again until the user 11492 // explicitly does so... but for persistent process, we really 11493 // need to keep it running. If a persistent process is actually 11494 // repeatedly crashing, then badness for everyone. 11495 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11496 app.info.processName); 11497 if (!app.isolated) { 11498 // XXX We don't have a way to mark isolated processes 11499 // as bad, since they don't have a peristent identity. 11500 mBadProcesses.put(app.info.processName, app.uid, 11501 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11502 mProcessCrashTimes.remove(app.info.processName, app.uid); 11503 } 11504 app.bad = true; 11505 app.removed = true; 11506 // Don't let services in this process be restarted and potentially 11507 // annoy the user repeatedly. Unless it is persistent, since those 11508 // processes run critical code. 11509 removeProcessLocked(app, false, false, "crash"); 11510 mStackSupervisor.resumeTopActivitiesLocked(); 11511 return false; 11512 } 11513 mStackSupervisor.resumeTopActivitiesLocked(); 11514 } else { 11515 mStackSupervisor.finishTopRunningActivityLocked(app); 11516 } 11517 11518 // Bump up the crash count of any services currently running in the proc. 11519 for (int i=app.services.size()-1; i>=0; i--) { 11520 // Any services running in the application need to be placed 11521 // back in the pending list. 11522 ServiceRecord sr = app.services.valueAt(i); 11523 sr.crashCount++; 11524 } 11525 11526 // If the crashing process is what we consider to be the "home process" and it has been 11527 // replaced by a third-party app, clear the package preferred activities from packages 11528 // with a home activity running in the process to prevent a repeatedly crashing app 11529 // from blocking the user to manually clear the list. 11530 final ArrayList<ActivityRecord> activities = app.activities; 11531 if (app == mHomeProcess && activities.size() > 0 11532 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11533 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11534 final ActivityRecord r = activities.get(activityNdx); 11535 if (r.isHomeActivity()) { 11536 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11537 try { 11538 ActivityThread.getPackageManager() 11539 .clearPackagePreferredActivities(r.packageName); 11540 } catch (RemoteException c) { 11541 // pm is in same process, this will never happen. 11542 } 11543 } 11544 } 11545 } 11546 11547 if (!app.isolated) { 11548 // XXX Can't keep track of crash times for isolated processes, 11549 // because they don't have a perisistent identity. 11550 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11551 } 11552 11553 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11554 return true; 11555 } 11556 11557 void startAppProblemLocked(ProcessRecord app) { 11558 // If this app is not running under the current user, then we 11559 // can't give it a report button because that would require 11560 // launching the report UI under a different user. 11561 app.errorReportReceiver = null; 11562 11563 for (int userId : mCurrentProfileIds) { 11564 if (app.userId == userId) { 11565 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11566 mContext, app.info.packageName, app.info.flags); 11567 } 11568 } 11569 skipCurrentReceiverLocked(app); 11570 } 11571 11572 void skipCurrentReceiverLocked(ProcessRecord app) { 11573 for (BroadcastQueue queue : mBroadcastQueues) { 11574 queue.skipCurrentReceiverLocked(app); 11575 } 11576 } 11577 11578 /** 11579 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11580 * The application process will exit immediately after this call returns. 11581 * @param app object of the crashing app, null for the system server 11582 * @param crashInfo describing the exception 11583 */ 11584 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11585 ProcessRecord r = findAppProcess(app, "Crash"); 11586 final String processName = app == null ? "system_server" 11587 : (r == null ? "unknown" : r.processName); 11588 11589 handleApplicationCrashInner("crash", r, processName, crashInfo); 11590 } 11591 11592 /* Native crash reporting uses this inner version because it needs to be somewhat 11593 * decoupled from the AM-managed cleanup lifecycle 11594 */ 11595 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11596 ApplicationErrorReport.CrashInfo crashInfo) { 11597 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11598 UserHandle.getUserId(Binder.getCallingUid()), processName, 11599 r == null ? -1 : r.info.flags, 11600 crashInfo.exceptionClassName, 11601 crashInfo.exceptionMessage, 11602 crashInfo.throwFileName, 11603 crashInfo.throwLineNumber); 11604 11605 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11606 11607 crashApplication(r, crashInfo); 11608 } 11609 11610 public void handleApplicationStrictModeViolation( 11611 IBinder app, 11612 int violationMask, 11613 StrictMode.ViolationInfo info) { 11614 ProcessRecord r = findAppProcess(app, "StrictMode"); 11615 if (r == null) { 11616 return; 11617 } 11618 11619 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11620 Integer stackFingerprint = info.hashCode(); 11621 boolean logIt = true; 11622 synchronized (mAlreadyLoggedViolatedStacks) { 11623 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11624 logIt = false; 11625 // TODO: sub-sample into EventLog for these, with 11626 // the info.durationMillis? Then we'd get 11627 // the relative pain numbers, without logging all 11628 // the stack traces repeatedly. We'd want to do 11629 // likewise in the client code, which also does 11630 // dup suppression, before the Binder call. 11631 } else { 11632 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11633 mAlreadyLoggedViolatedStacks.clear(); 11634 } 11635 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11636 } 11637 } 11638 if (logIt) { 11639 logStrictModeViolationToDropBox(r, info); 11640 } 11641 } 11642 11643 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11644 AppErrorResult result = new AppErrorResult(); 11645 synchronized (this) { 11646 final long origId = Binder.clearCallingIdentity(); 11647 11648 Message msg = Message.obtain(); 11649 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11650 HashMap<String, Object> data = new HashMap<String, Object>(); 11651 data.put("result", result); 11652 data.put("app", r); 11653 data.put("violationMask", violationMask); 11654 data.put("info", info); 11655 msg.obj = data; 11656 mHandler.sendMessage(msg); 11657 11658 Binder.restoreCallingIdentity(origId); 11659 } 11660 int res = result.get(); 11661 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11662 } 11663 } 11664 11665 // Depending on the policy in effect, there could be a bunch of 11666 // these in quick succession so we try to batch these together to 11667 // minimize disk writes, number of dropbox entries, and maximize 11668 // compression, by having more fewer, larger records. 11669 private void logStrictModeViolationToDropBox( 11670 ProcessRecord process, 11671 StrictMode.ViolationInfo info) { 11672 if (info == null) { 11673 return; 11674 } 11675 final boolean isSystemApp = process == null || 11676 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11677 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11678 final String processName = process == null ? "unknown" : process.processName; 11679 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11680 final DropBoxManager dbox = (DropBoxManager) 11681 mContext.getSystemService(Context.DROPBOX_SERVICE); 11682 11683 // Exit early if the dropbox isn't configured to accept this report type. 11684 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11685 11686 boolean bufferWasEmpty; 11687 boolean needsFlush; 11688 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11689 synchronized (sb) { 11690 bufferWasEmpty = sb.length() == 0; 11691 appendDropBoxProcessHeaders(process, processName, sb); 11692 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11693 sb.append("System-App: ").append(isSystemApp).append("\n"); 11694 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11695 if (info.violationNumThisLoop != 0) { 11696 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11697 } 11698 if (info.numAnimationsRunning != 0) { 11699 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11700 } 11701 if (info.broadcastIntentAction != null) { 11702 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11703 } 11704 if (info.durationMillis != -1) { 11705 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11706 } 11707 if (info.numInstances != -1) { 11708 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11709 } 11710 if (info.tags != null) { 11711 for (String tag : info.tags) { 11712 sb.append("Span-Tag: ").append(tag).append("\n"); 11713 } 11714 } 11715 sb.append("\n"); 11716 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11717 sb.append(info.crashInfo.stackTrace); 11718 } 11719 sb.append("\n"); 11720 11721 // Only buffer up to ~64k. Various logging bits truncate 11722 // things at 128k. 11723 needsFlush = (sb.length() > 64 * 1024); 11724 } 11725 11726 // Flush immediately if the buffer's grown too large, or this 11727 // is a non-system app. Non-system apps are isolated with a 11728 // different tag & policy and not batched. 11729 // 11730 // Batching is useful during internal testing with 11731 // StrictMode settings turned up high. Without batching, 11732 // thousands of separate files could be created on boot. 11733 if (!isSystemApp || needsFlush) { 11734 new Thread("Error dump: " + dropboxTag) { 11735 @Override 11736 public void run() { 11737 String report; 11738 synchronized (sb) { 11739 report = sb.toString(); 11740 sb.delete(0, sb.length()); 11741 sb.trimToSize(); 11742 } 11743 if (report.length() != 0) { 11744 dbox.addText(dropboxTag, report); 11745 } 11746 } 11747 }.start(); 11748 return; 11749 } 11750 11751 // System app batching: 11752 if (!bufferWasEmpty) { 11753 // An existing dropbox-writing thread is outstanding, so 11754 // we don't need to start it up. The existing thread will 11755 // catch the buffer appends we just did. 11756 return; 11757 } 11758 11759 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11760 // (After this point, we shouldn't access AMS internal data structures.) 11761 new Thread("Error dump: " + dropboxTag) { 11762 @Override 11763 public void run() { 11764 // 5 second sleep to let stacks arrive and be batched together 11765 try { 11766 Thread.sleep(5000); // 5 seconds 11767 } catch (InterruptedException e) {} 11768 11769 String errorReport; 11770 synchronized (mStrictModeBuffer) { 11771 errorReport = mStrictModeBuffer.toString(); 11772 if (errorReport.length() == 0) { 11773 return; 11774 } 11775 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11776 mStrictModeBuffer.trimToSize(); 11777 } 11778 dbox.addText(dropboxTag, errorReport); 11779 } 11780 }.start(); 11781 } 11782 11783 /** 11784 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11785 * @param app object of the crashing app, null for the system server 11786 * @param tag reported by the caller 11787 * @param system whether this wtf is coming from the system 11788 * @param crashInfo describing the context of the error 11789 * @return true if the process should exit immediately (WTF is fatal) 11790 */ 11791 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11792 final ApplicationErrorReport.CrashInfo crashInfo) { 11793 final int callingUid = Binder.getCallingUid(); 11794 final int callingPid = Binder.getCallingPid(); 11795 11796 if (system) { 11797 // If this is coming from the system, we could very well have low-level 11798 // system locks held, so we want to do this all asynchronously. And we 11799 // never want this to become fatal, so there is that too. 11800 mHandler.post(new Runnable() { 11801 @Override public void run() { 11802 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11803 } 11804 }); 11805 return false; 11806 } 11807 11808 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11809 crashInfo); 11810 11811 if (r != null && r.pid != Process.myPid() && 11812 Settings.Global.getInt(mContext.getContentResolver(), 11813 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11814 crashApplication(r, crashInfo); 11815 return true; 11816 } else { 11817 return false; 11818 } 11819 } 11820 11821 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11822 final ApplicationErrorReport.CrashInfo crashInfo) { 11823 final ProcessRecord r = findAppProcess(app, "WTF"); 11824 final String processName = app == null ? "system_server" 11825 : (r == null ? "unknown" : r.processName); 11826 11827 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11828 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11829 11830 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11831 11832 return r; 11833 } 11834 11835 /** 11836 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11837 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11838 */ 11839 private ProcessRecord findAppProcess(IBinder app, String reason) { 11840 if (app == null) { 11841 return null; 11842 } 11843 11844 synchronized (this) { 11845 final int NP = mProcessNames.getMap().size(); 11846 for (int ip=0; ip<NP; ip++) { 11847 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11848 final int NA = apps.size(); 11849 for (int ia=0; ia<NA; ia++) { 11850 ProcessRecord p = apps.valueAt(ia); 11851 if (p.thread != null && p.thread.asBinder() == app) { 11852 return p; 11853 } 11854 } 11855 } 11856 11857 Slog.w(TAG, "Can't find mystery application for " + reason 11858 + " from pid=" + Binder.getCallingPid() 11859 + " uid=" + Binder.getCallingUid() + ": " + app); 11860 return null; 11861 } 11862 } 11863 11864 /** 11865 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11866 * to append various headers to the dropbox log text. 11867 */ 11868 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11869 StringBuilder sb) { 11870 // Watchdog thread ends up invoking this function (with 11871 // a null ProcessRecord) to add the stack file to dropbox. 11872 // Do not acquire a lock on this (am) in such cases, as it 11873 // could cause a potential deadlock, if and when watchdog 11874 // is invoked due to unavailability of lock on am and it 11875 // would prevent watchdog from killing system_server. 11876 if (process == null) { 11877 sb.append("Process: ").append(processName).append("\n"); 11878 return; 11879 } 11880 // Note: ProcessRecord 'process' is guarded by the service 11881 // instance. (notably process.pkgList, which could otherwise change 11882 // concurrently during execution of this method) 11883 synchronized (this) { 11884 sb.append("Process: ").append(processName).append("\n"); 11885 int flags = process.info.flags; 11886 IPackageManager pm = AppGlobals.getPackageManager(); 11887 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11888 for (int ip=0; ip<process.pkgList.size(); ip++) { 11889 String pkg = process.pkgList.keyAt(ip); 11890 sb.append("Package: ").append(pkg); 11891 try { 11892 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11893 if (pi != null) { 11894 sb.append(" v").append(pi.versionCode); 11895 if (pi.versionName != null) { 11896 sb.append(" (").append(pi.versionName).append(")"); 11897 } 11898 } 11899 } catch (RemoteException e) { 11900 Slog.e(TAG, "Error getting package info: " + pkg, e); 11901 } 11902 sb.append("\n"); 11903 } 11904 } 11905 } 11906 11907 private static String processClass(ProcessRecord process) { 11908 if (process == null || process.pid == MY_PID) { 11909 return "system_server"; 11910 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11911 return "system_app"; 11912 } else { 11913 return "data_app"; 11914 } 11915 } 11916 11917 /** 11918 * Write a description of an error (crash, WTF, ANR) to the drop box. 11919 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11920 * @param process which caused the error, null means the system server 11921 * @param activity which triggered the error, null if unknown 11922 * @param parent activity related to the error, null if unknown 11923 * @param subject line related to the error, null if absent 11924 * @param report in long form describing the error, null if absent 11925 * @param logFile to include in the report, null if none 11926 * @param crashInfo giving an application stack trace, null if absent 11927 */ 11928 public void addErrorToDropBox(String eventType, 11929 ProcessRecord process, String processName, ActivityRecord activity, 11930 ActivityRecord parent, String subject, 11931 final String report, final File logFile, 11932 final ApplicationErrorReport.CrashInfo crashInfo) { 11933 // NOTE -- this must never acquire the ActivityManagerService lock, 11934 // otherwise the watchdog may be prevented from resetting the system. 11935 11936 final String dropboxTag = processClass(process) + "_" + eventType; 11937 final DropBoxManager dbox = (DropBoxManager) 11938 mContext.getSystemService(Context.DROPBOX_SERVICE); 11939 11940 // Exit early if the dropbox isn't configured to accept this report type. 11941 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11942 11943 final StringBuilder sb = new StringBuilder(1024); 11944 appendDropBoxProcessHeaders(process, processName, sb); 11945 if (activity != null) { 11946 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11947 } 11948 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11949 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11950 } 11951 if (parent != null && parent != activity) { 11952 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11953 } 11954 if (subject != null) { 11955 sb.append("Subject: ").append(subject).append("\n"); 11956 } 11957 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11958 if (Debug.isDebuggerConnected()) { 11959 sb.append("Debugger: Connected\n"); 11960 } 11961 sb.append("\n"); 11962 11963 // Do the rest in a worker thread to avoid blocking the caller on I/O 11964 // (After this point, we shouldn't access AMS internal data structures.) 11965 Thread worker = new Thread("Error dump: " + dropboxTag) { 11966 @Override 11967 public void run() { 11968 if (report != null) { 11969 sb.append(report); 11970 } 11971 if (logFile != null) { 11972 try { 11973 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11974 "\n\n[[TRUNCATED]]")); 11975 } catch (IOException e) { 11976 Slog.e(TAG, "Error reading " + logFile, e); 11977 } 11978 } 11979 if (crashInfo != null && crashInfo.stackTrace != null) { 11980 sb.append(crashInfo.stackTrace); 11981 } 11982 11983 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11984 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11985 if (lines > 0) { 11986 sb.append("\n"); 11987 11988 // Merge several logcat streams, and take the last N lines 11989 InputStreamReader input = null; 11990 try { 11991 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11992 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11993 "-b", "crash", 11994 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11995 11996 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11997 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11998 input = new InputStreamReader(logcat.getInputStream()); 11999 12000 int num; 12001 char[] buf = new char[8192]; 12002 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12003 } catch (IOException e) { 12004 Slog.e(TAG, "Error running logcat", e); 12005 } finally { 12006 if (input != null) try { input.close(); } catch (IOException e) {} 12007 } 12008 } 12009 12010 dbox.addText(dropboxTag, sb.toString()); 12011 } 12012 }; 12013 12014 if (process == null) { 12015 // If process is null, we are being called from some internal code 12016 // and may be about to die -- run this synchronously. 12017 worker.run(); 12018 } else { 12019 worker.start(); 12020 } 12021 } 12022 12023 /** 12024 * Bring up the "unexpected error" dialog box for a crashing app. 12025 * Deal with edge cases (intercepts from instrumented applications, 12026 * ActivityController, error intent receivers, that sort of thing). 12027 * @param r the application crashing 12028 * @param crashInfo describing the failure 12029 */ 12030 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12031 long timeMillis = System.currentTimeMillis(); 12032 String shortMsg = crashInfo.exceptionClassName; 12033 String longMsg = crashInfo.exceptionMessage; 12034 String stackTrace = crashInfo.stackTrace; 12035 if (shortMsg != null && longMsg != null) { 12036 longMsg = shortMsg + ": " + longMsg; 12037 } else if (shortMsg != null) { 12038 longMsg = shortMsg; 12039 } 12040 12041 AppErrorResult result = new AppErrorResult(); 12042 synchronized (this) { 12043 if (mController != null) { 12044 try { 12045 String name = r != null ? r.processName : null; 12046 int pid = r != null ? r.pid : Binder.getCallingPid(); 12047 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12048 if (!mController.appCrashed(name, pid, 12049 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12050 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12051 && "Native crash".equals(crashInfo.exceptionClassName)) { 12052 Slog.w(TAG, "Skip killing native crashed app " + name 12053 + "(" + pid + ") during testing"); 12054 } else { 12055 Slog.w(TAG, "Force-killing crashed app " + name 12056 + " at watcher's request"); 12057 if (r != null) { 12058 r.kill("crash", true); 12059 } else { 12060 // Huh. 12061 Process.killProcess(pid); 12062 Process.killProcessGroup(uid, pid); 12063 } 12064 } 12065 return; 12066 } 12067 } catch (RemoteException e) { 12068 mController = null; 12069 Watchdog.getInstance().setActivityController(null); 12070 } 12071 } 12072 12073 final long origId = Binder.clearCallingIdentity(); 12074 12075 // If this process is running instrumentation, finish it. 12076 if (r != null && r.instrumentationClass != null) { 12077 Slog.w(TAG, "Error in app " + r.processName 12078 + " running instrumentation " + r.instrumentationClass + ":"); 12079 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12080 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12081 Bundle info = new Bundle(); 12082 info.putString("shortMsg", shortMsg); 12083 info.putString("longMsg", longMsg); 12084 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12085 Binder.restoreCallingIdentity(origId); 12086 return; 12087 } 12088 12089 // If we can't identify the process or it's already exceeded its crash quota, 12090 // quit right away without showing a crash dialog. 12091 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12092 Binder.restoreCallingIdentity(origId); 12093 return; 12094 } 12095 12096 Message msg = Message.obtain(); 12097 msg.what = SHOW_ERROR_MSG; 12098 HashMap data = new HashMap(); 12099 data.put("result", result); 12100 data.put("app", r); 12101 msg.obj = data; 12102 mHandler.sendMessage(msg); 12103 12104 Binder.restoreCallingIdentity(origId); 12105 } 12106 12107 int res = result.get(); 12108 12109 Intent appErrorIntent = null; 12110 synchronized (this) { 12111 if (r != null && !r.isolated) { 12112 // XXX Can't keep track of crash time for isolated processes, 12113 // since they don't have a persistent identity. 12114 mProcessCrashTimes.put(r.info.processName, r.uid, 12115 SystemClock.uptimeMillis()); 12116 } 12117 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12118 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12119 } 12120 } 12121 12122 if (appErrorIntent != null) { 12123 try { 12124 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12125 } catch (ActivityNotFoundException e) { 12126 Slog.w(TAG, "bug report receiver dissappeared", e); 12127 } 12128 } 12129 } 12130 12131 Intent createAppErrorIntentLocked(ProcessRecord r, 12132 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12133 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12134 if (report == null) { 12135 return null; 12136 } 12137 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12138 result.setComponent(r.errorReportReceiver); 12139 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12140 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12141 return result; 12142 } 12143 12144 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12145 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12146 if (r.errorReportReceiver == null) { 12147 return null; 12148 } 12149 12150 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12151 return null; 12152 } 12153 12154 ApplicationErrorReport report = new ApplicationErrorReport(); 12155 report.packageName = r.info.packageName; 12156 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12157 report.processName = r.processName; 12158 report.time = timeMillis; 12159 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12160 12161 if (r.crashing || r.forceCrashReport) { 12162 report.type = ApplicationErrorReport.TYPE_CRASH; 12163 report.crashInfo = crashInfo; 12164 } else if (r.notResponding) { 12165 report.type = ApplicationErrorReport.TYPE_ANR; 12166 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12167 12168 report.anrInfo.activity = r.notRespondingReport.tag; 12169 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12170 report.anrInfo.info = r.notRespondingReport.longMsg; 12171 } 12172 12173 return report; 12174 } 12175 12176 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12177 enforceNotIsolatedCaller("getProcessesInErrorState"); 12178 // assume our apps are happy - lazy create the list 12179 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12180 12181 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12182 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12183 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12184 12185 synchronized (this) { 12186 12187 // iterate across all processes 12188 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12189 ProcessRecord app = mLruProcesses.get(i); 12190 if (!allUsers && app.userId != userId) { 12191 continue; 12192 } 12193 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12194 // This one's in trouble, so we'll generate a report for it 12195 // crashes are higher priority (in case there's a crash *and* an anr) 12196 ActivityManager.ProcessErrorStateInfo report = null; 12197 if (app.crashing) { 12198 report = app.crashingReport; 12199 } else if (app.notResponding) { 12200 report = app.notRespondingReport; 12201 } 12202 12203 if (report != null) { 12204 if (errList == null) { 12205 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12206 } 12207 errList.add(report); 12208 } else { 12209 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12210 " crashing = " + app.crashing + 12211 " notResponding = " + app.notResponding); 12212 } 12213 } 12214 } 12215 } 12216 12217 return errList; 12218 } 12219 12220 static int procStateToImportance(int procState, int memAdj, 12221 ActivityManager.RunningAppProcessInfo currApp) { 12222 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12223 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12224 currApp.lru = memAdj; 12225 } else { 12226 currApp.lru = 0; 12227 } 12228 return imp; 12229 } 12230 12231 private void fillInProcMemInfo(ProcessRecord app, 12232 ActivityManager.RunningAppProcessInfo outInfo) { 12233 outInfo.pid = app.pid; 12234 outInfo.uid = app.info.uid; 12235 if (mHeavyWeightProcess == app) { 12236 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12237 } 12238 if (app.persistent) { 12239 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12240 } 12241 if (app.activities.size() > 0) { 12242 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12243 } 12244 outInfo.lastTrimLevel = app.trimMemoryLevel; 12245 int adj = app.curAdj; 12246 int procState = app.curProcState; 12247 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12248 outInfo.importanceReasonCode = app.adjTypeCode; 12249 outInfo.processState = app.curProcState; 12250 } 12251 12252 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12253 enforceNotIsolatedCaller("getRunningAppProcesses"); 12254 // Lazy instantiation of list 12255 List<ActivityManager.RunningAppProcessInfo> runList = null; 12256 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12257 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12258 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12259 synchronized (this) { 12260 // Iterate across all processes 12261 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12262 ProcessRecord app = mLruProcesses.get(i); 12263 if (!allUsers && app.userId != userId) { 12264 continue; 12265 } 12266 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12267 // Generate process state info for running application 12268 ActivityManager.RunningAppProcessInfo currApp = 12269 new ActivityManager.RunningAppProcessInfo(app.processName, 12270 app.pid, app.getPackageList()); 12271 fillInProcMemInfo(app, currApp); 12272 if (app.adjSource instanceof ProcessRecord) { 12273 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12274 currApp.importanceReasonImportance = 12275 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12276 app.adjSourceProcState); 12277 } else if (app.adjSource instanceof ActivityRecord) { 12278 ActivityRecord r = (ActivityRecord)app.adjSource; 12279 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12280 } 12281 if (app.adjTarget instanceof ComponentName) { 12282 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12283 } 12284 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12285 // + " lru=" + currApp.lru); 12286 if (runList == null) { 12287 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12288 } 12289 runList.add(currApp); 12290 } 12291 } 12292 } 12293 return runList; 12294 } 12295 12296 public List<ApplicationInfo> getRunningExternalApplications() { 12297 enforceNotIsolatedCaller("getRunningExternalApplications"); 12298 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12299 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12300 if (runningApps != null && runningApps.size() > 0) { 12301 Set<String> extList = new HashSet<String>(); 12302 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12303 if (app.pkgList != null) { 12304 for (String pkg : app.pkgList) { 12305 extList.add(pkg); 12306 } 12307 } 12308 } 12309 IPackageManager pm = AppGlobals.getPackageManager(); 12310 for (String pkg : extList) { 12311 try { 12312 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12313 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12314 retList.add(info); 12315 } 12316 } catch (RemoteException e) { 12317 } 12318 } 12319 } 12320 return retList; 12321 } 12322 12323 @Override 12324 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12325 enforceNotIsolatedCaller("getMyMemoryState"); 12326 synchronized (this) { 12327 ProcessRecord proc; 12328 synchronized (mPidsSelfLocked) { 12329 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12330 } 12331 fillInProcMemInfo(proc, outInfo); 12332 } 12333 } 12334 12335 @Override 12336 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12337 if (checkCallingPermission(android.Manifest.permission.DUMP) 12338 != PackageManager.PERMISSION_GRANTED) { 12339 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12340 + Binder.getCallingPid() 12341 + ", uid=" + Binder.getCallingUid() 12342 + " without permission " 12343 + android.Manifest.permission.DUMP); 12344 return; 12345 } 12346 12347 boolean dumpAll = false; 12348 boolean dumpClient = false; 12349 String dumpPackage = null; 12350 12351 int opti = 0; 12352 while (opti < args.length) { 12353 String opt = args[opti]; 12354 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12355 break; 12356 } 12357 opti++; 12358 if ("-a".equals(opt)) { 12359 dumpAll = true; 12360 } else if ("-c".equals(opt)) { 12361 dumpClient = true; 12362 } else if ("-h".equals(opt)) { 12363 pw.println("Activity manager dump options:"); 12364 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12365 pw.println(" cmd may be one of:"); 12366 pw.println(" a[ctivities]: activity stack state"); 12367 pw.println(" r[recents]: recent activities state"); 12368 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12369 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12370 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12371 pw.println(" o[om]: out of memory management"); 12372 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12373 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12374 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12375 pw.println(" service [COMP_SPEC]: service client-side state"); 12376 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12377 pw.println(" all: dump all activities"); 12378 pw.println(" top: dump the top activity"); 12379 pw.println(" write: write all pending state to storage"); 12380 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12381 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12382 pw.println(" a partial substring in a component name, a"); 12383 pw.println(" hex object identifier."); 12384 pw.println(" -a: include all available server state."); 12385 pw.println(" -c: include client state."); 12386 return; 12387 } else { 12388 pw.println("Unknown argument: " + opt + "; use -h for help"); 12389 } 12390 } 12391 12392 long origId = Binder.clearCallingIdentity(); 12393 boolean more = false; 12394 // Is the caller requesting to dump a particular piece of data? 12395 if (opti < args.length) { 12396 String cmd = args[opti]; 12397 opti++; 12398 if ("activities".equals(cmd) || "a".equals(cmd)) { 12399 synchronized (this) { 12400 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12401 } 12402 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12403 synchronized (this) { 12404 dumpRecentsLocked(fd, pw, args, opti, true, null); 12405 } 12406 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12407 String[] newArgs; 12408 String name; 12409 if (opti >= args.length) { 12410 name = null; 12411 newArgs = EMPTY_STRING_ARRAY; 12412 } else { 12413 name = args[opti]; 12414 opti++; 12415 newArgs = new String[args.length - opti]; 12416 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12417 args.length - opti); 12418 } 12419 synchronized (this) { 12420 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12421 } 12422 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12423 String[] newArgs; 12424 String name; 12425 if (opti >= args.length) { 12426 name = null; 12427 newArgs = EMPTY_STRING_ARRAY; 12428 } else { 12429 name = args[opti]; 12430 opti++; 12431 newArgs = new String[args.length - opti]; 12432 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12433 args.length - opti); 12434 } 12435 synchronized (this) { 12436 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12437 } 12438 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12439 String[] newArgs; 12440 String name; 12441 if (opti >= args.length) { 12442 name = null; 12443 newArgs = EMPTY_STRING_ARRAY; 12444 } else { 12445 name = args[opti]; 12446 opti++; 12447 newArgs = new String[args.length - opti]; 12448 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12449 args.length - opti); 12450 } 12451 synchronized (this) { 12452 dumpProcessesLocked(fd, pw, args, opti, true, name); 12453 } 12454 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12455 synchronized (this) { 12456 dumpOomLocked(fd, pw, args, opti, true); 12457 } 12458 } else if ("provider".equals(cmd)) { 12459 String[] newArgs; 12460 String name; 12461 if (opti >= args.length) { 12462 name = null; 12463 newArgs = EMPTY_STRING_ARRAY; 12464 } else { 12465 name = args[opti]; 12466 opti++; 12467 newArgs = new String[args.length - opti]; 12468 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12469 } 12470 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12471 pw.println("No providers match: " + name); 12472 pw.println("Use -h for help."); 12473 } 12474 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12475 synchronized (this) { 12476 dumpProvidersLocked(fd, pw, args, opti, true, null); 12477 } 12478 } else if ("service".equals(cmd)) { 12479 String[] newArgs; 12480 String name; 12481 if (opti >= args.length) { 12482 name = null; 12483 newArgs = EMPTY_STRING_ARRAY; 12484 } else { 12485 name = args[opti]; 12486 opti++; 12487 newArgs = new String[args.length - opti]; 12488 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12489 args.length - opti); 12490 } 12491 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12492 pw.println("No services match: " + name); 12493 pw.println("Use -h for help."); 12494 } 12495 } else if ("package".equals(cmd)) { 12496 String[] newArgs; 12497 if (opti >= args.length) { 12498 pw.println("package: no package name specified"); 12499 pw.println("Use -h for help."); 12500 } else { 12501 dumpPackage = args[opti]; 12502 opti++; 12503 newArgs = new String[args.length - opti]; 12504 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12505 args.length - opti); 12506 args = newArgs; 12507 opti = 0; 12508 more = true; 12509 } 12510 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12511 synchronized (this) { 12512 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12513 } 12514 } else if ("write".equals(cmd)) { 12515 mTaskPersister.flush(); 12516 pw.println("All tasks persisted."); 12517 return; 12518 } else { 12519 // Dumping a single activity? 12520 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12521 pw.println("Bad activity command, or no activities match: " + cmd); 12522 pw.println("Use -h for help."); 12523 } 12524 } 12525 if (!more) { 12526 Binder.restoreCallingIdentity(origId); 12527 return; 12528 } 12529 } 12530 12531 // No piece of data specified, dump everything. 12532 synchronized (this) { 12533 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12534 pw.println(); 12535 if (dumpAll) { 12536 pw.println("-------------------------------------------------------------------------------"); 12537 } 12538 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12539 pw.println(); 12540 if (dumpAll) { 12541 pw.println("-------------------------------------------------------------------------------"); 12542 } 12543 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12544 pw.println(); 12545 if (dumpAll) { 12546 pw.println("-------------------------------------------------------------------------------"); 12547 } 12548 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12549 pw.println(); 12550 if (dumpAll) { 12551 pw.println("-------------------------------------------------------------------------------"); 12552 } 12553 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12554 pw.println(); 12555 if (dumpAll) { 12556 pw.println("-------------------------------------------------------------------------------"); 12557 } 12558 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12559 pw.println(); 12560 if (dumpAll) { 12561 pw.println("-------------------------------------------------------------------------------"); 12562 } 12563 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12564 } 12565 Binder.restoreCallingIdentity(origId); 12566 } 12567 12568 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12569 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12570 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12571 12572 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12573 dumpPackage); 12574 boolean needSep = printedAnything; 12575 12576 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12577 dumpPackage, needSep, " mFocusedActivity: "); 12578 if (printed) { 12579 printedAnything = true; 12580 needSep = false; 12581 } 12582 12583 if (dumpPackage == null) { 12584 if (needSep) { 12585 pw.println(); 12586 } 12587 needSep = true; 12588 printedAnything = true; 12589 mStackSupervisor.dump(pw, " "); 12590 } 12591 12592 if (!printedAnything) { 12593 pw.println(" (nothing)"); 12594 } 12595 } 12596 12597 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12598 int opti, boolean dumpAll, String dumpPackage) { 12599 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12600 12601 boolean printedAnything = false; 12602 12603 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12604 boolean printedHeader = false; 12605 12606 final int N = mRecentTasks.size(); 12607 for (int i=0; i<N; i++) { 12608 TaskRecord tr = mRecentTasks.get(i); 12609 if (dumpPackage != null) { 12610 if (tr.realActivity == null || 12611 !dumpPackage.equals(tr.realActivity)) { 12612 continue; 12613 } 12614 } 12615 if (!printedHeader) { 12616 pw.println(" Recent tasks:"); 12617 printedHeader = true; 12618 printedAnything = true; 12619 } 12620 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12621 pw.println(tr); 12622 if (dumpAll) { 12623 mRecentTasks.get(i).dump(pw, " "); 12624 } 12625 } 12626 } 12627 12628 if (!printedAnything) { 12629 pw.println(" (nothing)"); 12630 } 12631 } 12632 12633 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12634 int opti, boolean dumpAll, String dumpPackage) { 12635 boolean needSep = false; 12636 boolean printedAnything = false; 12637 int numPers = 0; 12638 12639 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12640 12641 if (dumpAll) { 12642 final int NP = mProcessNames.getMap().size(); 12643 for (int ip=0; ip<NP; ip++) { 12644 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12645 final int NA = procs.size(); 12646 for (int ia=0; ia<NA; ia++) { 12647 ProcessRecord r = procs.valueAt(ia); 12648 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12649 continue; 12650 } 12651 if (!needSep) { 12652 pw.println(" All known processes:"); 12653 needSep = true; 12654 printedAnything = true; 12655 } 12656 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12657 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12658 pw.print(" "); pw.println(r); 12659 r.dump(pw, " "); 12660 if (r.persistent) { 12661 numPers++; 12662 } 12663 } 12664 } 12665 } 12666 12667 if (mIsolatedProcesses.size() > 0) { 12668 boolean printed = false; 12669 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12670 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12671 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12672 continue; 12673 } 12674 if (!printed) { 12675 if (needSep) { 12676 pw.println(); 12677 } 12678 pw.println(" Isolated process list (sorted by uid):"); 12679 printedAnything = true; 12680 printed = true; 12681 needSep = true; 12682 } 12683 pw.println(String.format("%sIsolated #%2d: %s", 12684 " ", i, r.toString())); 12685 } 12686 } 12687 12688 if (mLruProcesses.size() > 0) { 12689 if (needSep) { 12690 pw.println(); 12691 } 12692 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12693 pw.print(" total, non-act at "); 12694 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12695 pw.print(", non-svc at "); 12696 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12697 pw.println("):"); 12698 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12699 needSep = true; 12700 printedAnything = true; 12701 } 12702 12703 if (dumpAll || dumpPackage != null) { 12704 synchronized (mPidsSelfLocked) { 12705 boolean printed = false; 12706 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12707 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12708 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12709 continue; 12710 } 12711 if (!printed) { 12712 if (needSep) pw.println(); 12713 needSep = true; 12714 pw.println(" PID mappings:"); 12715 printed = true; 12716 printedAnything = true; 12717 } 12718 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12719 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12720 } 12721 } 12722 } 12723 12724 if (mForegroundProcesses.size() > 0) { 12725 synchronized (mPidsSelfLocked) { 12726 boolean printed = false; 12727 for (int i=0; i<mForegroundProcesses.size(); i++) { 12728 ProcessRecord r = mPidsSelfLocked.get( 12729 mForegroundProcesses.valueAt(i).pid); 12730 if (dumpPackage != null && (r == null 12731 || !r.pkgList.containsKey(dumpPackage))) { 12732 continue; 12733 } 12734 if (!printed) { 12735 if (needSep) pw.println(); 12736 needSep = true; 12737 pw.println(" Foreground Processes:"); 12738 printed = true; 12739 printedAnything = true; 12740 } 12741 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12742 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12743 } 12744 } 12745 } 12746 12747 if (mPersistentStartingProcesses.size() > 0) { 12748 if (needSep) pw.println(); 12749 needSep = true; 12750 printedAnything = true; 12751 pw.println(" Persisent processes that are starting:"); 12752 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12753 "Starting Norm", "Restarting PERS", dumpPackage); 12754 } 12755 12756 if (mRemovedProcesses.size() > 0) { 12757 if (needSep) pw.println(); 12758 needSep = true; 12759 printedAnything = true; 12760 pw.println(" Processes that are being removed:"); 12761 dumpProcessList(pw, this, mRemovedProcesses, " ", 12762 "Removed Norm", "Removed PERS", dumpPackage); 12763 } 12764 12765 if (mProcessesOnHold.size() > 0) { 12766 if (needSep) pw.println(); 12767 needSep = true; 12768 printedAnything = true; 12769 pw.println(" Processes that are on old until the system is ready:"); 12770 dumpProcessList(pw, this, mProcessesOnHold, " ", 12771 "OnHold Norm", "OnHold PERS", dumpPackage); 12772 } 12773 12774 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12775 12776 if (mProcessCrashTimes.getMap().size() > 0) { 12777 boolean printed = false; 12778 long now = SystemClock.uptimeMillis(); 12779 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12780 final int NP = pmap.size(); 12781 for (int ip=0; ip<NP; ip++) { 12782 String pname = pmap.keyAt(ip); 12783 SparseArray<Long> uids = pmap.valueAt(ip); 12784 final int N = uids.size(); 12785 for (int i=0; i<N; i++) { 12786 int puid = uids.keyAt(i); 12787 ProcessRecord r = mProcessNames.get(pname, puid); 12788 if (dumpPackage != null && (r == null 12789 || !r.pkgList.containsKey(dumpPackage))) { 12790 continue; 12791 } 12792 if (!printed) { 12793 if (needSep) pw.println(); 12794 needSep = true; 12795 pw.println(" Time since processes crashed:"); 12796 printed = true; 12797 printedAnything = true; 12798 } 12799 pw.print(" Process "); pw.print(pname); 12800 pw.print(" uid "); pw.print(puid); 12801 pw.print(": last crashed "); 12802 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12803 pw.println(" ago"); 12804 } 12805 } 12806 } 12807 12808 if (mBadProcesses.getMap().size() > 0) { 12809 boolean printed = false; 12810 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12811 final int NP = pmap.size(); 12812 for (int ip=0; ip<NP; ip++) { 12813 String pname = pmap.keyAt(ip); 12814 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12815 final int N = uids.size(); 12816 for (int i=0; i<N; i++) { 12817 int puid = uids.keyAt(i); 12818 ProcessRecord r = mProcessNames.get(pname, puid); 12819 if (dumpPackage != null && (r == null 12820 || !r.pkgList.containsKey(dumpPackage))) { 12821 continue; 12822 } 12823 if (!printed) { 12824 if (needSep) pw.println(); 12825 needSep = true; 12826 pw.println(" Bad processes:"); 12827 printedAnything = true; 12828 } 12829 BadProcessInfo info = uids.valueAt(i); 12830 pw.print(" Bad process "); pw.print(pname); 12831 pw.print(" uid "); pw.print(puid); 12832 pw.print(": crashed at time "); pw.println(info.time); 12833 if (info.shortMsg != null) { 12834 pw.print(" Short msg: "); pw.println(info.shortMsg); 12835 } 12836 if (info.longMsg != null) { 12837 pw.print(" Long msg: "); pw.println(info.longMsg); 12838 } 12839 if (info.stack != null) { 12840 pw.println(" Stack:"); 12841 int lastPos = 0; 12842 for (int pos=0; pos<info.stack.length(); pos++) { 12843 if (info.stack.charAt(pos) == '\n') { 12844 pw.print(" "); 12845 pw.write(info.stack, lastPos, pos-lastPos); 12846 pw.println(); 12847 lastPos = pos+1; 12848 } 12849 } 12850 if (lastPos < info.stack.length()) { 12851 pw.print(" "); 12852 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12853 pw.println(); 12854 } 12855 } 12856 } 12857 } 12858 } 12859 12860 if (dumpPackage == null) { 12861 pw.println(); 12862 needSep = false; 12863 pw.println(" mStartedUsers:"); 12864 for (int i=0; i<mStartedUsers.size(); i++) { 12865 UserStartedState uss = mStartedUsers.valueAt(i); 12866 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12867 pw.print(": "); uss.dump("", pw); 12868 } 12869 pw.print(" mStartedUserArray: ["); 12870 for (int i=0; i<mStartedUserArray.length; i++) { 12871 if (i > 0) pw.print(", "); 12872 pw.print(mStartedUserArray[i]); 12873 } 12874 pw.println("]"); 12875 pw.print(" mUserLru: ["); 12876 for (int i=0; i<mUserLru.size(); i++) { 12877 if (i > 0) pw.print(", "); 12878 pw.print(mUserLru.get(i)); 12879 } 12880 pw.println("]"); 12881 if (dumpAll) { 12882 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12883 } 12884 synchronized (mUserProfileGroupIdsSelfLocked) { 12885 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12886 pw.println(" mUserProfileGroupIds:"); 12887 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12888 pw.print(" User #"); 12889 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12890 pw.print(" -> profile #"); 12891 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12892 } 12893 } 12894 } 12895 } 12896 if (mHomeProcess != null && (dumpPackage == null 12897 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12898 if (needSep) { 12899 pw.println(); 12900 needSep = false; 12901 } 12902 pw.println(" mHomeProcess: " + mHomeProcess); 12903 } 12904 if (mPreviousProcess != null && (dumpPackage == null 12905 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12906 if (needSep) { 12907 pw.println(); 12908 needSep = false; 12909 } 12910 pw.println(" mPreviousProcess: " + mPreviousProcess); 12911 } 12912 if (dumpAll) { 12913 StringBuilder sb = new StringBuilder(128); 12914 sb.append(" mPreviousProcessVisibleTime: "); 12915 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12916 pw.println(sb); 12917 } 12918 if (mHeavyWeightProcess != null && (dumpPackage == null 12919 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12920 if (needSep) { 12921 pw.println(); 12922 needSep = false; 12923 } 12924 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12925 } 12926 if (dumpPackage == null) { 12927 pw.println(" mConfiguration: " + mConfiguration); 12928 } 12929 if (dumpAll) { 12930 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12931 if (mCompatModePackages.getPackages().size() > 0) { 12932 boolean printed = false; 12933 for (Map.Entry<String, Integer> entry 12934 : mCompatModePackages.getPackages().entrySet()) { 12935 String pkg = entry.getKey(); 12936 int mode = entry.getValue(); 12937 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12938 continue; 12939 } 12940 if (!printed) { 12941 pw.println(" mScreenCompatPackages:"); 12942 printed = true; 12943 } 12944 pw.print(" "); pw.print(pkg); pw.print(": "); 12945 pw.print(mode); pw.println(); 12946 } 12947 } 12948 } 12949 if (dumpPackage == null) { 12950 if (mSleeping || mWentToSleep || mLockScreenShown) { 12951 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12952 + " mLockScreenShown " + mLockScreenShown); 12953 } 12954 if (mShuttingDown || mRunningVoice) { 12955 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12956 } 12957 } 12958 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12959 || mOrigWaitForDebugger) { 12960 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12961 || dumpPackage.equals(mOrigDebugApp)) { 12962 if (needSep) { 12963 pw.println(); 12964 needSep = false; 12965 } 12966 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12967 + " mDebugTransient=" + mDebugTransient 12968 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12969 } 12970 } 12971 if (mOpenGlTraceApp != null) { 12972 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12973 if (needSep) { 12974 pw.println(); 12975 needSep = false; 12976 } 12977 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12978 } 12979 } 12980 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12981 || mProfileFd != null) { 12982 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12983 if (needSep) { 12984 pw.println(); 12985 needSep = false; 12986 } 12987 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12988 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12989 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12990 + mAutoStopProfiler); 12991 pw.println(" mProfileType=" + mProfileType); 12992 } 12993 } 12994 if (dumpPackage == null) { 12995 if (mAlwaysFinishActivities || mController != null) { 12996 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12997 + " mController=" + mController); 12998 } 12999 if (dumpAll) { 13000 pw.println(" Total persistent processes: " + numPers); 13001 pw.println(" mProcessesReady=" + mProcessesReady 13002 + " mSystemReady=" + mSystemReady 13003 + " mBooted=" + mBooted 13004 + " mFactoryTest=" + mFactoryTest); 13005 pw.println(" mBooting=" + mBooting 13006 + " mCallFinishBooting=" + mCallFinishBooting 13007 + " mBootAnimationComplete=" + mBootAnimationComplete); 13008 pw.print(" mLastPowerCheckRealtime="); 13009 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13010 pw.println(""); 13011 pw.print(" mLastPowerCheckUptime="); 13012 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13013 pw.println(""); 13014 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13015 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13016 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13017 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13018 + " (" + mLruProcesses.size() + " total)" 13019 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13020 + " mNumServiceProcs=" + mNumServiceProcs 13021 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13022 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13023 + " mLastMemoryLevel" + mLastMemoryLevel 13024 + " mLastNumProcesses" + mLastNumProcesses); 13025 long now = SystemClock.uptimeMillis(); 13026 pw.print(" mLastIdleTime="); 13027 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13028 pw.print(" mLowRamSinceLastIdle="); 13029 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13030 pw.println(); 13031 } 13032 } 13033 13034 if (!printedAnything) { 13035 pw.println(" (nothing)"); 13036 } 13037 } 13038 13039 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13040 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13041 if (mProcessesToGc.size() > 0) { 13042 boolean printed = false; 13043 long now = SystemClock.uptimeMillis(); 13044 for (int i=0; i<mProcessesToGc.size(); i++) { 13045 ProcessRecord proc = mProcessesToGc.get(i); 13046 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13047 continue; 13048 } 13049 if (!printed) { 13050 if (needSep) pw.println(); 13051 needSep = true; 13052 pw.println(" Processes that are waiting to GC:"); 13053 printed = true; 13054 } 13055 pw.print(" Process "); pw.println(proc); 13056 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13057 pw.print(", last gced="); 13058 pw.print(now-proc.lastRequestedGc); 13059 pw.print(" ms ago, last lowMem="); 13060 pw.print(now-proc.lastLowMemory); 13061 pw.println(" ms ago"); 13062 13063 } 13064 } 13065 return needSep; 13066 } 13067 13068 void printOomLevel(PrintWriter pw, String name, int adj) { 13069 pw.print(" "); 13070 if (adj >= 0) { 13071 pw.print(' '); 13072 if (adj < 10) pw.print(' '); 13073 } else { 13074 if (adj > -10) pw.print(' '); 13075 } 13076 pw.print(adj); 13077 pw.print(": "); 13078 pw.print(name); 13079 pw.print(" ("); 13080 pw.print(mProcessList.getMemLevel(adj)/1024); 13081 pw.println(" kB)"); 13082 } 13083 13084 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13085 int opti, boolean dumpAll) { 13086 boolean needSep = false; 13087 13088 if (mLruProcesses.size() > 0) { 13089 if (needSep) pw.println(); 13090 needSep = true; 13091 pw.println(" OOM levels:"); 13092 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13093 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13094 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13095 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13096 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13097 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13098 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13099 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13100 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13101 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13102 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13103 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13104 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13105 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13106 13107 if (needSep) pw.println(); 13108 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13109 pw.print(" total, non-act at "); 13110 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13111 pw.print(", non-svc at "); 13112 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13113 pw.println("):"); 13114 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13115 needSep = true; 13116 } 13117 13118 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13119 13120 pw.println(); 13121 pw.println(" mHomeProcess: " + mHomeProcess); 13122 pw.println(" mPreviousProcess: " + mPreviousProcess); 13123 if (mHeavyWeightProcess != null) { 13124 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13125 } 13126 13127 return true; 13128 } 13129 13130 /** 13131 * There are three ways to call this: 13132 * - no provider specified: dump all the providers 13133 * - a flattened component name that matched an existing provider was specified as the 13134 * first arg: dump that one provider 13135 * - the first arg isn't the flattened component name of an existing provider: 13136 * dump all providers whose component contains the first arg as a substring 13137 */ 13138 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13139 int opti, boolean dumpAll) { 13140 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13141 } 13142 13143 static class ItemMatcher { 13144 ArrayList<ComponentName> components; 13145 ArrayList<String> strings; 13146 ArrayList<Integer> objects; 13147 boolean all; 13148 13149 ItemMatcher() { 13150 all = true; 13151 } 13152 13153 void build(String name) { 13154 ComponentName componentName = ComponentName.unflattenFromString(name); 13155 if (componentName != null) { 13156 if (components == null) { 13157 components = new ArrayList<ComponentName>(); 13158 } 13159 components.add(componentName); 13160 all = false; 13161 } else { 13162 int objectId = 0; 13163 // Not a '/' separated full component name; maybe an object ID? 13164 try { 13165 objectId = Integer.parseInt(name, 16); 13166 if (objects == null) { 13167 objects = new ArrayList<Integer>(); 13168 } 13169 objects.add(objectId); 13170 all = false; 13171 } catch (RuntimeException e) { 13172 // Not an integer; just do string match. 13173 if (strings == null) { 13174 strings = new ArrayList<String>(); 13175 } 13176 strings.add(name); 13177 all = false; 13178 } 13179 } 13180 } 13181 13182 int build(String[] args, int opti) { 13183 for (; opti<args.length; opti++) { 13184 String name = args[opti]; 13185 if ("--".equals(name)) { 13186 return opti+1; 13187 } 13188 build(name); 13189 } 13190 return opti; 13191 } 13192 13193 boolean match(Object object, ComponentName comp) { 13194 if (all) { 13195 return true; 13196 } 13197 if (components != null) { 13198 for (int i=0; i<components.size(); i++) { 13199 if (components.get(i).equals(comp)) { 13200 return true; 13201 } 13202 } 13203 } 13204 if (objects != null) { 13205 for (int i=0; i<objects.size(); i++) { 13206 if (System.identityHashCode(object) == objects.get(i)) { 13207 return true; 13208 } 13209 } 13210 } 13211 if (strings != null) { 13212 String flat = comp.flattenToString(); 13213 for (int i=0; i<strings.size(); i++) { 13214 if (flat.contains(strings.get(i))) { 13215 return true; 13216 } 13217 } 13218 } 13219 return false; 13220 } 13221 } 13222 13223 /** 13224 * There are three things that cmd can be: 13225 * - a flattened component name that matches an existing activity 13226 * - the cmd arg isn't the flattened component name of an existing activity: 13227 * dump all activity whose component contains the cmd as a substring 13228 * - A hex number of the ActivityRecord object instance. 13229 */ 13230 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13231 int opti, boolean dumpAll) { 13232 ArrayList<ActivityRecord> activities; 13233 13234 synchronized (this) { 13235 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13236 } 13237 13238 if (activities.size() <= 0) { 13239 return false; 13240 } 13241 13242 String[] newArgs = new String[args.length - opti]; 13243 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13244 13245 TaskRecord lastTask = null; 13246 boolean needSep = false; 13247 for (int i=activities.size()-1; i>=0; i--) { 13248 ActivityRecord r = activities.get(i); 13249 if (needSep) { 13250 pw.println(); 13251 } 13252 needSep = true; 13253 synchronized (this) { 13254 if (lastTask != r.task) { 13255 lastTask = r.task; 13256 pw.print("TASK "); pw.print(lastTask.affinity); 13257 pw.print(" id="); pw.println(lastTask.taskId); 13258 if (dumpAll) { 13259 lastTask.dump(pw, " "); 13260 } 13261 } 13262 } 13263 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13264 } 13265 return true; 13266 } 13267 13268 /** 13269 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13270 * there is a thread associated with the activity. 13271 */ 13272 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13273 final ActivityRecord r, String[] args, boolean dumpAll) { 13274 String innerPrefix = prefix + " "; 13275 synchronized (this) { 13276 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13277 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13278 pw.print(" pid="); 13279 if (r.app != null) pw.println(r.app.pid); 13280 else pw.println("(not running)"); 13281 if (dumpAll) { 13282 r.dump(pw, innerPrefix); 13283 } 13284 } 13285 if (r.app != null && r.app.thread != null) { 13286 // flush anything that is already in the PrintWriter since the thread is going 13287 // to write to the file descriptor directly 13288 pw.flush(); 13289 try { 13290 TransferPipe tp = new TransferPipe(); 13291 try { 13292 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13293 r.appToken, innerPrefix, args); 13294 tp.go(fd); 13295 } finally { 13296 tp.kill(); 13297 } 13298 } catch (IOException e) { 13299 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13300 } catch (RemoteException e) { 13301 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13302 } 13303 } 13304 } 13305 13306 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13307 int opti, boolean dumpAll, String dumpPackage) { 13308 boolean needSep = false; 13309 boolean onlyHistory = false; 13310 boolean printedAnything = false; 13311 13312 if ("history".equals(dumpPackage)) { 13313 if (opti < args.length && "-s".equals(args[opti])) { 13314 dumpAll = false; 13315 } 13316 onlyHistory = true; 13317 dumpPackage = null; 13318 } 13319 13320 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13321 if (!onlyHistory && dumpAll) { 13322 if (mRegisteredReceivers.size() > 0) { 13323 boolean printed = false; 13324 Iterator it = mRegisteredReceivers.values().iterator(); 13325 while (it.hasNext()) { 13326 ReceiverList r = (ReceiverList)it.next(); 13327 if (dumpPackage != null && (r.app == null || 13328 !dumpPackage.equals(r.app.info.packageName))) { 13329 continue; 13330 } 13331 if (!printed) { 13332 pw.println(" Registered Receivers:"); 13333 needSep = true; 13334 printed = true; 13335 printedAnything = true; 13336 } 13337 pw.print(" * "); pw.println(r); 13338 r.dump(pw, " "); 13339 } 13340 } 13341 13342 if (mReceiverResolver.dump(pw, needSep ? 13343 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13344 " ", dumpPackage, false)) { 13345 needSep = true; 13346 printedAnything = true; 13347 } 13348 } 13349 13350 for (BroadcastQueue q : mBroadcastQueues) { 13351 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13352 printedAnything |= needSep; 13353 } 13354 13355 needSep = true; 13356 13357 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13358 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13359 if (needSep) { 13360 pw.println(); 13361 } 13362 needSep = true; 13363 printedAnything = true; 13364 pw.print(" Sticky broadcasts for user "); 13365 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13366 StringBuilder sb = new StringBuilder(128); 13367 for (Map.Entry<String, ArrayList<Intent>> ent 13368 : mStickyBroadcasts.valueAt(user).entrySet()) { 13369 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13370 if (dumpAll) { 13371 pw.println(":"); 13372 ArrayList<Intent> intents = ent.getValue(); 13373 final int N = intents.size(); 13374 for (int i=0; i<N; i++) { 13375 sb.setLength(0); 13376 sb.append(" Intent: "); 13377 intents.get(i).toShortString(sb, false, true, false, false); 13378 pw.println(sb.toString()); 13379 Bundle bundle = intents.get(i).getExtras(); 13380 if (bundle != null) { 13381 pw.print(" "); 13382 pw.println(bundle.toString()); 13383 } 13384 } 13385 } else { 13386 pw.println(""); 13387 } 13388 } 13389 } 13390 } 13391 13392 if (!onlyHistory && dumpAll) { 13393 pw.println(); 13394 for (BroadcastQueue queue : mBroadcastQueues) { 13395 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13396 + queue.mBroadcastsScheduled); 13397 } 13398 pw.println(" mHandler:"); 13399 mHandler.dump(new PrintWriterPrinter(pw), " "); 13400 needSep = true; 13401 printedAnything = true; 13402 } 13403 13404 if (!printedAnything) { 13405 pw.println(" (nothing)"); 13406 } 13407 } 13408 13409 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13410 int opti, boolean dumpAll, String dumpPackage) { 13411 boolean needSep; 13412 boolean printedAnything = false; 13413 13414 ItemMatcher matcher = new ItemMatcher(); 13415 matcher.build(args, opti); 13416 13417 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13418 13419 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13420 printedAnything |= needSep; 13421 13422 if (mLaunchingProviders.size() > 0) { 13423 boolean printed = false; 13424 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13425 ContentProviderRecord r = mLaunchingProviders.get(i); 13426 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13427 continue; 13428 } 13429 if (!printed) { 13430 if (needSep) pw.println(); 13431 needSep = true; 13432 pw.println(" Launching content providers:"); 13433 printed = true; 13434 printedAnything = true; 13435 } 13436 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13437 pw.println(r); 13438 } 13439 } 13440 13441 if (mGrantedUriPermissions.size() > 0) { 13442 boolean printed = false; 13443 int dumpUid = -2; 13444 if (dumpPackage != null) { 13445 try { 13446 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13447 } catch (NameNotFoundException e) { 13448 dumpUid = -1; 13449 } 13450 } 13451 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13452 int uid = mGrantedUriPermissions.keyAt(i); 13453 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13454 continue; 13455 } 13456 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13457 if (!printed) { 13458 if (needSep) pw.println(); 13459 needSep = true; 13460 pw.println(" Granted Uri Permissions:"); 13461 printed = true; 13462 printedAnything = true; 13463 } 13464 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13465 for (UriPermission perm : perms.values()) { 13466 pw.print(" "); pw.println(perm); 13467 if (dumpAll) { 13468 perm.dump(pw, " "); 13469 } 13470 } 13471 } 13472 } 13473 13474 if (!printedAnything) { 13475 pw.println(" (nothing)"); 13476 } 13477 } 13478 13479 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13480 int opti, boolean dumpAll, String dumpPackage) { 13481 boolean printed = false; 13482 13483 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13484 13485 if (mIntentSenderRecords.size() > 0) { 13486 Iterator<WeakReference<PendingIntentRecord>> it 13487 = mIntentSenderRecords.values().iterator(); 13488 while (it.hasNext()) { 13489 WeakReference<PendingIntentRecord> ref = it.next(); 13490 PendingIntentRecord rec = ref != null ? ref.get(): null; 13491 if (dumpPackage != null && (rec == null 13492 || !dumpPackage.equals(rec.key.packageName))) { 13493 continue; 13494 } 13495 printed = true; 13496 if (rec != null) { 13497 pw.print(" * "); pw.println(rec); 13498 if (dumpAll) { 13499 rec.dump(pw, " "); 13500 } 13501 } else { 13502 pw.print(" * "); pw.println(ref); 13503 } 13504 } 13505 } 13506 13507 if (!printed) { 13508 pw.println(" (nothing)"); 13509 } 13510 } 13511 13512 private static final int dumpProcessList(PrintWriter pw, 13513 ActivityManagerService service, List list, 13514 String prefix, String normalLabel, String persistentLabel, 13515 String dumpPackage) { 13516 int numPers = 0; 13517 final int N = list.size()-1; 13518 for (int i=N; i>=0; i--) { 13519 ProcessRecord r = (ProcessRecord)list.get(i); 13520 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13521 continue; 13522 } 13523 pw.println(String.format("%s%s #%2d: %s", 13524 prefix, (r.persistent ? persistentLabel : normalLabel), 13525 i, r.toString())); 13526 if (r.persistent) { 13527 numPers++; 13528 } 13529 } 13530 return numPers; 13531 } 13532 13533 private static final boolean dumpProcessOomList(PrintWriter pw, 13534 ActivityManagerService service, List<ProcessRecord> origList, 13535 String prefix, String normalLabel, String persistentLabel, 13536 boolean inclDetails, String dumpPackage) { 13537 13538 ArrayList<Pair<ProcessRecord, Integer>> list 13539 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13540 for (int i=0; i<origList.size(); i++) { 13541 ProcessRecord r = origList.get(i); 13542 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13543 continue; 13544 } 13545 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13546 } 13547 13548 if (list.size() <= 0) { 13549 return false; 13550 } 13551 13552 Comparator<Pair<ProcessRecord, Integer>> comparator 13553 = new Comparator<Pair<ProcessRecord, Integer>>() { 13554 @Override 13555 public int compare(Pair<ProcessRecord, Integer> object1, 13556 Pair<ProcessRecord, Integer> object2) { 13557 if (object1.first.setAdj != object2.first.setAdj) { 13558 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13559 } 13560 if (object1.second.intValue() != object2.second.intValue()) { 13561 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13562 } 13563 return 0; 13564 } 13565 }; 13566 13567 Collections.sort(list, comparator); 13568 13569 final long curRealtime = SystemClock.elapsedRealtime(); 13570 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13571 final long curUptime = SystemClock.uptimeMillis(); 13572 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13573 13574 for (int i=list.size()-1; i>=0; i--) { 13575 ProcessRecord r = list.get(i).first; 13576 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13577 char schedGroup; 13578 switch (r.setSchedGroup) { 13579 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13580 schedGroup = 'B'; 13581 break; 13582 case Process.THREAD_GROUP_DEFAULT: 13583 schedGroup = 'F'; 13584 break; 13585 default: 13586 schedGroup = '?'; 13587 break; 13588 } 13589 char foreground; 13590 if (r.foregroundActivities) { 13591 foreground = 'A'; 13592 } else if (r.foregroundServices) { 13593 foreground = 'S'; 13594 } else { 13595 foreground = ' '; 13596 } 13597 String procState = ProcessList.makeProcStateString(r.curProcState); 13598 pw.print(prefix); 13599 pw.print(r.persistent ? persistentLabel : normalLabel); 13600 pw.print(" #"); 13601 int num = (origList.size()-1)-list.get(i).second; 13602 if (num < 10) pw.print(' '); 13603 pw.print(num); 13604 pw.print(": "); 13605 pw.print(oomAdj); 13606 pw.print(' '); 13607 pw.print(schedGroup); 13608 pw.print('/'); 13609 pw.print(foreground); 13610 pw.print('/'); 13611 pw.print(procState); 13612 pw.print(" trm:"); 13613 if (r.trimMemoryLevel < 10) pw.print(' '); 13614 pw.print(r.trimMemoryLevel); 13615 pw.print(' '); 13616 pw.print(r.toShortString()); 13617 pw.print(" ("); 13618 pw.print(r.adjType); 13619 pw.println(')'); 13620 if (r.adjSource != null || r.adjTarget != null) { 13621 pw.print(prefix); 13622 pw.print(" "); 13623 if (r.adjTarget instanceof ComponentName) { 13624 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13625 } else if (r.adjTarget != null) { 13626 pw.print(r.adjTarget.toString()); 13627 } else { 13628 pw.print("{null}"); 13629 } 13630 pw.print("<="); 13631 if (r.adjSource instanceof ProcessRecord) { 13632 pw.print("Proc{"); 13633 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13634 pw.println("}"); 13635 } else if (r.adjSource != null) { 13636 pw.println(r.adjSource.toString()); 13637 } else { 13638 pw.println("{null}"); 13639 } 13640 } 13641 if (inclDetails) { 13642 pw.print(prefix); 13643 pw.print(" "); 13644 pw.print("oom: max="); pw.print(r.maxAdj); 13645 pw.print(" curRaw="); pw.print(r.curRawAdj); 13646 pw.print(" setRaw="); pw.print(r.setRawAdj); 13647 pw.print(" cur="); pw.print(r.curAdj); 13648 pw.print(" set="); pw.println(r.setAdj); 13649 pw.print(prefix); 13650 pw.print(" "); 13651 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13652 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13653 pw.print(" lastPss="); pw.print(r.lastPss); 13654 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13655 pw.print(prefix); 13656 pw.print(" "); 13657 pw.print("cached="); pw.print(r.cached); 13658 pw.print(" empty="); pw.print(r.empty); 13659 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13660 13661 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13662 if (r.lastWakeTime != 0) { 13663 long wtime; 13664 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13665 synchronized (stats) { 13666 wtime = stats.getProcessWakeTime(r.info.uid, 13667 r.pid, curRealtime); 13668 } 13669 long timeUsed = wtime - r.lastWakeTime; 13670 pw.print(prefix); 13671 pw.print(" "); 13672 pw.print("keep awake over "); 13673 TimeUtils.formatDuration(realtimeSince, pw); 13674 pw.print(" used "); 13675 TimeUtils.formatDuration(timeUsed, pw); 13676 pw.print(" ("); 13677 pw.print((timeUsed*100)/realtimeSince); 13678 pw.println("%)"); 13679 } 13680 if (r.lastCpuTime != 0) { 13681 long timeUsed = r.curCpuTime - r.lastCpuTime; 13682 pw.print(prefix); 13683 pw.print(" "); 13684 pw.print("run cpu over "); 13685 TimeUtils.formatDuration(uptimeSince, pw); 13686 pw.print(" used "); 13687 TimeUtils.formatDuration(timeUsed, pw); 13688 pw.print(" ("); 13689 pw.print((timeUsed*100)/uptimeSince); 13690 pw.println("%)"); 13691 } 13692 } 13693 } 13694 } 13695 return true; 13696 } 13697 13698 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13699 String[] args) { 13700 ArrayList<ProcessRecord> procs; 13701 synchronized (this) { 13702 if (args != null && args.length > start 13703 && args[start].charAt(0) != '-') { 13704 procs = new ArrayList<ProcessRecord>(); 13705 int pid = -1; 13706 try { 13707 pid = Integer.parseInt(args[start]); 13708 } catch (NumberFormatException e) { 13709 } 13710 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13711 ProcessRecord proc = mLruProcesses.get(i); 13712 if (proc.pid == pid) { 13713 procs.add(proc); 13714 } else if (allPkgs && proc.pkgList != null 13715 && proc.pkgList.containsKey(args[start])) { 13716 procs.add(proc); 13717 } else if (proc.processName.equals(args[start])) { 13718 procs.add(proc); 13719 } 13720 } 13721 if (procs.size() <= 0) { 13722 return null; 13723 } 13724 } else { 13725 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13726 } 13727 } 13728 return procs; 13729 } 13730 13731 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13732 PrintWriter pw, String[] args) { 13733 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13734 if (procs == null) { 13735 pw.println("No process found for: " + args[0]); 13736 return; 13737 } 13738 13739 long uptime = SystemClock.uptimeMillis(); 13740 long realtime = SystemClock.elapsedRealtime(); 13741 pw.println("Applications Graphics Acceleration Info:"); 13742 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13743 13744 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13745 ProcessRecord r = procs.get(i); 13746 if (r.thread != null) { 13747 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13748 pw.flush(); 13749 try { 13750 TransferPipe tp = new TransferPipe(); 13751 try { 13752 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13753 tp.go(fd); 13754 } finally { 13755 tp.kill(); 13756 } 13757 } catch (IOException e) { 13758 pw.println("Failure while dumping the app: " + r); 13759 pw.flush(); 13760 } catch (RemoteException e) { 13761 pw.println("Got a RemoteException while dumping the app " + r); 13762 pw.flush(); 13763 } 13764 } 13765 } 13766 } 13767 13768 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13769 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13770 if (procs == null) { 13771 pw.println("No process found for: " + args[0]); 13772 return; 13773 } 13774 13775 pw.println("Applications Database Info:"); 13776 13777 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13778 ProcessRecord r = procs.get(i); 13779 if (r.thread != null) { 13780 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13781 pw.flush(); 13782 try { 13783 TransferPipe tp = new TransferPipe(); 13784 try { 13785 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13786 tp.go(fd); 13787 } finally { 13788 tp.kill(); 13789 } 13790 } catch (IOException e) { 13791 pw.println("Failure while dumping the app: " + r); 13792 pw.flush(); 13793 } catch (RemoteException e) { 13794 pw.println("Got a RemoteException while dumping the app " + r); 13795 pw.flush(); 13796 } 13797 } 13798 } 13799 } 13800 13801 final static class MemItem { 13802 final boolean isProc; 13803 final String label; 13804 final String shortLabel; 13805 final long pss; 13806 final int id; 13807 final boolean hasActivities; 13808 ArrayList<MemItem> subitems; 13809 13810 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13811 boolean _hasActivities) { 13812 isProc = true; 13813 label = _label; 13814 shortLabel = _shortLabel; 13815 pss = _pss; 13816 id = _id; 13817 hasActivities = _hasActivities; 13818 } 13819 13820 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13821 isProc = false; 13822 label = _label; 13823 shortLabel = _shortLabel; 13824 pss = _pss; 13825 id = _id; 13826 hasActivities = false; 13827 } 13828 } 13829 13830 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13831 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13832 if (sort && !isCompact) { 13833 Collections.sort(items, new Comparator<MemItem>() { 13834 @Override 13835 public int compare(MemItem lhs, MemItem rhs) { 13836 if (lhs.pss < rhs.pss) { 13837 return 1; 13838 } else if (lhs.pss > rhs.pss) { 13839 return -1; 13840 } 13841 return 0; 13842 } 13843 }); 13844 } 13845 13846 for (int i=0; i<items.size(); i++) { 13847 MemItem mi = items.get(i); 13848 if (!isCompact) { 13849 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13850 } else if (mi.isProc) { 13851 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13852 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13853 pw.println(mi.hasActivities ? ",a" : ",e"); 13854 } else { 13855 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13856 pw.println(mi.pss); 13857 } 13858 if (mi.subitems != null) { 13859 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13860 true, isCompact); 13861 } 13862 } 13863 } 13864 13865 // These are in KB. 13866 static final long[] DUMP_MEM_BUCKETS = new long[] { 13867 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13868 120*1024, 160*1024, 200*1024, 13869 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13870 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13871 }; 13872 13873 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13874 boolean stackLike) { 13875 int start = label.lastIndexOf('.'); 13876 if (start >= 0) start++; 13877 else start = 0; 13878 int end = label.length(); 13879 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13880 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13881 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13882 out.append(bucket); 13883 out.append(stackLike ? "MB." : "MB "); 13884 out.append(label, start, end); 13885 return; 13886 } 13887 } 13888 out.append(memKB/1024); 13889 out.append(stackLike ? "MB." : "MB "); 13890 out.append(label, start, end); 13891 } 13892 13893 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13894 ProcessList.NATIVE_ADJ, 13895 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13896 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13897 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13898 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13899 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13900 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13901 }; 13902 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13903 "Native", 13904 "System", "Persistent", "Persistent Service", "Foreground", 13905 "Visible", "Perceptible", 13906 "Heavy Weight", "Backup", 13907 "A Services", "Home", 13908 "Previous", "B Services", "Cached" 13909 }; 13910 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13911 "native", 13912 "sys", "pers", "persvc", "fore", 13913 "vis", "percept", 13914 "heavy", "backup", 13915 "servicea", "home", 13916 "prev", "serviceb", "cached" 13917 }; 13918 13919 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13920 long realtime, boolean isCheckinRequest, boolean isCompact) { 13921 if (isCheckinRequest || isCompact) { 13922 // short checkin version 13923 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13924 } else { 13925 pw.println("Applications Memory Usage (kB):"); 13926 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13927 } 13928 } 13929 13930 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13931 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13932 boolean dumpDetails = false; 13933 boolean dumpFullDetails = false; 13934 boolean dumpDalvik = false; 13935 boolean oomOnly = false; 13936 boolean isCompact = false; 13937 boolean localOnly = false; 13938 boolean packages = false; 13939 13940 int opti = 0; 13941 while (opti < args.length) { 13942 String opt = args[opti]; 13943 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13944 break; 13945 } 13946 opti++; 13947 if ("-a".equals(opt)) { 13948 dumpDetails = true; 13949 dumpFullDetails = true; 13950 dumpDalvik = true; 13951 } else if ("-d".equals(opt)) { 13952 dumpDalvik = true; 13953 } else if ("-c".equals(opt)) { 13954 isCompact = true; 13955 } else if ("--oom".equals(opt)) { 13956 oomOnly = true; 13957 } else if ("--local".equals(opt)) { 13958 localOnly = true; 13959 } else if ("--package".equals(opt)) { 13960 packages = true; 13961 } else if ("-h".equals(opt)) { 13962 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13963 pw.println(" -a: include all available information for each process."); 13964 pw.println(" -d: include dalvik details when dumping process details."); 13965 pw.println(" -c: dump in a compact machine-parseable representation."); 13966 pw.println(" --oom: only show processes organized by oom adj."); 13967 pw.println(" --local: only collect details locally, don't call process."); 13968 pw.println(" --package: interpret process arg as package, dumping all"); 13969 pw.println(" processes that have loaded that package."); 13970 pw.println("If [process] is specified it can be the name or "); 13971 pw.println("pid of a specific process to dump."); 13972 return; 13973 } else { 13974 pw.println("Unknown argument: " + opt + "; use -h for help"); 13975 } 13976 } 13977 13978 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13979 long uptime = SystemClock.uptimeMillis(); 13980 long realtime = SystemClock.elapsedRealtime(); 13981 final long[] tmpLong = new long[1]; 13982 13983 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13984 if (procs == null) { 13985 // No Java processes. Maybe they want to print a native process. 13986 if (args != null && args.length > opti 13987 && args[opti].charAt(0) != '-') { 13988 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13989 = new ArrayList<ProcessCpuTracker.Stats>(); 13990 updateCpuStatsNow(); 13991 int findPid = -1; 13992 try { 13993 findPid = Integer.parseInt(args[opti]); 13994 } catch (NumberFormatException e) { 13995 } 13996 synchronized (mProcessCpuTracker) { 13997 final int N = mProcessCpuTracker.countStats(); 13998 for (int i=0; i<N; i++) { 13999 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14000 if (st.pid == findPid || (st.baseName != null 14001 && st.baseName.equals(args[opti]))) { 14002 nativeProcs.add(st); 14003 } 14004 } 14005 } 14006 if (nativeProcs.size() > 0) { 14007 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14008 isCompact); 14009 Debug.MemoryInfo mi = null; 14010 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14011 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14012 final int pid = r.pid; 14013 if (!isCheckinRequest && dumpDetails) { 14014 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14015 } 14016 if (mi == null) { 14017 mi = new Debug.MemoryInfo(); 14018 } 14019 if (dumpDetails || (!brief && !oomOnly)) { 14020 Debug.getMemoryInfo(pid, mi); 14021 } else { 14022 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14023 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14024 } 14025 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14026 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14027 if (isCheckinRequest) { 14028 pw.println(); 14029 } 14030 } 14031 return; 14032 } 14033 } 14034 pw.println("No process found for: " + args[opti]); 14035 return; 14036 } 14037 14038 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14039 dumpDetails = true; 14040 } 14041 14042 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14043 14044 String[] innerArgs = new String[args.length-opti]; 14045 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14046 14047 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14048 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14049 long nativePss=0, dalvikPss=0, otherPss=0; 14050 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14051 14052 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14053 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14054 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14055 14056 long totalPss = 0; 14057 long cachedPss = 0; 14058 14059 Debug.MemoryInfo mi = null; 14060 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14061 final ProcessRecord r = procs.get(i); 14062 final IApplicationThread thread; 14063 final int pid; 14064 final int oomAdj; 14065 final boolean hasActivities; 14066 synchronized (this) { 14067 thread = r.thread; 14068 pid = r.pid; 14069 oomAdj = r.getSetAdjWithServices(); 14070 hasActivities = r.activities.size() > 0; 14071 } 14072 if (thread != null) { 14073 if (!isCheckinRequest && dumpDetails) { 14074 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14075 } 14076 if (mi == null) { 14077 mi = new Debug.MemoryInfo(); 14078 } 14079 if (dumpDetails || (!brief && !oomOnly)) { 14080 Debug.getMemoryInfo(pid, mi); 14081 } else { 14082 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14083 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14084 } 14085 if (dumpDetails) { 14086 if (localOnly) { 14087 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14088 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14089 if (isCheckinRequest) { 14090 pw.println(); 14091 } 14092 } else { 14093 try { 14094 pw.flush(); 14095 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14096 dumpDalvik, innerArgs); 14097 } catch (RemoteException e) { 14098 if (!isCheckinRequest) { 14099 pw.println("Got RemoteException!"); 14100 pw.flush(); 14101 } 14102 } 14103 } 14104 } 14105 14106 final long myTotalPss = mi.getTotalPss(); 14107 final long myTotalUss = mi.getTotalUss(); 14108 14109 synchronized (this) { 14110 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14111 // Record this for posterity if the process has been stable. 14112 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14113 } 14114 } 14115 14116 if (!isCheckinRequest && mi != null) { 14117 totalPss += myTotalPss; 14118 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14119 (hasActivities ? " / activities)" : ")"), 14120 r.processName, myTotalPss, pid, hasActivities); 14121 procMems.add(pssItem); 14122 procMemsMap.put(pid, pssItem); 14123 14124 nativePss += mi.nativePss; 14125 dalvikPss += mi.dalvikPss; 14126 otherPss += mi.otherPss; 14127 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14128 long mem = mi.getOtherPss(j); 14129 miscPss[j] += mem; 14130 otherPss -= mem; 14131 } 14132 14133 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14134 cachedPss += myTotalPss; 14135 } 14136 14137 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14138 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14139 || oomIndex == (oomPss.length-1)) { 14140 oomPss[oomIndex] += myTotalPss; 14141 if (oomProcs[oomIndex] == null) { 14142 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14143 } 14144 oomProcs[oomIndex].add(pssItem); 14145 break; 14146 } 14147 } 14148 } 14149 } 14150 } 14151 14152 long nativeProcTotalPss = 0; 14153 14154 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14155 // If we are showing aggregations, also look for native processes to 14156 // include so that our aggregations are more accurate. 14157 updateCpuStatsNow(); 14158 synchronized (mProcessCpuTracker) { 14159 final int N = mProcessCpuTracker.countStats(); 14160 for (int i=0; i<N; i++) { 14161 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14162 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14163 if (mi == null) { 14164 mi = new Debug.MemoryInfo(); 14165 } 14166 if (!brief && !oomOnly) { 14167 Debug.getMemoryInfo(st.pid, mi); 14168 } else { 14169 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14170 mi.nativePrivateDirty = (int)tmpLong[0]; 14171 } 14172 14173 final long myTotalPss = mi.getTotalPss(); 14174 totalPss += myTotalPss; 14175 nativeProcTotalPss += myTotalPss; 14176 14177 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14178 st.name, myTotalPss, st.pid, false); 14179 procMems.add(pssItem); 14180 14181 nativePss += mi.nativePss; 14182 dalvikPss += mi.dalvikPss; 14183 otherPss += mi.otherPss; 14184 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14185 long mem = mi.getOtherPss(j); 14186 miscPss[j] += mem; 14187 otherPss -= mem; 14188 } 14189 oomPss[0] += myTotalPss; 14190 if (oomProcs[0] == null) { 14191 oomProcs[0] = new ArrayList<MemItem>(); 14192 } 14193 oomProcs[0].add(pssItem); 14194 } 14195 } 14196 } 14197 14198 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14199 14200 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14201 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14202 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14203 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14204 String label = Debug.MemoryInfo.getOtherLabel(j); 14205 catMems.add(new MemItem(label, label, miscPss[j], j)); 14206 } 14207 14208 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14209 for (int j=0; j<oomPss.length; j++) { 14210 if (oomPss[j] != 0) { 14211 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14212 : DUMP_MEM_OOM_LABEL[j]; 14213 MemItem item = new MemItem(label, label, oomPss[j], 14214 DUMP_MEM_OOM_ADJ[j]); 14215 item.subitems = oomProcs[j]; 14216 oomMems.add(item); 14217 } 14218 } 14219 14220 if (!brief && !oomOnly && !isCompact) { 14221 pw.println(); 14222 pw.println("Total PSS by process:"); 14223 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14224 pw.println(); 14225 } 14226 if (!isCompact) { 14227 pw.println("Total PSS by OOM adjustment:"); 14228 } 14229 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14230 if (!brief && !oomOnly) { 14231 PrintWriter out = categoryPw != null ? categoryPw : pw; 14232 if (!isCompact) { 14233 out.println(); 14234 out.println("Total PSS by category:"); 14235 } 14236 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14237 } 14238 if (!isCompact) { 14239 pw.println(); 14240 } 14241 MemInfoReader memInfo = new MemInfoReader(); 14242 memInfo.readMemInfo(); 14243 if (nativeProcTotalPss > 0) { 14244 synchronized (this) { 14245 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14246 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14247 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14248 } 14249 } 14250 if (!brief) { 14251 if (!isCompact) { 14252 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14253 pw.print(" kB (status "); 14254 switch (mLastMemoryLevel) { 14255 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14256 pw.println("normal)"); 14257 break; 14258 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14259 pw.println("moderate)"); 14260 break; 14261 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14262 pw.println("low)"); 14263 break; 14264 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14265 pw.println("critical)"); 14266 break; 14267 default: 14268 pw.print(mLastMemoryLevel); 14269 pw.println(")"); 14270 break; 14271 } 14272 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14273 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14274 pw.print(cachedPss); pw.print(" cached pss + "); 14275 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14276 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14277 } else { 14278 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14279 pw.print(cachedPss + memInfo.getCachedSizeKb() 14280 + memInfo.getFreeSizeKb()); pw.print(","); 14281 pw.println(totalPss - cachedPss); 14282 } 14283 } 14284 if (!isCompact) { 14285 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14286 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14287 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14288 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14289 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14290 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14291 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14292 } 14293 if (!brief) { 14294 if (memInfo.getZramTotalSizeKb() != 0) { 14295 if (!isCompact) { 14296 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14297 pw.print(" kB physical used for "); 14298 pw.print(memInfo.getSwapTotalSizeKb() 14299 - memInfo.getSwapFreeSizeKb()); 14300 pw.print(" kB in swap ("); 14301 pw.print(memInfo.getSwapTotalSizeKb()); 14302 pw.println(" kB total swap)"); 14303 } else { 14304 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14305 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14306 pw.println(memInfo.getSwapFreeSizeKb()); 14307 } 14308 } 14309 final int[] SINGLE_LONG_FORMAT = new int[] { 14310 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14311 }; 14312 long[] longOut = new long[1]; 14313 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14314 SINGLE_LONG_FORMAT, null, longOut, null); 14315 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14316 longOut[0] = 0; 14317 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14318 SINGLE_LONG_FORMAT, null, longOut, null); 14319 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14320 longOut[0] = 0; 14321 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14322 SINGLE_LONG_FORMAT, null, longOut, null); 14323 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14324 longOut[0] = 0; 14325 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14326 SINGLE_LONG_FORMAT, null, longOut, null); 14327 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14328 if (!isCompact) { 14329 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14330 pw.print(" KSM: "); pw.print(sharing); 14331 pw.print(" kB saved from shared "); 14332 pw.print(shared); pw.println(" kB"); 14333 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14334 pw.print(voltile); pw.println(" kB volatile"); 14335 } 14336 pw.print(" Tuning: "); 14337 pw.print(ActivityManager.staticGetMemoryClass()); 14338 pw.print(" (large "); 14339 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14340 pw.print("), oom "); 14341 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14342 pw.print(" kB"); 14343 pw.print(", restore limit "); 14344 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14345 pw.print(" kB"); 14346 if (ActivityManager.isLowRamDeviceStatic()) { 14347 pw.print(" (low-ram)"); 14348 } 14349 if (ActivityManager.isHighEndGfx()) { 14350 pw.print(" (high-end-gfx)"); 14351 } 14352 pw.println(); 14353 } else { 14354 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14355 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14356 pw.println(voltile); 14357 pw.print("tuning,"); 14358 pw.print(ActivityManager.staticGetMemoryClass()); 14359 pw.print(','); 14360 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14361 pw.print(','); 14362 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14363 if (ActivityManager.isLowRamDeviceStatic()) { 14364 pw.print(",low-ram"); 14365 } 14366 if (ActivityManager.isHighEndGfx()) { 14367 pw.print(",high-end-gfx"); 14368 } 14369 pw.println(); 14370 } 14371 } 14372 } 14373 } 14374 14375 /** 14376 * Searches array of arguments for the specified string 14377 * @param args array of argument strings 14378 * @param value value to search for 14379 * @return true if the value is contained in the array 14380 */ 14381 private static boolean scanArgs(String[] args, String value) { 14382 if (args != null) { 14383 for (String arg : args) { 14384 if (value.equals(arg)) { 14385 return true; 14386 } 14387 } 14388 } 14389 return false; 14390 } 14391 14392 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14393 ContentProviderRecord cpr, boolean always) { 14394 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14395 14396 if (!inLaunching || always) { 14397 synchronized (cpr) { 14398 cpr.launchingApp = null; 14399 cpr.notifyAll(); 14400 } 14401 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14402 String names[] = cpr.info.authority.split(";"); 14403 for (int j = 0; j < names.length; j++) { 14404 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14405 } 14406 } 14407 14408 for (int i=0; i<cpr.connections.size(); i++) { 14409 ContentProviderConnection conn = cpr.connections.get(i); 14410 if (conn.waiting) { 14411 // If this connection is waiting for the provider, then we don't 14412 // need to mess with its process unless we are always removing 14413 // or for some reason the provider is not currently launching. 14414 if (inLaunching && !always) { 14415 continue; 14416 } 14417 } 14418 ProcessRecord capp = conn.client; 14419 conn.dead = true; 14420 if (conn.stableCount > 0) { 14421 if (!capp.persistent && capp.thread != null 14422 && capp.pid != 0 14423 && capp.pid != MY_PID) { 14424 capp.kill("depends on provider " 14425 + cpr.name.flattenToShortString() 14426 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14427 } 14428 } else if (capp.thread != null && conn.provider.provider != null) { 14429 try { 14430 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14431 } catch (RemoteException e) { 14432 } 14433 // In the protocol here, we don't expect the client to correctly 14434 // clean up this connection, we'll just remove it. 14435 cpr.connections.remove(i); 14436 conn.client.conProviders.remove(conn); 14437 } 14438 } 14439 14440 if (inLaunching && always) { 14441 mLaunchingProviders.remove(cpr); 14442 } 14443 return inLaunching; 14444 } 14445 14446 /** 14447 * Main code for cleaning up a process when it has gone away. This is 14448 * called both as a result of the process dying, or directly when stopping 14449 * a process when running in single process mode. 14450 * 14451 * @return Returns true if the given process has been restarted, so the 14452 * app that was passed in must remain on the process lists. 14453 */ 14454 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14455 boolean restarting, boolean allowRestart, int index) { 14456 if (index >= 0) { 14457 removeLruProcessLocked(app); 14458 ProcessList.remove(app.pid); 14459 } 14460 14461 mProcessesToGc.remove(app); 14462 mPendingPssProcesses.remove(app); 14463 14464 // Dismiss any open dialogs. 14465 if (app.crashDialog != null && !app.forceCrashReport) { 14466 app.crashDialog.dismiss(); 14467 app.crashDialog = null; 14468 } 14469 if (app.anrDialog != null) { 14470 app.anrDialog.dismiss(); 14471 app.anrDialog = null; 14472 } 14473 if (app.waitDialog != null) { 14474 app.waitDialog.dismiss(); 14475 app.waitDialog = null; 14476 } 14477 14478 app.crashing = false; 14479 app.notResponding = false; 14480 14481 app.resetPackageList(mProcessStats); 14482 app.unlinkDeathRecipient(); 14483 app.makeInactive(mProcessStats); 14484 app.waitingToKill = null; 14485 app.forcingToForeground = null; 14486 updateProcessForegroundLocked(app, false, false); 14487 app.foregroundActivities = false; 14488 app.hasShownUi = false; 14489 app.treatLikeActivity = false; 14490 app.hasAboveClient = false; 14491 app.hasClientActivities = false; 14492 14493 mServices.killServicesLocked(app, allowRestart); 14494 14495 boolean restart = false; 14496 14497 // Remove published content providers. 14498 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14499 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14500 final boolean always = app.bad || !allowRestart; 14501 if (removeDyingProviderLocked(app, cpr, always) || always) { 14502 // We left the provider in the launching list, need to 14503 // restart it. 14504 restart = true; 14505 } 14506 14507 cpr.provider = null; 14508 cpr.proc = null; 14509 } 14510 app.pubProviders.clear(); 14511 14512 // Take care of any launching providers waiting for this process. 14513 if (checkAppInLaunchingProvidersLocked(app, false)) { 14514 restart = true; 14515 } 14516 14517 // Unregister from connected content providers. 14518 if (!app.conProviders.isEmpty()) { 14519 for (int i=0; i<app.conProviders.size(); i++) { 14520 ContentProviderConnection conn = app.conProviders.get(i); 14521 conn.provider.connections.remove(conn); 14522 } 14523 app.conProviders.clear(); 14524 } 14525 14526 // At this point there may be remaining entries in mLaunchingProviders 14527 // where we were the only one waiting, so they are no longer of use. 14528 // Look for these and clean up if found. 14529 // XXX Commented out for now. Trying to figure out a way to reproduce 14530 // the actual situation to identify what is actually going on. 14531 if (false) { 14532 for (int i=0; i<mLaunchingProviders.size(); i++) { 14533 ContentProviderRecord cpr = (ContentProviderRecord) 14534 mLaunchingProviders.get(i); 14535 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14536 synchronized (cpr) { 14537 cpr.launchingApp = null; 14538 cpr.notifyAll(); 14539 } 14540 } 14541 } 14542 } 14543 14544 skipCurrentReceiverLocked(app); 14545 14546 // Unregister any receivers. 14547 for (int i=app.receivers.size()-1; i>=0; i--) { 14548 removeReceiverLocked(app.receivers.valueAt(i)); 14549 } 14550 app.receivers.clear(); 14551 14552 // If the app is undergoing backup, tell the backup manager about it 14553 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14554 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14555 + mBackupTarget.appInfo + " died during backup"); 14556 try { 14557 IBackupManager bm = IBackupManager.Stub.asInterface( 14558 ServiceManager.getService(Context.BACKUP_SERVICE)); 14559 bm.agentDisconnected(app.info.packageName); 14560 } catch (RemoteException e) { 14561 // can't happen; backup manager is local 14562 } 14563 } 14564 14565 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14566 ProcessChangeItem item = mPendingProcessChanges.get(i); 14567 if (item.pid == app.pid) { 14568 mPendingProcessChanges.remove(i); 14569 mAvailProcessChanges.add(item); 14570 } 14571 } 14572 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14573 14574 // If the caller is restarting this app, then leave it in its 14575 // current lists and let the caller take care of it. 14576 if (restarting) { 14577 return false; 14578 } 14579 14580 if (!app.persistent || app.isolated) { 14581 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14582 "Removing non-persistent process during cleanup: " + app); 14583 mProcessNames.remove(app.processName, app.uid); 14584 mIsolatedProcesses.remove(app.uid); 14585 if (mHeavyWeightProcess == app) { 14586 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14587 mHeavyWeightProcess.userId, 0)); 14588 mHeavyWeightProcess = null; 14589 } 14590 } else if (!app.removed) { 14591 // This app is persistent, so we need to keep its record around. 14592 // If it is not already on the pending app list, add it there 14593 // and start a new process for it. 14594 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14595 mPersistentStartingProcesses.add(app); 14596 restart = true; 14597 } 14598 } 14599 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14600 "Clean-up removing on hold: " + app); 14601 mProcessesOnHold.remove(app); 14602 14603 if (app == mHomeProcess) { 14604 mHomeProcess = null; 14605 } 14606 if (app == mPreviousProcess) { 14607 mPreviousProcess = null; 14608 } 14609 14610 if (restart && !app.isolated) { 14611 // We have components that still need to be running in the 14612 // process, so re-launch it. 14613 if (index < 0) { 14614 ProcessList.remove(app.pid); 14615 } 14616 mProcessNames.put(app.processName, app.uid, app); 14617 startProcessLocked(app, "restart", app.processName); 14618 return true; 14619 } else if (app.pid > 0 && app.pid != MY_PID) { 14620 // Goodbye! 14621 boolean removed; 14622 synchronized (mPidsSelfLocked) { 14623 mPidsSelfLocked.remove(app.pid); 14624 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14625 } 14626 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14627 if (app.isolated) { 14628 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14629 } 14630 app.setPid(0); 14631 } 14632 return false; 14633 } 14634 14635 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14636 // Look through the content providers we are waiting to have launched, 14637 // and if any run in this process then either schedule a restart of 14638 // the process or kill the client waiting for it if this process has 14639 // gone bad. 14640 int NL = mLaunchingProviders.size(); 14641 boolean restart = false; 14642 for (int i=0; i<NL; i++) { 14643 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14644 if (cpr.launchingApp == app) { 14645 if (!alwaysBad && !app.bad) { 14646 restart = true; 14647 } else { 14648 removeDyingProviderLocked(app, cpr, true); 14649 // cpr should have been removed from mLaunchingProviders 14650 NL = mLaunchingProviders.size(); 14651 i--; 14652 } 14653 } 14654 } 14655 return restart; 14656 } 14657 14658 // ========================================================= 14659 // SERVICES 14660 // ========================================================= 14661 14662 @Override 14663 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14664 int flags) { 14665 enforceNotIsolatedCaller("getServices"); 14666 synchronized (this) { 14667 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14668 } 14669 } 14670 14671 @Override 14672 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14673 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14674 synchronized (this) { 14675 return mServices.getRunningServiceControlPanelLocked(name); 14676 } 14677 } 14678 14679 @Override 14680 public ComponentName startService(IApplicationThread caller, Intent service, 14681 String resolvedType, int userId) { 14682 enforceNotIsolatedCaller("startService"); 14683 // Refuse possible leaked file descriptors 14684 if (service != null && service.hasFileDescriptors() == true) { 14685 throw new IllegalArgumentException("File descriptors passed in Intent"); 14686 } 14687 14688 if (DEBUG_SERVICE) 14689 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14690 synchronized(this) { 14691 final int callingPid = Binder.getCallingPid(); 14692 final int callingUid = Binder.getCallingUid(); 14693 final long origId = Binder.clearCallingIdentity(); 14694 ComponentName res = mServices.startServiceLocked(caller, service, 14695 resolvedType, callingPid, callingUid, userId); 14696 Binder.restoreCallingIdentity(origId); 14697 return res; 14698 } 14699 } 14700 14701 ComponentName startServiceInPackage(int uid, 14702 Intent service, String resolvedType, int userId) { 14703 synchronized(this) { 14704 if (DEBUG_SERVICE) 14705 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14706 final long origId = Binder.clearCallingIdentity(); 14707 ComponentName res = mServices.startServiceLocked(null, service, 14708 resolvedType, -1, uid, userId); 14709 Binder.restoreCallingIdentity(origId); 14710 return res; 14711 } 14712 } 14713 14714 @Override 14715 public int stopService(IApplicationThread caller, Intent service, 14716 String resolvedType, int userId) { 14717 enforceNotIsolatedCaller("stopService"); 14718 // Refuse possible leaked file descriptors 14719 if (service != null && service.hasFileDescriptors() == true) { 14720 throw new IllegalArgumentException("File descriptors passed in Intent"); 14721 } 14722 14723 synchronized(this) { 14724 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14725 } 14726 } 14727 14728 @Override 14729 public IBinder peekService(Intent service, String resolvedType) { 14730 enforceNotIsolatedCaller("peekService"); 14731 // Refuse possible leaked file descriptors 14732 if (service != null && service.hasFileDescriptors() == true) { 14733 throw new IllegalArgumentException("File descriptors passed in Intent"); 14734 } 14735 synchronized(this) { 14736 return mServices.peekServiceLocked(service, resolvedType); 14737 } 14738 } 14739 14740 @Override 14741 public boolean stopServiceToken(ComponentName className, IBinder token, 14742 int startId) { 14743 synchronized(this) { 14744 return mServices.stopServiceTokenLocked(className, token, startId); 14745 } 14746 } 14747 14748 @Override 14749 public void setServiceForeground(ComponentName className, IBinder token, 14750 int id, Notification notification, boolean removeNotification) { 14751 synchronized(this) { 14752 mServices.setServiceForegroundLocked(className, token, id, notification, 14753 removeNotification); 14754 } 14755 } 14756 14757 @Override 14758 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14759 boolean requireFull, String name, String callerPackage) { 14760 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14761 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14762 } 14763 14764 int unsafeConvertIncomingUser(int userId) { 14765 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14766 ? mCurrentUserId : userId; 14767 } 14768 14769 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14770 int allowMode, String name, String callerPackage) { 14771 final int callingUserId = UserHandle.getUserId(callingUid); 14772 if (callingUserId == userId) { 14773 return userId; 14774 } 14775 14776 // Note that we may be accessing mCurrentUserId outside of a lock... 14777 // shouldn't be a big deal, if this is being called outside 14778 // of a locked context there is intrinsically a race with 14779 // the value the caller will receive and someone else changing it. 14780 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14781 // we will switch to the calling user if access to the current user fails. 14782 int targetUserId = unsafeConvertIncomingUser(userId); 14783 14784 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14785 final boolean allow; 14786 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14787 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14788 // If the caller has this permission, they always pass go. And collect $200. 14789 allow = true; 14790 } else if (allowMode == ALLOW_FULL_ONLY) { 14791 // We require full access, sucks to be you. 14792 allow = false; 14793 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14794 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14795 // If the caller does not have either permission, they are always doomed. 14796 allow = false; 14797 } else if (allowMode == ALLOW_NON_FULL) { 14798 // We are blanket allowing non-full access, you lucky caller! 14799 allow = true; 14800 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14801 // We may or may not allow this depending on whether the two users are 14802 // in the same profile. 14803 synchronized (mUserProfileGroupIdsSelfLocked) { 14804 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14805 UserInfo.NO_PROFILE_GROUP_ID); 14806 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14807 UserInfo.NO_PROFILE_GROUP_ID); 14808 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14809 && callingProfile == targetProfile; 14810 } 14811 } else { 14812 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14813 } 14814 if (!allow) { 14815 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14816 // In this case, they would like to just execute as their 14817 // owner user instead of failing. 14818 targetUserId = callingUserId; 14819 } else { 14820 StringBuilder builder = new StringBuilder(128); 14821 builder.append("Permission Denial: "); 14822 builder.append(name); 14823 if (callerPackage != null) { 14824 builder.append(" from "); 14825 builder.append(callerPackage); 14826 } 14827 builder.append(" asks to run as user "); 14828 builder.append(userId); 14829 builder.append(" but is calling from user "); 14830 builder.append(UserHandle.getUserId(callingUid)); 14831 builder.append("; this requires "); 14832 builder.append(INTERACT_ACROSS_USERS_FULL); 14833 if (allowMode != ALLOW_FULL_ONLY) { 14834 builder.append(" or "); 14835 builder.append(INTERACT_ACROSS_USERS); 14836 } 14837 String msg = builder.toString(); 14838 Slog.w(TAG, msg); 14839 throw new SecurityException(msg); 14840 } 14841 } 14842 } 14843 if (!allowAll && targetUserId < 0) { 14844 throw new IllegalArgumentException( 14845 "Call does not support special user #" + targetUserId); 14846 } 14847 // Check shell permission 14848 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14849 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14850 targetUserId)) { 14851 throw new SecurityException("Shell does not have permission to access user " 14852 + targetUserId + "\n " + Debug.getCallers(3)); 14853 } 14854 } 14855 return targetUserId; 14856 } 14857 14858 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14859 String className, int flags) { 14860 boolean result = false; 14861 // For apps that don't have pre-defined UIDs, check for permission 14862 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14863 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14864 if (ActivityManager.checkUidPermission( 14865 INTERACT_ACROSS_USERS, 14866 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14867 ComponentName comp = new ComponentName(aInfo.packageName, className); 14868 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14869 + " requests FLAG_SINGLE_USER, but app does not hold " 14870 + INTERACT_ACROSS_USERS; 14871 Slog.w(TAG, msg); 14872 throw new SecurityException(msg); 14873 } 14874 // Permission passed 14875 result = true; 14876 } 14877 } else if ("system".equals(componentProcessName)) { 14878 result = true; 14879 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14880 // Phone app and persistent apps are allowed to export singleuser providers. 14881 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14882 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14883 } 14884 if (DEBUG_MU) { 14885 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14886 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14887 } 14888 return result; 14889 } 14890 14891 /** 14892 * Checks to see if the caller is in the same app as the singleton 14893 * component, or the component is in a special app. It allows special apps 14894 * to export singleton components but prevents exporting singleton 14895 * components for regular apps. 14896 */ 14897 boolean isValidSingletonCall(int callingUid, int componentUid) { 14898 int componentAppId = UserHandle.getAppId(componentUid); 14899 return UserHandle.isSameApp(callingUid, componentUid) 14900 || componentAppId == Process.SYSTEM_UID 14901 || componentAppId == Process.PHONE_UID 14902 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14903 == PackageManager.PERMISSION_GRANTED; 14904 } 14905 14906 public int bindService(IApplicationThread caller, IBinder token, 14907 Intent service, String resolvedType, 14908 IServiceConnection connection, int flags, int userId) { 14909 enforceNotIsolatedCaller("bindService"); 14910 14911 // Refuse possible leaked file descriptors 14912 if (service != null && service.hasFileDescriptors() == true) { 14913 throw new IllegalArgumentException("File descriptors passed in Intent"); 14914 } 14915 14916 synchronized(this) { 14917 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14918 connection, flags, userId); 14919 } 14920 } 14921 14922 public boolean unbindService(IServiceConnection connection) { 14923 synchronized (this) { 14924 return mServices.unbindServiceLocked(connection); 14925 } 14926 } 14927 14928 public void publishService(IBinder token, Intent intent, IBinder service) { 14929 // Refuse possible leaked file descriptors 14930 if (intent != null && intent.hasFileDescriptors() == true) { 14931 throw new IllegalArgumentException("File descriptors passed in Intent"); 14932 } 14933 14934 synchronized(this) { 14935 if (!(token instanceof ServiceRecord)) { 14936 throw new IllegalArgumentException("Invalid service token"); 14937 } 14938 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14939 } 14940 } 14941 14942 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14943 // Refuse possible leaked file descriptors 14944 if (intent != null && intent.hasFileDescriptors() == true) { 14945 throw new IllegalArgumentException("File descriptors passed in Intent"); 14946 } 14947 14948 synchronized(this) { 14949 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14950 } 14951 } 14952 14953 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14954 synchronized(this) { 14955 if (!(token instanceof ServiceRecord)) { 14956 throw new IllegalArgumentException("Invalid service token"); 14957 } 14958 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14959 } 14960 } 14961 14962 // ========================================================= 14963 // BACKUP AND RESTORE 14964 // ========================================================= 14965 14966 // Cause the target app to be launched if necessary and its backup agent 14967 // instantiated. The backup agent will invoke backupAgentCreated() on the 14968 // activity manager to announce its creation. 14969 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14970 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14971 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14972 14973 synchronized(this) { 14974 // !!! TODO: currently no check here that we're already bound 14975 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14976 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14977 synchronized (stats) { 14978 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14979 } 14980 14981 // Backup agent is now in use, its package can't be stopped. 14982 try { 14983 AppGlobals.getPackageManager().setPackageStoppedState( 14984 app.packageName, false, UserHandle.getUserId(app.uid)); 14985 } catch (RemoteException e) { 14986 } catch (IllegalArgumentException e) { 14987 Slog.w(TAG, "Failed trying to unstop package " 14988 + app.packageName + ": " + e); 14989 } 14990 14991 BackupRecord r = new BackupRecord(ss, app, backupMode); 14992 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14993 ? new ComponentName(app.packageName, app.backupAgentName) 14994 : new ComponentName("android", "FullBackupAgent"); 14995 // startProcessLocked() returns existing proc's record if it's already running 14996 ProcessRecord proc = startProcessLocked(app.processName, app, 14997 false, 0, "backup", hostingName, false, false, false); 14998 if (proc == null) { 14999 Slog.e(TAG, "Unable to start backup agent process " + r); 15000 return false; 15001 } 15002 15003 r.app = proc; 15004 mBackupTarget = r; 15005 mBackupAppName = app.packageName; 15006 15007 // Try not to kill the process during backup 15008 updateOomAdjLocked(proc); 15009 15010 // If the process is already attached, schedule the creation of the backup agent now. 15011 // If it is not yet live, this will be done when it attaches to the framework. 15012 if (proc.thread != null) { 15013 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15014 try { 15015 proc.thread.scheduleCreateBackupAgent(app, 15016 compatibilityInfoForPackageLocked(app), backupMode); 15017 } catch (RemoteException e) { 15018 // Will time out on the backup manager side 15019 } 15020 } else { 15021 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15022 } 15023 // Invariants: at this point, the target app process exists and the application 15024 // is either already running or in the process of coming up. mBackupTarget and 15025 // mBackupAppName describe the app, so that when it binds back to the AM we 15026 // know that it's scheduled for a backup-agent operation. 15027 } 15028 15029 return true; 15030 } 15031 15032 @Override 15033 public void clearPendingBackup() { 15034 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15035 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15036 15037 synchronized (this) { 15038 mBackupTarget = null; 15039 mBackupAppName = null; 15040 } 15041 } 15042 15043 // A backup agent has just come up 15044 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15045 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15046 + " = " + agent); 15047 15048 synchronized(this) { 15049 if (!agentPackageName.equals(mBackupAppName)) { 15050 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15051 return; 15052 } 15053 } 15054 15055 long oldIdent = Binder.clearCallingIdentity(); 15056 try { 15057 IBackupManager bm = IBackupManager.Stub.asInterface( 15058 ServiceManager.getService(Context.BACKUP_SERVICE)); 15059 bm.agentConnected(agentPackageName, agent); 15060 } catch (RemoteException e) { 15061 // can't happen; the backup manager service is local 15062 } catch (Exception e) { 15063 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15064 e.printStackTrace(); 15065 } finally { 15066 Binder.restoreCallingIdentity(oldIdent); 15067 } 15068 } 15069 15070 // done with this agent 15071 public void unbindBackupAgent(ApplicationInfo appInfo) { 15072 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15073 if (appInfo == null) { 15074 Slog.w(TAG, "unbind backup agent for null app"); 15075 return; 15076 } 15077 15078 synchronized(this) { 15079 try { 15080 if (mBackupAppName == null) { 15081 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15082 return; 15083 } 15084 15085 if (!mBackupAppName.equals(appInfo.packageName)) { 15086 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15087 return; 15088 } 15089 15090 // Not backing this app up any more; reset its OOM adjustment 15091 final ProcessRecord proc = mBackupTarget.app; 15092 updateOomAdjLocked(proc); 15093 15094 // If the app crashed during backup, 'thread' will be null here 15095 if (proc.thread != null) { 15096 try { 15097 proc.thread.scheduleDestroyBackupAgent(appInfo, 15098 compatibilityInfoForPackageLocked(appInfo)); 15099 } catch (Exception e) { 15100 Slog.e(TAG, "Exception when unbinding backup agent:"); 15101 e.printStackTrace(); 15102 } 15103 } 15104 } finally { 15105 mBackupTarget = null; 15106 mBackupAppName = null; 15107 } 15108 } 15109 } 15110 // ========================================================= 15111 // BROADCASTS 15112 // ========================================================= 15113 15114 private final List getStickiesLocked(String action, IntentFilter filter, 15115 List cur, int userId) { 15116 final ContentResolver resolver = mContext.getContentResolver(); 15117 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15118 if (stickies == null) { 15119 return cur; 15120 } 15121 final ArrayList<Intent> list = stickies.get(action); 15122 if (list == null) { 15123 return cur; 15124 } 15125 int N = list.size(); 15126 for (int i=0; i<N; i++) { 15127 Intent intent = list.get(i); 15128 if (filter.match(resolver, intent, true, TAG) >= 0) { 15129 if (cur == null) { 15130 cur = new ArrayList<Intent>(); 15131 } 15132 cur.add(intent); 15133 } 15134 } 15135 return cur; 15136 } 15137 15138 boolean isPendingBroadcastProcessLocked(int pid) { 15139 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15140 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15141 } 15142 15143 void skipPendingBroadcastLocked(int pid) { 15144 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15145 for (BroadcastQueue queue : mBroadcastQueues) { 15146 queue.skipPendingBroadcastLocked(pid); 15147 } 15148 } 15149 15150 // The app just attached; send any pending broadcasts that it should receive 15151 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15152 boolean didSomething = false; 15153 for (BroadcastQueue queue : mBroadcastQueues) { 15154 didSomething |= queue.sendPendingBroadcastsLocked(app); 15155 } 15156 return didSomething; 15157 } 15158 15159 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15160 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15161 enforceNotIsolatedCaller("registerReceiver"); 15162 int callingUid; 15163 int callingPid; 15164 synchronized(this) { 15165 ProcessRecord callerApp = null; 15166 if (caller != null) { 15167 callerApp = getRecordForAppLocked(caller); 15168 if (callerApp == null) { 15169 throw new SecurityException( 15170 "Unable to find app for caller " + caller 15171 + " (pid=" + Binder.getCallingPid() 15172 + ") when registering receiver " + receiver); 15173 } 15174 if (callerApp.info.uid != Process.SYSTEM_UID && 15175 !callerApp.pkgList.containsKey(callerPackage) && 15176 !"android".equals(callerPackage)) { 15177 throw new SecurityException("Given caller package " + callerPackage 15178 + " is not running in process " + callerApp); 15179 } 15180 callingUid = callerApp.info.uid; 15181 callingPid = callerApp.pid; 15182 } else { 15183 callerPackage = null; 15184 callingUid = Binder.getCallingUid(); 15185 callingPid = Binder.getCallingPid(); 15186 } 15187 15188 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15189 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15190 15191 List allSticky = null; 15192 15193 // Look for any matching sticky broadcasts... 15194 Iterator actions = filter.actionsIterator(); 15195 if (actions != null) { 15196 while (actions.hasNext()) { 15197 String action = (String)actions.next(); 15198 allSticky = getStickiesLocked(action, filter, allSticky, 15199 UserHandle.USER_ALL); 15200 allSticky = getStickiesLocked(action, filter, allSticky, 15201 UserHandle.getUserId(callingUid)); 15202 } 15203 } else { 15204 allSticky = getStickiesLocked(null, filter, allSticky, 15205 UserHandle.USER_ALL); 15206 allSticky = getStickiesLocked(null, filter, allSticky, 15207 UserHandle.getUserId(callingUid)); 15208 } 15209 15210 // The first sticky in the list is returned directly back to 15211 // the client. 15212 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15213 15214 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15215 + ": " + sticky); 15216 15217 if (receiver == null) { 15218 return sticky; 15219 } 15220 15221 ReceiverList rl 15222 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15223 if (rl == null) { 15224 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15225 userId, receiver); 15226 if (rl.app != null) { 15227 rl.app.receivers.add(rl); 15228 } else { 15229 try { 15230 receiver.asBinder().linkToDeath(rl, 0); 15231 } catch (RemoteException e) { 15232 return sticky; 15233 } 15234 rl.linkedToDeath = true; 15235 } 15236 mRegisteredReceivers.put(receiver.asBinder(), rl); 15237 } else if (rl.uid != callingUid) { 15238 throw new IllegalArgumentException( 15239 "Receiver requested to register for uid " + callingUid 15240 + " was previously registered for uid " + rl.uid); 15241 } else if (rl.pid != callingPid) { 15242 throw new IllegalArgumentException( 15243 "Receiver requested to register for pid " + callingPid 15244 + " was previously registered for pid " + rl.pid); 15245 } else if (rl.userId != userId) { 15246 throw new IllegalArgumentException( 15247 "Receiver requested to register for user " + userId 15248 + " was previously registered for user " + rl.userId); 15249 } 15250 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15251 permission, callingUid, userId); 15252 rl.add(bf); 15253 if (!bf.debugCheck()) { 15254 Slog.w(TAG, "==> For Dynamic broadast"); 15255 } 15256 mReceiverResolver.addFilter(bf); 15257 15258 // Enqueue broadcasts for all existing stickies that match 15259 // this filter. 15260 if (allSticky != null) { 15261 ArrayList receivers = new ArrayList(); 15262 receivers.add(bf); 15263 15264 int N = allSticky.size(); 15265 for (int i=0; i<N; i++) { 15266 Intent intent = (Intent)allSticky.get(i); 15267 BroadcastQueue queue = broadcastQueueForIntent(intent); 15268 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15269 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15270 null, null, false, true, true, -1); 15271 queue.enqueueParallelBroadcastLocked(r); 15272 queue.scheduleBroadcastsLocked(); 15273 } 15274 } 15275 15276 return sticky; 15277 } 15278 } 15279 15280 public void unregisterReceiver(IIntentReceiver receiver) { 15281 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15282 15283 final long origId = Binder.clearCallingIdentity(); 15284 try { 15285 boolean doTrim = false; 15286 15287 synchronized(this) { 15288 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15289 if (rl != null) { 15290 if (rl.curBroadcast != null) { 15291 BroadcastRecord r = rl.curBroadcast; 15292 final boolean doNext = finishReceiverLocked( 15293 receiver.asBinder(), r.resultCode, r.resultData, 15294 r.resultExtras, r.resultAbort); 15295 if (doNext) { 15296 doTrim = true; 15297 r.queue.processNextBroadcast(false); 15298 } 15299 } 15300 15301 if (rl.app != null) { 15302 rl.app.receivers.remove(rl); 15303 } 15304 removeReceiverLocked(rl); 15305 if (rl.linkedToDeath) { 15306 rl.linkedToDeath = false; 15307 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15308 } 15309 } 15310 } 15311 15312 // If we actually concluded any broadcasts, we might now be able 15313 // to trim the recipients' apps from our working set 15314 if (doTrim) { 15315 trimApplications(); 15316 return; 15317 } 15318 15319 } finally { 15320 Binder.restoreCallingIdentity(origId); 15321 } 15322 } 15323 15324 void removeReceiverLocked(ReceiverList rl) { 15325 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15326 int N = rl.size(); 15327 for (int i=0; i<N; i++) { 15328 mReceiverResolver.removeFilter(rl.get(i)); 15329 } 15330 } 15331 15332 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15334 ProcessRecord r = mLruProcesses.get(i); 15335 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15336 try { 15337 r.thread.dispatchPackageBroadcast(cmd, packages); 15338 } catch (RemoteException ex) { 15339 } 15340 } 15341 } 15342 } 15343 15344 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15345 int callingUid, int[] users) { 15346 List<ResolveInfo> receivers = null; 15347 try { 15348 HashSet<ComponentName> singleUserReceivers = null; 15349 boolean scannedFirstReceivers = false; 15350 for (int user : users) { 15351 // Skip users that have Shell restrictions 15352 if (callingUid == Process.SHELL_UID 15353 && getUserManagerLocked().hasUserRestriction( 15354 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15355 continue; 15356 } 15357 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15358 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15359 if (user != 0 && newReceivers != null) { 15360 // If this is not the primary user, we need to check for 15361 // any receivers that should be filtered out. 15362 for (int i=0; i<newReceivers.size(); i++) { 15363 ResolveInfo ri = newReceivers.get(i); 15364 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15365 newReceivers.remove(i); 15366 i--; 15367 } 15368 } 15369 } 15370 if (newReceivers != null && newReceivers.size() == 0) { 15371 newReceivers = null; 15372 } 15373 if (receivers == null) { 15374 receivers = newReceivers; 15375 } else if (newReceivers != null) { 15376 // We need to concatenate the additional receivers 15377 // found with what we have do far. This would be easy, 15378 // but we also need to de-dup any receivers that are 15379 // singleUser. 15380 if (!scannedFirstReceivers) { 15381 // Collect any single user receivers we had already retrieved. 15382 scannedFirstReceivers = true; 15383 for (int i=0; i<receivers.size(); i++) { 15384 ResolveInfo ri = receivers.get(i); 15385 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15386 ComponentName cn = new ComponentName( 15387 ri.activityInfo.packageName, ri.activityInfo.name); 15388 if (singleUserReceivers == null) { 15389 singleUserReceivers = new HashSet<ComponentName>(); 15390 } 15391 singleUserReceivers.add(cn); 15392 } 15393 } 15394 } 15395 // Add the new results to the existing results, tracking 15396 // and de-dupping single user receivers. 15397 for (int i=0; i<newReceivers.size(); i++) { 15398 ResolveInfo ri = newReceivers.get(i); 15399 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15400 ComponentName cn = new ComponentName( 15401 ri.activityInfo.packageName, ri.activityInfo.name); 15402 if (singleUserReceivers == null) { 15403 singleUserReceivers = new HashSet<ComponentName>(); 15404 } 15405 if (!singleUserReceivers.contains(cn)) { 15406 singleUserReceivers.add(cn); 15407 receivers.add(ri); 15408 } 15409 } else { 15410 receivers.add(ri); 15411 } 15412 } 15413 } 15414 } 15415 } catch (RemoteException ex) { 15416 // pm is in same process, this will never happen. 15417 } 15418 return receivers; 15419 } 15420 15421 private final int broadcastIntentLocked(ProcessRecord callerApp, 15422 String callerPackage, Intent intent, String resolvedType, 15423 IIntentReceiver resultTo, int resultCode, String resultData, 15424 Bundle map, String requiredPermission, int appOp, 15425 boolean ordered, boolean sticky, int callingPid, int callingUid, 15426 int userId) { 15427 intent = new Intent(intent); 15428 15429 // By default broadcasts do not go to stopped apps. 15430 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15431 15432 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15433 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15434 + " ordered=" + ordered + " userid=" + userId); 15435 if ((resultTo != null) && !ordered) { 15436 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15437 } 15438 15439 userId = handleIncomingUser(callingPid, callingUid, userId, 15440 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15441 15442 // Make sure that the user who is receiving this broadcast is started. 15443 // If not, we will just skip it. 15444 15445 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15446 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15447 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15448 Slog.w(TAG, "Skipping broadcast of " + intent 15449 + ": user " + userId + " is stopped"); 15450 return ActivityManager.BROADCAST_SUCCESS; 15451 } 15452 } 15453 15454 /* 15455 * Prevent non-system code (defined here to be non-persistent 15456 * processes) from sending protected broadcasts. 15457 */ 15458 int callingAppId = UserHandle.getAppId(callingUid); 15459 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15460 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15461 || callingAppId == Process.NFC_UID || callingUid == 0) { 15462 // Always okay. 15463 } else if (callerApp == null || !callerApp.persistent) { 15464 try { 15465 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15466 intent.getAction())) { 15467 String msg = "Permission Denial: not allowed to send broadcast " 15468 + intent.getAction() + " from pid=" 15469 + callingPid + ", uid=" + callingUid; 15470 Slog.w(TAG, msg); 15471 throw new SecurityException(msg); 15472 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15473 // Special case for compatibility: we don't want apps to send this, 15474 // but historically it has not been protected and apps may be using it 15475 // to poke their own app widget. So, instead of making it protected, 15476 // just limit it to the caller. 15477 if (callerApp == null) { 15478 String msg = "Permission Denial: not allowed to send broadcast " 15479 + intent.getAction() + " from unknown caller."; 15480 Slog.w(TAG, msg); 15481 throw new SecurityException(msg); 15482 } else if (intent.getComponent() != null) { 15483 // They are good enough to send to an explicit component... verify 15484 // it is being sent to the calling app. 15485 if (!intent.getComponent().getPackageName().equals( 15486 callerApp.info.packageName)) { 15487 String msg = "Permission Denial: not allowed to send broadcast " 15488 + intent.getAction() + " to " 15489 + intent.getComponent().getPackageName() + " from " 15490 + callerApp.info.packageName; 15491 Slog.w(TAG, msg); 15492 throw new SecurityException(msg); 15493 } 15494 } else { 15495 // Limit broadcast to their own package. 15496 intent.setPackage(callerApp.info.packageName); 15497 } 15498 } 15499 } catch (RemoteException e) { 15500 Slog.w(TAG, "Remote exception", e); 15501 return ActivityManager.BROADCAST_SUCCESS; 15502 } 15503 } 15504 15505 // Handle special intents: if this broadcast is from the package 15506 // manager about a package being removed, we need to remove all of 15507 // its activities from the history stack. 15508 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15509 intent.getAction()); 15510 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15511 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15512 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15513 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15514 || uidRemoved) { 15515 if (checkComponentPermission( 15516 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15517 callingPid, callingUid, -1, true) 15518 == PackageManager.PERMISSION_GRANTED) { 15519 if (uidRemoved) { 15520 final Bundle intentExtras = intent.getExtras(); 15521 final int uid = intentExtras != null 15522 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15523 if (uid >= 0) { 15524 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15525 synchronized (bs) { 15526 bs.removeUidStatsLocked(uid); 15527 } 15528 mAppOpsService.uidRemoved(uid); 15529 } 15530 } else { 15531 // If resources are unavailable just force stop all 15532 // those packages and flush the attribute cache as well. 15533 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15534 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15535 if (list != null && (list.length > 0)) { 15536 for (String pkg : list) { 15537 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15538 "storage unmount"); 15539 } 15540 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15541 sendPackageBroadcastLocked( 15542 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15543 } 15544 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15545 intent.getAction())) { 15546 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15547 } else { 15548 Uri data = intent.getData(); 15549 String ssp; 15550 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15551 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15552 intent.getAction()); 15553 boolean fullUninstall = removed && 15554 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15555 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15556 forceStopPackageLocked(ssp, UserHandle.getAppId( 15557 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15558 false, fullUninstall, userId, 15559 removed ? "pkg removed" : "pkg changed"); 15560 } 15561 if (removed) { 15562 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15563 new String[] {ssp}, userId); 15564 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15565 mAppOpsService.packageRemoved( 15566 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15567 15568 // Remove all permissions granted from/to this package 15569 removeUriPermissionsForPackageLocked(ssp, userId, true); 15570 } 15571 } 15572 } 15573 } 15574 } 15575 } else { 15576 String msg = "Permission Denial: " + intent.getAction() 15577 + " broadcast from " + callerPackage + " (pid=" + callingPid 15578 + ", uid=" + callingUid + ")" 15579 + " requires " 15580 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15581 Slog.w(TAG, msg); 15582 throw new SecurityException(msg); 15583 } 15584 15585 // Special case for adding a package: by default turn on compatibility 15586 // mode. 15587 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15588 Uri data = intent.getData(); 15589 String ssp; 15590 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15591 mCompatModePackages.handlePackageAddedLocked(ssp, 15592 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15593 } 15594 } 15595 15596 /* 15597 * If this is the time zone changed action, queue up a message that will reset the timezone 15598 * of all currently running processes. This message will get queued up before the broadcast 15599 * happens. 15600 */ 15601 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15602 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15603 } 15604 15605 /* 15606 * If the user set the time, let all running processes know. 15607 */ 15608 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15609 final int is24Hour = intent.getBooleanExtra( 15610 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15611 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15612 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15613 synchronized (stats) { 15614 stats.noteCurrentTimeChangedLocked(); 15615 } 15616 } 15617 15618 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15619 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15620 } 15621 15622 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15623 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15624 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15625 } 15626 15627 // Add to the sticky list if requested. 15628 if (sticky) { 15629 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15630 callingPid, callingUid) 15631 != PackageManager.PERMISSION_GRANTED) { 15632 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15633 + callingPid + ", uid=" + callingUid 15634 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15635 Slog.w(TAG, msg); 15636 throw new SecurityException(msg); 15637 } 15638 if (requiredPermission != null) { 15639 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15640 + " and enforce permission " + requiredPermission); 15641 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15642 } 15643 if (intent.getComponent() != null) { 15644 throw new SecurityException( 15645 "Sticky broadcasts can't target a specific component"); 15646 } 15647 // We use userId directly here, since the "all" target is maintained 15648 // as a separate set of sticky broadcasts. 15649 if (userId != UserHandle.USER_ALL) { 15650 // But first, if this is not a broadcast to all users, then 15651 // make sure it doesn't conflict with an existing broadcast to 15652 // all users. 15653 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15654 UserHandle.USER_ALL); 15655 if (stickies != null) { 15656 ArrayList<Intent> list = stickies.get(intent.getAction()); 15657 if (list != null) { 15658 int N = list.size(); 15659 int i; 15660 for (i=0; i<N; i++) { 15661 if (intent.filterEquals(list.get(i))) { 15662 throw new IllegalArgumentException( 15663 "Sticky broadcast " + intent + " for user " 15664 + userId + " conflicts with existing global broadcast"); 15665 } 15666 } 15667 } 15668 } 15669 } 15670 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15671 if (stickies == null) { 15672 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15673 mStickyBroadcasts.put(userId, stickies); 15674 } 15675 ArrayList<Intent> list = stickies.get(intent.getAction()); 15676 if (list == null) { 15677 list = new ArrayList<Intent>(); 15678 stickies.put(intent.getAction(), list); 15679 } 15680 int N = list.size(); 15681 int i; 15682 for (i=0; i<N; i++) { 15683 if (intent.filterEquals(list.get(i))) { 15684 // This sticky already exists, replace it. 15685 list.set(i, new Intent(intent)); 15686 break; 15687 } 15688 } 15689 if (i >= N) { 15690 list.add(new Intent(intent)); 15691 } 15692 } 15693 15694 int[] users; 15695 if (userId == UserHandle.USER_ALL) { 15696 // Caller wants broadcast to go to all started users. 15697 users = mStartedUserArray; 15698 } else { 15699 // Caller wants broadcast to go to one specific user. 15700 users = new int[] {userId}; 15701 } 15702 15703 // Figure out who all will receive this broadcast. 15704 List receivers = null; 15705 List<BroadcastFilter> registeredReceivers = null; 15706 // Need to resolve the intent to interested receivers... 15707 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15708 == 0) { 15709 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15710 } 15711 if (intent.getComponent() == null) { 15712 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15713 // Query one target user at a time, excluding shell-restricted users 15714 UserManagerService ums = getUserManagerLocked(); 15715 for (int i = 0; i < users.length; i++) { 15716 if (ums.hasUserRestriction( 15717 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15718 continue; 15719 } 15720 List<BroadcastFilter> registeredReceiversForUser = 15721 mReceiverResolver.queryIntent(intent, 15722 resolvedType, false, users[i]); 15723 if (registeredReceivers == null) { 15724 registeredReceivers = registeredReceiversForUser; 15725 } else if (registeredReceiversForUser != null) { 15726 registeredReceivers.addAll(registeredReceiversForUser); 15727 } 15728 } 15729 } else { 15730 registeredReceivers = mReceiverResolver.queryIntent(intent, 15731 resolvedType, false, userId); 15732 } 15733 } 15734 15735 final boolean replacePending = 15736 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15737 15738 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15739 + " replacePending=" + replacePending); 15740 15741 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15742 if (!ordered && NR > 0) { 15743 // If we are not serializing this broadcast, then send the 15744 // registered receivers separately so they don't wait for the 15745 // components to be launched. 15746 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15747 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15748 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15749 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15750 ordered, sticky, false, userId); 15751 if (DEBUG_BROADCAST) Slog.v( 15752 TAG, "Enqueueing parallel broadcast " + r); 15753 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15754 if (!replaced) { 15755 queue.enqueueParallelBroadcastLocked(r); 15756 queue.scheduleBroadcastsLocked(); 15757 } 15758 registeredReceivers = null; 15759 NR = 0; 15760 } 15761 15762 // Merge into one list. 15763 int ir = 0; 15764 if (receivers != null) { 15765 // A special case for PACKAGE_ADDED: do not allow the package 15766 // being added to see this broadcast. This prevents them from 15767 // using this as a back door to get run as soon as they are 15768 // installed. Maybe in the future we want to have a special install 15769 // broadcast or such for apps, but we'd like to deliberately make 15770 // this decision. 15771 String skipPackages[] = null; 15772 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15773 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15774 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15775 Uri data = intent.getData(); 15776 if (data != null) { 15777 String pkgName = data.getSchemeSpecificPart(); 15778 if (pkgName != null) { 15779 skipPackages = new String[] { pkgName }; 15780 } 15781 } 15782 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15783 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15784 } 15785 if (skipPackages != null && (skipPackages.length > 0)) { 15786 for (String skipPackage : skipPackages) { 15787 if (skipPackage != null) { 15788 int NT = receivers.size(); 15789 for (int it=0; it<NT; it++) { 15790 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15791 if (curt.activityInfo.packageName.equals(skipPackage)) { 15792 receivers.remove(it); 15793 it--; 15794 NT--; 15795 } 15796 } 15797 } 15798 } 15799 } 15800 15801 int NT = receivers != null ? receivers.size() : 0; 15802 int it = 0; 15803 ResolveInfo curt = null; 15804 BroadcastFilter curr = null; 15805 while (it < NT && ir < NR) { 15806 if (curt == null) { 15807 curt = (ResolveInfo)receivers.get(it); 15808 } 15809 if (curr == null) { 15810 curr = registeredReceivers.get(ir); 15811 } 15812 if (curr.getPriority() >= curt.priority) { 15813 // Insert this broadcast record into the final list. 15814 receivers.add(it, curr); 15815 ir++; 15816 curr = null; 15817 it++; 15818 NT++; 15819 } else { 15820 // Skip to the next ResolveInfo in the final list. 15821 it++; 15822 curt = null; 15823 } 15824 } 15825 } 15826 while (ir < NR) { 15827 if (receivers == null) { 15828 receivers = new ArrayList(); 15829 } 15830 receivers.add(registeredReceivers.get(ir)); 15831 ir++; 15832 } 15833 15834 if ((receivers != null && receivers.size() > 0) 15835 || resultTo != null) { 15836 BroadcastQueue queue = broadcastQueueForIntent(intent); 15837 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15838 callerPackage, callingPid, callingUid, resolvedType, 15839 requiredPermission, appOp, receivers, resultTo, resultCode, 15840 resultData, map, ordered, sticky, false, userId); 15841 if (DEBUG_BROADCAST) Slog.v( 15842 TAG, "Enqueueing ordered broadcast " + r 15843 + ": prev had " + queue.mOrderedBroadcasts.size()); 15844 if (DEBUG_BROADCAST) { 15845 int seq = r.intent.getIntExtra("seq", -1); 15846 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15847 } 15848 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15849 if (!replaced) { 15850 queue.enqueueOrderedBroadcastLocked(r); 15851 queue.scheduleBroadcastsLocked(); 15852 } 15853 } 15854 15855 return ActivityManager.BROADCAST_SUCCESS; 15856 } 15857 15858 final Intent verifyBroadcastLocked(Intent intent) { 15859 // Refuse possible leaked file descriptors 15860 if (intent != null && intent.hasFileDescriptors() == true) { 15861 throw new IllegalArgumentException("File descriptors passed in Intent"); 15862 } 15863 15864 int flags = intent.getFlags(); 15865 15866 if (!mProcessesReady) { 15867 // if the caller really truly claims to know what they're doing, go 15868 // ahead and allow the broadcast without launching any receivers 15869 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15870 intent = new Intent(intent); 15871 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15872 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15873 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15874 + " before boot completion"); 15875 throw new IllegalStateException("Cannot broadcast before boot completed"); 15876 } 15877 } 15878 15879 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15880 throw new IllegalArgumentException( 15881 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15882 } 15883 15884 return intent; 15885 } 15886 15887 public final int broadcastIntent(IApplicationThread caller, 15888 Intent intent, String resolvedType, IIntentReceiver resultTo, 15889 int resultCode, String resultData, Bundle map, 15890 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15891 enforceNotIsolatedCaller("broadcastIntent"); 15892 synchronized(this) { 15893 intent = verifyBroadcastLocked(intent); 15894 15895 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15896 final int callingPid = Binder.getCallingPid(); 15897 final int callingUid = Binder.getCallingUid(); 15898 final long origId = Binder.clearCallingIdentity(); 15899 int res = broadcastIntentLocked(callerApp, 15900 callerApp != null ? callerApp.info.packageName : null, 15901 intent, resolvedType, resultTo, 15902 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15903 callingPid, callingUid, userId); 15904 Binder.restoreCallingIdentity(origId); 15905 return res; 15906 } 15907 } 15908 15909 int broadcastIntentInPackage(String packageName, int uid, 15910 Intent intent, String resolvedType, IIntentReceiver resultTo, 15911 int resultCode, String resultData, Bundle map, 15912 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15913 synchronized(this) { 15914 intent = verifyBroadcastLocked(intent); 15915 15916 final long origId = Binder.clearCallingIdentity(); 15917 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15918 resultTo, resultCode, resultData, map, requiredPermission, 15919 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15920 Binder.restoreCallingIdentity(origId); 15921 return res; 15922 } 15923 } 15924 15925 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15926 // Refuse possible leaked file descriptors 15927 if (intent != null && intent.hasFileDescriptors() == true) { 15928 throw new IllegalArgumentException("File descriptors passed in Intent"); 15929 } 15930 15931 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15932 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15933 15934 synchronized(this) { 15935 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15936 != PackageManager.PERMISSION_GRANTED) { 15937 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15938 + Binder.getCallingPid() 15939 + ", uid=" + Binder.getCallingUid() 15940 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15941 Slog.w(TAG, msg); 15942 throw new SecurityException(msg); 15943 } 15944 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15945 if (stickies != null) { 15946 ArrayList<Intent> list = stickies.get(intent.getAction()); 15947 if (list != null) { 15948 int N = list.size(); 15949 int i; 15950 for (i=0; i<N; i++) { 15951 if (intent.filterEquals(list.get(i))) { 15952 list.remove(i); 15953 break; 15954 } 15955 } 15956 if (list.size() <= 0) { 15957 stickies.remove(intent.getAction()); 15958 } 15959 } 15960 if (stickies.size() <= 0) { 15961 mStickyBroadcasts.remove(userId); 15962 } 15963 } 15964 } 15965 } 15966 15967 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15968 String resultData, Bundle resultExtras, boolean resultAbort) { 15969 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15970 if (r == null) { 15971 Slog.w(TAG, "finishReceiver called but not found on queue"); 15972 return false; 15973 } 15974 15975 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15976 } 15977 15978 void backgroundServicesFinishedLocked(int userId) { 15979 for (BroadcastQueue queue : mBroadcastQueues) { 15980 queue.backgroundServicesFinishedLocked(userId); 15981 } 15982 } 15983 15984 public void finishReceiver(IBinder who, int resultCode, String resultData, 15985 Bundle resultExtras, boolean resultAbort) { 15986 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15987 15988 // Refuse possible leaked file descriptors 15989 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15990 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15991 } 15992 15993 final long origId = Binder.clearCallingIdentity(); 15994 try { 15995 boolean doNext = false; 15996 BroadcastRecord r; 15997 15998 synchronized(this) { 15999 r = broadcastRecordForReceiverLocked(who); 16000 if (r != null) { 16001 doNext = r.queue.finishReceiverLocked(r, resultCode, 16002 resultData, resultExtras, resultAbort, true); 16003 } 16004 } 16005 16006 if (doNext) { 16007 r.queue.processNextBroadcast(false); 16008 } 16009 trimApplications(); 16010 } finally { 16011 Binder.restoreCallingIdentity(origId); 16012 } 16013 } 16014 16015 // ========================================================= 16016 // INSTRUMENTATION 16017 // ========================================================= 16018 16019 public boolean startInstrumentation(ComponentName className, 16020 String profileFile, int flags, Bundle arguments, 16021 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16022 int userId, String abiOverride) { 16023 enforceNotIsolatedCaller("startInstrumentation"); 16024 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16025 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16026 // Refuse possible leaked file descriptors 16027 if (arguments != null && arguments.hasFileDescriptors()) { 16028 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16029 } 16030 16031 synchronized(this) { 16032 InstrumentationInfo ii = null; 16033 ApplicationInfo ai = null; 16034 try { 16035 ii = mContext.getPackageManager().getInstrumentationInfo( 16036 className, STOCK_PM_FLAGS); 16037 ai = AppGlobals.getPackageManager().getApplicationInfo( 16038 ii.targetPackage, STOCK_PM_FLAGS, userId); 16039 } catch (PackageManager.NameNotFoundException e) { 16040 } catch (RemoteException e) { 16041 } 16042 if (ii == null) { 16043 reportStartInstrumentationFailure(watcher, className, 16044 "Unable to find instrumentation info for: " + className); 16045 return false; 16046 } 16047 if (ai == null) { 16048 reportStartInstrumentationFailure(watcher, className, 16049 "Unable to find instrumentation target package: " + ii.targetPackage); 16050 return false; 16051 } 16052 16053 int match = mContext.getPackageManager().checkSignatures( 16054 ii.targetPackage, ii.packageName); 16055 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16056 String msg = "Permission Denial: starting instrumentation " 16057 + className + " from pid=" 16058 + Binder.getCallingPid() 16059 + ", uid=" + Binder.getCallingPid() 16060 + " not allowed because package " + ii.packageName 16061 + " does not have a signature matching the target " 16062 + ii.targetPackage; 16063 reportStartInstrumentationFailure(watcher, className, msg); 16064 throw new SecurityException(msg); 16065 } 16066 16067 final long origId = Binder.clearCallingIdentity(); 16068 // Instrumentation can kill and relaunch even persistent processes 16069 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16070 "start instr"); 16071 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16072 app.instrumentationClass = className; 16073 app.instrumentationInfo = ai; 16074 app.instrumentationProfileFile = profileFile; 16075 app.instrumentationArguments = arguments; 16076 app.instrumentationWatcher = watcher; 16077 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16078 app.instrumentationResultClass = className; 16079 Binder.restoreCallingIdentity(origId); 16080 } 16081 16082 return true; 16083 } 16084 16085 /** 16086 * Report errors that occur while attempting to start Instrumentation. Always writes the 16087 * error to the logs, but if somebody is watching, send the report there too. This enables 16088 * the "am" command to report errors with more information. 16089 * 16090 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16091 * @param cn The component name of the instrumentation. 16092 * @param report The error report. 16093 */ 16094 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16095 ComponentName cn, String report) { 16096 Slog.w(TAG, report); 16097 try { 16098 if (watcher != null) { 16099 Bundle results = new Bundle(); 16100 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16101 results.putString("Error", report); 16102 watcher.instrumentationStatus(cn, -1, results); 16103 } 16104 } catch (RemoteException e) { 16105 Slog.w(TAG, e); 16106 } 16107 } 16108 16109 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16110 if (app.instrumentationWatcher != null) { 16111 try { 16112 // NOTE: IInstrumentationWatcher *must* be oneway here 16113 app.instrumentationWatcher.instrumentationFinished( 16114 app.instrumentationClass, 16115 resultCode, 16116 results); 16117 } catch (RemoteException e) { 16118 } 16119 } 16120 if (app.instrumentationUiAutomationConnection != null) { 16121 try { 16122 app.instrumentationUiAutomationConnection.shutdown(); 16123 } catch (RemoteException re) { 16124 /* ignore */ 16125 } 16126 // Only a UiAutomation can set this flag and now that 16127 // it is finished we make sure it is reset to its default. 16128 mUserIsMonkey = false; 16129 } 16130 app.instrumentationWatcher = null; 16131 app.instrumentationUiAutomationConnection = null; 16132 app.instrumentationClass = null; 16133 app.instrumentationInfo = null; 16134 app.instrumentationProfileFile = null; 16135 app.instrumentationArguments = null; 16136 16137 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16138 "finished inst"); 16139 } 16140 16141 public void finishInstrumentation(IApplicationThread target, 16142 int resultCode, Bundle results) { 16143 int userId = UserHandle.getCallingUserId(); 16144 // Refuse possible leaked file descriptors 16145 if (results != null && results.hasFileDescriptors()) { 16146 throw new IllegalArgumentException("File descriptors passed in Intent"); 16147 } 16148 16149 synchronized(this) { 16150 ProcessRecord app = getRecordForAppLocked(target); 16151 if (app == null) { 16152 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16153 return; 16154 } 16155 final long origId = Binder.clearCallingIdentity(); 16156 finishInstrumentationLocked(app, resultCode, results); 16157 Binder.restoreCallingIdentity(origId); 16158 } 16159 } 16160 16161 // ========================================================= 16162 // CONFIGURATION 16163 // ========================================================= 16164 16165 public ConfigurationInfo getDeviceConfigurationInfo() { 16166 ConfigurationInfo config = new ConfigurationInfo(); 16167 synchronized (this) { 16168 config.reqTouchScreen = mConfiguration.touchscreen; 16169 config.reqKeyboardType = mConfiguration.keyboard; 16170 config.reqNavigation = mConfiguration.navigation; 16171 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16172 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16173 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16174 } 16175 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16176 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16177 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16178 } 16179 config.reqGlEsVersion = GL_ES_VERSION; 16180 } 16181 return config; 16182 } 16183 16184 ActivityStack getFocusedStack() { 16185 return mStackSupervisor.getFocusedStack(); 16186 } 16187 16188 public Configuration getConfiguration() { 16189 Configuration ci; 16190 synchronized(this) { 16191 ci = new Configuration(mConfiguration); 16192 } 16193 return ci; 16194 } 16195 16196 public void updatePersistentConfiguration(Configuration values) { 16197 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16198 "updateConfiguration()"); 16199 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16200 "updateConfiguration()"); 16201 if (values == null) { 16202 throw new NullPointerException("Configuration must not be null"); 16203 } 16204 16205 synchronized(this) { 16206 final long origId = Binder.clearCallingIdentity(); 16207 updateConfigurationLocked(values, null, true, false); 16208 Binder.restoreCallingIdentity(origId); 16209 } 16210 } 16211 16212 public void updateConfiguration(Configuration values) { 16213 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16214 "updateConfiguration()"); 16215 16216 synchronized(this) { 16217 if (values == null && mWindowManager != null) { 16218 // sentinel: fetch the current configuration from the window manager 16219 values = mWindowManager.computeNewConfiguration(); 16220 } 16221 16222 if (mWindowManager != null) { 16223 mProcessList.applyDisplaySize(mWindowManager); 16224 } 16225 16226 final long origId = Binder.clearCallingIdentity(); 16227 if (values != null) { 16228 Settings.System.clearConfiguration(values); 16229 } 16230 updateConfigurationLocked(values, null, false, false); 16231 Binder.restoreCallingIdentity(origId); 16232 } 16233 } 16234 16235 /** 16236 * Do either or both things: (1) change the current configuration, and (2) 16237 * make sure the given activity is running with the (now) current 16238 * configuration. Returns true if the activity has been left running, or 16239 * false if <var>starting</var> is being destroyed to match the new 16240 * configuration. 16241 * @param persistent TODO 16242 */ 16243 boolean updateConfigurationLocked(Configuration values, 16244 ActivityRecord starting, boolean persistent, boolean initLocale) { 16245 int changes = 0; 16246 16247 if (values != null) { 16248 Configuration newConfig = new Configuration(mConfiguration); 16249 changes = newConfig.updateFrom(values); 16250 if (changes != 0) { 16251 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16252 Slog.i(TAG, "Updating configuration to: " + values); 16253 } 16254 16255 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16256 16257 if (values.locale != null && !initLocale) { 16258 saveLocaleLocked(values.locale, 16259 !values.locale.equals(mConfiguration.locale), 16260 values.userSetLocale); 16261 } 16262 16263 mConfigurationSeq++; 16264 if (mConfigurationSeq <= 0) { 16265 mConfigurationSeq = 1; 16266 } 16267 newConfig.seq = mConfigurationSeq; 16268 mConfiguration = newConfig; 16269 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16270 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16271 //mUsageStatsService.noteStartConfig(newConfig); 16272 16273 final Configuration configCopy = new Configuration(mConfiguration); 16274 16275 // TODO: If our config changes, should we auto dismiss any currently 16276 // showing dialogs? 16277 mShowDialogs = shouldShowDialogs(newConfig); 16278 16279 AttributeCache ac = AttributeCache.instance(); 16280 if (ac != null) { 16281 ac.updateConfiguration(configCopy); 16282 } 16283 16284 // Make sure all resources in our process are updated 16285 // right now, so that anyone who is going to retrieve 16286 // resource values after we return will be sure to get 16287 // the new ones. This is especially important during 16288 // boot, where the first config change needs to guarantee 16289 // all resources have that config before following boot 16290 // code is executed. 16291 mSystemThread.applyConfigurationToResources(configCopy); 16292 16293 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16294 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16295 msg.obj = new Configuration(configCopy); 16296 mHandler.sendMessage(msg); 16297 } 16298 16299 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16300 ProcessRecord app = mLruProcesses.get(i); 16301 try { 16302 if (app.thread != null) { 16303 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16304 + app.processName + " new config " + mConfiguration); 16305 app.thread.scheduleConfigurationChanged(configCopy); 16306 } 16307 } catch (Exception e) { 16308 } 16309 } 16310 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16311 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16312 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16313 | Intent.FLAG_RECEIVER_FOREGROUND); 16314 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16315 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16316 Process.SYSTEM_UID, UserHandle.USER_ALL); 16317 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16318 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16319 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16320 broadcastIntentLocked(null, null, intent, 16321 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16322 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16323 } 16324 } 16325 } 16326 16327 boolean kept = true; 16328 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16329 // mainStack is null during startup. 16330 if (mainStack != null) { 16331 if (changes != 0 && starting == null) { 16332 // If the configuration changed, and the caller is not already 16333 // in the process of starting an activity, then find the top 16334 // activity to check if its configuration needs to change. 16335 starting = mainStack.topRunningActivityLocked(null); 16336 } 16337 16338 if (starting != null) { 16339 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16340 // And we need to make sure at this point that all other activities 16341 // are made visible with the correct configuration. 16342 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16343 } 16344 } 16345 16346 if (values != null && mWindowManager != null) { 16347 mWindowManager.setNewConfiguration(mConfiguration); 16348 } 16349 16350 return kept; 16351 } 16352 16353 /** 16354 * Decide based on the configuration whether we should shouw the ANR, 16355 * crash, etc dialogs. The idea is that if there is no affordnace to 16356 * press the on-screen buttons, we shouldn't show the dialog. 16357 * 16358 * A thought: SystemUI might also want to get told about this, the Power 16359 * dialog / global actions also might want different behaviors. 16360 */ 16361 private static final boolean shouldShowDialogs(Configuration config) { 16362 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16363 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16364 } 16365 16366 /** 16367 * Save the locale. You must be inside a synchronized (this) block. 16368 */ 16369 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16370 if(isDiff) { 16371 SystemProperties.set("user.language", l.getLanguage()); 16372 SystemProperties.set("user.region", l.getCountry()); 16373 } 16374 16375 if(isPersist) { 16376 SystemProperties.set("persist.sys.language", l.getLanguage()); 16377 SystemProperties.set("persist.sys.country", l.getCountry()); 16378 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16379 16380 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16381 } 16382 } 16383 16384 @Override 16385 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16386 synchronized (this) { 16387 ActivityRecord srec = ActivityRecord.forToken(token); 16388 if (srec.task != null && srec.task.stack != null) { 16389 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16390 } 16391 } 16392 return false; 16393 } 16394 16395 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16396 Intent resultData) { 16397 16398 synchronized (this) { 16399 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16400 if (stack != null) { 16401 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16402 } 16403 return false; 16404 } 16405 } 16406 16407 public int getLaunchedFromUid(IBinder activityToken) { 16408 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16409 if (srec == null) { 16410 return -1; 16411 } 16412 return srec.launchedFromUid; 16413 } 16414 16415 public String getLaunchedFromPackage(IBinder activityToken) { 16416 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16417 if (srec == null) { 16418 return null; 16419 } 16420 return srec.launchedFromPackage; 16421 } 16422 16423 // ========================================================= 16424 // LIFETIME MANAGEMENT 16425 // ========================================================= 16426 16427 // Returns which broadcast queue the app is the current [or imminent] receiver 16428 // on, or 'null' if the app is not an active broadcast recipient. 16429 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16430 BroadcastRecord r = app.curReceiver; 16431 if (r != null) { 16432 return r.queue; 16433 } 16434 16435 // It's not the current receiver, but it might be starting up to become one 16436 synchronized (this) { 16437 for (BroadcastQueue queue : mBroadcastQueues) { 16438 r = queue.mPendingBroadcast; 16439 if (r != null && r.curApp == app) { 16440 // found it; report which queue it's in 16441 return queue; 16442 } 16443 } 16444 } 16445 16446 return null; 16447 } 16448 16449 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16450 boolean doingAll, long now) { 16451 if (mAdjSeq == app.adjSeq) { 16452 // This adjustment has already been computed. 16453 return app.curRawAdj; 16454 } 16455 16456 if (app.thread == null) { 16457 app.adjSeq = mAdjSeq; 16458 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16459 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16460 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16461 } 16462 16463 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16464 app.adjSource = null; 16465 app.adjTarget = null; 16466 app.empty = false; 16467 app.cached = false; 16468 16469 final int activitiesSize = app.activities.size(); 16470 16471 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16472 // The max adjustment doesn't allow this app to be anything 16473 // below foreground, so it is not worth doing work for it. 16474 app.adjType = "fixed"; 16475 app.adjSeq = mAdjSeq; 16476 app.curRawAdj = app.maxAdj; 16477 app.foregroundActivities = false; 16478 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16479 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16480 // System processes can do UI, and when they do we want to have 16481 // them trim their memory after the user leaves the UI. To 16482 // facilitate this, here we need to determine whether or not it 16483 // is currently showing UI. 16484 app.systemNoUi = true; 16485 if (app == TOP_APP) { 16486 app.systemNoUi = false; 16487 } else if (activitiesSize > 0) { 16488 for (int j = 0; j < activitiesSize; j++) { 16489 final ActivityRecord r = app.activities.get(j); 16490 if (r.visible) { 16491 app.systemNoUi = false; 16492 } 16493 } 16494 } 16495 if (!app.systemNoUi) { 16496 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16497 } 16498 return (app.curAdj=app.maxAdj); 16499 } 16500 16501 app.systemNoUi = false; 16502 16503 // Determine the importance of the process, starting with most 16504 // important to least, and assign an appropriate OOM adjustment. 16505 int adj; 16506 int schedGroup; 16507 int procState; 16508 boolean foregroundActivities = false; 16509 BroadcastQueue queue; 16510 if (app == TOP_APP) { 16511 // The last app on the list is the foreground app. 16512 adj = ProcessList.FOREGROUND_APP_ADJ; 16513 schedGroup = Process.THREAD_GROUP_DEFAULT; 16514 app.adjType = "top-activity"; 16515 foregroundActivities = true; 16516 procState = ActivityManager.PROCESS_STATE_TOP; 16517 } else if (app.instrumentationClass != null) { 16518 // Don't want to kill running instrumentation. 16519 adj = ProcessList.FOREGROUND_APP_ADJ; 16520 schedGroup = Process.THREAD_GROUP_DEFAULT; 16521 app.adjType = "instrumentation"; 16522 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16523 } else if ((queue = isReceivingBroadcast(app)) != null) { 16524 // An app that is currently receiving a broadcast also 16525 // counts as being in the foreground for OOM killer purposes. 16526 // It's placed in a sched group based on the nature of the 16527 // broadcast as reflected by which queue it's active in. 16528 adj = ProcessList.FOREGROUND_APP_ADJ; 16529 schedGroup = (queue == mFgBroadcastQueue) 16530 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16531 app.adjType = "broadcast"; 16532 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16533 } else if (app.executingServices.size() > 0) { 16534 // An app that is currently executing a service callback also 16535 // counts as being in the foreground. 16536 adj = ProcessList.FOREGROUND_APP_ADJ; 16537 schedGroup = app.execServicesFg ? 16538 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16539 app.adjType = "exec-service"; 16540 procState = ActivityManager.PROCESS_STATE_SERVICE; 16541 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16542 } else { 16543 // As far as we know the process is empty. We may change our mind later. 16544 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16545 // At this point we don't actually know the adjustment. Use the cached adj 16546 // value that the caller wants us to. 16547 adj = cachedAdj; 16548 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16549 app.cached = true; 16550 app.empty = true; 16551 app.adjType = "cch-empty"; 16552 } 16553 16554 // Examine all activities if not already foreground. 16555 if (!foregroundActivities && activitiesSize > 0) { 16556 for (int j = 0; j < activitiesSize; j++) { 16557 final ActivityRecord r = app.activities.get(j); 16558 if (r.app != app) { 16559 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16560 + app + "?!?"); 16561 continue; 16562 } 16563 if (r.visible) { 16564 // App has a visible activity; only upgrade adjustment. 16565 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16566 adj = ProcessList.VISIBLE_APP_ADJ; 16567 app.adjType = "visible"; 16568 } 16569 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16570 procState = ActivityManager.PROCESS_STATE_TOP; 16571 } 16572 schedGroup = Process.THREAD_GROUP_DEFAULT; 16573 app.cached = false; 16574 app.empty = false; 16575 foregroundActivities = true; 16576 break; 16577 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16578 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16579 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16580 app.adjType = "pausing"; 16581 } 16582 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16583 procState = ActivityManager.PROCESS_STATE_TOP; 16584 } 16585 schedGroup = Process.THREAD_GROUP_DEFAULT; 16586 app.cached = false; 16587 app.empty = false; 16588 foregroundActivities = true; 16589 } else if (r.state == ActivityState.STOPPING) { 16590 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16591 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16592 app.adjType = "stopping"; 16593 } 16594 // For the process state, we will at this point consider the 16595 // process to be cached. It will be cached either as an activity 16596 // or empty depending on whether the activity is finishing. We do 16597 // this so that we can treat the process as cached for purposes of 16598 // memory trimming (determing current memory level, trim command to 16599 // send to process) since there can be an arbitrary number of stopping 16600 // processes and they should soon all go into the cached state. 16601 if (!r.finishing) { 16602 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16603 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16604 } 16605 } 16606 app.cached = false; 16607 app.empty = false; 16608 foregroundActivities = true; 16609 } else { 16610 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16611 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16612 app.adjType = "cch-act"; 16613 } 16614 } 16615 } 16616 } 16617 16618 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16619 if (app.foregroundServices) { 16620 // The user is aware of this app, so make it visible. 16621 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16622 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16623 app.cached = false; 16624 app.adjType = "fg-service"; 16625 schedGroup = Process.THREAD_GROUP_DEFAULT; 16626 } else if (app.forcingToForeground != null) { 16627 // The user is aware of this app, so make it visible. 16628 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16629 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16630 app.cached = false; 16631 app.adjType = "force-fg"; 16632 app.adjSource = app.forcingToForeground; 16633 schedGroup = Process.THREAD_GROUP_DEFAULT; 16634 } 16635 } 16636 16637 if (app == mHeavyWeightProcess) { 16638 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16639 // We don't want to kill the current heavy-weight process. 16640 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16641 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16642 app.cached = false; 16643 app.adjType = "heavy"; 16644 } 16645 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16646 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16647 } 16648 } 16649 16650 if (app == mHomeProcess) { 16651 if (adj > ProcessList.HOME_APP_ADJ) { 16652 // This process is hosting what we currently consider to be the 16653 // home app, so we don't want to let it go into the background. 16654 adj = ProcessList.HOME_APP_ADJ; 16655 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16656 app.cached = false; 16657 app.adjType = "home"; 16658 } 16659 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16660 procState = ActivityManager.PROCESS_STATE_HOME; 16661 } 16662 } 16663 16664 if (app == mPreviousProcess && app.activities.size() > 0) { 16665 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16666 // This was the previous process that showed UI to the user. 16667 // We want to try to keep it around more aggressively, to give 16668 // a good experience around switching between two apps. 16669 adj = ProcessList.PREVIOUS_APP_ADJ; 16670 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16671 app.cached = false; 16672 app.adjType = "previous"; 16673 } 16674 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16675 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16676 } 16677 } 16678 16679 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16680 + " reason=" + app.adjType); 16681 16682 // By default, we use the computed adjustment. It may be changed if 16683 // there are applications dependent on our services or providers, but 16684 // this gives us a baseline and makes sure we don't get into an 16685 // infinite recursion. 16686 app.adjSeq = mAdjSeq; 16687 app.curRawAdj = adj; 16688 app.hasStartedServices = false; 16689 16690 if (mBackupTarget != null && app == mBackupTarget.app) { 16691 // If possible we want to avoid killing apps while they're being backed up 16692 if (adj > ProcessList.BACKUP_APP_ADJ) { 16693 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16694 adj = ProcessList.BACKUP_APP_ADJ; 16695 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16696 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16697 } 16698 app.adjType = "backup"; 16699 app.cached = false; 16700 } 16701 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16702 procState = ActivityManager.PROCESS_STATE_BACKUP; 16703 } 16704 } 16705 16706 boolean mayBeTop = false; 16707 16708 for (int is = app.services.size()-1; 16709 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16710 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16711 || procState > ActivityManager.PROCESS_STATE_TOP); 16712 is--) { 16713 ServiceRecord s = app.services.valueAt(is); 16714 if (s.startRequested) { 16715 app.hasStartedServices = true; 16716 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16717 procState = ActivityManager.PROCESS_STATE_SERVICE; 16718 } 16719 if (app.hasShownUi && app != mHomeProcess) { 16720 // If this process has shown some UI, let it immediately 16721 // go to the LRU list because it may be pretty heavy with 16722 // UI stuff. We'll tag it with a label just to help 16723 // debug and understand what is going on. 16724 if (adj > ProcessList.SERVICE_ADJ) { 16725 app.adjType = "cch-started-ui-services"; 16726 } 16727 } else { 16728 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16729 // This service has seen some activity within 16730 // recent memory, so we will keep its process ahead 16731 // of the background processes. 16732 if (adj > ProcessList.SERVICE_ADJ) { 16733 adj = ProcessList.SERVICE_ADJ; 16734 app.adjType = "started-services"; 16735 app.cached = false; 16736 } 16737 } 16738 // If we have let the service slide into the background 16739 // state, still have some text describing what it is doing 16740 // even though the service no longer has an impact. 16741 if (adj > ProcessList.SERVICE_ADJ) { 16742 app.adjType = "cch-started-services"; 16743 } 16744 } 16745 } 16746 for (int conni = s.connections.size()-1; 16747 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16748 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16749 || procState > ActivityManager.PROCESS_STATE_TOP); 16750 conni--) { 16751 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16752 for (int i = 0; 16753 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16754 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16755 || procState > ActivityManager.PROCESS_STATE_TOP); 16756 i++) { 16757 // XXX should compute this based on the max of 16758 // all connected clients. 16759 ConnectionRecord cr = clist.get(i); 16760 if (cr.binding.client == app) { 16761 // Binding to ourself is not interesting. 16762 continue; 16763 } 16764 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16765 ProcessRecord client = cr.binding.client; 16766 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16767 TOP_APP, doingAll, now); 16768 int clientProcState = client.curProcState; 16769 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16770 // If the other app is cached for any reason, for purposes here 16771 // we are going to consider it empty. The specific cached state 16772 // doesn't propagate except under certain conditions. 16773 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16774 } 16775 String adjType = null; 16776 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16777 // Not doing bind OOM management, so treat 16778 // this guy more like a started service. 16779 if (app.hasShownUi && app != mHomeProcess) { 16780 // If this process has shown some UI, let it immediately 16781 // go to the LRU list because it may be pretty heavy with 16782 // UI stuff. We'll tag it with a label just to help 16783 // debug and understand what is going on. 16784 if (adj > clientAdj) { 16785 adjType = "cch-bound-ui-services"; 16786 } 16787 app.cached = false; 16788 clientAdj = adj; 16789 clientProcState = procState; 16790 } else { 16791 if (now >= (s.lastActivity 16792 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16793 // This service has not seen activity within 16794 // recent memory, so allow it to drop to the 16795 // LRU list if there is no other reason to keep 16796 // it around. We'll also tag it with a label just 16797 // to help debug and undertand what is going on. 16798 if (adj > clientAdj) { 16799 adjType = "cch-bound-services"; 16800 } 16801 clientAdj = adj; 16802 } 16803 } 16804 } 16805 if (adj > clientAdj) { 16806 // If this process has recently shown UI, and 16807 // the process that is binding to it is less 16808 // important than being visible, then we don't 16809 // care about the binding as much as we care 16810 // about letting this process get into the LRU 16811 // list to be killed and restarted if needed for 16812 // memory. 16813 if (app.hasShownUi && app != mHomeProcess 16814 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16815 adjType = "cch-bound-ui-services"; 16816 } else { 16817 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16818 |Context.BIND_IMPORTANT)) != 0) { 16819 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16820 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16821 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16822 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16823 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16824 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16825 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16826 adj = clientAdj; 16827 } else { 16828 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16829 adj = ProcessList.VISIBLE_APP_ADJ; 16830 } 16831 } 16832 if (!client.cached) { 16833 app.cached = false; 16834 } 16835 adjType = "service"; 16836 } 16837 } 16838 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16839 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16840 schedGroup = Process.THREAD_GROUP_DEFAULT; 16841 } 16842 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16843 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16844 // Special handling of clients who are in the top state. 16845 // We *may* want to consider this process to be in the 16846 // top state as well, but only if there is not another 16847 // reason for it to be running. Being on the top is a 16848 // special state, meaning you are specifically running 16849 // for the current top app. If the process is already 16850 // running in the background for some other reason, it 16851 // is more important to continue considering it to be 16852 // in the background state. 16853 mayBeTop = true; 16854 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16855 } else { 16856 // Special handling for above-top states (persistent 16857 // processes). These should not bring the current process 16858 // into the top state, since they are not on top. Instead 16859 // give them the best state after that. 16860 clientProcState = 16861 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16862 } 16863 } 16864 } else { 16865 if (clientProcState < 16866 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16867 clientProcState = 16868 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16869 } 16870 } 16871 if (procState > clientProcState) { 16872 procState = clientProcState; 16873 } 16874 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16875 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16876 app.pendingUiClean = true; 16877 } 16878 if (adjType != null) { 16879 app.adjType = adjType; 16880 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16881 .REASON_SERVICE_IN_USE; 16882 app.adjSource = cr.binding.client; 16883 app.adjSourceProcState = clientProcState; 16884 app.adjTarget = s.name; 16885 } 16886 } 16887 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16888 app.treatLikeActivity = true; 16889 } 16890 final ActivityRecord a = cr.activity; 16891 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16892 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16893 (a.visible || a.state == ActivityState.RESUMED 16894 || a.state == ActivityState.PAUSING)) { 16895 adj = ProcessList.FOREGROUND_APP_ADJ; 16896 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16897 schedGroup = Process.THREAD_GROUP_DEFAULT; 16898 } 16899 app.cached = false; 16900 app.adjType = "service"; 16901 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16902 .REASON_SERVICE_IN_USE; 16903 app.adjSource = a; 16904 app.adjSourceProcState = procState; 16905 app.adjTarget = s.name; 16906 } 16907 } 16908 } 16909 } 16910 } 16911 16912 for (int provi = app.pubProviders.size()-1; 16913 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16914 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16915 || procState > ActivityManager.PROCESS_STATE_TOP); 16916 provi--) { 16917 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16918 for (int i = cpr.connections.size()-1; 16919 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16920 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16921 || procState > ActivityManager.PROCESS_STATE_TOP); 16922 i--) { 16923 ContentProviderConnection conn = cpr.connections.get(i); 16924 ProcessRecord client = conn.client; 16925 if (client == app) { 16926 // Being our own client is not interesting. 16927 continue; 16928 } 16929 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16930 int clientProcState = client.curProcState; 16931 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16932 // If the other app is cached for any reason, for purposes here 16933 // we are going to consider it empty. 16934 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16935 } 16936 if (adj > clientAdj) { 16937 if (app.hasShownUi && app != mHomeProcess 16938 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16939 app.adjType = "cch-ui-provider"; 16940 } else { 16941 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16942 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16943 app.adjType = "provider"; 16944 } 16945 app.cached &= client.cached; 16946 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16947 .REASON_PROVIDER_IN_USE; 16948 app.adjSource = client; 16949 app.adjSourceProcState = clientProcState; 16950 app.adjTarget = cpr.name; 16951 } 16952 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16953 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16954 // Special handling of clients who are in the top state. 16955 // We *may* want to consider this process to be in the 16956 // top state as well, but only if there is not another 16957 // reason for it to be running. Being on the top is a 16958 // special state, meaning you are specifically running 16959 // for the current top app. If the process is already 16960 // running in the background for some other reason, it 16961 // is more important to continue considering it to be 16962 // in the background state. 16963 mayBeTop = true; 16964 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16965 } else { 16966 // Special handling for above-top states (persistent 16967 // processes). These should not bring the current process 16968 // into the top state, since they are not on top. Instead 16969 // give them the best state after that. 16970 clientProcState = 16971 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16972 } 16973 } 16974 if (procState > clientProcState) { 16975 procState = clientProcState; 16976 } 16977 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16978 schedGroup = Process.THREAD_GROUP_DEFAULT; 16979 } 16980 } 16981 // If the provider has external (non-framework) process 16982 // dependencies, ensure that its adjustment is at least 16983 // FOREGROUND_APP_ADJ. 16984 if (cpr.hasExternalProcessHandles()) { 16985 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16986 adj = ProcessList.FOREGROUND_APP_ADJ; 16987 schedGroup = Process.THREAD_GROUP_DEFAULT; 16988 app.cached = false; 16989 app.adjType = "provider"; 16990 app.adjTarget = cpr.name; 16991 } 16992 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16993 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16994 } 16995 } 16996 } 16997 16998 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16999 // A client of one of our services or providers is in the top state. We 17000 // *may* want to be in the top state, but not if we are already running in 17001 // the background for some other reason. For the decision here, we are going 17002 // to pick out a few specific states that we want to remain in when a client 17003 // is top (states that tend to be longer-term) and otherwise allow it to go 17004 // to the top state. 17005 switch (procState) { 17006 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17007 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17008 case ActivityManager.PROCESS_STATE_SERVICE: 17009 // These all are longer-term states, so pull them up to the top 17010 // of the background states, but not all the way to the top state. 17011 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17012 break; 17013 default: 17014 // Otherwise, top is a better choice, so take it. 17015 procState = ActivityManager.PROCESS_STATE_TOP; 17016 break; 17017 } 17018 } 17019 17020 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17021 if (app.hasClientActivities) { 17022 // This is a cached process, but with client activities. Mark it so. 17023 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17024 app.adjType = "cch-client-act"; 17025 } else if (app.treatLikeActivity) { 17026 // This is a cached process, but somebody wants us to treat it like it has 17027 // an activity, okay! 17028 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17029 app.adjType = "cch-as-act"; 17030 } 17031 } 17032 17033 if (adj == ProcessList.SERVICE_ADJ) { 17034 if (doingAll) { 17035 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17036 mNewNumServiceProcs++; 17037 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17038 if (!app.serviceb) { 17039 // This service isn't far enough down on the LRU list to 17040 // normally be a B service, but if we are low on RAM and it 17041 // is large we want to force it down since we would prefer to 17042 // keep launcher over it. 17043 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17044 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17045 app.serviceHighRam = true; 17046 app.serviceb = true; 17047 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17048 } else { 17049 mNewNumAServiceProcs++; 17050 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17051 } 17052 } else { 17053 app.serviceHighRam = false; 17054 } 17055 } 17056 if (app.serviceb) { 17057 adj = ProcessList.SERVICE_B_ADJ; 17058 } 17059 } 17060 17061 app.curRawAdj = adj; 17062 17063 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17064 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17065 if (adj > app.maxAdj) { 17066 adj = app.maxAdj; 17067 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17068 schedGroup = Process.THREAD_GROUP_DEFAULT; 17069 } 17070 } 17071 17072 // Do final modification to adj. Everything we do between here and applying 17073 // the final setAdj must be done in this function, because we will also use 17074 // it when computing the final cached adj later. Note that we don't need to 17075 // worry about this for max adj above, since max adj will always be used to 17076 // keep it out of the cached vaues. 17077 app.curAdj = app.modifyRawOomAdj(adj); 17078 app.curSchedGroup = schedGroup; 17079 app.curProcState = procState; 17080 app.foregroundActivities = foregroundActivities; 17081 17082 return app.curRawAdj; 17083 } 17084 17085 /** 17086 * Schedule PSS collection of a process. 17087 */ 17088 void requestPssLocked(ProcessRecord proc, int procState) { 17089 if (mPendingPssProcesses.contains(proc)) { 17090 return; 17091 } 17092 if (mPendingPssProcesses.size() == 0) { 17093 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17094 } 17095 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17096 proc.pssProcState = procState; 17097 mPendingPssProcesses.add(proc); 17098 } 17099 17100 /** 17101 * Schedule PSS collection of all processes. 17102 */ 17103 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17104 if (!always) { 17105 if (now < (mLastFullPssTime + 17106 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17107 return; 17108 } 17109 } 17110 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17111 mLastFullPssTime = now; 17112 mFullPssPending = true; 17113 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17114 mPendingPssProcesses.clear(); 17115 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17116 ProcessRecord app = mLruProcesses.get(i); 17117 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17118 app.pssProcState = app.setProcState; 17119 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17120 isSleeping(), now); 17121 mPendingPssProcesses.add(app); 17122 } 17123 } 17124 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17125 } 17126 17127 /** 17128 * Ask a given process to GC right now. 17129 */ 17130 final void performAppGcLocked(ProcessRecord app) { 17131 try { 17132 app.lastRequestedGc = SystemClock.uptimeMillis(); 17133 if (app.thread != null) { 17134 if (app.reportLowMemory) { 17135 app.reportLowMemory = false; 17136 app.thread.scheduleLowMemory(); 17137 } else { 17138 app.thread.processInBackground(); 17139 } 17140 } 17141 } catch (Exception e) { 17142 // whatever. 17143 } 17144 } 17145 17146 /** 17147 * Returns true if things are idle enough to perform GCs. 17148 */ 17149 private final boolean canGcNowLocked() { 17150 boolean processingBroadcasts = false; 17151 for (BroadcastQueue q : mBroadcastQueues) { 17152 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17153 processingBroadcasts = true; 17154 } 17155 } 17156 return !processingBroadcasts 17157 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17158 } 17159 17160 /** 17161 * Perform GCs on all processes that are waiting for it, but only 17162 * if things are idle. 17163 */ 17164 final void performAppGcsLocked() { 17165 final int N = mProcessesToGc.size(); 17166 if (N <= 0) { 17167 return; 17168 } 17169 if (canGcNowLocked()) { 17170 while (mProcessesToGc.size() > 0) { 17171 ProcessRecord proc = mProcessesToGc.remove(0); 17172 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17173 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17174 <= SystemClock.uptimeMillis()) { 17175 // To avoid spamming the system, we will GC processes one 17176 // at a time, waiting a few seconds between each. 17177 performAppGcLocked(proc); 17178 scheduleAppGcsLocked(); 17179 return; 17180 } else { 17181 // It hasn't been long enough since we last GCed this 17182 // process... put it in the list to wait for its time. 17183 addProcessToGcListLocked(proc); 17184 break; 17185 } 17186 } 17187 } 17188 17189 scheduleAppGcsLocked(); 17190 } 17191 } 17192 17193 /** 17194 * If all looks good, perform GCs on all processes waiting for them. 17195 */ 17196 final void performAppGcsIfAppropriateLocked() { 17197 if (canGcNowLocked()) { 17198 performAppGcsLocked(); 17199 return; 17200 } 17201 // Still not idle, wait some more. 17202 scheduleAppGcsLocked(); 17203 } 17204 17205 /** 17206 * Schedule the execution of all pending app GCs. 17207 */ 17208 final void scheduleAppGcsLocked() { 17209 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17210 17211 if (mProcessesToGc.size() > 0) { 17212 // Schedule a GC for the time to the next process. 17213 ProcessRecord proc = mProcessesToGc.get(0); 17214 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17215 17216 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17217 long now = SystemClock.uptimeMillis(); 17218 if (when < (now+GC_TIMEOUT)) { 17219 when = now + GC_TIMEOUT; 17220 } 17221 mHandler.sendMessageAtTime(msg, when); 17222 } 17223 } 17224 17225 /** 17226 * Add a process to the array of processes waiting to be GCed. Keeps the 17227 * list in sorted order by the last GC time. The process can't already be 17228 * on the list. 17229 */ 17230 final void addProcessToGcListLocked(ProcessRecord proc) { 17231 boolean added = false; 17232 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17233 if (mProcessesToGc.get(i).lastRequestedGc < 17234 proc.lastRequestedGc) { 17235 added = true; 17236 mProcessesToGc.add(i+1, proc); 17237 break; 17238 } 17239 } 17240 if (!added) { 17241 mProcessesToGc.add(0, proc); 17242 } 17243 } 17244 17245 /** 17246 * Set up to ask a process to GC itself. This will either do it 17247 * immediately, or put it on the list of processes to gc the next 17248 * time things are idle. 17249 */ 17250 final void scheduleAppGcLocked(ProcessRecord app) { 17251 long now = SystemClock.uptimeMillis(); 17252 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17253 return; 17254 } 17255 if (!mProcessesToGc.contains(app)) { 17256 addProcessToGcListLocked(app); 17257 scheduleAppGcsLocked(); 17258 } 17259 } 17260 17261 final void checkExcessivePowerUsageLocked(boolean doKills) { 17262 updateCpuStatsNow(); 17263 17264 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17265 boolean doWakeKills = doKills; 17266 boolean doCpuKills = doKills; 17267 if (mLastPowerCheckRealtime == 0) { 17268 doWakeKills = false; 17269 } 17270 if (mLastPowerCheckUptime == 0) { 17271 doCpuKills = false; 17272 } 17273 if (stats.isScreenOn()) { 17274 doWakeKills = false; 17275 } 17276 final long curRealtime = SystemClock.elapsedRealtime(); 17277 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17278 final long curUptime = SystemClock.uptimeMillis(); 17279 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17280 mLastPowerCheckRealtime = curRealtime; 17281 mLastPowerCheckUptime = curUptime; 17282 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17283 doWakeKills = false; 17284 } 17285 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17286 doCpuKills = false; 17287 } 17288 int i = mLruProcesses.size(); 17289 while (i > 0) { 17290 i--; 17291 ProcessRecord app = mLruProcesses.get(i); 17292 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17293 long wtime; 17294 synchronized (stats) { 17295 wtime = stats.getProcessWakeTime(app.info.uid, 17296 app.pid, curRealtime); 17297 } 17298 long wtimeUsed = wtime - app.lastWakeTime; 17299 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17300 if (DEBUG_POWER) { 17301 StringBuilder sb = new StringBuilder(128); 17302 sb.append("Wake for "); 17303 app.toShortString(sb); 17304 sb.append(": over "); 17305 TimeUtils.formatDuration(realtimeSince, sb); 17306 sb.append(" used "); 17307 TimeUtils.formatDuration(wtimeUsed, sb); 17308 sb.append(" ("); 17309 sb.append((wtimeUsed*100)/realtimeSince); 17310 sb.append("%)"); 17311 Slog.i(TAG, sb.toString()); 17312 sb.setLength(0); 17313 sb.append("CPU for "); 17314 app.toShortString(sb); 17315 sb.append(": over "); 17316 TimeUtils.formatDuration(uptimeSince, sb); 17317 sb.append(" used "); 17318 TimeUtils.formatDuration(cputimeUsed, sb); 17319 sb.append(" ("); 17320 sb.append((cputimeUsed*100)/uptimeSince); 17321 sb.append("%)"); 17322 Slog.i(TAG, sb.toString()); 17323 } 17324 // If a process has held a wake lock for more 17325 // than 50% of the time during this period, 17326 // that sounds bad. Kill! 17327 if (doWakeKills && realtimeSince > 0 17328 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17329 synchronized (stats) { 17330 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17331 realtimeSince, wtimeUsed); 17332 } 17333 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17334 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17335 } else if (doCpuKills && uptimeSince > 0 17336 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17337 synchronized (stats) { 17338 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17339 uptimeSince, cputimeUsed); 17340 } 17341 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17342 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17343 } else { 17344 app.lastWakeTime = wtime; 17345 app.lastCpuTime = app.curCpuTime; 17346 } 17347 } 17348 } 17349 } 17350 17351 private final boolean applyOomAdjLocked(ProcessRecord app, 17352 ProcessRecord TOP_APP, boolean doingAll, long now) { 17353 boolean success = true; 17354 17355 if (app.curRawAdj != app.setRawAdj) { 17356 app.setRawAdj = app.curRawAdj; 17357 } 17358 17359 int changes = 0; 17360 17361 if (app.curAdj != app.setAdj) { 17362 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17363 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17364 TAG, "Set " + app.pid + " " + app.processName + 17365 " adj " + app.curAdj + ": " + app.adjType); 17366 app.setAdj = app.curAdj; 17367 } 17368 17369 if (app.setSchedGroup != app.curSchedGroup) { 17370 app.setSchedGroup = app.curSchedGroup; 17371 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17372 "Setting process group of " + app.processName 17373 + " to " + app.curSchedGroup); 17374 if (app.waitingToKill != null && 17375 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17376 app.kill(app.waitingToKill, true); 17377 success = false; 17378 } else { 17379 if (true) { 17380 long oldId = Binder.clearCallingIdentity(); 17381 try { 17382 Process.setProcessGroup(app.pid, app.curSchedGroup); 17383 } catch (Exception e) { 17384 Slog.w(TAG, "Failed setting process group of " + app.pid 17385 + " to " + app.curSchedGroup); 17386 e.printStackTrace(); 17387 } finally { 17388 Binder.restoreCallingIdentity(oldId); 17389 } 17390 } else { 17391 if (app.thread != null) { 17392 try { 17393 app.thread.setSchedulingGroup(app.curSchedGroup); 17394 } catch (RemoteException e) { 17395 } 17396 } 17397 } 17398 Process.setSwappiness(app.pid, 17399 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17400 } 17401 } 17402 if (app.repForegroundActivities != app.foregroundActivities) { 17403 app.repForegroundActivities = app.foregroundActivities; 17404 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17405 } 17406 if (app.repProcState != app.curProcState) { 17407 app.repProcState = app.curProcState; 17408 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17409 if (app.thread != null) { 17410 try { 17411 if (false) { 17412 //RuntimeException h = new RuntimeException("here"); 17413 Slog.i(TAG, "Sending new process state " + app.repProcState 17414 + " to " + app /*, h*/); 17415 } 17416 app.thread.setProcessState(app.repProcState); 17417 } catch (RemoteException e) { 17418 } 17419 } 17420 } 17421 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17422 app.setProcState)) { 17423 app.lastStateTime = now; 17424 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17425 isSleeping(), now); 17426 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17427 + ProcessList.makeProcStateString(app.setProcState) + " to " 17428 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17429 + (app.nextPssTime-now) + ": " + app); 17430 } else { 17431 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17432 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17433 requestPssLocked(app, app.setProcState); 17434 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17435 isSleeping(), now); 17436 } else if (false && DEBUG_PSS) { 17437 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17438 } 17439 } 17440 if (app.setProcState != app.curProcState) { 17441 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17442 "Proc state change of " + app.processName 17443 + " to " + app.curProcState); 17444 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17445 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17446 if (setImportant && !curImportant) { 17447 // This app is no longer something we consider important enough to allow to 17448 // use arbitrary amounts of battery power. Note 17449 // its current wake lock time to later know to kill it if 17450 // it is not behaving well. 17451 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17452 synchronized (stats) { 17453 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17454 app.pid, SystemClock.elapsedRealtime()); 17455 } 17456 app.lastCpuTime = app.curCpuTime; 17457 17458 } 17459 app.setProcState = app.curProcState; 17460 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17461 app.notCachedSinceIdle = false; 17462 } 17463 if (!doingAll) { 17464 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17465 } else { 17466 app.procStateChanged = true; 17467 } 17468 } 17469 17470 if (changes != 0) { 17471 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17472 int i = mPendingProcessChanges.size()-1; 17473 ProcessChangeItem item = null; 17474 while (i >= 0) { 17475 item = mPendingProcessChanges.get(i); 17476 if (item.pid == app.pid) { 17477 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17478 break; 17479 } 17480 i--; 17481 } 17482 if (i < 0) { 17483 // No existing item in pending changes; need a new one. 17484 final int NA = mAvailProcessChanges.size(); 17485 if (NA > 0) { 17486 item = mAvailProcessChanges.remove(NA-1); 17487 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17488 } else { 17489 item = new ProcessChangeItem(); 17490 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17491 } 17492 item.changes = 0; 17493 item.pid = app.pid; 17494 item.uid = app.info.uid; 17495 if (mPendingProcessChanges.size() == 0) { 17496 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17497 "*** Enqueueing dispatch processes changed!"); 17498 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17499 } 17500 mPendingProcessChanges.add(item); 17501 } 17502 item.changes |= changes; 17503 item.processState = app.repProcState; 17504 item.foregroundActivities = app.repForegroundActivities; 17505 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17506 + Integer.toHexString(System.identityHashCode(item)) 17507 + " " + app.toShortString() + ": changes=" + item.changes 17508 + " procState=" + item.processState 17509 + " foreground=" + item.foregroundActivities 17510 + " type=" + app.adjType + " source=" + app.adjSource 17511 + " target=" + app.adjTarget); 17512 } 17513 17514 return success; 17515 } 17516 17517 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17518 if (proc.thread != null) { 17519 if (proc.baseProcessTracker != null) { 17520 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17521 } 17522 if (proc.repProcState >= 0) { 17523 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17524 proc.repProcState); 17525 } 17526 } 17527 } 17528 17529 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17530 ProcessRecord TOP_APP, boolean doingAll, long now) { 17531 if (app.thread == null) { 17532 return false; 17533 } 17534 17535 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17536 17537 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17538 } 17539 17540 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17541 boolean oomAdj) { 17542 if (isForeground != proc.foregroundServices) { 17543 proc.foregroundServices = isForeground; 17544 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17545 proc.info.uid); 17546 if (isForeground) { 17547 if (curProcs == null) { 17548 curProcs = new ArrayList<ProcessRecord>(); 17549 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17550 } 17551 if (!curProcs.contains(proc)) { 17552 curProcs.add(proc); 17553 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17554 proc.info.packageName, proc.info.uid); 17555 } 17556 } else { 17557 if (curProcs != null) { 17558 if (curProcs.remove(proc)) { 17559 mBatteryStatsService.noteEvent( 17560 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17561 proc.info.packageName, proc.info.uid); 17562 if (curProcs.size() <= 0) { 17563 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17564 } 17565 } 17566 } 17567 } 17568 if (oomAdj) { 17569 updateOomAdjLocked(); 17570 } 17571 } 17572 } 17573 17574 private final ActivityRecord resumedAppLocked() { 17575 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17576 String pkg; 17577 int uid; 17578 if (act != null) { 17579 pkg = act.packageName; 17580 uid = act.info.applicationInfo.uid; 17581 } else { 17582 pkg = null; 17583 uid = -1; 17584 } 17585 // Has the UID or resumed package name changed? 17586 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17587 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17588 if (mCurResumedPackage != null) { 17589 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17590 mCurResumedPackage, mCurResumedUid); 17591 } 17592 mCurResumedPackage = pkg; 17593 mCurResumedUid = uid; 17594 if (mCurResumedPackage != null) { 17595 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17596 mCurResumedPackage, mCurResumedUid); 17597 } 17598 } 17599 return act; 17600 } 17601 17602 final boolean updateOomAdjLocked(ProcessRecord app) { 17603 final ActivityRecord TOP_ACT = resumedAppLocked(); 17604 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17605 final boolean wasCached = app.cached; 17606 17607 mAdjSeq++; 17608 17609 // This is the desired cached adjusment we want to tell it to use. 17610 // If our app is currently cached, we know it, and that is it. Otherwise, 17611 // we don't know it yet, and it needs to now be cached we will then 17612 // need to do a complete oom adj. 17613 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17614 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17615 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17616 SystemClock.uptimeMillis()); 17617 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17618 // Changed to/from cached state, so apps after it in the LRU 17619 // list may also be changed. 17620 updateOomAdjLocked(); 17621 } 17622 return success; 17623 } 17624 17625 final void updateOomAdjLocked() { 17626 final ActivityRecord TOP_ACT = resumedAppLocked(); 17627 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17628 final long now = SystemClock.uptimeMillis(); 17629 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17630 final int N = mLruProcesses.size(); 17631 17632 if (false) { 17633 RuntimeException e = new RuntimeException(); 17634 e.fillInStackTrace(); 17635 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17636 } 17637 17638 mAdjSeq++; 17639 mNewNumServiceProcs = 0; 17640 mNewNumAServiceProcs = 0; 17641 17642 final int emptyProcessLimit; 17643 final int cachedProcessLimit; 17644 if (mProcessLimit <= 0) { 17645 emptyProcessLimit = cachedProcessLimit = 0; 17646 } else if (mProcessLimit == 1) { 17647 emptyProcessLimit = 1; 17648 cachedProcessLimit = 0; 17649 } else { 17650 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17651 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17652 } 17653 17654 // Let's determine how many processes we have running vs. 17655 // how many slots we have for background processes; we may want 17656 // to put multiple processes in a slot of there are enough of 17657 // them. 17658 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17659 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17660 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17661 if (numEmptyProcs > cachedProcessLimit) { 17662 // If there are more empty processes than our limit on cached 17663 // processes, then use the cached process limit for the factor. 17664 // This ensures that the really old empty processes get pushed 17665 // down to the bottom, so if we are running low on memory we will 17666 // have a better chance at keeping around more cached processes 17667 // instead of a gazillion empty processes. 17668 numEmptyProcs = cachedProcessLimit; 17669 } 17670 int emptyFactor = numEmptyProcs/numSlots; 17671 if (emptyFactor < 1) emptyFactor = 1; 17672 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17673 if (cachedFactor < 1) cachedFactor = 1; 17674 int stepCached = 0; 17675 int stepEmpty = 0; 17676 int numCached = 0; 17677 int numEmpty = 0; 17678 int numTrimming = 0; 17679 17680 mNumNonCachedProcs = 0; 17681 mNumCachedHiddenProcs = 0; 17682 17683 // First update the OOM adjustment for each of the 17684 // application processes based on their current state. 17685 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17686 int nextCachedAdj = curCachedAdj+1; 17687 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17688 int nextEmptyAdj = curEmptyAdj+2; 17689 for (int i=N-1; i>=0; i--) { 17690 ProcessRecord app = mLruProcesses.get(i); 17691 if (!app.killedByAm && app.thread != null) { 17692 app.procStateChanged = false; 17693 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17694 17695 // If we haven't yet assigned the final cached adj 17696 // to the process, do that now. 17697 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17698 switch (app.curProcState) { 17699 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17700 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17701 // This process is a cached process holding activities... 17702 // assign it the next cached value for that type, and then 17703 // step that cached level. 17704 app.curRawAdj = curCachedAdj; 17705 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17706 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17707 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17708 + ")"); 17709 if (curCachedAdj != nextCachedAdj) { 17710 stepCached++; 17711 if (stepCached >= cachedFactor) { 17712 stepCached = 0; 17713 curCachedAdj = nextCachedAdj; 17714 nextCachedAdj += 2; 17715 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17716 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17717 } 17718 } 17719 } 17720 break; 17721 default: 17722 // For everything else, assign next empty cached process 17723 // level and bump that up. Note that this means that 17724 // long-running services that have dropped down to the 17725 // cached level will be treated as empty (since their process 17726 // state is still as a service), which is what we want. 17727 app.curRawAdj = curEmptyAdj; 17728 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17729 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17730 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17731 + ")"); 17732 if (curEmptyAdj != nextEmptyAdj) { 17733 stepEmpty++; 17734 if (stepEmpty >= emptyFactor) { 17735 stepEmpty = 0; 17736 curEmptyAdj = nextEmptyAdj; 17737 nextEmptyAdj += 2; 17738 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17739 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17740 } 17741 } 17742 } 17743 break; 17744 } 17745 } 17746 17747 applyOomAdjLocked(app, TOP_APP, true, now); 17748 17749 // Count the number of process types. 17750 switch (app.curProcState) { 17751 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17752 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17753 mNumCachedHiddenProcs++; 17754 numCached++; 17755 if (numCached > cachedProcessLimit) { 17756 app.kill("cached #" + numCached, true); 17757 } 17758 break; 17759 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17760 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17761 && app.lastActivityTime < oldTime) { 17762 app.kill("empty for " 17763 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17764 / 1000) + "s", true); 17765 } else { 17766 numEmpty++; 17767 if (numEmpty > emptyProcessLimit) { 17768 app.kill("empty #" + numEmpty, true); 17769 } 17770 } 17771 break; 17772 default: 17773 mNumNonCachedProcs++; 17774 break; 17775 } 17776 17777 if (app.isolated && app.services.size() <= 0) { 17778 // If this is an isolated process, and there are no 17779 // services running in it, then the process is no longer 17780 // needed. We agressively kill these because we can by 17781 // definition not re-use the same process again, and it is 17782 // good to avoid having whatever code was running in them 17783 // left sitting around after no longer needed. 17784 app.kill("isolated not needed", true); 17785 } 17786 17787 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17788 && !app.killedByAm) { 17789 numTrimming++; 17790 } 17791 } 17792 } 17793 17794 mNumServiceProcs = mNewNumServiceProcs; 17795 17796 // Now determine the memory trimming level of background processes. 17797 // Unfortunately we need to start at the back of the list to do this 17798 // properly. We only do this if the number of background apps we 17799 // are managing to keep around is less than half the maximum we desire; 17800 // if we are keeping a good number around, we'll let them use whatever 17801 // memory they want. 17802 final int numCachedAndEmpty = numCached + numEmpty; 17803 int memFactor; 17804 if (numCached <= ProcessList.TRIM_CACHED_APPS 17805 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17806 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17807 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17808 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17809 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17810 } else { 17811 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17812 } 17813 } else { 17814 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17815 } 17816 // We always allow the memory level to go up (better). We only allow it to go 17817 // down if we are in a state where that is allowed, *and* the total number of processes 17818 // has gone down since last time. 17819 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17820 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17821 + " last=" + mLastNumProcesses); 17822 if (memFactor > mLastMemoryLevel) { 17823 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17824 memFactor = mLastMemoryLevel; 17825 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17826 } 17827 } 17828 mLastMemoryLevel = memFactor; 17829 mLastNumProcesses = mLruProcesses.size(); 17830 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17831 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17832 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17833 if (mLowRamStartTime == 0) { 17834 mLowRamStartTime = now; 17835 } 17836 int step = 0; 17837 int fgTrimLevel; 17838 switch (memFactor) { 17839 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17840 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17841 break; 17842 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17843 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17844 break; 17845 default: 17846 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17847 break; 17848 } 17849 int factor = numTrimming/3; 17850 int minFactor = 2; 17851 if (mHomeProcess != null) minFactor++; 17852 if (mPreviousProcess != null) minFactor++; 17853 if (factor < minFactor) factor = minFactor; 17854 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17855 for (int i=N-1; i>=0; i--) { 17856 ProcessRecord app = mLruProcesses.get(i); 17857 if (allChanged || app.procStateChanged) { 17858 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17859 app.procStateChanged = false; 17860 } 17861 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17862 && !app.killedByAm) { 17863 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17864 try { 17865 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17866 "Trimming memory of " + app.processName 17867 + " to " + curLevel); 17868 app.thread.scheduleTrimMemory(curLevel); 17869 } catch (RemoteException e) { 17870 } 17871 if (false) { 17872 // For now we won't do this; our memory trimming seems 17873 // to be good enough at this point that destroying 17874 // activities causes more harm than good. 17875 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17876 && app != mHomeProcess && app != mPreviousProcess) { 17877 // Need to do this on its own message because the stack may not 17878 // be in a consistent state at this point. 17879 // For these apps we will also finish their activities 17880 // to help them free memory. 17881 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17882 } 17883 } 17884 } 17885 app.trimMemoryLevel = curLevel; 17886 step++; 17887 if (step >= factor) { 17888 step = 0; 17889 switch (curLevel) { 17890 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17891 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17892 break; 17893 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17894 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17895 break; 17896 } 17897 } 17898 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17899 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17900 && app.thread != null) { 17901 try { 17902 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17903 "Trimming memory of heavy-weight " + app.processName 17904 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17905 app.thread.scheduleTrimMemory( 17906 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17907 } catch (RemoteException e) { 17908 } 17909 } 17910 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17911 } else { 17912 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17913 || app.systemNoUi) && app.pendingUiClean) { 17914 // If this application is now in the background and it 17915 // had done UI, then give it the special trim level to 17916 // have it free UI resources. 17917 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17918 if (app.trimMemoryLevel < level && app.thread != null) { 17919 try { 17920 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17921 "Trimming memory of bg-ui " + app.processName 17922 + " to " + level); 17923 app.thread.scheduleTrimMemory(level); 17924 } catch (RemoteException e) { 17925 } 17926 } 17927 app.pendingUiClean = false; 17928 } 17929 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17930 try { 17931 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17932 "Trimming memory of fg " + app.processName 17933 + " to " + fgTrimLevel); 17934 app.thread.scheduleTrimMemory(fgTrimLevel); 17935 } catch (RemoteException e) { 17936 } 17937 } 17938 app.trimMemoryLevel = fgTrimLevel; 17939 } 17940 } 17941 } else { 17942 if (mLowRamStartTime != 0) { 17943 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17944 mLowRamStartTime = 0; 17945 } 17946 for (int i=N-1; i>=0; i--) { 17947 ProcessRecord app = mLruProcesses.get(i); 17948 if (allChanged || app.procStateChanged) { 17949 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17950 app.procStateChanged = false; 17951 } 17952 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17953 || app.systemNoUi) && app.pendingUiClean) { 17954 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17955 && app.thread != null) { 17956 try { 17957 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17958 "Trimming memory of ui hidden " + app.processName 17959 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17960 app.thread.scheduleTrimMemory( 17961 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17962 } catch (RemoteException e) { 17963 } 17964 } 17965 app.pendingUiClean = false; 17966 } 17967 app.trimMemoryLevel = 0; 17968 } 17969 } 17970 17971 if (mAlwaysFinishActivities) { 17972 // Need to do this on its own message because the stack may not 17973 // be in a consistent state at this point. 17974 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17975 } 17976 17977 if (allChanged) { 17978 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17979 } 17980 17981 if (mProcessStats.shouldWriteNowLocked(now)) { 17982 mHandler.post(new Runnable() { 17983 @Override public void run() { 17984 synchronized (ActivityManagerService.this) { 17985 mProcessStats.writeStateAsyncLocked(); 17986 } 17987 } 17988 }); 17989 } 17990 17991 if (DEBUG_OOM_ADJ) { 17992 if (false) { 17993 RuntimeException here = new RuntimeException("here"); 17994 here.fillInStackTrace(); 17995 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17996 } else { 17997 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17998 } 17999 } 18000 } 18001 18002 final void trimApplications() { 18003 synchronized (this) { 18004 int i; 18005 18006 // First remove any unused application processes whose package 18007 // has been removed. 18008 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18009 final ProcessRecord app = mRemovedProcesses.get(i); 18010 if (app.activities.size() == 0 18011 && app.curReceiver == null && app.services.size() == 0) { 18012 Slog.i( 18013 TAG, "Exiting empty application process " 18014 + app.processName + " (" 18015 + (app.thread != null ? app.thread.asBinder() : null) 18016 + ")\n"); 18017 if (app.pid > 0 && app.pid != MY_PID) { 18018 app.kill("empty", false); 18019 } else { 18020 try { 18021 app.thread.scheduleExit(); 18022 } catch (Exception e) { 18023 // Ignore exceptions. 18024 } 18025 } 18026 cleanUpApplicationRecordLocked(app, false, true, -1); 18027 mRemovedProcesses.remove(i); 18028 18029 if (app.persistent) { 18030 addAppLocked(app.info, false, null /* ABI override */); 18031 } 18032 } 18033 } 18034 18035 // Now update the oom adj for all processes. 18036 updateOomAdjLocked(); 18037 } 18038 } 18039 18040 /** This method sends the specified signal to each of the persistent apps */ 18041 public void signalPersistentProcesses(int sig) throws RemoteException { 18042 if (sig != Process.SIGNAL_USR1) { 18043 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18044 } 18045 18046 synchronized (this) { 18047 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18048 != PackageManager.PERMISSION_GRANTED) { 18049 throw new SecurityException("Requires permission " 18050 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18051 } 18052 18053 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18054 ProcessRecord r = mLruProcesses.get(i); 18055 if (r.thread != null && r.persistent) { 18056 Process.sendSignal(r.pid, sig); 18057 } 18058 } 18059 } 18060 } 18061 18062 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18063 if (proc == null || proc == mProfileProc) { 18064 proc = mProfileProc; 18065 profileType = mProfileType; 18066 clearProfilerLocked(); 18067 } 18068 if (proc == null) { 18069 return; 18070 } 18071 try { 18072 proc.thread.profilerControl(false, null, profileType); 18073 } catch (RemoteException e) { 18074 throw new IllegalStateException("Process disappeared"); 18075 } 18076 } 18077 18078 private void clearProfilerLocked() { 18079 if (mProfileFd != null) { 18080 try { 18081 mProfileFd.close(); 18082 } catch (IOException e) { 18083 } 18084 } 18085 mProfileApp = null; 18086 mProfileProc = null; 18087 mProfileFile = null; 18088 mProfileType = 0; 18089 mAutoStopProfiler = false; 18090 mSamplingInterval = 0; 18091 } 18092 18093 public boolean profileControl(String process, int userId, boolean start, 18094 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18095 18096 try { 18097 synchronized (this) { 18098 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18099 // its own permission. 18100 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18101 != PackageManager.PERMISSION_GRANTED) { 18102 throw new SecurityException("Requires permission " 18103 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18104 } 18105 18106 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18107 throw new IllegalArgumentException("null profile info or fd"); 18108 } 18109 18110 ProcessRecord proc = null; 18111 if (process != null) { 18112 proc = findProcessLocked(process, userId, "profileControl"); 18113 } 18114 18115 if (start && (proc == null || proc.thread == null)) { 18116 throw new IllegalArgumentException("Unknown process: " + process); 18117 } 18118 18119 if (start) { 18120 stopProfilerLocked(null, 0); 18121 setProfileApp(proc.info, proc.processName, profilerInfo); 18122 mProfileProc = proc; 18123 mProfileType = profileType; 18124 ParcelFileDescriptor fd = profilerInfo.profileFd; 18125 try { 18126 fd = fd.dup(); 18127 } catch (IOException e) { 18128 fd = null; 18129 } 18130 profilerInfo.profileFd = fd; 18131 proc.thread.profilerControl(start, profilerInfo, profileType); 18132 fd = null; 18133 mProfileFd = null; 18134 } else { 18135 stopProfilerLocked(proc, profileType); 18136 if (profilerInfo != null && profilerInfo.profileFd != null) { 18137 try { 18138 profilerInfo.profileFd.close(); 18139 } catch (IOException e) { 18140 } 18141 } 18142 } 18143 18144 return true; 18145 } 18146 } catch (RemoteException e) { 18147 throw new IllegalStateException("Process disappeared"); 18148 } finally { 18149 if (profilerInfo != null && profilerInfo.profileFd != null) { 18150 try { 18151 profilerInfo.profileFd.close(); 18152 } catch (IOException e) { 18153 } 18154 } 18155 } 18156 } 18157 18158 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18159 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18160 userId, true, ALLOW_FULL_ONLY, callName, null); 18161 ProcessRecord proc = null; 18162 try { 18163 int pid = Integer.parseInt(process); 18164 synchronized (mPidsSelfLocked) { 18165 proc = mPidsSelfLocked.get(pid); 18166 } 18167 } catch (NumberFormatException e) { 18168 } 18169 18170 if (proc == null) { 18171 ArrayMap<String, SparseArray<ProcessRecord>> all 18172 = mProcessNames.getMap(); 18173 SparseArray<ProcessRecord> procs = all.get(process); 18174 if (procs != null && procs.size() > 0) { 18175 proc = procs.valueAt(0); 18176 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18177 for (int i=1; i<procs.size(); i++) { 18178 ProcessRecord thisProc = procs.valueAt(i); 18179 if (thisProc.userId == userId) { 18180 proc = thisProc; 18181 break; 18182 } 18183 } 18184 } 18185 } 18186 } 18187 18188 return proc; 18189 } 18190 18191 public boolean dumpHeap(String process, int userId, boolean managed, 18192 String path, ParcelFileDescriptor fd) throws RemoteException { 18193 18194 try { 18195 synchronized (this) { 18196 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18197 // its own permission (same as profileControl). 18198 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18199 != PackageManager.PERMISSION_GRANTED) { 18200 throw new SecurityException("Requires permission " 18201 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18202 } 18203 18204 if (fd == null) { 18205 throw new IllegalArgumentException("null fd"); 18206 } 18207 18208 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18209 if (proc == null || proc.thread == null) { 18210 throw new IllegalArgumentException("Unknown process: " + process); 18211 } 18212 18213 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18214 if (!isDebuggable) { 18215 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18216 throw new SecurityException("Process not debuggable: " + proc); 18217 } 18218 } 18219 18220 proc.thread.dumpHeap(managed, path, fd); 18221 fd = null; 18222 return true; 18223 } 18224 } catch (RemoteException e) { 18225 throw new IllegalStateException("Process disappeared"); 18226 } finally { 18227 if (fd != null) { 18228 try { 18229 fd.close(); 18230 } catch (IOException e) { 18231 } 18232 } 18233 } 18234 } 18235 18236 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18237 public void monitor() { 18238 synchronized (this) { } 18239 } 18240 18241 void onCoreSettingsChange(Bundle settings) { 18242 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18243 ProcessRecord processRecord = mLruProcesses.get(i); 18244 try { 18245 if (processRecord.thread != null) { 18246 processRecord.thread.setCoreSettings(settings); 18247 } 18248 } catch (RemoteException re) { 18249 /* ignore */ 18250 } 18251 } 18252 } 18253 18254 // Multi-user methods 18255 18256 /** 18257 * Start user, if its not already running, but don't bring it to foreground. 18258 */ 18259 @Override 18260 public boolean startUserInBackground(final int userId) { 18261 return startUser(userId, /* foreground */ false); 18262 } 18263 18264 /** 18265 * Start user, if its not already running, and bring it to foreground. 18266 */ 18267 boolean startUserInForeground(final int userId, Dialog dlg) { 18268 boolean result = startUser(userId, /* foreground */ true); 18269 dlg.dismiss(); 18270 return result; 18271 } 18272 18273 /** 18274 * Refreshes the list of users related to the current user when either a 18275 * user switch happens or when a new related user is started in the 18276 * background. 18277 */ 18278 private void updateCurrentProfileIdsLocked() { 18279 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18280 mCurrentUserId, false /* enabledOnly */); 18281 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18282 for (int i = 0; i < currentProfileIds.length; i++) { 18283 currentProfileIds[i] = profiles.get(i).id; 18284 } 18285 mCurrentProfileIds = currentProfileIds; 18286 18287 synchronized (mUserProfileGroupIdsSelfLocked) { 18288 mUserProfileGroupIdsSelfLocked.clear(); 18289 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18290 for (int i = 0; i < users.size(); i++) { 18291 UserInfo user = users.get(i); 18292 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18293 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18294 } 18295 } 18296 } 18297 } 18298 18299 private Set getProfileIdsLocked(int userId) { 18300 Set userIds = new HashSet<Integer>(); 18301 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18302 userId, false /* enabledOnly */); 18303 for (UserInfo user : profiles) { 18304 userIds.add(Integer.valueOf(user.id)); 18305 } 18306 return userIds; 18307 } 18308 18309 @Override 18310 public boolean switchUser(final int userId) { 18311 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18312 String userName; 18313 synchronized (this) { 18314 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18315 if (userInfo == null) { 18316 Slog.w(TAG, "No user info for user #" + userId); 18317 return false; 18318 } 18319 if (userInfo.isManagedProfile()) { 18320 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18321 return false; 18322 } 18323 userName = userInfo.name; 18324 mTargetUserId = userId; 18325 } 18326 mHandler.removeMessages(START_USER_SWITCH_MSG); 18327 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18328 return true; 18329 } 18330 18331 private void showUserSwitchDialog(int userId, String userName) { 18332 // The dialog will show and then initiate the user switch by calling startUserInForeground 18333 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18334 true /* above system */); 18335 d.show(); 18336 } 18337 18338 private boolean startUser(final int userId, final boolean foreground) { 18339 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18340 != PackageManager.PERMISSION_GRANTED) { 18341 String msg = "Permission Denial: switchUser() from pid=" 18342 + Binder.getCallingPid() 18343 + ", uid=" + Binder.getCallingUid() 18344 + " requires " + INTERACT_ACROSS_USERS_FULL; 18345 Slog.w(TAG, msg); 18346 throw new SecurityException(msg); 18347 } 18348 18349 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18350 18351 final long ident = Binder.clearCallingIdentity(); 18352 try { 18353 synchronized (this) { 18354 final int oldUserId = mCurrentUserId; 18355 if (oldUserId == userId) { 18356 return true; 18357 } 18358 18359 mStackSupervisor.setLockTaskModeLocked(null, false); 18360 18361 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18362 if (userInfo == null) { 18363 Slog.w(TAG, "No user info for user #" + userId); 18364 return false; 18365 } 18366 if (foreground && userInfo.isManagedProfile()) { 18367 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18368 return false; 18369 } 18370 18371 if (foreground) { 18372 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18373 R.anim.screen_user_enter); 18374 } 18375 18376 boolean needStart = false; 18377 18378 // If the user we are switching to is not currently started, then 18379 // we need to start it now. 18380 if (mStartedUsers.get(userId) == null) { 18381 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18382 updateStartedUserArrayLocked(); 18383 needStart = true; 18384 } 18385 18386 final Integer userIdInt = Integer.valueOf(userId); 18387 mUserLru.remove(userIdInt); 18388 mUserLru.add(userIdInt); 18389 18390 if (foreground) { 18391 mCurrentUserId = userId; 18392 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18393 updateCurrentProfileIdsLocked(); 18394 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18395 // Once the internal notion of the active user has switched, we lock the device 18396 // with the option to show the user switcher on the keyguard. 18397 mWindowManager.lockNow(null); 18398 } else { 18399 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18400 updateCurrentProfileIdsLocked(); 18401 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18402 mUserLru.remove(currentUserIdInt); 18403 mUserLru.add(currentUserIdInt); 18404 } 18405 18406 final UserStartedState uss = mStartedUsers.get(userId); 18407 18408 // Make sure user is in the started state. If it is currently 18409 // stopping, we need to knock that off. 18410 if (uss.mState == UserStartedState.STATE_STOPPING) { 18411 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18412 // so we can just fairly silently bring the user back from 18413 // the almost-dead. 18414 uss.mState = UserStartedState.STATE_RUNNING; 18415 updateStartedUserArrayLocked(); 18416 needStart = true; 18417 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18418 // This means ACTION_SHUTDOWN has been sent, so we will 18419 // need to treat this as a new boot of the user. 18420 uss.mState = UserStartedState.STATE_BOOTING; 18421 updateStartedUserArrayLocked(); 18422 needStart = true; 18423 } 18424 18425 if (uss.mState == UserStartedState.STATE_BOOTING) { 18426 // Booting up a new user, need to tell system services about it. 18427 // Note that this is on the same handler as scheduling of broadcasts, 18428 // which is important because it needs to go first. 18429 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18430 } 18431 18432 if (foreground) { 18433 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18434 oldUserId)); 18435 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18436 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18437 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18438 oldUserId, userId, uss)); 18439 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18440 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18441 } 18442 18443 if (needStart) { 18444 // Send USER_STARTED broadcast 18445 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18446 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18447 | Intent.FLAG_RECEIVER_FOREGROUND); 18448 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18449 broadcastIntentLocked(null, null, intent, 18450 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18451 false, false, MY_PID, Process.SYSTEM_UID, userId); 18452 } 18453 18454 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18455 if (userId != UserHandle.USER_OWNER) { 18456 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18457 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18458 broadcastIntentLocked(null, null, intent, null, 18459 new IIntentReceiver.Stub() { 18460 public void performReceive(Intent intent, int resultCode, 18461 String data, Bundle extras, boolean ordered, 18462 boolean sticky, int sendingUser) { 18463 onUserInitialized(uss, foreground, oldUserId, userId); 18464 } 18465 }, 0, null, null, null, AppOpsManager.OP_NONE, 18466 true, false, MY_PID, Process.SYSTEM_UID, 18467 userId); 18468 uss.initializing = true; 18469 } else { 18470 getUserManagerLocked().makeInitialized(userInfo.id); 18471 } 18472 } 18473 18474 if (foreground) { 18475 if (!uss.initializing) { 18476 moveUserToForeground(uss, oldUserId, userId); 18477 } 18478 } else { 18479 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18480 } 18481 18482 if (needStart) { 18483 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18484 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18485 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18486 broadcastIntentLocked(null, null, intent, 18487 null, new IIntentReceiver.Stub() { 18488 @Override 18489 public void performReceive(Intent intent, int resultCode, String data, 18490 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18491 throws RemoteException { 18492 } 18493 }, 0, null, null, 18494 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18495 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18496 } 18497 } 18498 } finally { 18499 Binder.restoreCallingIdentity(ident); 18500 } 18501 18502 return true; 18503 } 18504 18505 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18506 long ident = Binder.clearCallingIdentity(); 18507 try { 18508 Intent intent; 18509 if (oldUserId >= 0) { 18510 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18511 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18512 int count = profiles.size(); 18513 for (int i = 0; i < count; i++) { 18514 int profileUserId = profiles.get(i).id; 18515 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18517 | Intent.FLAG_RECEIVER_FOREGROUND); 18518 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18519 broadcastIntentLocked(null, null, intent, 18520 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18521 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18522 } 18523 } 18524 if (newUserId >= 0) { 18525 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18526 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18527 int count = profiles.size(); 18528 for (int i = 0; i < count; i++) { 18529 int profileUserId = profiles.get(i).id; 18530 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18531 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18532 | Intent.FLAG_RECEIVER_FOREGROUND); 18533 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18534 broadcastIntentLocked(null, null, intent, 18535 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18536 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18537 } 18538 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18539 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18540 | Intent.FLAG_RECEIVER_FOREGROUND); 18541 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18542 broadcastIntentLocked(null, null, intent, 18543 null, null, 0, null, null, 18544 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18545 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18546 } 18547 } finally { 18548 Binder.restoreCallingIdentity(ident); 18549 } 18550 } 18551 18552 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18553 final int newUserId) { 18554 final int N = mUserSwitchObservers.beginBroadcast(); 18555 if (N > 0) { 18556 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18557 int mCount = 0; 18558 @Override 18559 public void sendResult(Bundle data) throws RemoteException { 18560 synchronized (ActivityManagerService.this) { 18561 if (mCurUserSwitchCallback == this) { 18562 mCount++; 18563 if (mCount == N) { 18564 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18565 } 18566 } 18567 } 18568 } 18569 }; 18570 synchronized (this) { 18571 uss.switching = true; 18572 mCurUserSwitchCallback = callback; 18573 } 18574 for (int i=0; i<N; i++) { 18575 try { 18576 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18577 newUserId, callback); 18578 } catch (RemoteException e) { 18579 } 18580 } 18581 } else { 18582 synchronized (this) { 18583 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18584 } 18585 } 18586 mUserSwitchObservers.finishBroadcast(); 18587 } 18588 18589 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18590 synchronized (this) { 18591 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18592 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18593 } 18594 } 18595 18596 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18597 mCurUserSwitchCallback = null; 18598 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18599 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18600 oldUserId, newUserId, uss)); 18601 } 18602 18603 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18604 synchronized (this) { 18605 if (foreground) { 18606 moveUserToForeground(uss, oldUserId, newUserId); 18607 } 18608 } 18609 18610 completeSwitchAndInitalize(uss, newUserId, true, false); 18611 } 18612 18613 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18614 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18615 if (homeInFront) { 18616 startHomeActivityLocked(newUserId); 18617 } else { 18618 mStackSupervisor.resumeTopActivitiesLocked(); 18619 } 18620 EventLogTags.writeAmSwitchUser(newUserId); 18621 getUserManagerLocked().userForeground(newUserId); 18622 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18623 } 18624 18625 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18626 completeSwitchAndInitalize(uss, newUserId, false, true); 18627 } 18628 18629 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18630 boolean clearInitializing, boolean clearSwitching) { 18631 boolean unfrozen = false; 18632 synchronized (this) { 18633 if (clearInitializing) { 18634 uss.initializing = false; 18635 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18636 } 18637 if (clearSwitching) { 18638 uss.switching = false; 18639 } 18640 if (!uss.switching && !uss.initializing) { 18641 mWindowManager.stopFreezingScreen(); 18642 unfrozen = true; 18643 } 18644 } 18645 if (unfrozen) { 18646 final int N = mUserSwitchObservers.beginBroadcast(); 18647 for (int i=0; i<N; i++) { 18648 try { 18649 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18650 } catch (RemoteException e) { 18651 } 18652 } 18653 mUserSwitchObservers.finishBroadcast(); 18654 } 18655 } 18656 18657 void scheduleStartProfilesLocked() { 18658 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18659 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18660 DateUtils.SECOND_IN_MILLIS); 18661 } 18662 } 18663 18664 void startProfilesLocked() { 18665 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18666 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18667 mCurrentUserId, false /* enabledOnly */); 18668 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18669 for (UserInfo user : profiles) { 18670 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18671 && user.id != mCurrentUserId) { 18672 toStart.add(user); 18673 } 18674 } 18675 final int n = toStart.size(); 18676 int i = 0; 18677 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18678 startUserInBackground(toStart.get(i).id); 18679 } 18680 if (i < n) { 18681 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18682 } 18683 } 18684 18685 void finishUserBoot(UserStartedState uss) { 18686 synchronized (this) { 18687 if (uss.mState == UserStartedState.STATE_BOOTING 18688 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18689 uss.mState = UserStartedState.STATE_RUNNING; 18690 final int userId = uss.mHandle.getIdentifier(); 18691 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18692 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18693 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18694 broadcastIntentLocked(null, null, intent, 18695 null, null, 0, null, null, 18696 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18697 true, false, MY_PID, Process.SYSTEM_UID, userId); 18698 } 18699 } 18700 } 18701 18702 void finishUserSwitch(UserStartedState uss) { 18703 synchronized (this) { 18704 finishUserBoot(uss); 18705 18706 startProfilesLocked(); 18707 18708 int num = mUserLru.size(); 18709 int i = 0; 18710 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18711 Integer oldUserId = mUserLru.get(i); 18712 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18713 if (oldUss == null) { 18714 // Shouldn't happen, but be sane if it does. 18715 mUserLru.remove(i); 18716 num--; 18717 continue; 18718 } 18719 if (oldUss.mState == UserStartedState.STATE_STOPPING 18720 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18721 // This user is already stopping, doesn't count. 18722 num--; 18723 i++; 18724 continue; 18725 } 18726 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18727 // Owner and current can't be stopped, but count as running. 18728 i++; 18729 continue; 18730 } 18731 // This is a user to be stopped. 18732 stopUserLocked(oldUserId, null); 18733 num--; 18734 i++; 18735 } 18736 } 18737 } 18738 18739 @Override 18740 public int stopUser(final int userId, final IStopUserCallback callback) { 18741 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18742 != PackageManager.PERMISSION_GRANTED) { 18743 String msg = "Permission Denial: switchUser() from pid=" 18744 + Binder.getCallingPid() 18745 + ", uid=" + Binder.getCallingUid() 18746 + " requires " + INTERACT_ACROSS_USERS_FULL; 18747 Slog.w(TAG, msg); 18748 throw new SecurityException(msg); 18749 } 18750 if (userId <= 0) { 18751 throw new IllegalArgumentException("Can't stop primary user " + userId); 18752 } 18753 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18754 synchronized (this) { 18755 return stopUserLocked(userId, callback); 18756 } 18757 } 18758 18759 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18760 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18761 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18762 return ActivityManager.USER_OP_IS_CURRENT; 18763 } 18764 18765 final UserStartedState uss = mStartedUsers.get(userId); 18766 if (uss == null) { 18767 // User is not started, nothing to do... but we do need to 18768 // callback if requested. 18769 if (callback != null) { 18770 mHandler.post(new Runnable() { 18771 @Override 18772 public void run() { 18773 try { 18774 callback.userStopped(userId); 18775 } catch (RemoteException e) { 18776 } 18777 } 18778 }); 18779 } 18780 return ActivityManager.USER_OP_SUCCESS; 18781 } 18782 18783 if (callback != null) { 18784 uss.mStopCallbacks.add(callback); 18785 } 18786 18787 if (uss.mState != UserStartedState.STATE_STOPPING 18788 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18789 uss.mState = UserStartedState.STATE_STOPPING; 18790 updateStartedUserArrayLocked(); 18791 18792 long ident = Binder.clearCallingIdentity(); 18793 try { 18794 // We are going to broadcast ACTION_USER_STOPPING and then 18795 // once that is done send a final ACTION_SHUTDOWN and then 18796 // stop the user. 18797 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18798 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18799 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18800 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18801 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18802 // This is the result receiver for the final shutdown broadcast. 18803 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18804 @Override 18805 public void performReceive(Intent intent, int resultCode, String data, 18806 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18807 finishUserStop(uss); 18808 } 18809 }; 18810 // This is the result receiver for the initial stopping broadcast. 18811 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18812 @Override 18813 public void performReceive(Intent intent, int resultCode, String data, 18814 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18815 // On to the next. 18816 synchronized (ActivityManagerService.this) { 18817 if (uss.mState != UserStartedState.STATE_STOPPING) { 18818 // Whoops, we are being started back up. Abort, abort! 18819 return; 18820 } 18821 uss.mState = UserStartedState.STATE_SHUTDOWN; 18822 } 18823 mBatteryStatsService.noteEvent( 18824 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18825 Integer.toString(userId), userId); 18826 mSystemServiceManager.stopUser(userId); 18827 broadcastIntentLocked(null, null, shutdownIntent, 18828 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18829 true, false, MY_PID, Process.SYSTEM_UID, userId); 18830 } 18831 }; 18832 // Kick things off. 18833 broadcastIntentLocked(null, null, stoppingIntent, 18834 null, stoppingReceiver, 0, null, null, 18835 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18836 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18837 } finally { 18838 Binder.restoreCallingIdentity(ident); 18839 } 18840 } 18841 18842 return ActivityManager.USER_OP_SUCCESS; 18843 } 18844 18845 void finishUserStop(UserStartedState uss) { 18846 final int userId = uss.mHandle.getIdentifier(); 18847 boolean stopped; 18848 ArrayList<IStopUserCallback> callbacks; 18849 synchronized (this) { 18850 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18851 if (mStartedUsers.get(userId) != uss) { 18852 stopped = false; 18853 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18854 stopped = false; 18855 } else { 18856 stopped = true; 18857 // User can no longer run. 18858 mStartedUsers.remove(userId); 18859 mUserLru.remove(Integer.valueOf(userId)); 18860 updateStartedUserArrayLocked(); 18861 18862 // Clean up all state and processes associated with the user. 18863 // Kill all the processes for the user. 18864 forceStopUserLocked(userId, "finish user"); 18865 } 18866 18867 // Explicitly remove the old information in mRecentTasks. 18868 removeRecentTasksForUserLocked(userId); 18869 } 18870 18871 for (int i=0; i<callbacks.size(); i++) { 18872 try { 18873 if (stopped) callbacks.get(i).userStopped(userId); 18874 else callbacks.get(i).userStopAborted(userId); 18875 } catch (RemoteException e) { 18876 } 18877 } 18878 18879 if (stopped) { 18880 mSystemServiceManager.cleanupUser(userId); 18881 synchronized (this) { 18882 mStackSupervisor.removeUserLocked(userId); 18883 } 18884 } 18885 } 18886 18887 @Override 18888 public UserInfo getCurrentUser() { 18889 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18890 != PackageManager.PERMISSION_GRANTED) && ( 18891 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18892 != PackageManager.PERMISSION_GRANTED)) { 18893 String msg = "Permission Denial: getCurrentUser() from pid=" 18894 + Binder.getCallingPid() 18895 + ", uid=" + Binder.getCallingUid() 18896 + " requires " + INTERACT_ACROSS_USERS; 18897 Slog.w(TAG, msg); 18898 throw new SecurityException(msg); 18899 } 18900 synchronized (this) { 18901 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18902 return getUserManagerLocked().getUserInfo(userId); 18903 } 18904 } 18905 18906 int getCurrentUserIdLocked() { 18907 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18908 } 18909 18910 @Override 18911 public boolean isUserRunning(int userId, boolean orStopped) { 18912 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18913 != PackageManager.PERMISSION_GRANTED) { 18914 String msg = "Permission Denial: isUserRunning() from pid=" 18915 + Binder.getCallingPid() 18916 + ", uid=" + Binder.getCallingUid() 18917 + " requires " + INTERACT_ACROSS_USERS; 18918 Slog.w(TAG, msg); 18919 throw new SecurityException(msg); 18920 } 18921 synchronized (this) { 18922 return isUserRunningLocked(userId, orStopped); 18923 } 18924 } 18925 18926 boolean isUserRunningLocked(int userId, boolean orStopped) { 18927 UserStartedState state = mStartedUsers.get(userId); 18928 if (state == null) { 18929 return false; 18930 } 18931 if (orStopped) { 18932 return true; 18933 } 18934 return state.mState != UserStartedState.STATE_STOPPING 18935 && state.mState != UserStartedState.STATE_SHUTDOWN; 18936 } 18937 18938 @Override 18939 public int[] getRunningUserIds() { 18940 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18941 != PackageManager.PERMISSION_GRANTED) { 18942 String msg = "Permission Denial: isUserRunning() from pid=" 18943 + Binder.getCallingPid() 18944 + ", uid=" + Binder.getCallingUid() 18945 + " requires " + INTERACT_ACROSS_USERS; 18946 Slog.w(TAG, msg); 18947 throw new SecurityException(msg); 18948 } 18949 synchronized (this) { 18950 return mStartedUserArray; 18951 } 18952 } 18953 18954 private void updateStartedUserArrayLocked() { 18955 int num = 0; 18956 for (int i=0; i<mStartedUsers.size(); i++) { 18957 UserStartedState uss = mStartedUsers.valueAt(i); 18958 // This list does not include stopping users. 18959 if (uss.mState != UserStartedState.STATE_STOPPING 18960 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18961 num++; 18962 } 18963 } 18964 mStartedUserArray = new int[num]; 18965 num = 0; 18966 for (int i=0; i<mStartedUsers.size(); i++) { 18967 UserStartedState uss = mStartedUsers.valueAt(i); 18968 if (uss.mState != UserStartedState.STATE_STOPPING 18969 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18970 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18971 num++; 18972 } 18973 } 18974 } 18975 18976 @Override 18977 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18978 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18979 != PackageManager.PERMISSION_GRANTED) { 18980 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18981 + Binder.getCallingPid() 18982 + ", uid=" + Binder.getCallingUid() 18983 + " requires " + INTERACT_ACROSS_USERS_FULL; 18984 Slog.w(TAG, msg); 18985 throw new SecurityException(msg); 18986 } 18987 18988 mUserSwitchObservers.register(observer); 18989 } 18990 18991 @Override 18992 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18993 mUserSwitchObservers.unregister(observer); 18994 } 18995 18996 private boolean userExists(int userId) { 18997 if (userId == 0) { 18998 return true; 18999 } 19000 UserManagerService ums = getUserManagerLocked(); 19001 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19002 } 19003 19004 int[] getUsersLocked() { 19005 UserManagerService ums = getUserManagerLocked(); 19006 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19007 } 19008 19009 UserManagerService getUserManagerLocked() { 19010 if (mUserManager == null) { 19011 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19012 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19013 } 19014 return mUserManager; 19015 } 19016 19017 private int applyUserId(int uid, int userId) { 19018 return UserHandle.getUid(userId, uid); 19019 } 19020 19021 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19022 if (info == null) return null; 19023 ApplicationInfo newInfo = new ApplicationInfo(info); 19024 newInfo.uid = applyUserId(info.uid, userId); 19025 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19026 + info.packageName; 19027 return newInfo; 19028 } 19029 19030 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19031 if (aInfo == null 19032 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19033 return aInfo; 19034 } 19035 19036 ActivityInfo info = new ActivityInfo(aInfo); 19037 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19038 return info; 19039 } 19040 19041 private final class LocalService extends ActivityManagerInternal { 19042 @Override 19043 public void goingToSleep() { 19044 ActivityManagerService.this.goingToSleep(); 19045 } 19046 19047 @Override 19048 public void wakingUp() { 19049 ActivityManagerService.this.wakingUp(); 19050 } 19051 19052 @Override 19053 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19054 String processName, String abiOverride, int uid, Runnable crashHandler) { 19055 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19056 processName, abiOverride, uid, crashHandler); 19057 } 19058 } 19059 19060 /** 19061 * An implementation of IAppTask, that allows an app to manage its own tasks via 19062 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19063 * only the process that calls getAppTasks() can call the AppTask methods. 19064 */ 19065 class AppTaskImpl extends IAppTask.Stub { 19066 private int mTaskId; 19067 private int mCallingUid; 19068 19069 public AppTaskImpl(int taskId, int callingUid) { 19070 mTaskId = taskId; 19071 mCallingUid = callingUid; 19072 } 19073 19074 private void checkCaller() { 19075 if (mCallingUid != Binder.getCallingUid()) { 19076 throw new SecurityException("Caller " + mCallingUid 19077 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19078 } 19079 } 19080 19081 @Override 19082 public void finishAndRemoveTask() { 19083 checkCaller(); 19084 19085 synchronized (ActivityManagerService.this) { 19086 long origId = Binder.clearCallingIdentity(); 19087 try { 19088 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19089 if (tr == null) { 19090 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19091 } 19092 // Only kill the process if we are not a new document 19093 int flags = tr.getBaseIntent().getFlags(); 19094 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19095 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19096 removeTaskByIdLocked(mTaskId, 19097 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19098 } finally { 19099 Binder.restoreCallingIdentity(origId); 19100 } 19101 } 19102 } 19103 19104 @Override 19105 public ActivityManager.RecentTaskInfo getTaskInfo() { 19106 checkCaller(); 19107 19108 synchronized (ActivityManagerService.this) { 19109 long origId = Binder.clearCallingIdentity(); 19110 try { 19111 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19112 if (tr == null) { 19113 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19114 } 19115 return createRecentTaskInfoFromTaskRecord(tr); 19116 } finally { 19117 Binder.restoreCallingIdentity(origId); 19118 } 19119 } 19120 } 19121 19122 @Override 19123 public void moveToFront() { 19124 checkCaller(); 19125 19126 final TaskRecord tr; 19127 synchronized (ActivityManagerService.this) { 19128 tr = recentTaskForIdLocked(mTaskId); 19129 if (tr == null) { 19130 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19131 } 19132 if (tr.getRootActivity() != null) { 19133 moveTaskToFrontLocked(tr.taskId, 0, null); 19134 return; 19135 } 19136 } 19137 19138 startActivityFromRecentsInner(tr.taskId, null); 19139 } 19140 19141 @Override 19142 public int startActivity(IBinder whoThread, String callingPackage, 19143 Intent intent, String resolvedType, Bundle options) { 19144 checkCaller(); 19145 19146 int callingUser = UserHandle.getCallingUserId(); 19147 TaskRecord tr; 19148 IApplicationThread appThread; 19149 synchronized (ActivityManagerService.this) { 19150 tr = recentTaskForIdLocked(mTaskId); 19151 if (tr == null) { 19152 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19153 } 19154 appThread = ApplicationThreadNative.asInterface(whoThread); 19155 if (appThread == null) { 19156 throw new IllegalArgumentException("Bad app thread " + appThread); 19157 } 19158 } 19159 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19160 resolvedType, null, null, null, null, 0, 0, null, null, 19161 null, options, callingUser, null, tr); 19162 } 19163 19164 @Override 19165 public void setExcludeFromRecents(boolean exclude) { 19166 checkCaller(); 19167 19168 synchronized (ActivityManagerService.this) { 19169 long origId = Binder.clearCallingIdentity(); 19170 try { 19171 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19172 if (tr == null) { 19173 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19174 } 19175 Intent intent = tr.getBaseIntent(); 19176 if (exclude) { 19177 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19178 } else { 19179 intent.setFlags(intent.getFlags() 19180 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19181 } 19182 } finally { 19183 Binder.restoreCallingIdentity(origId); 19184 } 19185 } 19186 } 19187 } 19188} 19189