ActivityManagerService.java revision b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6
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 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8856 throw new IllegalArgumentException("Invalid task, not in foreground"); 8857 } 8858 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8859 } 8860 } 8861 } finally { 8862 Binder.restoreCallingIdentity(ident); 8863 } 8864 } 8865 8866 @Override 8867 public void startLockTaskMode(int taskId) { 8868 final TaskRecord task; 8869 long ident = Binder.clearCallingIdentity(); 8870 try { 8871 synchronized (this) { 8872 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8873 } 8874 } finally { 8875 Binder.restoreCallingIdentity(ident); 8876 } 8877 if (task != null) { 8878 startLockTaskMode(task); 8879 } 8880 } 8881 8882 @Override 8883 public void startLockTaskMode(IBinder token) { 8884 final TaskRecord task; 8885 long ident = Binder.clearCallingIdentity(); 8886 try { 8887 synchronized (this) { 8888 final ActivityRecord r = ActivityRecord.forToken(token); 8889 if (r == null) { 8890 return; 8891 } 8892 task = r.task; 8893 } 8894 } finally { 8895 Binder.restoreCallingIdentity(ident); 8896 } 8897 if (task != null) { 8898 startLockTaskMode(task); 8899 } 8900 } 8901 8902 @Override 8903 public void startLockTaskModeOnCurrent() throws RemoteException { 8904 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8905 "startLockTaskModeOnCurrent"); 8906 ActivityRecord r = null; 8907 synchronized (this) { 8908 r = mStackSupervisor.topRunningActivityLocked(); 8909 } 8910 startLockTaskMode(r.task); 8911 } 8912 8913 @Override 8914 public void stopLockTaskMode() { 8915 // Verify that the user matches the package of the intent for the TaskRecord 8916 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8917 // and stopLockTaskMode. 8918 final int callingUid = Binder.getCallingUid(); 8919 if (callingUid != Process.SYSTEM_UID) { 8920 try { 8921 String pkg = 8922 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8923 int uid = mContext.getPackageManager().getPackageUid(pkg, 8924 Binder.getCallingUserHandle().getIdentifier()); 8925 if (uid != callingUid) { 8926 throw new SecurityException("Invalid uid, expected " + uid); 8927 } 8928 } catch (NameNotFoundException e) { 8929 Log.d(TAG, "stopLockTaskMode " + e); 8930 return; 8931 } 8932 } 8933 long ident = Binder.clearCallingIdentity(); 8934 try { 8935 Log.d(TAG, "stopLockTaskMode"); 8936 // Stop lock task 8937 synchronized (this) { 8938 mStackSupervisor.setLockTaskModeLocked(null, false); 8939 } 8940 } finally { 8941 Binder.restoreCallingIdentity(ident); 8942 } 8943 } 8944 8945 @Override 8946 public void stopLockTaskModeOnCurrent() throws RemoteException { 8947 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8948 "stopLockTaskModeOnCurrent"); 8949 long ident = Binder.clearCallingIdentity(); 8950 try { 8951 stopLockTaskMode(); 8952 } finally { 8953 Binder.restoreCallingIdentity(ident); 8954 } 8955 } 8956 8957 @Override 8958 public boolean isInLockTaskMode() { 8959 synchronized (this) { 8960 return mStackSupervisor.isInLockTaskMode(); 8961 } 8962 } 8963 8964 // ========================================================= 8965 // CONTENT PROVIDERS 8966 // ========================================================= 8967 8968 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8969 List<ProviderInfo> providers = null; 8970 try { 8971 providers = AppGlobals.getPackageManager(). 8972 queryContentProviders(app.processName, app.uid, 8973 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8974 } catch (RemoteException ex) { 8975 } 8976 if (DEBUG_MU) 8977 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8978 int userId = app.userId; 8979 if (providers != null) { 8980 int N = providers.size(); 8981 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8982 for (int i=0; i<N; i++) { 8983 ProviderInfo cpi = 8984 (ProviderInfo)providers.get(i); 8985 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8986 cpi.name, cpi.flags); 8987 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8988 // This is a singleton provider, but a user besides the 8989 // default user is asking to initialize a process it runs 8990 // in... well, no, it doesn't actually run in this process, 8991 // it runs in the process of the default user. Get rid of it. 8992 providers.remove(i); 8993 N--; 8994 i--; 8995 continue; 8996 } 8997 8998 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8999 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 9000 if (cpr == null) { 9001 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 9002 mProviderMap.putProviderByClass(comp, cpr); 9003 } 9004 if (DEBUG_MU) 9005 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9006 app.pubProviders.put(cpi.name, cpr); 9007 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9008 // Don't add this if it is a platform component that is marked 9009 // to run in multiple processes, because this is actually 9010 // part of the framework so doesn't make sense to track as a 9011 // separate apk in the process. 9012 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9013 mProcessStats); 9014 } 9015 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9016 } 9017 } 9018 return providers; 9019 } 9020 9021 /** 9022 * Check if {@link ProcessRecord} has a possible chance at accessing the 9023 * given {@link ProviderInfo}. Final permission checking is always done 9024 * in {@link ContentProvider}. 9025 */ 9026 private final String checkContentProviderPermissionLocked( 9027 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9028 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9029 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9030 boolean checkedGrants = false; 9031 if (checkUser) { 9032 // Looking for cross-user grants before enforcing the typical cross-users permissions 9033 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9034 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9035 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9036 return null; 9037 } 9038 checkedGrants = true; 9039 } 9040 userId = handleIncomingUser(callingPid, callingUid, userId, 9041 false, ALLOW_NON_FULL, 9042 "checkContentProviderPermissionLocked " + cpi.authority, null); 9043 if (userId != tmpTargetUserId) { 9044 // When we actually went to determine the final targer user ID, this ended 9045 // up different than our initial check for the authority. This is because 9046 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9047 // SELF. So we need to re-check the grants again. 9048 checkedGrants = false; 9049 } 9050 } 9051 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9052 cpi.applicationInfo.uid, cpi.exported) 9053 == PackageManager.PERMISSION_GRANTED) { 9054 return null; 9055 } 9056 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9057 cpi.applicationInfo.uid, cpi.exported) 9058 == PackageManager.PERMISSION_GRANTED) { 9059 return null; 9060 } 9061 9062 PathPermission[] pps = cpi.pathPermissions; 9063 if (pps != null) { 9064 int i = pps.length; 9065 while (i > 0) { 9066 i--; 9067 PathPermission pp = pps[i]; 9068 String pprperm = pp.getReadPermission(); 9069 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9070 cpi.applicationInfo.uid, cpi.exported) 9071 == PackageManager.PERMISSION_GRANTED) { 9072 return null; 9073 } 9074 String ppwperm = pp.getWritePermission(); 9075 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9076 cpi.applicationInfo.uid, cpi.exported) 9077 == PackageManager.PERMISSION_GRANTED) { 9078 return null; 9079 } 9080 } 9081 } 9082 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9083 return null; 9084 } 9085 9086 String msg; 9087 if (!cpi.exported) { 9088 msg = "Permission Denial: opening provider " + cpi.name 9089 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9090 + ", uid=" + callingUid + ") that is not exported from uid " 9091 + cpi.applicationInfo.uid; 9092 } else { 9093 msg = "Permission Denial: opening provider " + cpi.name 9094 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9095 + ", uid=" + callingUid + ") requires " 9096 + cpi.readPermission + " or " + cpi.writePermission; 9097 } 9098 Slog.w(TAG, msg); 9099 return msg; 9100 } 9101 9102 /** 9103 * Returns if the ContentProvider has granted a uri to callingUid 9104 */ 9105 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9106 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9107 if (perms != null) { 9108 for (int i=perms.size()-1; i>=0; i--) { 9109 GrantUri grantUri = perms.keyAt(i); 9110 if (grantUri.sourceUserId == userId || !checkUser) { 9111 if (matchesProvider(grantUri.uri, cpi)) { 9112 return true; 9113 } 9114 } 9115 } 9116 } 9117 return false; 9118 } 9119 9120 /** 9121 * Returns true if the uri authority is one of the authorities specified in the provider. 9122 */ 9123 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9124 String uriAuth = uri.getAuthority(); 9125 String cpiAuth = cpi.authority; 9126 if (cpiAuth.indexOf(';') == -1) { 9127 return cpiAuth.equals(uriAuth); 9128 } 9129 String[] cpiAuths = cpiAuth.split(";"); 9130 int length = cpiAuths.length; 9131 for (int i = 0; i < length; i++) { 9132 if (cpiAuths[i].equals(uriAuth)) return true; 9133 } 9134 return false; 9135 } 9136 9137 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9138 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9139 if (r != null) { 9140 for (int i=0; i<r.conProviders.size(); i++) { 9141 ContentProviderConnection conn = r.conProviders.get(i); 9142 if (conn.provider == cpr) { 9143 if (DEBUG_PROVIDER) Slog.v(TAG, 9144 "Adding provider requested by " 9145 + r.processName + " from process " 9146 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9147 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9148 if (stable) { 9149 conn.stableCount++; 9150 conn.numStableIncs++; 9151 } else { 9152 conn.unstableCount++; 9153 conn.numUnstableIncs++; 9154 } 9155 return conn; 9156 } 9157 } 9158 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9159 if (stable) { 9160 conn.stableCount = 1; 9161 conn.numStableIncs = 1; 9162 } else { 9163 conn.unstableCount = 1; 9164 conn.numUnstableIncs = 1; 9165 } 9166 cpr.connections.add(conn); 9167 r.conProviders.add(conn); 9168 return conn; 9169 } 9170 cpr.addExternalProcessHandleLocked(externalProcessToken); 9171 return null; 9172 } 9173 9174 boolean decProviderCountLocked(ContentProviderConnection conn, 9175 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9176 if (conn != null) { 9177 cpr = conn.provider; 9178 if (DEBUG_PROVIDER) Slog.v(TAG, 9179 "Removing provider requested by " 9180 + conn.client.processName + " from process " 9181 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9182 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9183 if (stable) { 9184 conn.stableCount--; 9185 } else { 9186 conn.unstableCount--; 9187 } 9188 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9189 cpr.connections.remove(conn); 9190 conn.client.conProviders.remove(conn); 9191 return true; 9192 } 9193 return false; 9194 } 9195 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9196 return false; 9197 } 9198 9199 private void checkTime(long startTime, String where) { 9200 long now = SystemClock.elapsedRealtime(); 9201 if ((now-startTime) > 1000) { 9202 // If we are taking more than a second, log about it. 9203 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9204 } 9205 } 9206 9207 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9208 String name, IBinder token, boolean stable, int userId) { 9209 ContentProviderRecord cpr; 9210 ContentProviderConnection conn = null; 9211 ProviderInfo cpi = null; 9212 9213 synchronized(this) { 9214 long startTime = SystemClock.elapsedRealtime(); 9215 9216 ProcessRecord r = null; 9217 if (caller != null) { 9218 r = getRecordForAppLocked(caller); 9219 if (r == null) { 9220 throw new SecurityException( 9221 "Unable to find app for caller " + caller 9222 + " (pid=" + Binder.getCallingPid() 9223 + ") when getting content provider " + name); 9224 } 9225 } 9226 9227 boolean checkCrossUser = true; 9228 9229 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9230 9231 // First check if this content provider has been published... 9232 cpr = mProviderMap.getProviderByName(name, userId); 9233 // If that didn't work, check if it exists for user 0 and then 9234 // verify that it's a singleton provider before using it. 9235 if (cpr == null && userId != UserHandle.USER_OWNER) { 9236 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9237 if (cpr != null) { 9238 cpi = cpr.info; 9239 if (isSingleton(cpi.processName, cpi.applicationInfo, 9240 cpi.name, cpi.flags) 9241 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9242 userId = UserHandle.USER_OWNER; 9243 checkCrossUser = false; 9244 } else { 9245 cpr = null; 9246 cpi = null; 9247 } 9248 } 9249 } 9250 9251 boolean providerRunning = cpr != null; 9252 if (providerRunning) { 9253 cpi = cpr.info; 9254 String msg; 9255 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9256 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9257 != null) { 9258 throw new SecurityException(msg); 9259 } 9260 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9261 9262 if (r != null && cpr.canRunHere(r)) { 9263 // This provider has been published or is in the process 9264 // of being published... but it is also allowed to run 9265 // in the caller's process, so don't make a connection 9266 // and just let the caller instantiate its own instance. 9267 ContentProviderHolder holder = cpr.newHolder(null); 9268 // don't give caller the provider object, it needs 9269 // to make its own. 9270 holder.provider = null; 9271 return holder; 9272 } 9273 9274 final long origId = Binder.clearCallingIdentity(); 9275 9276 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9277 9278 // In this case the provider instance already exists, so we can 9279 // return it right away. 9280 conn = incProviderCountLocked(r, cpr, token, stable); 9281 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9282 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9283 // If this is a perceptible app accessing the provider, 9284 // make sure to count it as being accessed and thus 9285 // back up on the LRU list. This is good because 9286 // content providers are often expensive to start. 9287 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9288 updateLruProcessLocked(cpr.proc, false, null); 9289 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9290 } 9291 } 9292 9293 if (cpr.proc != null) { 9294 if (false) { 9295 if (cpr.name.flattenToShortString().equals( 9296 "com.android.providers.calendar/.CalendarProvider2")) { 9297 Slog.v(TAG, "****************** KILLING " 9298 + cpr.name.flattenToShortString()); 9299 Process.killProcess(cpr.proc.pid); 9300 } 9301 } 9302 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9303 boolean success = updateOomAdjLocked(cpr.proc); 9304 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9305 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9306 // NOTE: there is still a race here where a signal could be 9307 // pending on the process even though we managed to update its 9308 // adj level. Not sure what to do about this, but at least 9309 // the race is now smaller. 9310 if (!success) { 9311 // Uh oh... it looks like the provider's process 9312 // has been killed on us. We need to wait for a new 9313 // process to be started, and make sure its death 9314 // doesn't kill our process. 9315 Slog.i(TAG, 9316 "Existing provider " + cpr.name.flattenToShortString() 9317 + " is crashing; detaching " + r); 9318 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9319 checkTime(startTime, "getContentProviderImpl: before appDied"); 9320 appDiedLocked(cpr.proc); 9321 checkTime(startTime, "getContentProviderImpl: after appDied"); 9322 if (!lastRef) { 9323 // This wasn't the last ref our process had on 9324 // the provider... we have now been killed, bail. 9325 return null; 9326 } 9327 providerRunning = false; 9328 conn = null; 9329 } 9330 } 9331 9332 Binder.restoreCallingIdentity(origId); 9333 } 9334 9335 boolean singleton; 9336 if (!providerRunning) { 9337 try { 9338 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9339 cpi = AppGlobals.getPackageManager(). 9340 resolveContentProvider(name, 9341 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9342 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9343 } catch (RemoteException ex) { 9344 } 9345 if (cpi == null) { 9346 return null; 9347 } 9348 // If the provider is a singleton AND 9349 // (it's a call within the same user || the provider is a 9350 // privileged app) 9351 // Then allow connecting to the singleton provider 9352 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9353 cpi.name, cpi.flags) 9354 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9355 if (singleton) { 9356 userId = UserHandle.USER_OWNER; 9357 } 9358 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9359 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9360 9361 String msg; 9362 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9363 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9364 != null) { 9365 throw new SecurityException(msg); 9366 } 9367 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9368 9369 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9370 && !cpi.processName.equals("system")) { 9371 // If this content provider does not run in the system 9372 // process, and the system is not yet ready to run other 9373 // processes, then fail fast instead of hanging. 9374 throw new IllegalArgumentException( 9375 "Attempt to launch content provider before system ready"); 9376 } 9377 9378 // Make sure that the user who owns this provider is started. If not, 9379 // we don't want to allow it to run. 9380 if (mStartedUsers.get(userId) == null) { 9381 Slog.w(TAG, "Unable to launch app " 9382 + cpi.applicationInfo.packageName + "/" 9383 + cpi.applicationInfo.uid + " for provider " 9384 + name + ": user " + userId + " is stopped"); 9385 return null; 9386 } 9387 9388 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9389 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9390 cpr = mProviderMap.getProviderByClass(comp, userId); 9391 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9392 final boolean firstClass = cpr == null; 9393 if (firstClass) { 9394 final long ident = Binder.clearCallingIdentity(); 9395 try { 9396 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9397 ApplicationInfo ai = 9398 AppGlobals.getPackageManager(). 9399 getApplicationInfo( 9400 cpi.applicationInfo.packageName, 9401 STOCK_PM_FLAGS, userId); 9402 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9403 if (ai == null) { 9404 Slog.w(TAG, "No package info for content provider " 9405 + cpi.name); 9406 return null; 9407 } 9408 ai = getAppInfoForUser(ai, userId); 9409 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9410 } catch (RemoteException ex) { 9411 // pm is in same process, this will never happen. 9412 } finally { 9413 Binder.restoreCallingIdentity(ident); 9414 } 9415 } 9416 9417 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9418 9419 if (r != null && cpr.canRunHere(r)) { 9420 // If this is a multiprocess provider, then just return its 9421 // info and allow the caller to instantiate it. Only do 9422 // this if the provider is the same user as the caller's 9423 // process, or can run as root (so can be in any process). 9424 return cpr.newHolder(null); 9425 } 9426 9427 if (DEBUG_PROVIDER) { 9428 RuntimeException e = new RuntimeException("here"); 9429 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9430 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9431 } 9432 9433 // This is single process, and our app is now connecting to it. 9434 // See if we are already in the process of launching this 9435 // provider. 9436 final int N = mLaunchingProviders.size(); 9437 int i; 9438 for (i=0; i<N; i++) { 9439 if (mLaunchingProviders.get(i) == cpr) { 9440 break; 9441 } 9442 } 9443 9444 // If the provider is not already being launched, then get it 9445 // started. 9446 if (i >= N) { 9447 final long origId = Binder.clearCallingIdentity(); 9448 9449 try { 9450 // Content provider is now in use, its package can't be stopped. 9451 try { 9452 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9453 AppGlobals.getPackageManager().setPackageStoppedState( 9454 cpr.appInfo.packageName, false, userId); 9455 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9456 } catch (RemoteException e) { 9457 } catch (IllegalArgumentException e) { 9458 Slog.w(TAG, "Failed trying to unstop package " 9459 + cpr.appInfo.packageName + ": " + e); 9460 } 9461 9462 // Use existing process if already started 9463 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9464 ProcessRecord proc = getProcessRecordLocked( 9465 cpi.processName, cpr.appInfo.uid, false); 9466 if (proc != null && proc.thread != null) { 9467 if (DEBUG_PROVIDER) { 9468 Slog.d(TAG, "Installing in existing process " + proc); 9469 } 9470 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9471 proc.pubProviders.put(cpi.name, cpr); 9472 try { 9473 proc.thread.scheduleInstallProvider(cpi); 9474 } catch (RemoteException e) { 9475 } 9476 } else { 9477 checkTime(startTime, "getContentProviderImpl: before start process"); 9478 proc = startProcessLocked(cpi.processName, 9479 cpr.appInfo, false, 0, "content provider", 9480 new ComponentName(cpi.applicationInfo.packageName, 9481 cpi.name), false, false, false); 9482 checkTime(startTime, "getContentProviderImpl: after start process"); 9483 if (proc == null) { 9484 Slog.w(TAG, "Unable to launch app " 9485 + cpi.applicationInfo.packageName + "/" 9486 + cpi.applicationInfo.uid + " for provider " 9487 + name + ": process is bad"); 9488 return null; 9489 } 9490 } 9491 cpr.launchingApp = proc; 9492 mLaunchingProviders.add(cpr); 9493 } finally { 9494 Binder.restoreCallingIdentity(origId); 9495 } 9496 } 9497 9498 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9499 9500 // Make sure the provider is published (the same provider class 9501 // may be published under multiple names). 9502 if (firstClass) { 9503 mProviderMap.putProviderByClass(comp, cpr); 9504 } 9505 9506 mProviderMap.putProviderByName(name, cpr); 9507 conn = incProviderCountLocked(r, cpr, token, stable); 9508 if (conn != null) { 9509 conn.waiting = true; 9510 } 9511 } 9512 checkTime(startTime, "getContentProviderImpl: done!"); 9513 } 9514 9515 // Wait for the provider to be published... 9516 synchronized (cpr) { 9517 while (cpr.provider == null) { 9518 if (cpr.launchingApp == null) { 9519 Slog.w(TAG, "Unable to launch app " 9520 + cpi.applicationInfo.packageName + "/" 9521 + cpi.applicationInfo.uid + " for provider " 9522 + name + ": launching app became null"); 9523 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9524 UserHandle.getUserId(cpi.applicationInfo.uid), 9525 cpi.applicationInfo.packageName, 9526 cpi.applicationInfo.uid, name); 9527 return null; 9528 } 9529 try { 9530 if (DEBUG_MU) { 9531 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9532 + cpr.launchingApp); 9533 } 9534 if (conn != null) { 9535 conn.waiting = true; 9536 } 9537 cpr.wait(); 9538 } catch (InterruptedException ex) { 9539 } finally { 9540 if (conn != null) { 9541 conn.waiting = false; 9542 } 9543 } 9544 } 9545 } 9546 return cpr != null ? cpr.newHolder(conn) : null; 9547 } 9548 9549 @Override 9550 public final ContentProviderHolder getContentProvider( 9551 IApplicationThread caller, String name, int userId, boolean stable) { 9552 enforceNotIsolatedCaller("getContentProvider"); 9553 if (caller == null) { 9554 String msg = "null IApplicationThread when getting content provider " 9555 + name; 9556 Slog.w(TAG, msg); 9557 throw new SecurityException(msg); 9558 } 9559 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9560 // with cross-user grant. 9561 return getContentProviderImpl(caller, name, null, stable, userId); 9562 } 9563 9564 public ContentProviderHolder getContentProviderExternal( 9565 String name, int userId, IBinder token) { 9566 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9567 "Do not have permission in call getContentProviderExternal()"); 9568 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9569 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9570 return getContentProviderExternalUnchecked(name, token, userId); 9571 } 9572 9573 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9574 IBinder token, int userId) { 9575 return getContentProviderImpl(null, name, token, true, userId); 9576 } 9577 9578 /** 9579 * Drop a content provider from a ProcessRecord's bookkeeping 9580 */ 9581 public void removeContentProvider(IBinder connection, boolean stable) { 9582 enforceNotIsolatedCaller("removeContentProvider"); 9583 long ident = Binder.clearCallingIdentity(); 9584 try { 9585 synchronized (this) { 9586 ContentProviderConnection conn; 9587 try { 9588 conn = (ContentProviderConnection)connection; 9589 } catch (ClassCastException e) { 9590 String msg ="removeContentProvider: " + connection 9591 + " not a ContentProviderConnection"; 9592 Slog.w(TAG, msg); 9593 throw new IllegalArgumentException(msg); 9594 } 9595 if (conn == null) { 9596 throw new NullPointerException("connection is null"); 9597 } 9598 if (decProviderCountLocked(conn, null, null, stable)) { 9599 updateOomAdjLocked(); 9600 } 9601 } 9602 } finally { 9603 Binder.restoreCallingIdentity(ident); 9604 } 9605 } 9606 9607 public void removeContentProviderExternal(String name, IBinder token) { 9608 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9609 "Do not have permission in call removeContentProviderExternal()"); 9610 int userId = UserHandle.getCallingUserId(); 9611 long ident = Binder.clearCallingIdentity(); 9612 try { 9613 removeContentProviderExternalUnchecked(name, token, userId); 9614 } finally { 9615 Binder.restoreCallingIdentity(ident); 9616 } 9617 } 9618 9619 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9620 synchronized (this) { 9621 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9622 if(cpr == null) { 9623 //remove from mProvidersByClass 9624 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9625 return; 9626 } 9627 9628 //update content provider record entry info 9629 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9630 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9631 if (localCpr.hasExternalProcessHandles()) { 9632 if (localCpr.removeExternalProcessHandleLocked(token)) { 9633 updateOomAdjLocked(); 9634 } else { 9635 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9636 + " with no external reference for token: " 9637 + token + "."); 9638 } 9639 } else { 9640 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9641 + " with no external references."); 9642 } 9643 } 9644 } 9645 9646 public final void publishContentProviders(IApplicationThread caller, 9647 List<ContentProviderHolder> providers) { 9648 if (providers == null) { 9649 return; 9650 } 9651 9652 enforceNotIsolatedCaller("publishContentProviders"); 9653 synchronized (this) { 9654 final ProcessRecord r = getRecordForAppLocked(caller); 9655 if (DEBUG_MU) 9656 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9657 if (r == null) { 9658 throw new SecurityException( 9659 "Unable to find app for caller " + caller 9660 + " (pid=" + Binder.getCallingPid() 9661 + ") when publishing content providers"); 9662 } 9663 9664 final long origId = Binder.clearCallingIdentity(); 9665 9666 final int N = providers.size(); 9667 for (int i=0; i<N; i++) { 9668 ContentProviderHolder src = providers.get(i); 9669 if (src == null || src.info == null || src.provider == null) { 9670 continue; 9671 } 9672 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9673 if (DEBUG_MU) 9674 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9675 if (dst != null) { 9676 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9677 mProviderMap.putProviderByClass(comp, dst); 9678 String names[] = dst.info.authority.split(";"); 9679 for (int j = 0; j < names.length; j++) { 9680 mProviderMap.putProviderByName(names[j], dst); 9681 } 9682 9683 int NL = mLaunchingProviders.size(); 9684 int j; 9685 for (j=0; j<NL; j++) { 9686 if (mLaunchingProviders.get(j) == dst) { 9687 mLaunchingProviders.remove(j); 9688 j--; 9689 NL--; 9690 } 9691 } 9692 synchronized (dst) { 9693 dst.provider = src.provider; 9694 dst.proc = r; 9695 dst.notifyAll(); 9696 } 9697 updateOomAdjLocked(r); 9698 } 9699 } 9700 9701 Binder.restoreCallingIdentity(origId); 9702 } 9703 } 9704 9705 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9706 ContentProviderConnection conn; 9707 try { 9708 conn = (ContentProviderConnection)connection; 9709 } catch (ClassCastException e) { 9710 String msg ="refContentProvider: " + connection 9711 + " not a ContentProviderConnection"; 9712 Slog.w(TAG, msg); 9713 throw new IllegalArgumentException(msg); 9714 } 9715 if (conn == null) { 9716 throw new NullPointerException("connection is null"); 9717 } 9718 9719 synchronized (this) { 9720 if (stable > 0) { 9721 conn.numStableIncs += stable; 9722 } 9723 stable = conn.stableCount + stable; 9724 if (stable < 0) { 9725 throw new IllegalStateException("stableCount < 0: " + stable); 9726 } 9727 9728 if (unstable > 0) { 9729 conn.numUnstableIncs += unstable; 9730 } 9731 unstable = conn.unstableCount + unstable; 9732 if (unstable < 0) { 9733 throw new IllegalStateException("unstableCount < 0: " + unstable); 9734 } 9735 9736 if ((stable+unstable) <= 0) { 9737 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9738 + stable + " unstable=" + unstable); 9739 } 9740 conn.stableCount = stable; 9741 conn.unstableCount = unstable; 9742 return !conn.dead; 9743 } 9744 } 9745 9746 public void unstableProviderDied(IBinder connection) { 9747 ContentProviderConnection conn; 9748 try { 9749 conn = (ContentProviderConnection)connection; 9750 } catch (ClassCastException e) { 9751 String msg ="refContentProvider: " + connection 9752 + " not a ContentProviderConnection"; 9753 Slog.w(TAG, msg); 9754 throw new IllegalArgumentException(msg); 9755 } 9756 if (conn == null) { 9757 throw new NullPointerException("connection is null"); 9758 } 9759 9760 // Safely retrieve the content provider associated with the connection. 9761 IContentProvider provider; 9762 synchronized (this) { 9763 provider = conn.provider.provider; 9764 } 9765 9766 if (provider == null) { 9767 // Um, yeah, we're way ahead of you. 9768 return; 9769 } 9770 9771 // Make sure the caller is being honest with us. 9772 if (provider.asBinder().pingBinder()) { 9773 // Er, no, still looks good to us. 9774 synchronized (this) { 9775 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9776 + " says " + conn + " died, but we don't agree"); 9777 return; 9778 } 9779 } 9780 9781 // Well look at that! It's dead! 9782 synchronized (this) { 9783 if (conn.provider.provider != provider) { 9784 // But something changed... good enough. 9785 return; 9786 } 9787 9788 ProcessRecord proc = conn.provider.proc; 9789 if (proc == null || proc.thread == null) { 9790 // Seems like the process is already cleaned up. 9791 return; 9792 } 9793 9794 // As far as we're concerned, this is just like receiving a 9795 // death notification... just a bit prematurely. 9796 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9797 + ") early provider death"); 9798 final long ident = Binder.clearCallingIdentity(); 9799 try { 9800 appDiedLocked(proc); 9801 } finally { 9802 Binder.restoreCallingIdentity(ident); 9803 } 9804 } 9805 } 9806 9807 @Override 9808 public void appNotRespondingViaProvider(IBinder connection) { 9809 enforceCallingPermission( 9810 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9811 9812 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9813 if (conn == null) { 9814 Slog.w(TAG, "ContentProviderConnection is null"); 9815 return; 9816 } 9817 9818 final ProcessRecord host = conn.provider.proc; 9819 if (host == null) { 9820 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9821 return; 9822 } 9823 9824 final long token = Binder.clearCallingIdentity(); 9825 try { 9826 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9827 } finally { 9828 Binder.restoreCallingIdentity(token); 9829 } 9830 } 9831 9832 public final void installSystemProviders() { 9833 List<ProviderInfo> providers; 9834 synchronized (this) { 9835 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9836 providers = generateApplicationProvidersLocked(app); 9837 if (providers != null) { 9838 for (int i=providers.size()-1; i>=0; i--) { 9839 ProviderInfo pi = (ProviderInfo)providers.get(i); 9840 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9841 Slog.w(TAG, "Not installing system proc provider " + pi.name 9842 + ": not system .apk"); 9843 providers.remove(i); 9844 } 9845 } 9846 } 9847 } 9848 if (providers != null) { 9849 mSystemThread.installSystemProviders(providers); 9850 } 9851 9852 mCoreSettingsObserver = new CoreSettingsObserver(this); 9853 9854 //mUsageStatsService.monitorPackages(); 9855 } 9856 9857 /** 9858 * Allows apps to retrieve the MIME type of a URI. 9859 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9860 * users, then it does not need permission to access the ContentProvider. 9861 * Either, it needs cross-user uri grants. 9862 * 9863 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9864 * 9865 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9866 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9867 */ 9868 public String getProviderMimeType(Uri uri, int userId) { 9869 enforceNotIsolatedCaller("getProviderMimeType"); 9870 final String name = uri.getAuthority(); 9871 int callingUid = Binder.getCallingUid(); 9872 int callingPid = Binder.getCallingPid(); 9873 long ident = 0; 9874 boolean clearedIdentity = false; 9875 userId = unsafeConvertIncomingUser(userId); 9876 if (canClearIdentity(callingPid, callingUid, userId)) { 9877 clearedIdentity = true; 9878 ident = Binder.clearCallingIdentity(); 9879 } 9880 ContentProviderHolder holder = null; 9881 try { 9882 holder = getContentProviderExternalUnchecked(name, null, userId); 9883 if (holder != null) { 9884 return holder.provider.getType(uri); 9885 } 9886 } catch (RemoteException e) { 9887 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9888 return null; 9889 } finally { 9890 // We need to clear the identity to call removeContentProviderExternalUnchecked 9891 if (!clearedIdentity) { 9892 ident = Binder.clearCallingIdentity(); 9893 } 9894 try { 9895 if (holder != null) { 9896 removeContentProviderExternalUnchecked(name, null, userId); 9897 } 9898 } finally { 9899 Binder.restoreCallingIdentity(ident); 9900 } 9901 } 9902 9903 return null; 9904 } 9905 9906 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9907 if (UserHandle.getUserId(callingUid) == userId) { 9908 return true; 9909 } 9910 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9911 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9912 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9913 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9914 return true; 9915 } 9916 return false; 9917 } 9918 9919 // ========================================================= 9920 // GLOBAL MANAGEMENT 9921 // ========================================================= 9922 9923 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9924 boolean isolated, int isolatedUid) { 9925 String proc = customProcess != null ? customProcess : info.processName; 9926 BatteryStatsImpl.Uid.Proc ps = null; 9927 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9928 int uid = info.uid; 9929 if (isolated) { 9930 if (isolatedUid == 0) { 9931 int userId = UserHandle.getUserId(uid); 9932 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9933 while (true) { 9934 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9935 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9936 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9937 } 9938 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9939 mNextIsolatedProcessUid++; 9940 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9941 // No process for this uid, use it. 9942 break; 9943 } 9944 stepsLeft--; 9945 if (stepsLeft <= 0) { 9946 return null; 9947 } 9948 } 9949 } else { 9950 // Special case for startIsolatedProcess (internal only), where 9951 // the uid of the isolated process is specified by the caller. 9952 uid = isolatedUid; 9953 } 9954 } 9955 return new ProcessRecord(stats, info, proc, uid); 9956 } 9957 9958 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9959 String abiOverride) { 9960 ProcessRecord app; 9961 if (!isolated) { 9962 app = getProcessRecordLocked(info.processName, info.uid, true); 9963 } else { 9964 app = null; 9965 } 9966 9967 if (app == null) { 9968 app = newProcessRecordLocked(info, null, isolated, 0); 9969 mProcessNames.put(info.processName, app.uid, app); 9970 if (isolated) { 9971 mIsolatedProcesses.put(app.uid, app); 9972 } 9973 updateLruProcessLocked(app, false, null); 9974 updateOomAdjLocked(); 9975 } 9976 9977 // This package really, really can not be stopped. 9978 try { 9979 AppGlobals.getPackageManager().setPackageStoppedState( 9980 info.packageName, false, UserHandle.getUserId(app.uid)); 9981 } catch (RemoteException e) { 9982 } catch (IllegalArgumentException e) { 9983 Slog.w(TAG, "Failed trying to unstop package " 9984 + info.packageName + ": " + e); 9985 } 9986 9987 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9988 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9989 app.persistent = true; 9990 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9991 } 9992 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9993 mPersistentStartingProcesses.add(app); 9994 startProcessLocked(app, "added application", app.processName, abiOverride, 9995 null /* entryPoint */, null /* entryPointArgs */); 9996 } 9997 9998 return app; 9999 } 10000 10001 public void unhandledBack() { 10002 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10003 "unhandledBack()"); 10004 10005 synchronized(this) { 10006 final long origId = Binder.clearCallingIdentity(); 10007 try { 10008 getFocusedStack().unhandledBackLocked(); 10009 } finally { 10010 Binder.restoreCallingIdentity(origId); 10011 } 10012 } 10013 } 10014 10015 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10016 enforceNotIsolatedCaller("openContentUri"); 10017 final int userId = UserHandle.getCallingUserId(); 10018 String name = uri.getAuthority(); 10019 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10020 ParcelFileDescriptor pfd = null; 10021 if (cph != null) { 10022 // We record the binder invoker's uid in thread-local storage before 10023 // going to the content provider to open the file. Later, in the code 10024 // that handles all permissions checks, we look for this uid and use 10025 // that rather than the Activity Manager's own uid. The effect is that 10026 // we do the check against the caller's permissions even though it looks 10027 // to the content provider like the Activity Manager itself is making 10028 // the request. 10029 sCallerIdentity.set(new Identity( 10030 Binder.getCallingPid(), Binder.getCallingUid())); 10031 try { 10032 pfd = cph.provider.openFile(null, uri, "r", null); 10033 } catch (FileNotFoundException e) { 10034 // do nothing; pfd will be returned null 10035 } finally { 10036 // Ensure that whatever happens, we clean up the identity state 10037 sCallerIdentity.remove(); 10038 } 10039 10040 // We've got the fd now, so we're done with the provider. 10041 removeContentProviderExternalUnchecked(name, null, userId); 10042 } else { 10043 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10044 } 10045 return pfd; 10046 } 10047 10048 // Actually is sleeping or shutting down or whatever else in the future 10049 // is an inactive state. 10050 public boolean isSleepingOrShuttingDown() { 10051 return isSleeping() || mShuttingDown; 10052 } 10053 10054 public boolean isSleeping() { 10055 return mSleeping; 10056 } 10057 10058 void goingToSleep() { 10059 synchronized(this) { 10060 mWentToSleep = true; 10061 goToSleepIfNeededLocked(); 10062 } 10063 } 10064 10065 void finishRunningVoiceLocked() { 10066 if (mRunningVoice) { 10067 mRunningVoice = false; 10068 goToSleepIfNeededLocked(); 10069 } 10070 } 10071 10072 void goToSleepIfNeededLocked() { 10073 if (mWentToSleep && !mRunningVoice) { 10074 if (!mSleeping) { 10075 mSleeping = true; 10076 mStackSupervisor.goingToSleepLocked(); 10077 10078 // Initialize the wake times of all processes. 10079 checkExcessivePowerUsageLocked(false); 10080 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10081 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10082 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10083 } 10084 } 10085 } 10086 10087 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10088 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10089 // Never persist the home stack. 10090 return; 10091 } 10092 mTaskPersister.wakeup(task, flush); 10093 } 10094 10095 @Override 10096 public boolean shutdown(int timeout) { 10097 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10098 != PackageManager.PERMISSION_GRANTED) { 10099 throw new SecurityException("Requires permission " 10100 + android.Manifest.permission.SHUTDOWN); 10101 } 10102 10103 boolean timedout = false; 10104 10105 synchronized(this) { 10106 mShuttingDown = true; 10107 updateEventDispatchingLocked(); 10108 timedout = mStackSupervisor.shutdownLocked(timeout); 10109 } 10110 10111 mAppOpsService.shutdown(); 10112 if (mUsageStatsService != null) { 10113 mUsageStatsService.prepareShutdown(); 10114 } 10115 mBatteryStatsService.shutdown(); 10116 synchronized (this) { 10117 mProcessStats.shutdownLocked(); 10118 } 10119 notifyTaskPersisterLocked(null, true); 10120 10121 return timedout; 10122 } 10123 10124 public final void activitySlept(IBinder token) { 10125 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10126 10127 final long origId = Binder.clearCallingIdentity(); 10128 10129 synchronized (this) { 10130 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10131 if (r != null) { 10132 mStackSupervisor.activitySleptLocked(r); 10133 } 10134 } 10135 10136 Binder.restoreCallingIdentity(origId); 10137 } 10138 10139 void logLockScreen(String msg) { 10140 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10141 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10142 mWentToSleep + " mSleeping=" + mSleeping); 10143 } 10144 10145 private void comeOutOfSleepIfNeededLocked() { 10146 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10147 if (mSleeping) { 10148 mSleeping = false; 10149 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10150 } 10151 } 10152 } 10153 10154 void wakingUp() { 10155 synchronized(this) { 10156 mWentToSleep = false; 10157 comeOutOfSleepIfNeededLocked(); 10158 } 10159 } 10160 10161 void startRunningVoiceLocked() { 10162 if (!mRunningVoice) { 10163 mRunningVoice = true; 10164 comeOutOfSleepIfNeededLocked(); 10165 } 10166 } 10167 10168 private void updateEventDispatchingLocked() { 10169 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10170 } 10171 10172 public void setLockScreenShown(boolean shown) { 10173 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10174 != PackageManager.PERMISSION_GRANTED) { 10175 throw new SecurityException("Requires permission " 10176 + android.Manifest.permission.DEVICE_POWER); 10177 } 10178 10179 synchronized(this) { 10180 long ident = Binder.clearCallingIdentity(); 10181 try { 10182 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10183 mLockScreenShown = shown; 10184 comeOutOfSleepIfNeededLocked(); 10185 } finally { 10186 Binder.restoreCallingIdentity(ident); 10187 } 10188 } 10189 } 10190 10191 @Override 10192 public void stopAppSwitches() { 10193 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10194 != PackageManager.PERMISSION_GRANTED) { 10195 throw new SecurityException("Requires permission " 10196 + android.Manifest.permission.STOP_APP_SWITCHES); 10197 } 10198 10199 synchronized(this) { 10200 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10201 + APP_SWITCH_DELAY_TIME; 10202 mDidAppSwitch = false; 10203 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10204 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10205 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10206 } 10207 } 10208 10209 public void resumeAppSwitches() { 10210 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10211 != PackageManager.PERMISSION_GRANTED) { 10212 throw new SecurityException("Requires permission " 10213 + android.Manifest.permission.STOP_APP_SWITCHES); 10214 } 10215 10216 synchronized(this) { 10217 // Note that we don't execute any pending app switches... we will 10218 // let those wait until either the timeout, or the next start 10219 // activity request. 10220 mAppSwitchesAllowedTime = 0; 10221 } 10222 } 10223 10224 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10225 int callingPid, int callingUid, String name) { 10226 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10227 return true; 10228 } 10229 10230 int perm = checkComponentPermission( 10231 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10232 sourceUid, -1, true); 10233 if (perm == PackageManager.PERMISSION_GRANTED) { 10234 return true; 10235 } 10236 10237 // If the actual IPC caller is different from the logical source, then 10238 // also see if they are allowed to control app switches. 10239 if (callingUid != -1 && callingUid != sourceUid) { 10240 perm = checkComponentPermission( 10241 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10242 callingUid, -1, true); 10243 if (perm == PackageManager.PERMISSION_GRANTED) { 10244 return true; 10245 } 10246 } 10247 10248 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10249 return false; 10250 } 10251 10252 public void setDebugApp(String packageName, boolean waitForDebugger, 10253 boolean persistent) { 10254 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10255 "setDebugApp()"); 10256 10257 long ident = Binder.clearCallingIdentity(); 10258 try { 10259 // Note that this is not really thread safe if there are multiple 10260 // callers into it at the same time, but that's not a situation we 10261 // care about. 10262 if (persistent) { 10263 final ContentResolver resolver = mContext.getContentResolver(); 10264 Settings.Global.putString( 10265 resolver, Settings.Global.DEBUG_APP, 10266 packageName); 10267 Settings.Global.putInt( 10268 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10269 waitForDebugger ? 1 : 0); 10270 } 10271 10272 synchronized (this) { 10273 if (!persistent) { 10274 mOrigDebugApp = mDebugApp; 10275 mOrigWaitForDebugger = mWaitForDebugger; 10276 } 10277 mDebugApp = packageName; 10278 mWaitForDebugger = waitForDebugger; 10279 mDebugTransient = !persistent; 10280 if (packageName != null) { 10281 forceStopPackageLocked(packageName, -1, false, false, true, true, 10282 false, UserHandle.USER_ALL, "set debug app"); 10283 } 10284 } 10285 } finally { 10286 Binder.restoreCallingIdentity(ident); 10287 } 10288 } 10289 10290 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10291 synchronized (this) { 10292 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10293 if (!isDebuggable) { 10294 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10295 throw new SecurityException("Process not debuggable: " + app.packageName); 10296 } 10297 } 10298 10299 mOpenGlTraceApp = processName; 10300 } 10301 } 10302 10303 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10304 synchronized (this) { 10305 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10306 if (!isDebuggable) { 10307 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10308 throw new SecurityException("Process not debuggable: " + app.packageName); 10309 } 10310 } 10311 mProfileApp = processName; 10312 mProfileFile = profilerInfo.profileFile; 10313 if (mProfileFd != null) { 10314 try { 10315 mProfileFd.close(); 10316 } catch (IOException e) { 10317 } 10318 mProfileFd = null; 10319 } 10320 mProfileFd = profilerInfo.profileFd; 10321 mSamplingInterval = profilerInfo.samplingInterval; 10322 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10323 mProfileType = 0; 10324 } 10325 } 10326 10327 @Override 10328 public void setAlwaysFinish(boolean enabled) { 10329 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10330 "setAlwaysFinish()"); 10331 10332 Settings.Global.putInt( 10333 mContext.getContentResolver(), 10334 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10335 10336 synchronized (this) { 10337 mAlwaysFinishActivities = enabled; 10338 } 10339 } 10340 10341 @Override 10342 public void setActivityController(IActivityController controller) { 10343 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10344 "setActivityController()"); 10345 synchronized (this) { 10346 mController = controller; 10347 Watchdog.getInstance().setActivityController(controller); 10348 } 10349 } 10350 10351 @Override 10352 public void setUserIsMonkey(boolean userIsMonkey) { 10353 synchronized (this) { 10354 synchronized (mPidsSelfLocked) { 10355 final int callingPid = Binder.getCallingPid(); 10356 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10357 if (precessRecord == null) { 10358 throw new SecurityException("Unknown process: " + callingPid); 10359 } 10360 if (precessRecord.instrumentationUiAutomationConnection == null) { 10361 throw new SecurityException("Only an instrumentation process " 10362 + "with a UiAutomation can call setUserIsMonkey"); 10363 } 10364 } 10365 mUserIsMonkey = userIsMonkey; 10366 } 10367 } 10368 10369 @Override 10370 public boolean isUserAMonkey() { 10371 synchronized (this) { 10372 // If there is a controller also implies the user is a monkey. 10373 return (mUserIsMonkey || mController != null); 10374 } 10375 } 10376 10377 public void requestBugReport() { 10378 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10379 SystemProperties.set("ctl.start", "bugreport"); 10380 } 10381 10382 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10383 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10384 } 10385 10386 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10387 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10388 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10389 } 10390 return KEY_DISPATCHING_TIMEOUT; 10391 } 10392 10393 @Override 10394 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10395 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10396 != PackageManager.PERMISSION_GRANTED) { 10397 throw new SecurityException("Requires permission " 10398 + android.Manifest.permission.FILTER_EVENTS); 10399 } 10400 ProcessRecord proc; 10401 long timeout; 10402 synchronized (this) { 10403 synchronized (mPidsSelfLocked) { 10404 proc = mPidsSelfLocked.get(pid); 10405 } 10406 timeout = getInputDispatchingTimeoutLocked(proc); 10407 } 10408 10409 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10410 return -1; 10411 } 10412 10413 return timeout; 10414 } 10415 10416 /** 10417 * Handle input dispatching timeouts. 10418 * Returns whether input dispatching should be aborted or not. 10419 */ 10420 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10421 final ActivityRecord activity, final ActivityRecord parent, 10422 final boolean aboveSystem, String reason) { 10423 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10424 != PackageManager.PERMISSION_GRANTED) { 10425 throw new SecurityException("Requires permission " 10426 + android.Manifest.permission.FILTER_EVENTS); 10427 } 10428 10429 final String annotation; 10430 if (reason == null) { 10431 annotation = "Input dispatching timed out"; 10432 } else { 10433 annotation = "Input dispatching timed out (" + reason + ")"; 10434 } 10435 10436 if (proc != null) { 10437 synchronized (this) { 10438 if (proc.debugging) { 10439 return false; 10440 } 10441 10442 if (mDidDexOpt) { 10443 // Give more time since we were dexopting. 10444 mDidDexOpt = false; 10445 return false; 10446 } 10447 10448 if (proc.instrumentationClass != null) { 10449 Bundle info = new Bundle(); 10450 info.putString("shortMsg", "keyDispatchingTimedOut"); 10451 info.putString("longMsg", annotation); 10452 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10453 return true; 10454 } 10455 } 10456 mHandler.post(new Runnable() { 10457 @Override 10458 public void run() { 10459 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10460 } 10461 }); 10462 } 10463 10464 return true; 10465 } 10466 10467 public Bundle getAssistContextExtras(int requestType) { 10468 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10469 UserHandle.getCallingUserId()); 10470 if (pae == null) { 10471 return null; 10472 } 10473 synchronized (pae) { 10474 while (!pae.haveResult) { 10475 try { 10476 pae.wait(); 10477 } catch (InterruptedException e) { 10478 } 10479 } 10480 if (pae.result != null) { 10481 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10482 } 10483 } 10484 synchronized (this) { 10485 mPendingAssistExtras.remove(pae); 10486 mHandler.removeCallbacks(pae); 10487 } 10488 return pae.extras; 10489 } 10490 10491 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10492 int userHandle) { 10493 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10494 "getAssistContextExtras()"); 10495 PendingAssistExtras pae; 10496 Bundle extras = new Bundle(); 10497 synchronized (this) { 10498 ActivityRecord activity = getFocusedStack().mResumedActivity; 10499 if (activity == null) { 10500 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10501 return null; 10502 } 10503 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10504 if (activity.app == null || activity.app.thread == null) { 10505 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10506 return null; 10507 } 10508 if (activity.app.pid == Binder.getCallingPid()) { 10509 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10510 return null; 10511 } 10512 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10513 try { 10514 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10515 requestType); 10516 mPendingAssistExtras.add(pae); 10517 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10518 } catch (RemoteException e) { 10519 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10520 return null; 10521 } 10522 return pae; 10523 } 10524 } 10525 10526 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10527 PendingAssistExtras pae = (PendingAssistExtras)token; 10528 synchronized (pae) { 10529 pae.result = extras; 10530 pae.haveResult = true; 10531 pae.notifyAll(); 10532 if (pae.intent == null) { 10533 // Caller is just waiting for the result. 10534 return; 10535 } 10536 } 10537 10538 // We are now ready to launch the assist activity. 10539 synchronized (this) { 10540 boolean exists = mPendingAssistExtras.remove(pae); 10541 mHandler.removeCallbacks(pae); 10542 if (!exists) { 10543 // Timed out. 10544 return; 10545 } 10546 } 10547 pae.intent.replaceExtras(extras); 10548 if (pae.hint != null) { 10549 pae.intent.putExtra(pae.hint, true); 10550 } 10551 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10552 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10553 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10554 closeSystemDialogs("assist"); 10555 try { 10556 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10557 } catch (ActivityNotFoundException e) { 10558 Slog.w(TAG, "No activity to handle assist action.", e); 10559 } 10560 } 10561 10562 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10563 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10564 } 10565 10566 public void registerProcessObserver(IProcessObserver observer) { 10567 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10568 "registerProcessObserver()"); 10569 synchronized (this) { 10570 mProcessObservers.register(observer); 10571 } 10572 } 10573 10574 @Override 10575 public void unregisterProcessObserver(IProcessObserver observer) { 10576 synchronized (this) { 10577 mProcessObservers.unregister(observer); 10578 } 10579 } 10580 10581 @Override 10582 public boolean convertFromTranslucent(IBinder token) { 10583 final long origId = Binder.clearCallingIdentity(); 10584 try { 10585 synchronized (this) { 10586 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10587 if (r == null) { 10588 return false; 10589 } 10590 final boolean translucentChanged = r.changeWindowTranslucency(true); 10591 if (translucentChanged) { 10592 r.task.stack.releaseBackgroundResources(); 10593 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10594 } 10595 mWindowManager.setAppFullscreen(token, true); 10596 return translucentChanged; 10597 } 10598 } finally { 10599 Binder.restoreCallingIdentity(origId); 10600 } 10601 } 10602 10603 @Override 10604 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10605 final long origId = Binder.clearCallingIdentity(); 10606 try { 10607 synchronized (this) { 10608 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10609 if (r == null) { 10610 return false; 10611 } 10612 int index = r.task.mActivities.lastIndexOf(r); 10613 if (index > 0) { 10614 ActivityRecord under = r.task.mActivities.get(index - 1); 10615 under.returningOptions = options; 10616 } 10617 final boolean translucentChanged = r.changeWindowTranslucency(false); 10618 if (translucentChanged) { 10619 r.task.stack.convertToTranslucent(r); 10620 } 10621 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10622 mWindowManager.setAppFullscreen(token, false); 10623 return translucentChanged; 10624 } 10625 } finally { 10626 Binder.restoreCallingIdentity(origId); 10627 } 10628 } 10629 10630 @Override 10631 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10632 final long origId = Binder.clearCallingIdentity(); 10633 try { 10634 synchronized (this) { 10635 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10636 if (r != null) { 10637 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10638 } 10639 } 10640 return false; 10641 } finally { 10642 Binder.restoreCallingIdentity(origId); 10643 } 10644 } 10645 10646 @Override 10647 public boolean isBackgroundVisibleBehind(IBinder token) { 10648 final long origId = Binder.clearCallingIdentity(); 10649 try { 10650 synchronized (this) { 10651 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10652 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10653 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10654 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10655 return visible; 10656 } 10657 } finally { 10658 Binder.restoreCallingIdentity(origId); 10659 } 10660 } 10661 10662 @Override 10663 public ActivityOptions getActivityOptions(IBinder token) { 10664 final long origId = Binder.clearCallingIdentity(); 10665 try { 10666 synchronized (this) { 10667 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10668 if (r != null) { 10669 final ActivityOptions activityOptions = r.pendingOptions; 10670 r.pendingOptions = null; 10671 return activityOptions; 10672 } 10673 return null; 10674 } 10675 } finally { 10676 Binder.restoreCallingIdentity(origId); 10677 } 10678 } 10679 10680 @Override 10681 public void setImmersive(IBinder token, boolean immersive) { 10682 synchronized(this) { 10683 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10684 if (r == null) { 10685 throw new IllegalArgumentException(); 10686 } 10687 r.immersive = immersive; 10688 10689 // update associated state if we're frontmost 10690 if (r == mFocusedActivity) { 10691 if (DEBUG_IMMERSIVE) { 10692 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10693 } 10694 applyUpdateLockStateLocked(r); 10695 } 10696 } 10697 } 10698 10699 @Override 10700 public boolean isImmersive(IBinder token) { 10701 synchronized (this) { 10702 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10703 if (r == null) { 10704 throw new IllegalArgumentException(); 10705 } 10706 return r.immersive; 10707 } 10708 } 10709 10710 public boolean isTopActivityImmersive() { 10711 enforceNotIsolatedCaller("startActivity"); 10712 synchronized (this) { 10713 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10714 return (r != null) ? r.immersive : false; 10715 } 10716 } 10717 10718 @Override 10719 public boolean isTopOfTask(IBinder token) { 10720 synchronized (this) { 10721 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10722 if (r == null) { 10723 throw new IllegalArgumentException(); 10724 } 10725 return r.task.getTopActivity() == r; 10726 } 10727 } 10728 10729 public final void enterSafeMode() { 10730 synchronized(this) { 10731 // It only makes sense to do this before the system is ready 10732 // and started launching other packages. 10733 if (!mSystemReady) { 10734 try { 10735 AppGlobals.getPackageManager().enterSafeMode(); 10736 } catch (RemoteException e) { 10737 } 10738 } 10739 10740 mSafeMode = true; 10741 } 10742 } 10743 10744 public final void showSafeModeOverlay() { 10745 View v = LayoutInflater.from(mContext).inflate( 10746 com.android.internal.R.layout.safe_mode, null); 10747 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10748 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10749 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10750 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10751 lp.gravity = Gravity.BOTTOM | Gravity.START; 10752 lp.format = v.getBackground().getOpacity(); 10753 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10754 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10755 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10756 ((WindowManager)mContext.getSystemService( 10757 Context.WINDOW_SERVICE)).addView(v, lp); 10758 } 10759 10760 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10761 if (!(sender instanceof PendingIntentRecord)) { 10762 return; 10763 } 10764 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10765 synchronized (stats) { 10766 if (mBatteryStatsService.isOnBattery()) { 10767 mBatteryStatsService.enforceCallingPermission(); 10768 PendingIntentRecord rec = (PendingIntentRecord)sender; 10769 int MY_UID = Binder.getCallingUid(); 10770 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10771 BatteryStatsImpl.Uid.Pkg pkg = 10772 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10773 sourcePkg != null ? sourcePkg : rec.key.packageName); 10774 pkg.incWakeupsLocked(); 10775 } 10776 } 10777 } 10778 10779 public boolean killPids(int[] pids, String pReason, boolean secure) { 10780 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10781 throw new SecurityException("killPids only available to the system"); 10782 } 10783 String reason = (pReason == null) ? "Unknown" : pReason; 10784 // XXX Note: don't acquire main activity lock here, because the window 10785 // manager calls in with its locks held. 10786 10787 boolean killed = false; 10788 synchronized (mPidsSelfLocked) { 10789 int[] types = new int[pids.length]; 10790 int worstType = 0; 10791 for (int i=0; i<pids.length; i++) { 10792 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10793 if (proc != null) { 10794 int type = proc.setAdj; 10795 types[i] = type; 10796 if (type > worstType) { 10797 worstType = type; 10798 } 10799 } 10800 } 10801 10802 // If the worst oom_adj is somewhere in the cached proc LRU range, 10803 // then constrain it so we will kill all cached procs. 10804 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10805 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10806 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10807 } 10808 10809 // If this is not a secure call, don't let it kill processes that 10810 // are important. 10811 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10812 worstType = ProcessList.SERVICE_ADJ; 10813 } 10814 10815 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10816 for (int i=0; i<pids.length; i++) { 10817 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10818 if (proc == null) { 10819 continue; 10820 } 10821 int adj = proc.setAdj; 10822 if (adj >= worstType && !proc.killedByAm) { 10823 proc.kill(reason, true); 10824 killed = true; 10825 } 10826 } 10827 } 10828 return killed; 10829 } 10830 10831 @Override 10832 public void killUid(int uid, String reason) { 10833 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10834 throw new SecurityException("killUid only available to the system"); 10835 } 10836 synchronized (this) { 10837 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10838 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10839 reason != null ? reason : "kill uid"); 10840 } 10841 } 10842 10843 @Override 10844 public boolean killProcessesBelowForeground(String reason) { 10845 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10846 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10847 } 10848 10849 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10850 } 10851 10852 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10853 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10854 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10855 } 10856 10857 boolean killed = false; 10858 synchronized (mPidsSelfLocked) { 10859 final int size = mPidsSelfLocked.size(); 10860 for (int i = 0; i < size; i++) { 10861 final int pid = mPidsSelfLocked.keyAt(i); 10862 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10863 if (proc == null) continue; 10864 10865 final int adj = proc.setAdj; 10866 if (adj > belowAdj && !proc.killedByAm) { 10867 proc.kill(reason, true); 10868 killed = true; 10869 } 10870 } 10871 } 10872 return killed; 10873 } 10874 10875 @Override 10876 public void hang(final IBinder who, boolean allowRestart) { 10877 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10878 != PackageManager.PERMISSION_GRANTED) { 10879 throw new SecurityException("Requires permission " 10880 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10881 } 10882 10883 final IBinder.DeathRecipient death = new DeathRecipient() { 10884 @Override 10885 public void binderDied() { 10886 synchronized (this) { 10887 notifyAll(); 10888 } 10889 } 10890 }; 10891 10892 try { 10893 who.linkToDeath(death, 0); 10894 } catch (RemoteException e) { 10895 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10896 return; 10897 } 10898 10899 synchronized (this) { 10900 Watchdog.getInstance().setAllowRestart(allowRestart); 10901 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10902 synchronized (death) { 10903 while (who.isBinderAlive()) { 10904 try { 10905 death.wait(); 10906 } catch (InterruptedException e) { 10907 } 10908 } 10909 } 10910 Watchdog.getInstance().setAllowRestart(true); 10911 } 10912 } 10913 10914 @Override 10915 public void restart() { 10916 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10917 != PackageManager.PERMISSION_GRANTED) { 10918 throw new SecurityException("Requires permission " 10919 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10920 } 10921 10922 Log.i(TAG, "Sending shutdown broadcast..."); 10923 10924 BroadcastReceiver br = new BroadcastReceiver() { 10925 @Override public void onReceive(Context context, Intent intent) { 10926 // Now the broadcast is done, finish up the low-level shutdown. 10927 Log.i(TAG, "Shutting down activity manager..."); 10928 shutdown(10000); 10929 Log.i(TAG, "Shutdown complete, restarting!"); 10930 Process.killProcess(Process.myPid()); 10931 System.exit(10); 10932 } 10933 }; 10934 10935 // First send the high-level shut down broadcast. 10936 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10937 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10938 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10939 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10940 mContext.sendOrderedBroadcastAsUser(intent, 10941 UserHandle.ALL, null, br, mHandler, 0, null, null); 10942 */ 10943 br.onReceive(mContext, intent); 10944 } 10945 10946 private long getLowRamTimeSinceIdle(long now) { 10947 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10948 } 10949 10950 @Override 10951 public void performIdleMaintenance() { 10952 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10953 != PackageManager.PERMISSION_GRANTED) { 10954 throw new SecurityException("Requires permission " 10955 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10956 } 10957 10958 synchronized (this) { 10959 final long now = SystemClock.uptimeMillis(); 10960 final long timeSinceLastIdle = now - mLastIdleTime; 10961 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10962 mLastIdleTime = now; 10963 mLowRamTimeSinceLastIdle = 0; 10964 if (mLowRamStartTime != 0) { 10965 mLowRamStartTime = now; 10966 } 10967 10968 StringBuilder sb = new StringBuilder(128); 10969 sb.append("Idle maintenance over "); 10970 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10971 sb.append(" low RAM for "); 10972 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10973 Slog.i(TAG, sb.toString()); 10974 10975 // If at least 1/3 of our time since the last idle period has been spent 10976 // with RAM low, then we want to kill processes. 10977 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10978 10979 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10980 ProcessRecord proc = mLruProcesses.get(i); 10981 if (proc.notCachedSinceIdle) { 10982 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10983 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10984 if (doKilling && proc.initialIdlePss != 0 10985 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10986 proc.kill("idle maint (pss " + proc.lastPss 10987 + " from " + proc.initialIdlePss + ")", true); 10988 } 10989 } 10990 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10991 proc.notCachedSinceIdle = true; 10992 proc.initialIdlePss = 0; 10993 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10994 isSleeping(), now); 10995 } 10996 } 10997 10998 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10999 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11000 } 11001 } 11002 11003 private void retrieveSettings() { 11004 final ContentResolver resolver = mContext.getContentResolver(); 11005 String debugApp = Settings.Global.getString( 11006 resolver, Settings.Global.DEBUG_APP); 11007 boolean waitForDebugger = Settings.Global.getInt( 11008 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11009 boolean alwaysFinishActivities = Settings.Global.getInt( 11010 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11011 boolean forceRtl = Settings.Global.getInt( 11012 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11013 // Transfer any global setting for forcing RTL layout, into a System Property 11014 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11015 11016 Configuration configuration = new Configuration(); 11017 Settings.System.getConfiguration(resolver, configuration); 11018 if (forceRtl) { 11019 // This will take care of setting the correct layout direction flags 11020 configuration.setLayoutDirection(configuration.locale); 11021 } 11022 11023 synchronized (this) { 11024 mDebugApp = mOrigDebugApp = debugApp; 11025 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11026 mAlwaysFinishActivities = alwaysFinishActivities; 11027 // This happens before any activities are started, so we can 11028 // change mConfiguration in-place. 11029 updateConfigurationLocked(configuration, null, false, true); 11030 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11031 } 11032 } 11033 11034 /** Loads resources after the current configuration has been set. */ 11035 private void loadResourcesOnSystemReady() { 11036 final Resources res = mContext.getResources(); 11037 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11038 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11039 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11040 } 11041 11042 public boolean testIsSystemReady() { 11043 // no need to synchronize(this) just to read & return the value 11044 return mSystemReady; 11045 } 11046 11047 private static File getCalledPreBootReceiversFile() { 11048 File dataDir = Environment.getDataDirectory(); 11049 File systemDir = new File(dataDir, "system"); 11050 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11051 return fname; 11052 } 11053 11054 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11055 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11056 File file = getCalledPreBootReceiversFile(); 11057 FileInputStream fis = null; 11058 try { 11059 fis = new FileInputStream(file); 11060 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11061 int fvers = dis.readInt(); 11062 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11063 String vers = dis.readUTF(); 11064 String codename = dis.readUTF(); 11065 String build = dis.readUTF(); 11066 if (android.os.Build.VERSION.RELEASE.equals(vers) 11067 && android.os.Build.VERSION.CODENAME.equals(codename) 11068 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11069 int num = dis.readInt(); 11070 while (num > 0) { 11071 num--; 11072 String pkg = dis.readUTF(); 11073 String cls = dis.readUTF(); 11074 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11075 } 11076 } 11077 } 11078 } catch (FileNotFoundException e) { 11079 } catch (IOException e) { 11080 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11081 } finally { 11082 if (fis != null) { 11083 try { 11084 fis.close(); 11085 } catch (IOException e) { 11086 } 11087 } 11088 } 11089 return lastDoneReceivers; 11090 } 11091 11092 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11093 File file = getCalledPreBootReceiversFile(); 11094 FileOutputStream fos = null; 11095 DataOutputStream dos = null; 11096 try { 11097 fos = new FileOutputStream(file); 11098 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11099 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11100 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11101 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11102 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11103 dos.writeInt(list.size()); 11104 for (int i=0; i<list.size(); i++) { 11105 dos.writeUTF(list.get(i).getPackageName()); 11106 dos.writeUTF(list.get(i).getClassName()); 11107 } 11108 } catch (IOException e) { 11109 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11110 file.delete(); 11111 } finally { 11112 FileUtils.sync(fos); 11113 if (dos != null) { 11114 try { 11115 dos.close(); 11116 } catch (IOException e) { 11117 // TODO Auto-generated catch block 11118 e.printStackTrace(); 11119 } 11120 } 11121 } 11122 } 11123 11124 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11125 ArrayList<ComponentName> doneReceivers, int userId) { 11126 boolean waitingUpdate = false; 11127 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11128 List<ResolveInfo> ris = null; 11129 try { 11130 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11131 intent, null, 0, userId); 11132 } catch (RemoteException e) { 11133 } 11134 if (ris != null) { 11135 for (int i=ris.size()-1; i>=0; i--) { 11136 if ((ris.get(i).activityInfo.applicationInfo.flags 11137 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11138 ris.remove(i); 11139 } 11140 } 11141 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11142 11143 // For User 0, load the version number. When delivering to a new user, deliver 11144 // to all receivers. 11145 if (userId == UserHandle.USER_OWNER) { 11146 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11147 for (int i=0; i<ris.size(); i++) { 11148 ActivityInfo ai = ris.get(i).activityInfo; 11149 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11150 if (lastDoneReceivers.contains(comp)) { 11151 // We already did the pre boot receiver for this app with the current 11152 // platform version, so don't do it again... 11153 ris.remove(i); 11154 i--; 11155 // ...however, do keep it as one that has been done, so we don't 11156 // forget about it when rewriting the file of last done receivers. 11157 doneReceivers.add(comp); 11158 } 11159 } 11160 } 11161 11162 // If primary user, send broadcast to all available users, else just to userId 11163 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11164 : new int[] { userId }; 11165 for (int i = 0; i < ris.size(); i++) { 11166 ActivityInfo ai = ris.get(i).activityInfo; 11167 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11168 doneReceivers.add(comp); 11169 intent.setComponent(comp); 11170 for (int j=0; j<users.length; j++) { 11171 IIntentReceiver finisher = null; 11172 // On last receiver and user, set up a completion callback 11173 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11174 finisher = new IIntentReceiver.Stub() { 11175 public void performReceive(Intent intent, int resultCode, 11176 String data, Bundle extras, boolean ordered, 11177 boolean sticky, int sendingUser) { 11178 // The raw IIntentReceiver interface is called 11179 // with the AM lock held, so redispatch to 11180 // execute our code without the lock. 11181 mHandler.post(onFinishCallback); 11182 } 11183 }; 11184 } 11185 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11186 + " for user " + users[j]); 11187 broadcastIntentLocked(null, null, intent, null, finisher, 11188 0, null, null, null, AppOpsManager.OP_NONE, 11189 true, false, MY_PID, Process.SYSTEM_UID, 11190 users[j]); 11191 if (finisher != null) { 11192 waitingUpdate = true; 11193 } 11194 } 11195 } 11196 } 11197 11198 return waitingUpdate; 11199 } 11200 11201 public void systemReady(final Runnable goingCallback) { 11202 synchronized(this) { 11203 if (mSystemReady) { 11204 // If we're done calling all the receivers, run the next "boot phase" passed in 11205 // by the SystemServer 11206 if (goingCallback != null) { 11207 goingCallback.run(); 11208 } 11209 return; 11210 } 11211 11212 // Make sure we have the current profile info, since it is needed for 11213 // security checks. 11214 updateCurrentProfileIdsLocked(); 11215 11216 if (mRecentTasks == null) { 11217 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11218 if (!mRecentTasks.isEmpty()) { 11219 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11220 } 11221 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11222 mTaskPersister.startPersisting(); 11223 } 11224 11225 // Check to see if there are any update receivers to run. 11226 if (!mDidUpdate) { 11227 if (mWaitingUpdate) { 11228 return; 11229 } 11230 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11231 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11232 public void run() { 11233 synchronized (ActivityManagerService.this) { 11234 mDidUpdate = true; 11235 } 11236 writeLastDonePreBootReceivers(doneReceivers); 11237 showBootMessage(mContext.getText( 11238 R.string.android_upgrading_complete), 11239 false); 11240 systemReady(goingCallback); 11241 } 11242 }, doneReceivers, UserHandle.USER_OWNER); 11243 11244 if (mWaitingUpdate) { 11245 return; 11246 } 11247 mDidUpdate = true; 11248 } 11249 11250 mAppOpsService.systemReady(); 11251 mSystemReady = true; 11252 } 11253 11254 ArrayList<ProcessRecord> procsToKill = null; 11255 synchronized(mPidsSelfLocked) { 11256 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11257 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11258 if (!isAllowedWhileBooting(proc.info)){ 11259 if (procsToKill == null) { 11260 procsToKill = new ArrayList<ProcessRecord>(); 11261 } 11262 procsToKill.add(proc); 11263 } 11264 } 11265 } 11266 11267 synchronized(this) { 11268 if (procsToKill != null) { 11269 for (int i=procsToKill.size()-1; i>=0; i--) { 11270 ProcessRecord proc = procsToKill.get(i); 11271 Slog.i(TAG, "Removing system update proc: " + proc); 11272 removeProcessLocked(proc, true, false, "system update done"); 11273 } 11274 } 11275 11276 // Now that we have cleaned up any update processes, we 11277 // are ready to start launching real processes and know that 11278 // we won't trample on them any more. 11279 mProcessesReady = true; 11280 } 11281 11282 Slog.i(TAG, "System now ready"); 11283 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11284 SystemClock.uptimeMillis()); 11285 11286 synchronized(this) { 11287 // Make sure we have no pre-ready processes sitting around. 11288 11289 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11290 ResolveInfo ri = mContext.getPackageManager() 11291 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11292 STOCK_PM_FLAGS); 11293 CharSequence errorMsg = null; 11294 if (ri != null) { 11295 ActivityInfo ai = ri.activityInfo; 11296 ApplicationInfo app = ai.applicationInfo; 11297 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11298 mTopAction = Intent.ACTION_FACTORY_TEST; 11299 mTopData = null; 11300 mTopComponent = new ComponentName(app.packageName, 11301 ai.name); 11302 } else { 11303 errorMsg = mContext.getResources().getText( 11304 com.android.internal.R.string.factorytest_not_system); 11305 } 11306 } else { 11307 errorMsg = mContext.getResources().getText( 11308 com.android.internal.R.string.factorytest_no_action); 11309 } 11310 if (errorMsg != null) { 11311 mTopAction = null; 11312 mTopData = null; 11313 mTopComponent = null; 11314 Message msg = Message.obtain(); 11315 msg.what = SHOW_FACTORY_ERROR_MSG; 11316 msg.getData().putCharSequence("msg", errorMsg); 11317 mHandler.sendMessage(msg); 11318 } 11319 } 11320 } 11321 11322 retrieveSettings(); 11323 loadResourcesOnSystemReady(); 11324 11325 synchronized (this) { 11326 readGrantedUriPermissionsLocked(); 11327 } 11328 11329 if (goingCallback != null) goingCallback.run(); 11330 11331 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11332 Integer.toString(mCurrentUserId), mCurrentUserId); 11333 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11334 Integer.toString(mCurrentUserId), mCurrentUserId); 11335 mSystemServiceManager.startUser(mCurrentUserId); 11336 11337 synchronized (this) { 11338 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11339 try { 11340 List apps = AppGlobals.getPackageManager(). 11341 getPersistentApplications(STOCK_PM_FLAGS); 11342 if (apps != null) { 11343 int N = apps.size(); 11344 int i; 11345 for (i=0; i<N; i++) { 11346 ApplicationInfo info 11347 = (ApplicationInfo)apps.get(i); 11348 if (info != null && 11349 !info.packageName.equals("android")) { 11350 addAppLocked(info, false, null /* ABI override */); 11351 } 11352 } 11353 } 11354 } catch (RemoteException ex) { 11355 // pm is in same process, this will never happen. 11356 } 11357 } 11358 11359 // Start up initial activity. 11360 mBooting = true; 11361 startHomeActivityLocked(mCurrentUserId); 11362 11363 try { 11364 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11365 Message msg = Message.obtain(); 11366 msg.what = SHOW_UID_ERROR_MSG; 11367 mHandler.sendMessage(msg); 11368 } 11369 } catch (RemoteException e) { 11370 } 11371 11372 long ident = Binder.clearCallingIdentity(); 11373 try { 11374 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11375 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11376 | Intent.FLAG_RECEIVER_FOREGROUND); 11377 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11378 broadcastIntentLocked(null, null, intent, 11379 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11380 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11381 intent = new Intent(Intent.ACTION_USER_STARTING); 11382 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11383 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11384 broadcastIntentLocked(null, null, intent, 11385 null, new IIntentReceiver.Stub() { 11386 @Override 11387 public void performReceive(Intent intent, int resultCode, String data, 11388 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11389 throws RemoteException { 11390 } 11391 }, 0, null, null, 11392 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11393 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11394 } catch (Throwable t) { 11395 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11396 } finally { 11397 Binder.restoreCallingIdentity(ident); 11398 } 11399 mStackSupervisor.resumeTopActivitiesLocked(); 11400 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11401 } 11402 } 11403 11404 private boolean makeAppCrashingLocked(ProcessRecord app, 11405 String shortMsg, String longMsg, String stackTrace) { 11406 app.crashing = true; 11407 app.crashingReport = generateProcessError(app, 11408 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11409 startAppProblemLocked(app); 11410 app.stopFreezingAllLocked(); 11411 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11412 } 11413 11414 private void makeAppNotRespondingLocked(ProcessRecord app, 11415 String activity, String shortMsg, String longMsg) { 11416 app.notResponding = true; 11417 app.notRespondingReport = generateProcessError(app, 11418 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11419 activity, shortMsg, longMsg, null); 11420 startAppProblemLocked(app); 11421 app.stopFreezingAllLocked(); 11422 } 11423 11424 /** 11425 * Generate a process error record, suitable for attachment to a ProcessRecord. 11426 * 11427 * @param app The ProcessRecord in which the error occurred. 11428 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11429 * ActivityManager.AppErrorStateInfo 11430 * @param activity The activity associated with the crash, if known. 11431 * @param shortMsg Short message describing the crash. 11432 * @param longMsg Long message describing the crash. 11433 * @param stackTrace Full crash stack trace, may be null. 11434 * 11435 * @return Returns a fully-formed AppErrorStateInfo record. 11436 */ 11437 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11438 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11439 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11440 11441 report.condition = condition; 11442 report.processName = app.processName; 11443 report.pid = app.pid; 11444 report.uid = app.info.uid; 11445 report.tag = activity; 11446 report.shortMsg = shortMsg; 11447 report.longMsg = longMsg; 11448 report.stackTrace = stackTrace; 11449 11450 return report; 11451 } 11452 11453 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11454 synchronized (this) { 11455 app.crashing = false; 11456 app.crashingReport = null; 11457 app.notResponding = false; 11458 app.notRespondingReport = null; 11459 if (app.anrDialog == fromDialog) { 11460 app.anrDialog = null; 11461 } 11462 if (app.waitDialog == fromDialog) { 11463 app.waitDialog = null; 11464 } 11465 if (app.pid > 0 && app.pid != MY_PID) { 11466 handleAppCrashLocked(app, null, null, null); 11467 app.kill("user request after error", true); 11468 } 11469 } 11470 } 11471 11472 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11473 String stackTrace) { 11474 long now = SystemClock.uptimeMillis(); 11475 11476 Long crashTime; 11477 if (!app.isolated) { 11478 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11479 } else { 11480 crashTime = null; 11481 } 11482 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11483 // This process loses! 11484 Slog.w(TAG, "Process " + app.info.processName 11485 + " has crashed too many times: killing!"); 11486 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11487 app.userId, app.info.processName, app.uid); 11488 mStackSupervisor.handleAppCrashLocked(app); 11489 if (!app.persistent) { 11490 // We don't want to start this process again until the user 11491 // explicitly does so... but for persistent process, we really 11492 // need to keep it running. If a persistent process is actually 11493 // repeatedly crashing, then badness for everyone. 11494 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11495 app.info.processName); 11496 if (!app.isolated) { 11497 // XXX We don't have a way to mark isolated processes 11498 // as bad, since they don't have a peristent identity. 11499 mBadProcesses.put(app.info.processName, app.uid, 11500 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11501 mProcessCrashTimes.remove(app.info.processName, app.uid); 11502 } 11503 app.bad = true; 11504 app.removed = true; 11505 // Don't let services in this process be restarted and potentially 11506 // annoy the user repeatedly. Unless it is persistent, since those 11507 // processes run critical code. 11508 removeProcessLocked(app, false, false, "crash"); 11509 mStackSupervisor.resumeTopActivitiesLocked(); 11510 return false; 11511 } 11512 mStackSupervisor.resumeTopActivitiesLocked(); 11513 } else { 11514 mStackSupervisor.finishTopRunningActivityLocked(app); 11515 } 11516 11517 // Bump up the crash count of any services currently running in the proc. 11518 for (int i=app.services.size()-1; i>=0; i--) { 11519 // Any services running in the application need to be placed 11520 // back in the pending list. 11521 ServiceRecord sr = app.services.valueAt(i); 11522 sr.crashCount++; 11523 } 11524 11525 // If the crashing process is what we consider to be the "home process" and it has been 11526 // replaced by a third-party app, clear the package preferred activities from packages 11527 // with a home activity running in the process to prevent a repeatedly crashing app 11528 // from blocking the user to manually clear the list. 11529 final ArrayList<ActivityRecord> activities = app.activities; 11530 if (app == mHomeProcess && activities.size() > 0 11531 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11532 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11533 final ActivityRecord r = activities.get(activityNdx); 11534 if (r.isHomeActivity()) { 11535 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11536 try { 11537 ActivityThread.getPackageManager() 11538 .clearPackagePreferredActivities(r.packageName); 11539 } catch (RemoteException c) { 11540 // pm is in same process, this will never happen. 11541 } 11542 } 11543 } 11544 } 11545 11546 if (!app.isolated) { 11547 // XXX Can't keep track of crash times for isolated processes, 11548 // because they don't have a perisistent identity. 11549 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11550 } 11551 11552 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11553 return true; 11554 } 11555 11556 void startAppProblemLocked(ProcessRecord app) { 11557 // If this app is not running under the current user, then we 11558 // can't give it a report button because that would require 11559 // launching the report UI under a different user. 11560 app.errorReportReceiver = null; 11561 11562 for (int userId : mCurrentProfileIds) { 11563 if (app.userId == userId) { 11564 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11565 mContext, app.info.packageName, app.info.flags); 11566 } 11567 } 11568 skipCurrentReceiverLocked(app); 11569 } 11570 11571 void skipCurrentReceiverLocked(ProcessRecord app) { 11572 for (BroadcastQueue queue : mBroadcastQueues) { 11573 queue.skipCurrentReceiverLocked(app); 11574 } 11575 } 11576 11577 /** 11578 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11579 * The application process will exit immediately after this call returns. 11580 * @param app object of the crashing app, null for the system server 11581 * @param crashInfo describing the exception 11582 */ 11583 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11584 ProcessRecord r = findAppProcess(app, "Crash"); 11585 final String processName = app == null ? "system_server" 11586 : (r == null ? "unknown" : r.processName); 11587 11588 handleApplicationCrashInner("crash", r, processName, crashInfo); 11589 } 11590 11591 /* Native crash reporting uses this inner version because it needs to be somewhat 11592 * decoupled from the AM-managed cleanup lifecycle 11593 */ 11594 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11595 ApplicationErrorReport.CrashInfo crashInfo) { 11596 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11597 UserHandle.getUserId(Binder.getCallingUid()), processName, 11598 r == null ? -1 : r.info.flags, 11599 crashInfo.exceptionClassName, 11600 crashInfo.exceptionMessage, 11601 crashInfo.throwFileName, 11602 crashInfo.throwLineNumber); 11603 11604 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11605 11606 crashApplication(r, crashInfo); 11607 } 11608 11609 public void handleApplicationStrictModeViolation( 11610 IBinder app, 11611 int violationMask, 11612 StrictMode.ViolationInfo info) { 11613 ProcessRecord r = findAppProcess(app, "StrictMode"); 11614 if (r == null) { 11615 return; 11616 } 11617 11618 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11619 Integer stackFingerprint = info.hashCode(); 11620 boolean logIt = true; 11621 synchronized (mAlreadyLoggedViolatedStacks) { 11622 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11623 logIt = false; 11624 // TODO: sub-sample into EventLog for these, with 11625 // the info.durationMillis? Then we'd get 11626 // the relative pain numbers, without logging all 11627 // the stack traces repeatedly. We'd want to do 11628 // likewise in the client code, which also does 11629 // dup suppression, before the Binder call. 11630 } else { 11631 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11632 mAlreadyLoggedViolatedStacks.clear(); 11633 } 11634 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11635 } 11636 } 11637 if (logIt) { 11638 logStrictModeViolationToDropBox(r, info); 11639 } 11640 } 11641 11642 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11643 AppErrorResult result = new AppErrorResult(); 11644 synchronized (this) { 11645 final long origId = Binder.clearCallingIdentity(); 11646 11647 Message msg = Message.obtain(); 11648 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11649 HashMap<String, Object> data = new HashMap<String, Object>(); 11650 data.put("result", result); 11651 data.put("app", r); 11652 data.put("violationMask", violationMask); 11653 data.put("info", info); 11654 msg.obj = data; 11655 mHandler.sendMessage(msg); 11656 11657 Binder.restoreCallingIdentity(origId); 11658 } 11659 int res = result.get(); 11660 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11661 } 11662 } 11663 11664 // Depending on the policy in effect, there could be a bunch of 11665 // these in quick succession so we try to batch these together to 11666 // minimize disk writes, number of dropbox entries, and maximize 11667 // compression, by having more fewer, larger records. 11668 private void logStrictModeViolationToDropBox( 11669 ProcessRecord process, 11670 StrictMode.ViolationInfo info) { 11671 if (info == null) { 11672 return; 11673 } 11674 final boolean isSystemApp = process == null || 11675 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11676 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11677 final String processName = process == null ? "unknown" : process.processName; 11678 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11679 final DropBoxManager dbox = (DropBoxManager) 11680 mContext.getSystemService(Context.DROPBOX_SERVICE); 11681 11682 // Exit early if the dropbox isn't configured to accept this report type. 11683 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11684 11685 boolean bufferWasEmpty; 11686 boolean needsFlush; 11687 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11688 synchronized (sb) { 11689 bufferWasEmpty = sb.length() == 0; 11690 appendDropBoxProcessHeaders(process, processName, sb); 11691 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11692 sb.append("System-App: ").append(isSystemApp).append("\n"); 11693 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11694 if (info.violationNumThisLoop != 0) { 11695 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11696 } 11697 if (info.numAnimationsRunning != 0) { 11698 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11699 } 11700 if (info.broadcastIntentAction != null) { 11701 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11702 } 11703 if (info.durationMillis != -1) { 11704 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11705 } 11706 if (info.numInstances != -1) { 11707 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11708 } 11709 if (info.tags != null) { 11710 for (String tag : info.tags) { 11711 sb.append("Span-Tag: ").append(tag).append("\n"); 11712 } 11713 } 11714 sb.append("\n"); 11715 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11716 sb.append(info.crashInfo.stackTrace); 11717 } 11718 sb.append("\n"); 11719 11720 // Only buffer up to ~64k. Various logging bits truncate 11721 // things at 128k. 11722 needsFlush = (sb.length() > 64 * 1024); 11723 } 11724 11725 // Flush immediately if the buffer's grown too large, or this 11726 // is a non-system app. Non-system apps are isolated with a 11727 // different tag & policy and not batched. 11728 // 11729 // Batching is useful during internal testing with 11730 // StrictMode settings turned up high. Without batching, 11731 // thousands of separate files could be created on boot. 11732 if (!isSystemApp || needsFlush) { 11733 new Thread("Error dump: " + dropboxTag) { 11734 @Override 11735 public void run() { 11736 String report; 11737 synchronized (sb) { 11738 report = sb.toString(); 11739 sb.delete(0, sb.length()); 11740 sb.trimToSize(); 11741 } 11742 if (report.length() != 0) { 11743 dbox.addText(dropboxTag, report); 11744 } 11745 } 11746 }.start(); 11747 return; 11748 } 11749 11750 // System app batching: 11751 if (!bufferWasEmpty) { 11752 // An existing dropbox-writing thread is outstanding, so 11753 // we don't need to start it up. The existing thread will 11754 // catch the buffer appends we just did. 11755 return; 11756 } 11757 11758 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11759 // (After this point, we shouldn't access AMS internal data structures.) 11760 new Thread("Error dump: " + dropboxTag) { 11761 @Override 11762 public void run() { 11763 // 5 second sleep to let stacks arrive and be batched together 11764 try { 11765 Thread.sleep(5000); // 5 seconds 11766 } catch (InterruptedException e) {} 11767 11768 String errorReport; 11769 synchronized (mStrictModeBuffer) { 11770 errorReport = mStrictModeBuffer.toString(); 11771 if (errorReport.length() == 0) { 11772 return; 11773 } 11774 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11775 mStrictModeBuffer.trimToSize(); 11776 } 11777 dbox.addText(dropboxTag, errorReport); 11778 } 11779 }.start(); 11780 } 11781 11782 /** 11783 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11784 * @param app object of the crashing app, null for the system server 11785 * @param tag reported by the caller 11786 * @param system whether this wtf is coming from the system 11787 * @param crashInfo describing the context of the error 11788 * @return true if the process should exit immediately (WTF is fatal) 11789 */ 11790 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11791 final ApplicationErrorReport.CrashInfo crashInfo) { 11792 final int callingUid = Binder.getCallingUid(); 11793 final int callingPid = Binder.getCallingPid(); 11794 11795 if (system) { 11796 // If this is coming from the system, we could very well have low-level 11797 // system locks held, so we want to do this all asynchronously. And we 11798 // never want this to become fatal, so there is that too. 11799 mHandler.post(new Runnable() { 11800 @Override public void run() { 11801 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11802 } 11803 }); 11804 return false; 11805 } 11806 11807 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11808 crashInfo); 11809 11810 if (r != null && r.pid != Process.myPid() && 11811 Settings.Global.getInt(mContext.getContentResolver(), 11812 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11813 crashApplication(r, crashInfo); 11814 return true; 11815 } else { 11816 return false; 11817 } 11818 } 11819 11820 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11821 final ApplicationErrorReport.CrashInfo crashInfo) { 11822 final ProcessRecord r = findAppProcess(app, "WTF"); 11823 final String processName = app == null ? "system_server" 11824 : (r == null ? "unknown" : r.processName); 11825 11826 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11827 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11828 11829 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11830 11831 return r; 11832 } 11833 11834 /** 11835 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11836 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11837 */ 11838 private ProcessRecord findAppProcess(IBinder app, String reason) { 11839 if (app == null) { 11840 return null; 11841 } 11842 11843 synchronized (this) { 11844 final int NP = mProcessNames.getMap().size(); 11845 for (int ip=0; ip<NP; ip++) { 11846 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11847 final int NA = apps.size(); 11848 for (int ia=0; ia<NA; ia++) { 11849 ProcessRecord p = apps.valueAt(ia); 11850 if (p.thread != null && p.thread.asBinder() == app) { 11851 return p; 11852 } 11853 } 11854 } 11855 11856 Slog.w(TAG, "Can't find mystery application for " + reason 11857 + " from pid=" + Binder.getCallingPid() 11858 + " uid=" + Binder.getCallingUid() + ": " + app); 11859 return null; 11860 } 11861 } 11862 11863 /** 11864 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11865 * to append various headers to the dropbox log text. 11866 */ 11867 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11868 StringBuilder sb) { 11869 // Watchdog thread ends up invoking this function (with 11870 // a null ProcessRecord) to add the stack file to dropbox. 11871 // Do not acquire a lock on this (am) in such cases, as it 11872 // could cause a potential deadlock, if and when watchdog 11873 // is invoked due to unavailability of lock on am and it 11874 // would prevent watchdog from killing system_server. 11875 if (process == null) { 11876 sb.append("Process: ").append(processName).append("\n"); 11877 return; 11878 } 11879 // Note: ProcessRecord 'process' is guarded by the service 11880 // instance. (notably process.pkgList, which could otherwise change 11881 // concurrently during execution of this method) 11882 synchronized (this) { 11883 sb.append("Process: ").append(processName).append("\n"); 11884 int flags = process.info.flags; 11885 IPackageManager pm = AppGlobals.getPackageManager(); 11886 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11887 for (int ip=0; ip<process.pkgList.size(); ip++) { 11888 String pkg = process.pkgList.keyAt(ip); 11889 sb.append("Package: ").append(pkg); 11890 try { 11891 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11892 if (pi != null) { 11893 sb.append(" v").append(pi.versionCode); 11894 if (pi.versionName != null) { 11895 sb.append(" (").append(pi.versionName).append(")"); 11896 } 11897 } 11898 } catch (RemoteException e) { 11899 Slog.e(TAG, "Error getting package info: " + pkg, e); 11900 } 11901 sb.append("\n"); 11902 } 11903 } 11904 } 11905 11906 private static String processClass(ProcessRecord process) { 11907 if (process == null || process.pid == MY_PID) { 11908 return "system_server"; 11909 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11910 return "system_app"; 11911 } else { 11912 return "data_app"; 11913 } 11914 } 11915 11916 /** 11917 * Write a description of an error (crash, WTF, ANR) to the drop box. 11918 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11919 * @param process which caused the error, null means the system server 11920 * @param activity which triggered the error, null if unknown 11921 * @param parent activity related to the error, null if unknown 11922 * @param subject line related to the error, null if absent 11923 * @param report in long form describing the error, null if absent 11924 * @param logFile to include in the report, null if none 11925 * @param crashInfo giving an application stack trace, null if absent 11926 */ 11927 public void addErrorToDropBox(String eventType, 11928 ProcessRecord process, String processName, ActivityRecord activity, 11929 ActivityRecord parent, String subject, 11930 final String report, final File logFile, 11931 final ApplicationErrorReport.CrashInfo crashInfo) { 11932 // NOTE -- this must never acquire the ActivityManagerService lock, 11933 // otherwise the watchdog may be prevented from resetting the system. 11934 11935 final String dropboxTag = processClass(process) + "_" + eventType; 11936 final DropBoxManager dbox = (DropBoxManager) 11937 mContext.getSystemService(Context.DROPBOX_SERVICE); 11938 11939 // Exit early if the dropbox isn't configured to accept this report type. 11940 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11941 11942 final StringBuilder sb = new StringBuilder(1024); 11943 appendDropBoxProcessHeaders(process, processName, sb); 11944 if (activity != null) { 11945 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11946 } 11947 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11948 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11949 } 11950 if (parent != null && parent != activity) { 11951 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11952 } 11953 if (subject != null) { 11954 sb.append("Subject: ").append(subject).append("\n"); 11955 } 11956 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11957 if (Debug.isDebuggerConnected()) { 11958 sb.append("Debugger: Connected\n"); 11959 } 11960 sb.append("\n"); 11961 11962 // Do the rest in a worker thread to avoid blocking the caller on I/O 11963 // (After this point, we shouldn't access AMS internal data structures.) 11964 Thread worker = new Thread("Error dump: " + dropboxTag) { 11965 @Override 11966 public void run() { 11967 if (report != null) { 11968 sb.append(report); 11969 } 11970 if (logFile != null) { 11971 try { 11972 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11973 "\n\n[[TRUNCATED]]")); 11974 } catch (IOException e) { 11975 Slog.e(TAG, "Error reading " + logFile, e); 11976 } 11977 } 11978 if (crashInfo != null && crashInfo.stackTrace != null) { 11979 sb.append(crashInfo.stackTrace); 11980 } 11981 11982 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11983 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11984 if (lines > 0) { 11985 sb.append("\n"); 11986 11987 // Merge several logcat streams, and take the last N lines 11988 InputStreamReader input = null; 11989 try { 11990 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11991 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11992 "-b", "crash", 11993 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11994 11995 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11996 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11997 input = new InputStreamReader(logcat.getInputStream()); 11998 11999 int num; 12000 char[] buf = new char[8192]; 12001 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12002 } catch (IOException e) { 12003 Slog.e(TAG, "Error running logcat", e); 12004 } finally { 12005 if (input != null) try { input.close(); } catch (IOException e) {} 12006 } 12007 } 12008 12009 dbox.addText(dropboxTag, sb.toString()); 12010 } 12011 }; 12012 12013 if (process == null) { 12014 // If process is null, we are being called from some internal code 12015 // and may be about to die -- run this synchronously. 12016 worker.run(); 12017 } else { 12018 worker.start(); 12019 } 12020 } 12021 12022 /** 12023 * Bring up the "unexpected error" dialog box for a crashing app. 12024 * Deal with edge cases (intercepts from instrumented applications, 12025 * ActivityController, error intent receivers, that sort of thing). 12026 * @param r the application crashing 12027 * @param crashInfo describing the failure 12028 */ 12029 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12030 long timeMillis = System.currentTimeMillis(); 12031 String shortMsg = crashInfo.exceptionClassName; 12032 String longMsg = crashInfo.exceptionMessage; 12033 String stackTrace = crashInfo.stackTrace; 12034 if (shortMsg != null && longMsg != null) { 12035 longMsg = shortMsg + ": " + longMsg; 12036 } else if (shortMsg != null) { 12037 longMsg = shortMsg; 12038 } 12039 12040 AppErrorResult result = new AppErrorResult(); 12041 synchronized (this) { 12042 if (mController != null) { 12043 try { 12044 String name = r != null ? r.processName : null; 12045 int pid = r != null ? r.pid : Binder.getCallingPid(); 12046 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12047 if (!mController.appCrashed(name, pid, 12048 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12049 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12050 && "Native crash".equals(crashInfo.exceptionClassName)) { 12051 Slog.w(TAG, "Skip killing native crashed app " + name 12052 + "(" + pid + ") during testing"); 12053 } else { 12054 Slog.w(TAG, "Force-killing crashed app " + name 12055 + " at watcher's request"); 12056 if (r != null) { 12057 r.kill("crash", true); 12058 } else { 12059 // Huh. 12060 Process.killProcess(pid); 12061 Process.killProcessGroup(uid, pid); 12062 } 12063 } 12064 return; 12065 } 12066 } catch (RemoteException e) { 12067 mController = null; 12068 Watchdog.getInstance().setActivityController(null); 12069 } 12070 } 12071 12072 final long origId = Binder.clearCallingIdentity(); 12073 12074 // If this process is running instrumentation, finish it. 12075 if (r != null && r.instrumentationClass != null) { 12076 Slog.w(TAG, "Error in app " + r.processName 12077 + " running instrumentation " + r.instrumentationClass + ":"); 12078 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12079 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12080 Bundle info = new Bundle(); 12081 info.putString("shortMsg", shortMsg); 12082 info.putString("longMsg", longMsg); 12083 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12084 Binder.restoreCallingIdentity(origId); 12085 return; 12086 } 12087 12088 // If we can't identify the process or it's already exceeded its crash quota, 12089 // quit right away without showing a crash dialog. 12090 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12091 Binder.restoreCallingIdentity(origId); 12092 return; 12093 } 12094 12095 Message msg = Message.obtain(); 12096 msg.what = SHOW_ERROR_MSG; 12097 HashMap data = new HashMap(); 12098 data.put("result", result); 12099 data.put("app", r); 12100 msg.obj = data; 12101 mHandler.sendMessage(msg); 12102 12103 Binder.restoreCallingIdentity(origId); 12104 } 12105 12106 int res = result.get(); 12107 12108 Intent appErrorIntent = null; 12109 synchronized (this) { 12110 if (r != null && !r.isolated) { 12111 // XXX Can't keep track of crash time for isolated processes, 12112 // since they don't have a persistent identity. 12113 mProcessCrashTimes.put(r.info.processName, r.uid, 12114 SystemClock.uptimeMillis()); 12115 } 12116 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12117 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12118 } 12119 } 12120 12121 if (appErrorIntent != null) { 12122 try { 12123 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12124 } catch (ActivityNotFoundException e) { 12125 Slog.w(TAG, "bug report receiver dissappeared", e); 12126 } 12127 } 12128 } 12129 12130 Intent createAppErrorIntentLocked(ProcessRecord r, 12131 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12132 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12133 if (report == null) { 12134 return null; 12135 } 12136 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12137 result.setComponent(r.errorReportReceiver); 12138 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12139 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12140 return result; 12141 } 12142 12143 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12144 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12145 if (r.errorReportReceiver == null) { 12146 return null; 12147 } 12148 12149 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12150 return null; 12151 } 12152 12153 ApplicationErrorReport report = new ApplicationErrorReport(); 12154 report.packageName = r.info.packageName; 12155 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12156 report.processName = r.processName; 12157 report.time = timeMillis; 12158 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12159 12160 if (r.crashing || r.forceCrashReport) { 12161 report.type = ApplicationErrorReport.TYPE_CRASH; 12162 report.crashInfo = crashInfo; 12163 } else if (r.notResponding) { 12164 report.type = ApplicationErrorReport.TYPE_ANR; 12165 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12166 12167 report.anrInfo.activity = r.notRespondingReport.tag; 12168 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12169 report.anrInfo.info = r.notRespondingReport.longMsg; 12170 } 12171 12172 return report; 12173 } 12174 12175 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12176 enforceNotIsolatedCaller("getProcessesInErrorState"); 12177 // assume our apps are happy - lazy create the list 12178 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12179 12180 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12181 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12182 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12183 12184 synchronized (this) { 12185 12186 // iterate across all processes 12187 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12188 ProcessRecord app = mLruProcesses.get(i); 12189 if (!allUsers && app.userId != userId) { 12190 continue; 12191 } 12192 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12193 // This one's in trouble, so we'll generate a report for it 12194 // crashes are higher priority (in case there's a crash *and* an anr) 12195 ActivityManager.ProcessErrorStateInfo report = null; 12196 if (app.crashing) { 12197 report = app.crashingReport; 12198 } else if (app.notResponding) { 12199 report = app.notRespondingReport; 12200 } 12201 12202 if (report != null) { 12203 if (errList == null) { 12204 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12205 } 12206 errList.add(report); 12207 } else { 12208 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12209 " crashing = " + app.crashing + 12210 " notResponding = " + app.notResponding); 12211 } 12212 } 12213 } 12214 } 12215 12216 return errList; 12217 } 12218 12219 static int procStateToImportance(int procState, int memAdj, 12220 ActivityManager.RunningAppProcessInfo currApp) { 12221 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12222 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12223 currApp.lru = memAdj; 12224 } else { 12225 currApp.lru = 0; 12226 } 12227 return imp; 12228 } 12229 12230 private void fillInProcMemInfo(ProcessRecord app, 12231 ActivityManager.RunningAppProcessInfo outInfo) { 12232 outInfo.pid = app.pid; 12233 outInfo.uid = app.info.uid; 12234 if (mHeavyWeightProcess == app) { 12235 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12236 } 12237 if (app.persistent) { 12238 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12239 } 12240 if (app.activities.size() > 0) { 12241 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12242 } 12243 outInfo.lastTrimLevel = app.trimMemoryLevel; 12244 int adj = app.curAdj; 12245 int procState = app.curProcState; 12246 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12247 outInfo.importanceReasonCode = app.adjTypeCode; 12248 outInfo.processState = app.curProcState; 12249 } 12250 12251 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12252 enforceNotIsolatedCaller("getRunningAppProcesses"); 12253 // Lazy instantiation of list 12254 List<ActivityManager.RunningAppProcessInfo> runList = null; 12255 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12256 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12257 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12258 synchronized (this) { 12259 // Iterate across all processes 12260 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12261 ProcessRecord app = mLruProcesses.get(i); 12262 if (!allUsers && app.userId != userId) { 12263 continue; 12264 } 12265 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12266 // Generate process state info for running application 12267 ActivityManager.RunningAppProcessInfo currApp = 12268 new ActivityManager.RunningAppProcessInfo(app.processName, 12269 app.pid, app.getPackageList()); 12270 fillInProcMemInfo(app, currApp); 12271 if (app.adjSource instanceof ProcessRecord) { 12272 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12273 currApp.importanceReasonImportance = 12274 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12275 app.adjSourceProcState); 12276 } else if (app.adjSource instanceof ActivityRecord) { 12277 ActivityRecord r = (ActivityRecord)app.adjSource; 12278 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12279 } 12280 if (app.adjTarget instanceof ComponentName) { 12281 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12282 } 12283 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12284 // + " lru=" + currApp.lru); 12285 if (runList == null) { 12286 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12287 } 12288 runList.add(currApp); 12289 } 12290 } 12291 } 12292 return runList; 12293 } 12294 12295 public List<ApplicationInfo> getRunningExternalApplications() { 12296 enforceNotIsolatedCaller("getRunningExternalApplications"); 12297 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12298 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12299 if (runningApps != null && runningApps.size() > 0) { 12300 Set<String> extList = new HashSet<String>(); 12301 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12302 if (app.pkgList != null) { 12303 for (String pkg : app.pkgList) { 12304 extList.add(pkg); 12305 } 12306 } 12307 } 12308 IPackageManager pm = AppGlobals.getPackageManager(); 12309 for (String pkg : extList) { 12310 try { 12311 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12312 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12313 retList.add(info); 12314 } 12315 } catch (RemoteException e) { 12316 } 12317 } 12318 } 12319 return retList; 12320 } 12321 12322 @Override 12323 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12324 enforceNotIsolatedCaller("getMyMemoryState"); 12325 synchronized (this) { 12326 ProcessRecord proc; 12327 synchronized (mPidsSelfLocked) { 12328 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12329 } 12330 fillInProcMemInfo(proc, outInfo); 12331 } 12332 } 12333 12334 @Override 12335 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12336 if (checkCallingPermission(android.Manifest.permission.DUMP) 12337 != PackageManager.PERMISSION_GRANTED) { 12338 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12339 + Binder.getCallingPid() 12340 + ", uid=" + Binder.getCallingUid() 12341 + " without permission " 12342 + android.Manifest.permission.DUMP); 12343 return; 12344 } 12345 12346 boolean dumpAll = false; 12347 boolean dumpClient = false; 12348 String dumpPackage = null; 12349 12350 int opti = 0; 12351 while (opti < args.length) { 12352 String opt = args[opti]; 12353 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12354 break; 12355 } 12356 opti++; 12357 if ("-a".equals(opt)) { 12358 dumpAll = true; 12359 } else if ("-c".equals(opt)) { 12360 dumpClient = true; 12361 } else if ("-h".equals(opt)) { 12362 pw.println("Activity manager dump options:"); 12363 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12364 pw.println(" cmd may be one of:"); 12365 pw.println(" a[ctivities]: activity stack state"); 12366 pw.println(" r[recents]: recent activities state"); 12367 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12368 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12369 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12370 pw.println(" o[om]: out of memory management"); 12371 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12372 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12373 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12374 pw.println(" service [COMP_SPEC]: service client-side state"); 12375 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12376 pw.println(" all: dump all activities"); 12377 pw.println(" top: dump the top activity"); 12378 pw.println(" write: write all pending state to storage"); 12379 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12380 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12381 pw.println(" a partial substring in a component name, a"); 12382 pw.println(" hex object identifier."); 12383 pw.println(" -a: include all available server state."); 12384 pw.println(" -c: include client state."); 12385 return; 12386 } else { 12387 pw.println("Unknown argument: " + opt + "; use -h for help"); 12388 } 12389 } 12390 12391 long origId = Binder.clearCallingIdentity(); 12392 boolean more = false; 12393 // Is the caller requesting to dump a particular piece of data? 12394 if (opti < args.length) { 12395 String cmd = args[opti]; 12396 opti++; 12397 if ("activities".equals(cmd) || "a".equals(cmd)) { 12398 synchronized (this) { 12399 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12400 } 12401 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12402 synchronized (this) { 12403 dumpRecentsLocked(fd, pw, args, opti, true, null); 12404 } 12405 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12406 String[] newArgs; 12407 String name; 12408 if (opti >= args.length) { 12409 name = null; 12410 newArgs = EMPTY_STRING_ARRAY; 12411 } else { 12412 name = args[opti]; 12413 opti++; 12414 newArgs = new String[args.length - opti]; 12415 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12416 args.length - opti); 12417 } 12418 synchronized (this) { 12419 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12420 } 12421 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12422 String[] newArgs; 12423 String name; 12424 if (opti >= args.length) { 12425 name = null; 12426 newArgs = EMPTY_STRING_ARRAY; 12427 } else { 12428 name = args[opti]; 12429 opti++; 12430 newArgs = new String[args.length - opti]; 12431 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12432 args.length - opti); 12433 } 12434 synchronized (this) { 12435 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12436 } 12437 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12438 String[] newArgs; 12439 String name; 12440 if (opti >= args.length) { 12441 name = null; 12442 newArgs = EMPTY_STRING_ARRAY; 12443 } else { 12444 name = args[opti]; 12445 opti++; 12446 newArgs = new String[args.length - opti]; 12447 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12448 args.length - opti); 12449 } 12450 synchronized (this) { 12451 dumpProcessesLocked(fd, pw, args, opti, true, name); 12452 } 12453 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12454 synchronized (this) { 12455 dumpOomLocked(fd, pw, args, opti, true); 12456 } 12457 } else if ("provider".equals(cmd)) { 12458 String[] newArgs; 12459 String name; 12460 if (opti >= args.length) { 12461 name = null; 12462 newArgs = EMPTY_STRING_ARRAY; 12463 } else { 12464 name = args[opti]; 12465 opti++; 12466 newArgs = new String[args.length - opti]; 12467 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12468 } 12469 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12470 pw.println("No providers match: " + name); 12471 pw.println("Use -h for help."); 12472 } 12473 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12474 synchronized (this) { 12475 dumpProvidersLocked(fd, pw, args, opti, true, null); 12476 } 12477 } else if ("service".equals(cmd)) { 12478 String[] newArgs; 12479 String name; 12480 if (opti >= args.length) { 12481 name = null; 12482 newArgs = EMPTY_STRING_ARRAY; 12483 } else { 12484 name = args[opti]; 12485 opti++; 12486 newArgs = new String[args.length - opti]; 12487 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12488 args.length - opti); 12489 } 12490 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12491 pw.println("No services match: " + name); 12492 pw.println("Use -h for help."); 12493 } 12494 } else if ("package".equals(cmd)) { 12495 String[] newArgs; 12496 if (opti >= args.length) { 12497 pw.println("package: no package name specified"); 12498 pw.println("Use -h for help."); 12499 } else { 12500 dumpPackage = args[opti]; 12501 opti++; 12502 newArgs = new String[args.length - opti]; 12503 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12504 args.length - opti); 12505 args = newArgs; 12506 opti = 0; 12507 more = true; 12508 } 12509 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12510 synchronized (this) { 12511 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12512 } 12513 } else if ("write".equals(cmd)) { 12514 mTaskPersister.flush(); 12515 pw.println("All tasks persisted."); 12516 return; 12517 } else { 12518 // Dumping a single activity? 12519 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12520 pw.println("Bad activity command, or no activities match: " + cmd); 12521 pw.println("Use -h for help."); 12522 } 12523 } 12524 if (!more) { 12525 Binder.restoreCallingIdentity(origId); 12526 return; 12527 } 12528 } 12529 12530 // No piece of data specified, dump everything. 12531 synchronized (this) { 12532 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12533 pw.println(); 12534 if (dumpAll) { 12535 pw.println("-------------------------------------------------------------------------------"); 12536 } 12537 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12538 pw.println(); 12539 if (dumpAll) { 12540 pw.println("-------------------------------------------------------------------------------"); 12541 } 12542 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12543 pw.println(); 12544 if (dumpAll) { 12545 pw.println("-------------------------------------------------------------------------------"); 12546 } 12547 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12548 pw.println(); 12549 if (dumpAll) { 12550 pw.println("-------------------------------------------------------------------------------"); 12551 } 12552 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12553 pw.println(); 12554 if (dumpAll) { 12555 pw.println("-------------------------------------------------------------------------------"); 12556 } 12557 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12558 pw.println(); 12559 if (dumpAll) { 12560 pw.println("-------------------------------------------------------------------------------"); 12561 } 12562 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12563 } 12564 Binder.restoreCallingIdentity(origId); 12565 } 12566 12567 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12568 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12569 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12570 12571 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12572 dumpPackage); 12573 boolean needSep = printedAnything; 12574 12575 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12576 dumpPackage, needSep, " mFocusedActivity: "); 12577 if (printed) { 12578 printedAnything = true; 12579 needSep = false; 12580 } 12581 12582 if (dumpPackage == null) { 12583 if (needSep) { 12584 pw.println(); 12585 } 12586 needSep = true; 12587 printedAnything = true; 12588 mStackSupervisor.dump(pw, " "); 12589 } 12590 12591 if (!printedAnything) { 12592 pw.println(" (nothing)"); 12593 } 12594 } 12595 12596 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12597 int opti, boolean dumpAll, String dumpPackage) { 12598 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12599 12600 boolean printedAnything = false; 12601 12602 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12603 boolean printedHeader = false; 12604 12605 final int N = mRecentTasks.size(); 12606 for (int i=0; i<N; i++) { 12607 TaskRecord tr = mRecentTasks.get(i); 12608 if (dumpPackage != null) { 12609 if (tr.realActivity == null || 12610 !dumpPackage.equals(tr.realActivity)) { 12611 continue; 12612 } 12613 } 12614 if (!printedHeader) { 12615 pw.println(" Recent tasks:"); 12616 printedHeader = true; 12617 printedAnything = true; 12618 } 12619 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12620 pw.println(tr); 12621 if (dumpAll) { 12622 mRecentTasks.get(i).dump(pw, " "); 12623 } 12624 } 12625 } 12626 12627 if (!printedAnything) { 12628 pw.println(" (nothing)"); 12629 } 12630 } 12631 12632 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12633 int opti, boolean dumpAll, String dumpPackage) { 12634 boolean needSep = false; 12635 boolean printedAnything = false; 12636 int numPers = 0; 12637 12638 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12639 12640 if (dumpAll) { 12641 final int NP = mProcessNames.getMap().size(); 12642 for (int ip=0; ip<NP; ip++) { 12643 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12644 final int NA = procs.size(); 12645 for (int ia=0; ia<NA; ia++) { 12646 ProcessRecord r = procs.valueAt(ia); 12647 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12648 continue; 12649 } 12650 if (!needSep) { 12651 pw.println(" All known processes:"); 12652 needSep = true; 12653 printedAnything = true; 12654 } 12655 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12656 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12657 pw.print(" "); pw.println(r); 12658 r.dump(pw, " "); 12659 if (r.persistent) { 12660 numPers++; 12661 } 12662 } 12663 } 12664 } 12665 12666 if (mIsolatedProcesses.size() > 0) { 12667 boolean printed = false; 12668 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12669 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12670 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12671 continue; 12672 } 12673 if (!printed) { 12674 if (needSep) { 12675 pw.println(); 12676 } 12677 pw.println(" Isolated process list (sorted by uid):"); 12678 printedAnything = true; 12679 printed = true; 12680 needSep = true; 12681 } 12682 pw.println(String.format("%sIsolated #%2d: %s", 12683 " ", i, r.toString())); 12684 } 12685 } 12686 12687 if (mLruProcesses.size() > 0) { 12688 if (needSep) { 12689 pw.println(); 12690 } 12691 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12692 pw.print(" total, non-act at "); 12693 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12694 pw.print(", non-svc at "); 12695 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12696 pw.println("):"); 12697 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12698 needSep = true; 12699 printedAnything = true; 12700 } 12701 12702 if (dumpAll || dumpPackage != null) { 12703 synchronized (mPidsSelfLocked) { 12704 boolean printed = false; 12705 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12706 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12707 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12708 continue; 12709 } 12710 if (!printed) { 12711 if (needSep) pw.println(); 12712 needSep = true; 12713 pw.println(" PID mappings:"); 12714 printed = true; 12715 printedAnything = true; 12716 } 12717 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12718 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12719 } 12720 } 12721 } 12722 12723 if (mForegroundProcesses.size() > 0) { 12724 synchronized (mPidsSelfLocked) { 12725 boolean printed = false; 12726 for (int i=0; i<mForegroundProcesses.size(); i++) { 12727 ProcessRecord r = mPidsSelfLocked.get( 12728 mForegroundProcesses.valueAt(i).pid); 12729 if (dumpPackage != null && (r == null 12730 || !r.pkgList.containsKey(dumpPackage))) { 12731 continue; 12732 } 12733 if (!printed) { 12734 if (needSep) pw.println(); 12735 needSep = true; 12736 pw.println(" Foreground Processes:"); 12737 printed = true; 12738 printedAnything = true; 12739 } 12740 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12741 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12742 } 12743 } 12744 } 12745 12746 if (mPersistentStartingProcesses.size() > 0) { 12747 if (needSep) pw.println(); 12748 needSep = true; 12749 printedAnything = true; 12750 pw.println(" Persisent processes that are starting:"); 12751 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12752 "Starting Norm", "Restarting PERS", dumpPackage); 12753 } 12754 12755 if (mRemovedProcesses.size() > 0) { 12756 if (needSep) pw.println(); 12757 needSep = true; 12758 printedAnything = true; 12759 pw.println(" Processes that are being removed:"); 12760 dumpProcessList(pw, this, mRemovedProcesses, " ", 12761 "Removed Norm", "Removed PERS", dumpPackage); 12762 } 12763 12764 if (mProcessesOnHold.size() > 0) { 12765 if (needSep) pw.println(); 12766 needSep = true; 12767 printedAnything = true; 12768 pw.println(" Processes that are on old until the system is ready:"); 12769 dumpProcessList(pw, this, mProcessesOnHold, " ", 12770 "OnHold Norm", "OnHold PERS", dumpPackage); 12771 } 12772 12773 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12774 12775 if (mProcessCrashTimes.getMap().size() > 0) { 12776 boolean printed = false; 12777 long now = SystemClock.uptimeMillis(); 12778 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12779 final int NP = pmap.size(); 12780 for (int ip=0; ip<NP; ip++) { 12781 String pname = pmap.keyAt(ip); 12782 SparseArray<Long> uids = pmap.valueAt(ip); 12783 final int N = uids.size(); 12784 for (int i=0; i<N; i++) { 12785 int puid = uids.keyAt(i); 12786 ProcessRecord r = mProcessNames.get(pname, puid); 12787 if (dumpPackage != null && (r == null 12788 || !r.pkgList.containsKey(dumpPackage))) { 12789 continue; 12790 } 12791 if (!printed) { 12792 if (needSep) pw.println(); 12793 needSep = true; 12794 pw.println(" Time since processes crashed:"); 12795 printed = true; 12796 printedAnything = true; 12797 } 12798 pw.print(" Process "); pw.print(pname); 12799 pw.print(" uid "); pw.print(puid); 12800 pw.print(": last crashed "); 12801 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12802 pw.println(" ago"); 12803 } 12804 } 12805 } 12806 12807 if (mBadProcesses.getMap().size() > 0) { 12808 boolean printed = false; 12809 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12810 final int NP = pmap.size(); 12811 for (int ip=0; ip<NP; ip++) { 12812 String pname = pmap.keyAt(ip); 12813 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12814 final int N = uids.size(); 12815 for (int i=0; i<N; i++) { 12816 int puid = uids.keyAt(i); 12817 ProcessRecord r = mProcessNames.get(pname, puid); 12818 if (dumpPackage != null && (r == null 12819 || !r.pkgList.containsKey(dumpPackage))) { 12820 continue; 12821 } 12822 if (!printed) { 12823 if (needSep) pw.println(); 12824 needSep = true; 12825 pw.println(" Bad processes:"); 12826 printedAnything = true; 12827 } 12828 BadProcessInfo info = uids.valueAt(i); 12829 pw.print(" Bad process "); pw.print(pname); 12830 pw.print(" uid "); pw.print(puid); 12831 pw.print(": crashed at time "); pw.println(info.time); 12832 if (info.shortMsg != null) { 12833 pw.print(" Short msg: "); pw.println(info.shortMsg); 12834 } 12835 if (info.longMsg != null) { 12836 pw.print(" Long msg: "); pw.println(info.longMsg); 12837 } 12838 if (info.stack != null) { 12839 pw.println(" Stack:"); 12840 int lastPos = 0; 12841 for (int pos=0; pos<info.stack.length(); pos++) { 12842 if (info.stack.charAt(pos) == '\n') { 12843 pw.print(" "); 12844 pw.write(info.stack, lastPos, pos-lastPos); 12845 pw.println(); 12846 lastPos = pos+1; 12847 } 12848 } 12849 if (lastPos < info.stack.length()) { 12850 pw.print(" "); 12851 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12852 pw.println(); 12853 } 12854 } 12855 } 12856 } 12857 } 12858 12859 if (dumpPackage == null) { 12860 pw.println(); 12861 needSep = false; 12862 pw.println(" mStartedUsers:"); 12863 for (int i=0; i<mStartedUsers.size(); i++) { 12864 UserStartedState uss = mStartedUsers.valueAt(i); 12865 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12866 pw.print(": "); uss.dump("", pw); 12867 } 12868 pw.print(" mStartedUserArray: ["); 12869 for (int i=0; i<mStartedUserArray.length; i++) { 12870 if (i > 0) pw.print(", "); 12871 pw.print(mStartedUserArray[i]); 12872 } 12873 pw.println("]"); 12874 pw.print(" mUserLru: ["); 12875 for (int i=0; i<mUserLru.size(); i++) { 12876 if (i > 0) pw.print(", "); 12877 pw.print(mUserLru.get(i)); 12878 } 12879 pw.println("]"); 12880 if (dumpAll) { 12881 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12882 } 12883 synchronized (mUserProfileGroupIdsSelfLocked) { 12884 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12885 pw.println(" mUserProfileGroupIds:"); 12886 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12887 pw.print(" User #"); 12888 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12889 pw.print(" -> profile #"); 12890 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12891 } 12892 } 12893 } 12894 } 12895 if (mHomeProcess != null && (dumpPackage == null 12896 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12897 if (needSep) { 12898 pw.println(); 12899 needSep = false; 12900 } 12901 pw.println(" mHomeProcess: " + mHomeProcess); 12902 } 12903 if (mPreviousProcess != null && (dumpPackage == null 12904 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12905 if (needSep) { 12906 pw.println(); 12907 needSep = false; 12908 } 12909 pw.println(" mPreviousProcess: " + mPreviousProcess); 12910 } 12911 if (dumpAll) { 12912 StringBuilder sb = new StringBuilder(128); 12913 sb.append(" mPreviousProcessVisibleTime: "); 12914 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12915 pw.println(sb); 12916 } 12917 if (mHeavyWeightProcess != null && (dumpPackage == null 12918 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12919 if (needSep) { 12920 pw.println(); 12921 needSep = false; 12922 } 12923 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12924 } 12925 if (dumpPackage == null) { 12926 pw.println(" mConfiguration: " + mConfiguration); 12927 } 12928 if (dumpAll) { 12929 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12930 if (mCompatModePackages.getPackages().size() > 0) { 12931 boolean printed = false; 12932 for (Map.Entry<String, Integer> entry 12933 : mCompatModePackages.getPackages().entrySet()) { 12934 String pkg = entry.getKey(); 12935 int mode = entry.getValue(); 12936 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12937 continue; 12938 } 12939 if (!printed) { 12940 pw.println(" mScreenCompatPackages:"); 12941 printed = true; 12942 } 12943 pw.print(" "); pw.print(pkg); pw.print(": "); 12944 pw.print(mode); pw.println(); 12945 } 12946 } 12947 } 12948 if (dumpPackage == null) { 12949 if (mSleeping || mWentToSleep || mLockScreenShown) { 12950 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12951 + " mLockScreenShown " + mLockScreenShown); 12952 } 12953 if (mShuttingDown || mRunningVoice) { 12954 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12955 } 12956 } 12957 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12958 || mOrigWaitForDebugger) { 12959 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12960 || dumpPackage.equals(mOrigDebugApp)) { 12961 if (needSep) { 12962 pw.println(); 12963 needSep = false; 12964 } 12965 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12966 + " mDebugTransient=" + mDebugTransient 12967 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12968 } 12969 } 12970 if (mOpenGlTraceApp != null) { 12971 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12972 if (needSep) { 12973 pw.println(); 12974 needSep = false; 12975 } 12976 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12977 } 12978 } 12979 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12980 || mProfileFd != null) { 12981 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12982 if (needSep) { 12983 pw.println(); 12984 needSep = false; 12985 } 12986 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12987 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12988 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12989 + mAutoStopProfiler); 12990 pw.println(" mProfileType=" + mProfileType); 12991 } 12992 } 12993 if (dumpPackage == null) { 12994 if (mAlwaysFinishActivities || mController != null) { 12995 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12996 + " mController=" + mController); 12997 } 12998 if (dumpAll) { 12999 pw.println(" Total persistent processes: " + numPers); 13000 pw.println(" mProcessesReady=" + mProcessesReady 13001 + " mSystemReady=" + mSystemReady 13002 + " mBooted=" + mBooted 13003 + " mFactoryTest=" + mFactoryTest); 13004 pw.println(" mBooting=" + mBooting 13005 + " mCallFinishBooting=" + mCallFinishBooting 13006 + " mBootAnimationComplete=" + mBootAnimationComplete); 13007 pw.print(" mLastPowerCheckRealtime="); 13008 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13009 pw.println(""); 13010 pw.print(" mLastPowerCheckUptime="); 13011 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13012 pw.println(""); 13013 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13014 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13015 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13016 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13017 + " (" + mLruProcesses.size() + " total)" 13018 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13019 + " mNumServiceProcs=" + mNumServiceProcs 13020 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13021 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13022 + " mLastMemoryLevel" + mLastMemoryLevel 13023 + " mLastNumProcesses" + mLastNumProcesses); 13024 long now = SystemClock.uptimeMillis(); 13025 pw.print(" mLastIdleTime="); 13026 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13027 pw.print(" mLowRamSinceLastIdle="); 13028 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13029 pw.println(); 13030 } 13031 } 13032 13033 if (!printedAnything) { 13034 pw.println(" (nothing)"); 13035 } 13036 } 13037 13038 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13039 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13040 if (mProcessesToGc.size() > 0) { 13041 boolean printed = false; 13042 long now = SystemClock.uptimeMillis(); 13043 for (int i=0; i<mProcessesToGc.size(); i++) { 13044 ProcessRecord proc = mProcessesToGc.get(i); 13045 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13046 continue; 13047 } 13048 if (!printed) { 13049 if (needSep) pw.println(); 13050 needSep = true; 13051 pw.println(" Processes that are waiting to GC:"); 13052 printed = true; 13053 } 13054 pw.print(" Process "); pw.println(proc); 13055 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13056 pw.print(", last gced="); 13057 pw.print(now-proc.lastRequestedGc); 13058 pw.print(" ms ago, last lowMem="); 13059 pw.print(now-proc.lastLowMemory); 13060 pw.println(" ms ago"); 13061 13062 } 13063 } 13064 return needSep; 13065 } 13066 13067 void printOomLevel(PrintWriter pw, String name, int adj) { 13068 pw.print(" "); 13069 if (adj >= 0) { 13070 pw.print(' '); 13071 if (adj < 10) pw.print(' '); 13072 } else { 13073 if (adj > -10) pw.print(' '); 13074 } 13075 pw.print(adj); 13076 pw.print(": "); 13077 pw.print(name); 13078 pw.print(" ("); 13079 pw.print(mProcessList.getMemLevel(adj)/1024); 13080 pw.println(" kB)"); 13081 } 13082 13083 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13084 int opti, boolean dumpAll) { 13085 boolean needSep = false; 13086 13087 if (mLruProcesses.size() > 0) { 13088 if (needSep) pw.println(); 13089 needSep = true; 13090 pw.println(" OOM levels:"); 13091 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13092 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13093 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13094 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13095 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13096 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13097 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13098 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13099 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13100 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13101 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13102 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13103 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13104 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13105 13106 if (needSep) pw.println(); 13107 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13108 pw.print(" total, non-act at "); 13109 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13110 pw.print(", non-svc at "); 13111 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13112 pw.println("):"); 13113 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13114 needSep = true; 13115 } 13116 13117 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13118 13119 pw.println(); 13120 pw.println(" mHomeProcess: " + mHomeProcess); 13121 pw.println(" mPreviousProcess: " + mPreviousProcess); 13122 if (mHeavyWeightProcess != null) { 13123 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13124 } 13125 13126 return true; 13127 } 13128 13129 /** 13130 * There are three ways to call this: 13131 * - no provider specified: dump all the providers 13132 * - a flattened component name that matched an existing provider was specified as the 13133 * first arg: dump that one provider 13134 * - the first arg isn't the flattened component name of an existing provider: 13135 * dump all providers whose component contains the first arg as a substring 13136 */ 13137 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13138 int opti, boolean dumpAll) { 13139 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13140 } 13141 13142 static class ItemMatcher { 13143 ArrayList<ComponentName> components; 13144 ArrayList<String> strings; 13145 ArrayList<Integer> objects; 13146 boolean all; 13147 13148 ItemMatcher() { 13149 all = true; 13150 } 13151 13152 void build(String name) { 13153 ComponentName componentName = ComponentName.unflattenFromString(name); 13154 if (componentName != null) { 13155 if (components == null) { 13156 components = new ArrayList<ComponentName>(); 13157 } 13158 components.add(componentName); 13159 all = false; 13160 } else { 13161 int objectId = 0; 13162 // Not a '/' separated full component name; maybe an object ID? 13163 try { 13164 objectId = Integer.parseInt(name, 16); 13165 if (objects == null) { 13166 objects = new ArrayList<Integer>(); 13167 } 13168 objects.add(objectId); 13169 all = false; 13170 } catch (RuntimeException e) { 13171 // Not an integer; just do string match. 13172 if (strings == null) { 13173 strings = new ArrayList<String>(); 13174 } 13175 strings.add(name); 13176 all = false; 13177 } 13178 } 13179 } 13180 13181 int build(String[] args, int opti) { 13182 for (; opti<args.length; opti++) { 13183 String name = args[opti]; 13184 if ("--".equals(name)) { 13185 return opti+1; 13186 } 13187 build(name); 13188 } 13189 return opti; 13190 } 13191 13192 boolean match(Object object, ComponentName comp) { 13193 if (all) { 13194 return true; 13195 } 13196 if (components != null) { 13197 for (int i=0; i<components.size(); i++) { 13198 if (components.get(i).equals(comp)) { 13199 return true; 13200 } 13201 } 13202 } 13203 if (objects != null) { 13204 for (int i=0; i<objects.size(); i++) { 13205 if (System.identityHashCode(object) == objects.get(i)) { 13206 return true; 13207 } 13208 } 13209 } 13210 if (strings != null) { 13211 String flat = comp.flattenToString(); 13212 for (int i=0; i<strings.size(); i++) { 13213 if (flat.contains(strings.get(i))) { 13214 return true; 13215 } 13216 } 13217 } 13218 return false; 13219 } 13220 } 13221 13222 /** 13223 * There are three things that cmd can be: 13224 * - a flattened component name that matches an existing activity 13225 * - the cmd arg isn't the flattened component name of an existing activity: 13226 * dump all activity whose component contains the cmd as a substring 13227 * - A hex number of the ActivityRecord object instance. 13228 */ 13229 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13230 int opti, boolean dumpAll) { 13231 ArrayList<ActivityRecord> activities; 13232 13233 synchronized (this) { 13234 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13235 } 13236 13237 if (activities.size() <= 0) { 13238 return false; 13239 } 13240 13241 String[] newArgs = new String[args.length - opti]; 13242 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13243 13244 TaskRecord lastTask = null; 13245 boolean needSep = false; 13246 for (int i=activities.size()-1; i>=0; i--) { 13247 ActivityRecord r = activities.get(i); 13248 if (needSep) { 13249 pw.println(); 13250 } 13251 needSep = true; 13252 synchronized (this) { 13253 if (lastTask != r.task) { 13254 lastTask = r.task; 13255 pw.print("TASK "); pw.print(lastTask.affinity); 13256 pw.print(" id="); pw.println(lastTask.taskId); 13257 if (dumpAll) { 13258 lastTask.dump(pw, " "); 13259 } 13260 } 13261 } 13262 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13263 } 13264 return true; 13265 } 13266 13267 /** 13268 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13269 * there is a thread associated with the activity. 13270 */ 13271 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13272 final ActivityRecord r, String[] args, boolean dumpAll) { 13273 String innerPrefix = prefix + " "; 13274 synchronized (this) { 13275 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13276 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13277 pw.print(" pid="); 13278 if (r.app != null) pw.println(r.app.pid); 13279 else pw.println("(not running)"); 13280 if (dumpAll) { 13281 r.dump(pw, innerPrefix); 13282 } 13283 } 13284 if (r.app != null && r.app.thread != null) { 13285 // flush anything that is already in the PrintWriter since the thread is going 13286 // to write to the file descriptor directly 13287 pw.flush(); 13288 try { 13289 TransferPipe tp = new TransferPipe(); 13290 try { 13291 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13292 r.appToken, innerPrefix, args); 13293 tp.go(fd); 13294 } finally { 13295 tp.kill(); 13296 } 13297 } catch (IOException e) { 13298 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13299 } catch (RemoteException e) { 13300 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13301 } 13302 } 13303 } 13304 13305 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13306 int opti, boolean dumpAll, String dumpPackage) { 13307 boolean needSep = false; 13308 boolean onlyHistory = false; 13309 boolean printedAnything = false; 13310 13311 if ("history".equals(dumpPackage)) { 13312 if (opti < args.length && "-s".equals(args[opti])) { 13313 dumpAll = false; 13314 } 13315 onlyHistory = true; 13316 dumpPackage = null; 13317 } 13318 13319 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13320 if (!onlyHistory && dumpAll) { 13321 if (mRegisteredReceivers.size() > 0) { 13322 boolean printed = false; 13323 Iterator it = mRegisteredReceivers.values().iterator(); 13324 while (it.hasNext()) { 13325 ReceiverList r = (ReceiverList)it.next(); 13326 if (dumpPackage != null && (r.app == null || 13327 !dumpPackage.equals(r.app.info.packageName))) { 13328 continue; 13329 } 13330 if (!printed) { 13331 pw.println(" Registered Receivers:"); 13332 needSep = true; 13333 printed = true; 13334 printedAnything = true; 13335 } 13336 pw.print(" * "); pw.println(r); 13337 r.dump(pw, " "); 13338 } 13339 } 13340 13341 if (mReceiverResolver.dump(pw, needSep ? 13342 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13343 " ", dumpPackage, false)) { 13344 needSep = true; 13345 printedAnything = true; 13346 } 13347 } 13348 13349 for (BroadcastQueue q : mBroadcastQueues) { 13350 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13351 printedAnything |= needSep; 13352 } 13353 13354 needSep = true; 13355 13356 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13357 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13358 if (needSep) { 13359 pw.println(); 13360 } 13361 needSep = true; 13362 printedAnything = true; 13363 pw.print(" Sticky broadcasts for user "); 13364 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13365 StringBuilder sb = new StringBuilder(128); 13366 for (Map.Entry<String, ArrayList<Intent>> ent 13367 : mStickyBroadcasts.valueAt(user).entrySet()) { 13368 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13369 if (dumpAll) { 13370 pw.println(":"); 13371 ArrayList<Intent> intents = ent.getValue(); 13372 final int N = intents.size(); 13373 for (int i=0; i<N; i++) { 13374 sb.setLength(0); 13375 sb.append(" Intent: "); 13376 intents.get(i).toShortString(sb, false, true, false, false); 13377 pw.println(sb.toString()); 13378 Bundle bundle = intents.get(i).getExtras(); 13379 if (bundle != null) { 13380 pw.print(" "); 13381 pw.println(bundle.toString()); 13382 } 13383 } 13384 } else { 13385 pw.println(""); 13386 } 13387 } 13388 } 13389 } 13390 13391 if (!onlyHistory && dumpAll) { 13392 pw.println(); 13393 for (BroadcastQueue queue : mBroadcastQueues) { 13394 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13395 + queue.mBroadcastsScheduled); 13396 } 13397 pw.println(" mHandler:"); 13398 mHandler.dump(new PrintWriterPrinter(pw), " "); 13399 needSep = true; 13400 printedAnything = true; 13401 } 13402 13403 if (!printedAnything) { 13404 pw.println(" (nothing)"); 13405 } 13406 } 13407 13408 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13409 int opti, boolean dumpAll, String dumpPackage) { 13410 boolean needSep; 13411 boolean printedAnything = false; 13412 13413 ItemMatcher matcher = new ItemMatcher(); 13414 matcher.build(args, opti); 13415 13416 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13417 13418 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13419 printedAnything |= needSep; 13420 13421 if (mLaunchingProviders.size() > 0) { 13422 boolean printed = false; 13423 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13424 ContentProviderRecord r = mLaunchingProviders.get(i); 13425 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13426 continue; 13427 } 13428 if (!printed) { 13429 if (needSep) pw.println(); 13430 needSep = true; 13431 pw.println(" Launching content providers:"); 13432 printed = true; 13433 printedAnything = true; 13434 } 13435 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13436 pw.println(r); 13437 } 13438 } 13439 13440 if (mGrantedUriPermissions.size() > 0) { 13441 boolean printed = false; 13442 int dumpUid = -2; 13443 if (dumpPackage != null) { 13444 try { 13445 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13446 } catch (NameNotFoundException e) { 13447 dumpUid = -1; 13448 } 13449 } 13450 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13451 int uid = mGrantedUriPermissions.keyAt(i); 13452 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13453 continue; 13454 } 13455 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13456 if (!printed) { 13457 if (needSep) pw.println(); 13458 needSep = true; 13459 pw.println(" Granted Uri Permissions:"); 13460 printed = true; 13461 printedAnything = true; 13462 } 13463 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13464 for (UriPermission perm : perms.values()) { 13465 pw.print(" "); pw.println(perm); 13466 if (dumpAll) { 13467 perm.dump(pw, " "); 13468 } 13469 } 13470 } 13471 } 13472 13473 if (!printedAnything) { 13474 pw.println(" (nothing)"); 13475 } 13476 } 13477 13478 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13479 int opti, boolean dumpAll, String dumpPackage) { 13480 boolean printed = false; 13481 13482 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13483 13484 if (mIntentSenderRecords.size() > 0) { 13485 Iterator<WeakReference<PendingIntentRecord>> it 13486 = mIntentSenderRecords.values().iterator(); 13487 while (it.hasNext()) { 13488 WeakReference<PendingIntentRecord> ref = it.next(); 13489 PendingIntentRecord rec = ref != null ? ref.get(): null; 13490 if (dumpPackage != null && (rec == null 13491 || !dumpPackage.equals(rec.key.packageName))) { 13492 continue; 13493 } 13494 printed = true; 13495 if (rec != null) { 13496 pw.print(" * "); pw.println(rec); 13497 if (dumpAll) { 13498 rec.dump(pw, " "); 13499 } 13500 } else { 13501 pw.print(" * "); pw.println(ref); 13502 } 13503 } 13504 } 13505 13506 if (!printed) { 13507 pw.println(" (nothing)"); 13508 } 13509 } 13510 13511 private static final int dumpProcessList(PrintWriter pw, 13512 ActivityManagerService service, List list, 13513 String prefix, String normalLabel, String persistentLabel, 13514 String dumpPackage) { 13515 int numPers = 0; 13516 final int N = list.size()-1; 13517 for (int i=N; i>=0; i--) { 13518 ProcessRecord r = (ProcessRecord)list.get(i); 13519 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13520 continue; 13521 } 13522 pw.println(String.format("%s%s #%2d: %s", 13523 prefix, (r.persistent ? persistentLabel : normalLabel), 13524 i, r.toString())); 13525 if (r.persistent) { 13526 numPers++; 13527 } 13528 } 13529 return numPers; 13530 } 13531 13532 private static final boolean dumpProcessOomList(PrintWriter pw, 13533 ActivityManagerService service, List<ProcessRecord> origList, 13534 String prefix, String normalLabel, String persistentLabel, 13535 boolean inclDetails, String dumpPackage) { 13536 13537 ArrayList<Pair<ProcessRecord, Integer>> list 13538 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13539 for (int i=0; i<origList.size(); i++) { 13540 ProcessRecord r = origList.get(i); 13541 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13542 continue; 13543 } 13544 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13545 } 13546 13547 if (list.size() <= 0) { 13548 return false; 13549 } 13550 13551 Comparator<Pair<ProcessRecord, Integer>> comparator 13552 = new Comparator<Pair<ProcessRecord, Integer>>() { 13553 @Override 13554 public int compare(Pair<ProcessRecord, Integer> object1, 13555 Pair<ProcessRecord, Integer> object2) { 13556 if (object1.first.setAdj != object2.first.setAdj) { 13557 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13558 } 13559 if (object1.second.intValue() != object2.second.intValue()) { 13560 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13561 } 13562 return 0; 13563 } 13564 }; 13565 13566 Collections.sort(list, comparator); 13567 13568 final long curRealtime = SystemClock.elapsedRealtime(); 13569 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13570 final long curUptime = SystemClock.uptimeMillis(); 13571 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13572 13573 for (int i=list.size()-1; i>=0; i--) { 13574 ProcessRecord r = list.get(i).first; 13575 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13576 char schedGroup; 13577 switch (r.setSchedGroup) { 13578 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13579 schedGroup = 'B'; 13580 break; 13581 case Process.THREAD_GROUP_DEFAULT: 13582 schedGroup = 'F'; 13583 break; 13584 default: 13585 schedGroup = '?'; 13586 break; 13587 } 13588 char foreground; 13589 if (r.foregroundActivities) { 13590 foreground = 'A'; 13591 } else if (r.foregroundServices) { 13592 foreground = 'S'; 13593 } else { 13594 foreground = ' '; 13595 } 13596 String procState = ProcessList.makeProcStateString(r.curProcState); 13597 pw.print(prefix); 13598 pw.print(r.persistent ? persistentLabel : normalLabel); 13599 pw.print(" #"); 13600 int num = (origList.size()-1)-list.get(i).second; 13601 if (num < 10) pw.print(' '); 13602 pw.print(num); 13603 pw.print(": "); 13604 pw.print(oomAdj); 13605 pw.print(' '); 13606 pw.print(schedGroup); 13607 pw.print('/'); 13608 pw.print(foreground); 13609 pw.print('/'); 13610 pw.print(procState); 13611 pw.print(" trm:"); 13612 if (r.trimMemoryLevel < 10) pw.print(' '); 13613 pw.print(r.trimMemoryLevel); 13614 pw.print(' '); 13615 pw.print(r.toShortString()); 13616 pw.print(" ("); 13617 pw.print(r.adjType); 13618 pw.println(')'); 13619 if (r.adjSource != null || r.adjTarget != null) { 13620 pw.print(prefix); 13621 pw.print(" "); 13622 if (r.adjTarget instanceof ComponentName) { 13623 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13624 } else if (r.adjTarget != null) { 13625 pw.print(r.adjTarget.toString()); 13626 } else { 13627 pw.print("{null}"); 13628 } 13629 pw.print("<="); 13630 if (r.adjSource instanceof ProcessRecord) { 13631 pw.print("Proc{"); 13632 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13633 pw.println("}"); 13634 } else if (r.adjSource != null) { 13635 pw.println(r.adjSource.toString()); 13636 } else { 13637 pw.println("{null}"); 13638 } 13639 } 13640 if (inclDetails) { 13641 pw.print(prefix); 13642 pw.print(" "); 13643 pw.print("oom: max="); pw.print(r.maxAdj); 13644 pw.print(" curRaw="); pw.print(r.curRawAdj); 13645 pw.print(" setRaw="); pw.print(r.setRawAdj); 13646 pw.print(" cur="); pw.print(r.curAdj); 13647 pw.print(" set="); pw.println(r.setAdj); 13648 pw.print(prefix); 13649 pw.print(" "); 13650 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13651 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13652 pw.print(" lastPss="); pw.print(r.lastPss); 13653 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13654 pw.print(prefix); 13655 pw.print(" "); 13656 pw.print("cached="); pw.print(r.cached); 13657 pw.print(" empty="); pw.print(r.empty); 13658 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13659 13660 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13661 if (r.lastWakeTime != 0) { 13662 long wtime; 13663 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13664 synchronized (stats) { 13665 wtime = stats.getProcessWakeTime(r.info.uid, 13666 r.pid, curRealtime); 13667 } 13668 long timeUsed = wtime - r.lastWakeTime; 13669 pw.print(prefix); 13670 pw.print(" "); 13671 pw.print("keep awake over "); 13672 TimeUtils.formatDuration(realtimeSince, pw); 13673 pw.print(" used "); 13674 TimeUtils.formatDuration(timeUsed, pw); 13675 pw.print(" ("); 13676 pw.print((timeUsed*100)/realtimeSince); 13677 pw.println("%)"); 13678 } 13679 if (r.lastCpuTime != 0) { 13680 long timeUsed = r.curCpuTime - r.lastCpuTime; 13681 pw.print(prefix); 13682 pw.print(" "); 13683 pw.print("run cpu over "); 13684 TimeUtils.formatDuration(uptimeSince, pw); 13685 pw.print(" used "); 13686 TimeUtils.formatDuration(timeUsed, pw); 13687 pw.print(" ("); 13688 pw.print((timeUsed*100)/uptimeSince); 13689 pw.println("%)"); 13690 } 13691 } 13692 } 13693 } 13694 return true; 13695 } 13696 13697 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13698 String[] args) { 13699 ArrayList<ProcessRecord> procs; 13700 synchronized (this) { 13701 if (args != null && args.length > start 13702 && args[start].charAt(0) != '-') { 13703 procs = new ArrayList<ProcessRecord>(); 13704 int pid = -1; 13705 try { 13706 pid = Integer.parseInt(args[start]); 13707 } catch (NumberFormatException e) { 13708 } 13709 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13710 ProcessRecord proc = mLruProcesses.get(i); 13711 if (proc.pid == pid) { 13712 procs.add(proc); 13713 } else if (allPkgs && proc.pkgList != null 13714 && proc.pkgList.containsKey(args[start])) { 13715 procs.add(proc); 13716 } else if (proc.processName.equals(args[start])) { 13717 procs.add(proc); 13718 } 13719 } 13720 if (procs.size() <= 0) { 13721 return null; 13722 } 13723 } else { 13724 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13725 } 13726 } 13727 return procs; 13728 } 13729 13730 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13731 PrintWriter pw, String[] args) { 13732 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13733 if (procs == null) { 13734 pw.println("No process found for: " + args[0]); 13735 return; 13736 } 13737 13738 long uptime = SystemClock.uptimeMillis(); 13739 long realtime = SystemClock.elapsedRealtime(); 13740 pw.println("Applications Graphics Acceleration Info:"); 13741 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13742 13743 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13744 ProcessRecord r = procs.get(i); 13745 if (r.thread != null) { 13746 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13747 pw.flush(); 13748 try { 13749 TransferPipe tp = new TransferPipe(); 13750 try { 13751 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13752 tp.go(fd); 13753 } finally { 13754 tp.kill(); 13755 } 13756 } catch (IOException e) { 13757 pw.println("Failure while dumping the app: " + r); 13758 pw.flush(); 13759 } catch (RemoteException e) { 13760 pw.println("Got a RemoteException while dumping the app " + r); 13761 pw.flush(); 13762 } 13763 } 13764 } 13765 } 13766 13767 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13768 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13769 if (procs == null) { 13770 pw.println("No process found for: " + args[0]); 13771 return; 13772 } 13773 13774 pw.println("Applications Database Info:"); 13775 13776 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13777 ProcessRecord r = procs.get(i); 13778 if (r.thread != null) { 13779 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13780 pw.flush(); 13781 try { 13782 TransferPipe tp = new TransferPipe(); 13783 try { 13784 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13785 tp.go(fd); 13786 } finally { 13787 tp.kill(); 13788 } 13789 } catch (IOException e) { 13790 pw.println("Failure while dumping the app: " + r); 13791 pw.flush(); 13792 } catch (RemoteException e) { 13793 pw.println("Got a RemoteException while dumping the app " + r); 13794 pw.flush(); 13795 } 13796 } 13797 } 13798 } 13799 13800 final static class MemItem { 13801 final boolean isProc; 13802 final String label; 13803 final String shortLabel; 13804 final long pss; 13805 final int id; 13806 final boolean hasActivities; 13807 ArrayList<MemItem> subitems; 13808 13809 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13810 boolean _hasActivities) { 13811 isProc = true; 13812 label = _label; 13813 shortLabel = _shortLabel; 13814 pss = _pss; 13815 id = _id; 13816 hasActivities = _hasActivities; 13817 } 13818 13819 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13820 isProc = false; 13821 label = _label; 13822 shortLabel = _shortLabel; 13823 pss = _pss; 13824 id = _id; 13825 hasActivities = false; 13826 } 13827 } 13828 13829 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13830 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13831 if (sort && !isCompact) { 13832 Collections.sort(items, new Comparator<MemItem>() { 13833 @Override 13834 public int compare(MemItem lhs, MemItem rhs) { 13835 if (lhs.pss < rhs.pss) { 13836 return 1; 13837 } else if (lhs.pss > rhs.pss) { 13838 return -1; 13839 } 13840 return 0; 13841 } 13842 }); 13843 } 13844 13845 for (int i=0; i<items.size(); i++) { 13846 MemItem mi = items.get(i); 13847 if (!isCompact) { 13848 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13849 } else if (mi.isProc) { 13850 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13851 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13852 pw.println(mi.hasActivities ? ",a" : ",e"); 13853 } else { 13854 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13855 pw.println(mi.pss); 13856 } 13857 if (mi.subitems != null) { 13858 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13859 true, isCompact); 13860 } 13861 } 13862 } 13863 13864 // These are in KB. 13865 static final long[] DUMP_MEM_BUCKETS = new long[] { 13866 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13867 120*1024, 160*1024, 200*1024, 13868 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13869 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13870 }; 13871 13872 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13873 boolean stackLike) { 13874 int start = label.lastIndexOf('.'); 13875 if (start >= 0) start++; 13876 else start = 0; 13877 int end = label.length(); 13878 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13879 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13880 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13881 out.append(bucket); 13882 out.append(stackLike ? "MB." : "MB "); 13883 out.append(label, start, end); 13884 return; 13885 } 13886 } 13887 out.append(memKB/1024); 13888 out.append(stackLike ? "MB." : "MB "); 13889 out.append(label, start, end); 13890 } 13891 13892 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13893 ProcessList.NATIVE_ADJ, 13894 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13895 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13896 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13897 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13898 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13899 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13900 }; 13901 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13902 "Native", 13903 "System", "Persistent", "Persistent Service", "Foreground", 13904 "Visible", "Perceptible", 13905 "Heavy Weight", "Backup", 13906 "A Services", "Home", 13907 "Previous", "B Services", "Cached" 13908 }; 13909 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13910 "native", 13911 "sys", "pers", "persvc", "fore", 13912 "vis", "percept", 13913 "heavy", "backup", 13914 "servicea", "home", 13915 "prev", "serviceb", "cached" 13916 }; 13917 13918 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13919 long realtime, boolean isCheckinRequest, boolean isCompact) { 13920 if (isCheckinRequest || isCompact) { 13921 // short checkin version 13922 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13923 } else { 13924 pw.println("Applications Memory Usage (kB):"); 13925 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13926 } 13927 } 13928 13929 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13930 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13931 boolean dumpDetails = false; 13932 boolean dumpFullDetails = false; 13933 boolean dumpDalvik = false; 13934 boolean oomOnly = false; 13935 boolean isCompact = false; 13936 boolean localOnly = false; 13937 boolean packages = false; 13938 13939 int opti = 0; 13940 while (opti < args.length) { 13941 String opt = args[opti]; 13942 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13943 break; 13944 } 13945 opti++; 13946 if ("-a".equals(opt)) { 13947 dumpDetails = true; 13948 dumpFullDetails = true; 13949 dumpDalvik = true; 13950 } else if ("-d".equals(opt)) { 13951 dumpDalvik = true; 13952 } else if ("-c".equals(opt)) { 13953 isCompact = true; 13954 } else if ("--oom".equals(opt)) { 13955 oomOnly = true; 13956 } else if ("--local".equals(opt)) { 13957 localOnly = true; 13958 } else if ("--package".equals(opt)) { 13959 packages = true; 13960 } else if ("-h".equals(opt)) { 13961 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13962 pw.println(" -a: include all available information for each process."); 13963 pw.println(" -d: include dalvik details when dumping process details."); 13964 pw.println(" -c: dump in a compact machine-parseable representation."); 13965 pw.println(" --oom: only show processes organized by oom adj."); 13966 pw.println(" --local: only collect details locally, don't call process."); 13967 pw.println(" --package: interpret process arg as package, dumping all"); 13968 pw.println(" processes that have loaded that package."); 13969 pw.println("If [process] is specified it can be the name or "); 13970 pw.println("pid of a specific process to dump."); 13971 return; 13972 } else { 13973 pw.println("Unknown argument: " + opt + "; use -h for help"); 13974 } 13975 } 13976 13977 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13978 long uptime = SystemClock.uptimeMillis(); 13979 long realtime = SystemClock.elapsedRealtime(); 13980 final long[] tmpLong = new long[1]; 13981 13982 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13983 if (procs == null) { 13984 // No Java processes. Maybe they want to print a native process. 13985 if (args != null && args.length > opti 13986 && args[opti].charAt(0) != '-') { 13987 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13988 = new ArrayList<ProcessCpuTracker.Stats>(); 13989 updateCpuStatsNow(); 13990 int findPid = -1; 13991 try { 13992 findPid = Integer.parseInt(args[opti]); 13993 } catch (NumberFormatException e) { 13994 } 13995 synchronized (mProcessCpuTracker) { 13996 final int N = mProcessCpuTracker.countStats(); 13997 for (int i=0; i<N; i++) { 13998 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13999 if (st.pid == findPid || (st.baseName != null 14000 && st.baseName.equals(args[opti]))) { 14001 nativeProcs.add(st); 14002 } 14003 } 14004 } 14005 if (nativeProcs.size() > 0) { 14006 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14007 isCompact); 14008 Debug.MemoryInfo mi = null; 14009 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14010 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14011 final int pid = r.pid; 14012 if (!isCheckinRequest && dumpDetails) { 14013 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14014 } 14015 if (mi == null) { 14016 mi = new Debug.MemoryInfo(); 14017 } 14018 if (dumpDetails || (!brief && !oomOnly)) { 14019 Debug.getMemoryInfo(pid, mi); 14020 } else { 14021 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14022 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14023 } 14024 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14025 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14026 if (isCheckinRequest) { 14027 pw.println(); 14028 } 14029 } 14030 return; 14031 } 14032 } 14033 pw.println("No process found for: " + args[opti]); 14034 return; 14035 } 14036 14037 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14038 dumpDetails = true; 14039 } 14040 14041 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14042 14043 String[] innerArgs = new String[args.length-opti]; 14044 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14045 14046 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14047 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14048 long nativePss=0, dalvikPss=0, otherPss=0; 14049 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14050 14051 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14052 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14053 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14054 14055 long totalPss = 0; 14056 long cachedPss = 0; 14057 14058 Debug.MemoryInfo mi = null; 14059 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14060 final ProcessRecord r = procs.get(i); 14061 final IApplicationThread thread; 14062 final int pid; 14063 final int oomAdj; 14064 final boolean hasActivities; 14065 synchronized (this) { 14066 thread = r.thread; 14067 pid = r.pid; 14068 oomAdj = r.getSetAdjWithServices(); 14069 hasActivities = r.activities.size() > 0; 14070 } 14071 if (thread != null) { 14072 if (!isCheckinRequest && dumpDetails) { 14073 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14074 } 14075 if (mi == null) { 14076 mi = new Debug.MemoryInfo(); 14077 } 14078 if (dumpDetails || (!brief && !oomOnly)) { 14079 Debug.getMemoryInfo(pid, mi); 14080 } else { 14081 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14082 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14083 } 14084 if (dumpDetails) { 14085 if (localOnly) { 14086 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14087 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14088 if (isCheckinRequest) { 14089 pw.println(); 14090 } 14091 } else { 14092 try { 14093 pw.flush(); 14094 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14095 dumpDalvik, innerArgs); 14096 } catch (RemoteException e) { 14097 if (!isCheckinRequest) { 14098 pw.println("Got RemoteException!"); 14099 pw.flush(); 14100 } 14101 } 14102 } 14103 } 14104 14105 final long myTotalPss = mi.getTotalPss(); 14106 final long myTotalUss = mi.getTotalUss(); 14107 14108 synchronized (this) { 14109 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14110 // Record this for posterity if the process has been stable. 14111 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14112 } 14113 } 14114 14115 if (!isCheckinRequest && mi != null) { 14116 totalPss += myTotalPss; 14117 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14118 (hasActivities ? " / activities)" : ")"), 14119 r.processName, myTotalPss, pid, hasActivities); 14120 procMems.add(pssItem); 14121 procMemsMap.put(pid, pssItem); 14122 14123 nativePss += mi.nativePss; 14124 dalvikPss += mi.dalvikPss; 14125 otherPss += mi.otherPss; 14126 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14127 long mem = mi.getOtherPss(j); 14128 miscPss[j] += mem; 14129 otherPss -= mem; 14130 } 14131 14132 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14133 cachedPss += myTotalPss; 14134 } 14135 14136 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14137 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14138 || oomIndex == (oomPss.length-1)) { 14139 oomPss[oomIndex] += myTotalPss; 14140 if (oomProcs[oomIndex] == null) { 14141 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14142 } 14143 oomProcs[oomIndex].add(pssItem); 14144 break; 14145 } 14146 } 14147 } 14148 } 14149 } 14150 14151 long nativeProcTotalPss = 0; 14152 14153 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14154 // If we are showing aggregations, also look for native processes to 14155 // include so that our aggregations are more accurate. 14156 updateCpuStatsNow(); 14157 synchronized (mProcessCpuTracker) { 14158 final int N = mProcessCpuTracker.countStats(); 14159 for (int i=0; i<N; i++) { 14160 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14161 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14162 if (mi == null) { 14163 mi = new Debug.MemoryInfo(); 14164 } 14165 if (!brief && !oomOnly) { 14166 Debug.getMemoryInfo(st.pid, mi); 14167 } else { 14168 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14169 mi.nativePrivateDirty = (int)tmpLong[0]; 14170 } 14171 14172 final long myTotalPss = mi.getTotalPss(); 14173 totalPss += myTotalPss; 14174 nativeProcTotalPss += myTotalPss; 14175 14176 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14177 st.name, myTotalPss, st.pid, false); 14178 procMems.add(pssItem); 14179 14180 nativePss += mi.nativePss; 14181 dalvikPss += mi.dalvikPss; 14182 otherPss += mi.otherPss; 14183 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14184 long mem = mi.getOtherPss(j); 14185 miscPss[j] += mem; 14186 otherPss -= mem; 14187 } 14188 oomPss[0] += myTotalPss; 14189 if (oomProcs[0] == null) { 14190 oomProcs[0] = new ArrayList<MemItem>(); 14191 } 14192 oomProcs[0].add(pssItem); 14193 } 14194 } 14195 } 14196 14197 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14198 14199 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14200 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14201 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14202 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14203 String label = Debug.MemoryInfo.getOtherLabel(j); 14204 catMems.add(new MemItem(label, label, miscPss[j], j)); 14205 } 14206 14207 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14208 for (int j=0; j<oomPss.length; j++) { 14209 if (oomPss[j] != 0) { 14210 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14211 : DUMP_MEM_OOM_LABEL[j]; 14212 MemItem item = new MemItem(label, label, oomPss[j], 14213 DUMP_MEM_OOM_ADJ[j]); 14214 item.subitems = oomProcs[j]; 14215 oomMems.add(item); 14216 } 14217 } 14218 14219 if (!brief && !oomOnly && !isCompact) { 14220 pw.println(); 14221 pw.println("Total PSS by process:"); 14222 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14223 pw.println(); 14224 } 14225 if (!isCompact) { 14226 pw.println("Total PSS by OOM adjustment:"); 14227 } 14228 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14229 if (!brief && !oomOnly) { 14230 PrintWriter out = categoryPw != null ? categoryPw : pw; 14231 if (!isCompact) { 14232 out.println(); 14233 out.println("Total PSS by category:"); 14234 } 14235 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14236 } 14237 if (!isCompact) { 14238 pw.println(); 14239 } 14240 MemInfoReader memInfo = new MemInfoReader(); 14241 memInfo.readMemInfo(); 14242 if (nativeProcTotalPss > 0) { 14243 synchronized (this) { 14244 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14245 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14246 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14247 } 14248 } 14249 if (!brief) { 14250 if (!isCompact) { 14251 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14252 pw.print(" kB (status "); 14253 switch (mLastMemoryLevel) { 14254 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14255 pw.println("normal)"); 14256 break; 14257 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14258 pw.println("moderate)"); 14259 break; 14260 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14261 pw.println("low)"); 14262 break; 14263 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14264 pw.println("critical)"); 14265 break; 14266 default: 14267 pw.print(mLastMemoryLevel); 14268 pw.println(")"); 14269 break; 14270 } 14271 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14272 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14273 pw.print(cachedPss); pw.print(" cached pss + "); 14274 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14275 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14276 } else { 14277 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14278 pw.print(cachedPss + memInfo.getCachedSizeKb() 14279 + memInfo.getFreeSizeKb()); pw.print(","); 14280 pw.println(totalPss - cachedPss); 14281 } 14282 } 14283 if (!isCompact) { 14284 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14285 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14286 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14287 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14288 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14289 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14290 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14291 } 14292 if (!brief) { 14293 if (memInfo.getZramTotalSizeKb() != 0) { 14294 if (!isCompact) { 14295 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14296 pw.print(" kB physical used for "); 14297 pw.print(memInfo.getSwapTotalSizeKb() 14298 - memInfo.getSwapFreeSizeKb()); 14299 pw.print(" kB in swap ("); 14300 pw.print(memInfo.getSwapTotalSizeKb()); 14301 pw.println(" kB total swap)"); 14302 } else { 14303 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14304 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14305 pw.println(memInfo.getSwapFreeSizeKb()); 14306 } 14307 } 14308 final int[] SINGLE_LONG_FORMAT = new int[] { 14309 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14310 }; 14311 long[] longOut = new long[1]; 14312 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14313 SINGLE_LONG_FORMAT, null, longOut, null); 14314 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14315 longOut[0] = 0; 14316 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14317 SINGLE_LONG_FORMAT, null, longOut, null); 14318 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14319 longOut[0] = 0; 14320 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14321 SINGLE_LONG_FORMAT, null, longOut, null); 14322 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14323 longOut[0] = 0; 14324 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14325 SINGLE_LONG_FORMAT, null, longOut, null); 14326 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14327 if (!isCompact) { 14328 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14329 pw.print(" KSM: "); pw.print(sharing); 14330 pw.print(" kB saved from shared "); 14331 pw.print(shared); pw.println(" kB"); 14332 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14333 pw.print(voltile); pw.println(" kB volatile"); 14334 } 14335 pw.print(" Tuning: "); 14336 pw.print(ActivityManager.staticGetMemoryClass()); 14337 pw.print(" (large "); 14338 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14339 pw.print("), oom "); 14340 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14341 pw.print(" kB"); 14342 pw.print(", restore limit "); 14343 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14344 pw.print(" kB"); 14345 if (ActivityManager.isLowRamDeviceStatic()) { 14346 pw.print(" (low-ram)"); 14347 } 14348 if (ActivityManager.isHighEndGfx()) { 14349 pw.print(" (high-end-gfx)"); 14350 } 14351 pw.println(); 14352 } else { 14353 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14354 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14355 pw.println(voltile); 14356 pw.print("tuning,"); 14357 pw.print(ActivityManager.staticGetMemoryClass()); 14358 pw.print(','); 14359 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14360 pw.print(','); 14361 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14362 if (ActivityManager.isLowRamDeviceStatic()) { 14363 pw.print(",low-ram"); 14364 } 14365 if (ActivityManager.isHighEndGfx()) { 14366 pw.print(",high-end-gfx"); 14367 } 14368 pw.println(); 14369 } 14370 } 14371 } 14372 } 14373 14374 /** 14375 * Searches array of arguments for the specified string 14376 * @param args array of argument strings 14377 * @param value value to search for 14378 * @return true if the value is contained in the array 14379 */ 14380 private static boolean scanArgs(String[] args, String value) { 14381 if (args != null) { 14382 for (String arg : args) { 14383 if (value.equals(arg)) { 14384 return true; 14385 } 14386 } 14387 } 14388 return false; 14389 } 14390 14391 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14392 ContentProviderRecord cpr, boolean always) { 14393 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14394 14395 if (!inLaunching || always) { 14396 synchronized (cpr) { 14397 cpr.launchingApp = null; 14398 cpr.notifyAll(); 14399 } 14400 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14401 String names[] = cpr.info.authority.split(";"); 14402 for (int j = 0; j < names.length; j++) { 14403 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14404 } 14405 } 14406 14407 for (int i=0; i<cpr.connections.size(); i++) { 14408 ContentProviderConnection conn = cpr.connections.get(i); 14409 if (conn.waiting) { 14410 // If this connection is waiting for the provider, then we don't 14411 // need to mess with its process unless we are always removing 14412 // or for some reason the provider is not currently launching. 14413 if (inLaunching && !always) { 14414 continue; 14415 } 14416 } 14417 ProcessRecord capp = conn.client; 14418 conn.dead = true; 14419 if (conn.stableCount > 0) { 14420 if (!capp.persistent && capp.thread != null 14421 && capp.pid != 0 14422 && capp.pid != MY_PID) { 14423 capp.kill("depends on provider " 14424 + cpr.name.flattenToShortString() 14425 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14426 } 14427 } else if (capp.thread != null && conn.provider.provider != null) { 14428 try { 14429 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14430 } catch (RemoteException e) { 14431 } 14432 // In the protocol here, we don't expect the client to correctly 14433 // clean up this connection, we'll just remove it. 14434 cpr.connections.remove(i); 14435 conn.client.conProviders.remove(conn); 14436 } 14437 } 14438 14439 if (inLaunching && always) { 14440 mLaunchingProviders.remove(cpr); 14441 } 14442 return inLaunching; 14443 } 14444 14445 /** 14446 * Main code for cleaning up a process when it has gone away. This is 14447 * called both as a result of the process dying, or directly when stopping 14448 * a process when running in single process mode. 14449 * 14450 * @return Returns true if the given process has been restarted, so the 14451 * app that was passed in must remain on the process lists. 14452 */ 14453 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14454 boolean restarting, boolean allowRestart, int index) { 14455 if (index >= 0) { 14456 removeLruProcessLocked(app); 14457 ProcessList.remove(app.pid); 14458 } 14459 14460 mProcessesToGc.remove(app); 14461 mPendingPssProcesses.remove(app); 14462 14463 // Dismiss any open dialogs. 14464 if (app.crashDialog != null && !app.forceCrashReport) { 14465 app.crashDialog.dismiss(); 14466 app.crashDialog = null; 14467 } 14468 if (app.anrDialog != null) { 14469 app.anrDialog.dismiss(); 14470 app.anrDialog = null; 14471 } 14472 if (app.waitDialog != null) { 14473 app.waitDialog.dismiss(); 14474 app.waitDialog = null; 14475 } 14476 14477 app.crashing = false; 14478 app.notResponding = false; 14479 14480 app.resetPackageList(mProcessStats); 14481 app.unlinkDeathRecipient(); 14482 app.makeInactive(mProcessStats); 14483 app.waitingToKill = null; 14484 app.forcingToForeground = null; 14485 updateProcessForegroundLocked(app, false, false); 14486 app.foregroundActivities = false; 14487 app.hasShownUi = false; 14488 app.treatLikeActivity = false; 14489 app.hasAboveClient = false; 14490 app.hasClientActivities = false; 14491 14492 mServices.killServicesLocked(app, allowRestart); 14493 14494 boolean restart = false; 14495 14496 // Remove published content providers. 14497 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14498 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14499 final boolean always = app.bad || !allowRestart; 14500 if (removeDyingProviderLocked(app, cpr, always) || always) { 14501 // We left the provider in the launching list, need to 14502 // restart it. 14503 restart = true; 14504 } 14505 14506 cpr.provider = null; 14507 cpr.proc = null; 14508 } 14509 app.pubProviders.clear(); 14510 14511 // Take care of any launching providers waiting for this process. 14512 if (checkAppInLaunchingProvidersLocked(app, false)) { 14513 restart = true; 14514 } 14515 14516 // Unregister from connected content providers. 14517 if (!app.conProviders.isEmpty()) { 14518 for (int i=0; i<app.conProviders.size(); i++) { 14519 ContentProviderConnection conn = app.conProviders.get(i); 14520 conn.provider.connections.remove(conn); 14521 } 14522 app.conProviders.clear(); 14523 } 14524 14525 // At this point there may be remaining entries in mLaunchingProviders 14526 // where we were the only one waiting, so they are no longer of use. 14527 // Look for these and clean up if found. 14528 // XXX Commented out for now. Trying to figure out a way to reproduce 14529 // the actual situation to identify what is actually going on. 14530 if (false) { 14531 for (int i=0; i<mLaunchingProviders.size(); i++) { 14532 ContentProviderRecord cpr = (ContentProviderRecord) 14533 mLaunchingProviders.get(i); 14534 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14535 synchronized (cpr) { 14536 cpr.launchingApp = null; 14537 cpr.notifyAll(); 14538 } 14539 } 14540 } 14541 } 14542 14543 skipCurrentReceiverLocked(app); 14544 14545 // Unregister any receivers. 14546 for (int i=app.receivers.size()-1; i>=0; i--) { 14547 removeReceiverLocked(app.receivers.valueAt(i)); 14548 } 14549 app.receivers.clear(); 14550 14551 // If the app is undergoing backup, tell the backup manager about it 14552 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14553 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14554 + mBackupTarget.appInfo + " died during backup"); 14555 try { 14556 IBackupManager bm = IBackupManager.Stub.asInterface( 14557 ServiceManager.getService(Context.BACKUP_SERVICE)); 14558 bm.agentDisconnected(app.info.packageName); 14559 } catch (RemoteException e) { 14560 // can't happen; backup manager is local 14561 } 14562 } 14563 14564 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14565 ProcessChangeItem item = mPendingProcessChanges.get(i); 14566 if (item.pid == app.pid) { 14567 mPendingProcessChanges.remove(i); 14568 mAvailProcessChanges.add(item); 14569 } 14570 } 14571 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14572 14573 // If the caller is restarting this app, then leave it in its 14574 // current lists and let the caller take care of it. 14575 if (restarting) { 14576 return false; 14577 } 14578 14579 if (!app.persistent || app.isolated) { 14580 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14581 "Removing non-persistent process during cleanup: " + app); 14582 mProcessNames.remove(app.processName, app.uid); 14583 mIsolatedProcesses.remove(app.uid); 14584 if (mHeavyWeightProcess == app) { 14585 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14586 mHeavyWeightProcess.userId, 0)); 14587 mHeavyWeightProcess = null; 14588 } 14589 } else if (!app.removed) { 14590 // This app is persistent, so we need to keep its record around. 14591 // If it is not already on the pending app list, add it there 14592 // and start a new process for it. 14593 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14594 mPersistentStartingProcesses.add(app); 14595 restart = true; 14596 } 14597 } 14598 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14599 "Clean-up removing on hold: " + app); 14600 mProcessesOnHold.remove(app); 14601 14602 if (app == mHomeProcess) { 14603 mHomeProcess = null; 14604 } 14605 if (app == mPreviousProcess) { 14606 mPreviousProcess = null; 14607 } 14608 14609 if (restart && !app.isolated) { 14610 // We have components that still need to be running in the 14611 // process, so re-launch it. 14612 if (index < 0) { 14613 ProcessList.remove(app.pid); 14614 } 14615 mProcessNames.put(app.processName, app.uid, app); 14616 startProcessLocked(app, "restart", app.processName); 14617 return true; 14618 } else if (app.pid > 0 && app.pid != MY_PID) { 14619 // Goodbye! 14620 boolean removed; 14621 synchronized (mPidsSelfLocked) { 14622 mPidsSelfLocked.remove(app.pid); 14623 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14624 } 14625 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14626 if (app.isolated) { 14627 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14628 } 14629 app.setPid(0); 14630 } 14631 return false; 14632 } 14633 14634 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14635 // Look through the content providers we are waiting to have launched, 14636 // and if any run in this process then either schedule a restart of 14637 // the process or kill the client waiting for it if this process has 14638 // gone bad. 14639 int NL = mLaunchingProviders.size(); 14640 boolean restart = false; 14641 for (int i=0; i<NL; i++) { 14642 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14643 if (cpr.launchingApp == app) { 14644 if (!alwaysBad && !app.bad) { 14645 restart = true; 14646 } else { 14647 removeDyingProviderLocked(app, cpr, true); 14648 // cpr should have been removed from mLaunchingProviders 14649 NL = mLaunchingProviders.size(); 14650 i--; 14651 } 14652 } 14653 } 14654 return restart; 14655 } 14656 14657 // ========================================================= 14658 // SERVICES 14659 // ========================================================= 14660 14661 @Override 14662 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14663 int flags) { 14664 enforceNotIsolatedCaller("getServices"); 14665 synchronized (this) { 14666 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14667 } 14668 } 14669 14670 @Override 14671 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14672 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14673 synchronized (this) { 14674 return mServices.getRunningServiceControlPanelLocked(name); 14675 } 14676 } 14677 14678 @Override 14679 public ComponentName startService(IApplicationThread caller, Intent service, 14680 String resolvedType, int userId) { 14681 enforceNotIsolatedCaller("startService"); 14682 // Refuse possible leaked file descriptors 14683 if (service != null && service.hasFileDescriptors() == true) { 14684 throw new IllegalArgumentException("File descriptors passed in Intent"); 14685 } 14686 14687 if (DEBUG_SERVICE) 14688 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14689 synchronized(this) { 14690 final int callingPid = Binder.getCallingPid(); 14691 final int callingUid = Binder.getCallingUid(); 14692 final long origId = Binder.clearCallingIdentity(); 14693 ComponentName res = mServices.startServiceLocked(caller, service, 14694 resolvedType, callingPid, callingUid, userId); 14695 Binder.restoreCallingIdentity(origId); 14696 return res; 14697 } 14698 } 14699 14700 ComponentName startServiceInPackage(int uid, 14701 Intent service, String resolvedType, int userId) { 14702 synchronized(this) { 14703 if (DEBUG_SERVICE) 14704 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14705 final long origId = Binder.clearCallingIdentity(); 14706 ComponentName res = mServices.startServiceLocked(null, service, 14707 resolvedType, -1, uid, userId); 14708 Binder.restoreCallingIdentity(origId); 14709 return res; 14710 } 14711 } 14712 14713 @Override 14714 public int stopService(IApplicationThread caller, Intent service, 14715 String resolvedType, int userId) { 14716 enforceNotIsolatedCaller("stopService"); 14717 // Refuse possible leaked file descriptors 14718 if (service != null && service.hasFileDescriptors() == true) { 14719 throw new IllegalArgumentException("File descriptors passed in Intent"); 14720 } 14721 14722 synchronized(this) { 14723 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14724 } 14725 } 14726 14727 @Override 14728 public IBinder peekService(Intent service, String resolvedType) { 14729 enforceNotIsolatedCaller("peekService"); 14730 // Refuse possible leaked file descriptors 14731 if (service != null && service.hasFileDescriptors() == true) { 14732 throw new IllegalArgumentException("File descriptors passed in Intent"); 14733 } 14734 synchronized(this) { 14735 return mServices.peekServiceLocked(service, resolvedType); 14736 } 14737 } 14738 14739 @Override 14740 public boolean stopServiceToken(ComponentName className, IBinder token, 14741 int startId) { 14742 synchronized(this) { 14743 return mServices.stopServiceTokenLocked(className, token, startId); 14744 } 14745 } 14746 14747 @Override 14748 public void setServiceForeground(ComponentName className, IBinder token, 14749 int id, Notification notification, boolean removeNotification) { 14750 synchronized(this) { 14751 mServices.setServiceForegroundLocked(className, token, id, notification, 14752 removeNotification); 14753 } 14754 } 14755 14756 @Override 14757 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14758 boolean requireFull, String name, String callerPackage) { 14759 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14760 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14761 } 14762 14763 int unsafeConvertIncomingUser(int userId) { 14764 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14765 ? mCurrentUserId : userId; 14766 } 14767 14768 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14769 int allowMode, String name, String callerPackage) { 14770 final int callingUserId = UserHandle.getUserId(callingUid); 14771 if (callingUserId == userId) { 14772 return userId; 14773 } 14774 14775 // Note that we may be accessing mCurrentUserId outside of a lock... 14776 // shouldn't be a big deal, if this is being called outside 14777 // of a locked context there is intrinsically a race with 14778 // the value the caller will receive and someone else changing it. 14779 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14780 // we will switch to the calling user if access to the current user fails. 14781 int targetUserId = unsafeConvertIncomingUser(userId); 14782 14783 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14784 final boolean allow; 14785 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14786 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14787 // If the caller has this permission, they always pass go. And collect $200. 14788 allow = true; 14789 } else if (allowMode == ALLOW_FULL_ONLY) { 14790 // We require full access, sucks to be you. 14791 allow = false; 14792 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14793 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14794 // If the caller does not have either permission, they are always doomed. 14795 allow = false; 14796 } else if (allowMode == ALLOW_NON_FULL) { 14797 // We are blanket allowing non-full access, you lucky caller! 14798 allow = true; 14799 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14800 // We may or may not allow this depending on whether the two users are 14801 // in the same profile. 14802 synchronized (mUserProfileGroupIdsSelfLocked) { 14803 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14804 UserInfo.NO_PROFILE_GROUP_ID); 14805 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14806 UserInfo.NO_PROFILE_GROUP_ID); 14807 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14808 && callingProfile == targetProfile; 14809 } 14810 } else { 14811 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14812 } 14813 if (!allow) { 14814 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14815 // In this case, they would like to just execute as their 14816 // owner user instead of failing. 14817 targetUserId = callingUserId; 14818 } else { 14819 StringBuilder builder = new StringBuilder(128); 14820 builder.append("Permission Denial: "); 14821 builder.append(name); 14822 if (callerPackage != null) { 14823 builder.append(" from "); 14824 builder.append(callerPackage); 14825 } 14826 builder.append(" asks to run as user "); 14827 builder.append(userId); 14828 builder.append(" but is calling from user "); 14829 builder.append(UserHandle.getUserId(callingUid)); 14830 builder.append("; this requires "); 14831 builder.append(INTERACT_ACROSS_USERS_FULL); 14832 if (allowMode != ALLOW_FULL_ONLY) { 14833 builder.append(" or "); 14834 builder.append(INTERACT_ACROSS_USERS); 14835 } 14836 String msg = builder.toString(); 14837 Slog.w(TAG, msg); 14838 throw new SecurityException(msg); 14839 } 14840 } 14841 } 14842 if (!allowAll && targetUserId < 0) { 14843 throw new IllegalArgumentException( 14844 "Call does not support special user #" + targetUserId); 14845 } 14846 // Check shell permission 14847 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14848 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14849 targetUserId)) { 14850 throw new SecurityException("Shell does not have permission to access user " 14851 + targetUserId + "\n " + Debug.getCallers(3)); 14852 } 14853 } 14854 return targetUserId; 14855 } 14856 14857 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14858 String className, int flags) { 14859 boolean result = false; 14860 // For apps that don't have pre-defined UIDs, check for permission 14861 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14862 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14863 if (ActivityManager.checkUidPermission( 14864 INTERACT_ACROSS_USERS, 14865 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14866 ComponentName comp = new ComponentName(aInfo.packageName, className); 14867 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14868 + " requests FLAG_SINGLE_USER, but app does not hold " 14869 + INTERACT_ACROSS_USERS; 14870 Slog.w(TAG, msg); 14871 throw new SecurityException(msg); 14872 } 14873 // Permission passed 14874 result = true; 14875 } 14876 } else if ("system".equals(componentProcessName)) { 14877 result = true; 14878 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14879 // Phone app and persistent apps are allowed to export singleuser providers. 14880 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14881 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14882 } 14883 if (DEBUG_MU) { 14884 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14885 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14886 } 14887 return result; 14888 } 14889 14890 /** 14891 * Checks to see if the caller is in the same app as the singleton 14892 * component, or the component is in a special app. It allows special apps 14893 * to export singleton components but prevents exporting singleton 14894 * components for regular apps. 14895 */ 14896 boolean isValidSingletonCall(int callingUid, int componentUid) { 14897 int componentAppId = UserHandle.getAppId(componentUid); 14898 return UserHandle.isSameApp(callingUid, componentUid) 14899 || componentAppId == Process.SYSTEM_UID 14900 || componentAppId == Process.PHONE_UID 14901 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14902 == PackageManager.PERMISSION_GRANTED; 14903 } 14904 14905 public int bindService(IApplicationThread caller, IBinder token, 14906 Intent service, String resolvedType, 14907 IServiceConnection connection, int flags, int userId) { 14908 enforceNotIsolatedCaller("bindService"); 14909 14910 // Refuse possible leaked file descriptors 14911 if (service != null && service.hasFileDescriptors() == true) { 14912 throw new IllegalArgumentException("File descriptors passed in Intent"); 14913 } 14914 14915 synchronized(this) { 14916 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14917 connection, flags, userId); 14918 } 14919 } 14920 14921 public boolean unbindService(IServiceConnection connection) { 14922 synchronized (this) { 14923 return mServices.unbindServiceLocked(connection); 14924 } 14925 } 14926 14927 public void publishService(IBinder token, Intent intent, IBinder service) { 14928 // Refuse possible leaked file descriptors 14929 if (intent != null && intent.hasFileDescriptors() == true) { 14930 throw new IllegalArgumentException("File descriptors passed in Intent"); 14931 } 14932 14933 synchronized(this) { 14934 if (!(token instanceof ServiceRecord)) { 14935 throw new IllegalArgumentException("Invalid service token"); 14936 } 14937 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14938 } 14939 } 14940 14941 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14942 // Refuse possible leaked file descriptors 14943 if (intent != null && intent.hasFileDescriptors() == true) { 14944 throw new IllegalArgumentException("File descriptors passed in Intent"); 14945 } 14946 14947 synchronized(this) { 14948 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14949 } 14950 } 14951 14952 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14953 synchronized(this) { 14954 if (!(token instanceof ServiceRecord)) { 14955 throw new IllegalArgumentException("Invalid service token"); 14956 } 14957 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14958 } 14959 } 14960 14961 // ========================================================= 14962 // BACKUP AND RESTORE 14963 // ========================================================= 14964 14965 // Cause the target app to be launched if necessary and its backup agent 14966 // instantiated. The backup agent will invoke backupAgentCreated() on the 14967 // activity manager to announce its creation. 14968 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14969 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14970 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14971 14972 synchronized(this) { 14973 // !!! TODO: currently no check here that we're already bound 14974 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14975 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14976 synchronized (stats) { 14977 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14978 } 14979 14980 // Backup agent is now in use, its package can't be stopped. 14981 try { 14982 AppGlobals.getPackageManager().setPackageStoppedState( 14983 app.packageName, false, UserHandle.getUserId(app.uid)); 14984 } catch (RemoteException e) { 14985 } catch (IllegalArgumentException e) { 14986 Slog.w(TAG, "Failed trying to unstop package " 14987 + app.packageName + ": " + e); 14988 } 14989 14990 BackupRecord r = new BackupRecord(ss, app, backupMode); 14991 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14992 ? new ComponentName(app.packageName, app.backupAgentName) 14993 : new ComponentName("android", "FullBackupAgent"); 14994 // startProcessLocked() returns existing proc's record if it's already running 14995 ProcessRecord proc = startProcessLocked(app.processName, app, 14996 false, 0, "backup", hostingName, false, false, false); 14997 if (proc == null) { 14998 Slog.e(TAG, "Unable to start backup agent process " + r); 14999 return false; 15000 } 15001 15002 r.app = proc; 15003 mBackupTarget = r; 15004 mBackupAppName = app.packageName; 15005 15006 // Try not to kill the process during backup 15007 updateOomAdjLocked(proc); 15008 15009 // If the process is already attached, schedule the creation of the backup agent now. 15010 // If it is not yet live, this will be done when it attaches to the framework. 15011 if (proc.thread != null) { 15012 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15013 try { 15014 proc.thread.scheduleCreateBackupAgent(app, 15015 compatibilityInfoForPackageLocked(app), backupMode); 15016 } catch (RemoteException e) { 15017 // Will time out on the backup manager side 15018 } 15019 } else { 15020 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15021 } 15022 // Invariants: at this point, the target app process exists and the application 15023 // is either already running or in the process of coming up. mBackupTarget and 15024 // mBackupAppName describe the app, so that when it binds back to the AM we 15025 // know that it's scheduled for a backup-agent operation. 15026 } 15027 15028 return true; 15029 } 15030 15031 @Override 15032 public void clearPendingBackup() { 15033 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15034 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15035 15036 synchronized (this) { 15037 mBackupTarget = null; 15038 mBackupAppName = null; 15039 } 15040 } 15041 15042 // A backup agent has just come up 15043 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15044 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15045 + " = " + agent); 15046 15047 synchronized(this) { 15048 if (!agentPackageName.equals(mBackupAppName)) { 15049 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15050 return; 15051 } 15052 } 15053 15054 long oldIdent = Binder.clearCallingIdentity(); 15055 try { 15056 IBackupManager bm = IBackupManager.Stub.asInterface( 15057 ServiceManager.getService(Context.BACKUP_SERVICE)); 15058 bm.agentConnected(agentPackageName, agent); 15059 } catch (RemoteException e) { 15060 // can't happen; the backup manager service is local 15061 } catch (Exception e) { 15062 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15063 e.printStackTrace(); 15064 } finally { 15065 Binder.restoreCallingIdentity(oldIdent); 15066 } 15067 } 15068 15069 // done with this agent 15070 public void unbindBackupAgent(ApplicationInfo appInfo) { 15071 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15072 if (appInfo == null) { 15073 Slog.w(TAG, "unbind backup agent for null app"); 15074 return; 15075 } 15076 15077 synchronized(this) { 15078 try { 15079 if (mBackupAppName == null) { 15080 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15081 return; 15082 } 15083 15084 if (!mBackupAppName.equals(appInfo.packageName)) { 15085 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15086 return; 15087 } 15088 15089 // Not backing this app up any more; reset its OOM adjustment 15090 final ProcessRecord proc = mBackupTarget.app; 15091 updateOomAdjLocked(proc); 15092 15093 // If the app crashed during backup, 'thread' will be null here 15094 if (proc.thread != null) { 15095 try { 15096 proc.thread.scheduleDestroyBackupAgent(appInfo, 15097 compatibilityInfoForPackageLocked(appInfo)); 15098 } catch (Exception e) { 15099 Slog.e(TAG, "Exception when unbinding backup agent:"); 15100 e.printStackTrace(); 15101 } 15102 } 15103 } finally { 15104 mBackupTarget = null; 15105 mBackupAppName = null; 15106 } 15107 } 15108 } 15109 // ========================================================= 15110 // BROADCASTS 15111 // ========================================================= 15112 15113 private final List getStickiesLocked(String action, IntentFilter filter, 15114 List cur, int userId) { 15115 final ContentResolver resolver = mContext.getContentResolver(); 15116 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15117 if (stickies == null) { 15118 return cur; 15119 } 15120 final ArrayList<Intent> list = stickies.get(action); 15121 if (list == null) { 15122 return cur; 15123 } 15124 int N = list.size(); 15125 for (int i=0; i<N; i++) { 15126 Intent intent = list.get(i); 15127 if (filter.match(resolver, intent, true, TAG) >= 0) { 15128 if (cur == null) { 15129 cur = new ArrayList<Intent>(); 15130 } 15131 cur.add(intent); 15132 } 15133 } 15134 return cur; 15135 } 15136 15137 boolean isPendingBroadcastProcessLocked(int pid) { 15138 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15139 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15140 } 15141 15142 void skipPendingBroadcastLocked(int pid) { 15143 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15144 for (BroadcastQueue queue : mBroadcastQueues) { 15145 queue.skipPendingBroadcastLocked(pid); 15146 } 15147 } 15148 15149 // The app just attached; send any pending broadcasts that it should receive 15150 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15151 boolean didSomething = false; 15152 for (BroadcastQueue queue : mBroadcastQueues) { 15153 didSomething |= queue.sendPendingBroadcastsLocked(app); 15154 } 15155 return didSomething; 15156 } 15157 15158 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15159 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15160 enforceNotIsolatedCaller("registerReceiver"); 15161 int callingUid; 15162 int callingPid; 15163 synchronized(this) { 15164 ProcessRecord callerApp = null; 15165 if (caller != null) { 15166 callerApp = getRecordForAppLocked(caller); 15167 if (callerApp == null) { 15168 throw new SecurityException( 15169 "Unable to find app for caller " + caller 15170 + " (pid=" + Binder.getCallingPid() 15171 + ") when registering receiver " + receiver); 15172 } 15173 if (callerApp.info.uid != Process.SYSTEM_UID && 15174 !callerApp.pkgList.containsKey(callerPackage) && 15175 !"android".equals(callerPackage)) { 15176 throw new SecurityException("Given caller package " + callerPackage 15177 + " is not running in process " + callerApp); 15178 } 15179 callingUid = callerApp.info.uid; 15180 callingPid = callerApp.pid; 15181 } else { 15182 callerPackage = null; 15183 callingUid = Binder.getCallingUid(); 15184 callingPid = Binder.getCallingPid(); 15185 } 15186 15187 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15188 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15189 15190 List allSticky = null; 15191 15192 // Look for any matching sticky broadcasts... 15193 Iterator actions = filter.actionsIterator(); 15194 if (actions != null) { 15195 while (actions.hasNext()) { 15196 String action = (String)actions.next(); 15197 allSticky = getStickiesLocked(action, filter, allSticky, 15198 UserHandle.USER_ALL); 15199 allSticky = getStickiesLocked(action, filter, allSticky, 15200 UserHandle.getUserId(callingUid)); 15201 } 15202 } else { 15203 allSticky = getStickiesLocked(null, filter, allSticky, 15204 UserHandle.USER_ALL); 15205 allSticky = getStickiesLocked(null, filter, allSticky, 15206 UserHandle.getUserId(callingUid)); 15207 } 15208 15209 // The first sticky in the list is returned directly back to 15210 // the client. 15211 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15212 15213 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15214 + ": " + sticky); 15215 15216 if (receiver == null) { 15217 return sticky; 15218 } 15219 15220 ReceiverList rl 15221 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15222 if (rl == null) { 15223 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15224 userId, receiver); 15225 if (rl.app != null) { 15226 rl.app.receivers.add(rl); 15227 } else { 15228 try { 15229 receiver.asBinder().linkToDeath(rl, 0); 15230 } catch (RemoteException e) { 15231 return sticky; 15232 } 15233 rl.linkedToDeath = true; 15234 } 15235 mRegisteredReceivers.put(receiver.asBinder(), rl); 15236 } else if (rl.uid != callingUid) { 15237 throw new IllegalArgumentException( 15238 "Receiver requested to register for uid " + callingUid 15239 + " was previously registered for uid " + rl.uid); 15240 } else if (rl.pid != callingPid) { 15241 throw new IllegalArgumentException( 15242 "Receiver requested to register for pid " + callingPid 15243 + " was previously registered for pid " + rl.pid); 15244 } else if (rl.userId != userId) { 15245 throw new IllegalArgumentException( 15246 "Receiver requested to register for user " + userId 15247 + " was previously registered for user " + rl.userId); 15248 } 15249 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15250 permission, callingUid, userId); 15251 rl.add(bf); 15252 if (!bf.debugCheck()) { 15253 Slog.w(TAG, "==> For Dynamic broadast"); 15254 } 15255 mReceiverResolver.addFilter(bf); 15256 15257 // Enqueue broadcasts for all existing stickies that match 15258 // this filter. 15259 if (allSticky != null) { 15260 ArrayList receivers = new ArrayList(); 15261 receivers.add(bf); 15262 15263 int N = allSticky.size(); 15264 for (int i=0; i<N; i++) { 15265 Intent intent = (Intent)allSticky.get(i); 15266 BroadcastQueue queue = broadcastQueueForIntent(intent); 15267 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15268 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15269 null, null, false, true, true, -1); 15270 queue.enqueueParallelBroadcastLocked(r); 15271 queue.scheduleBroadcastsLocked(); 15272 } 15273 } 15274 15275 return sticky; 15276 } 15277 } 15278 15279 public void unregisterReceiver(IIntentReceiver receiver) { 15280 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15281 15282 final long origId = Binder.clearCallingIdentity(); 15283 try { 15284 boolean doTrim = false; 15285 15286 synchronized(this) { 15287 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15288 if (rl != null) { 15289 if (rl.curBroadcast != null) { 15290 BroadcastRecord r = rl.curBroadcast; 15291 final boolean doNext = finishReceiverLocked( 15292 receiver.asBinder(), r.resultCode, r.resultData, 15293 r.resultExtras, r.resultAbort); 15294 if (doNext) { 15295 doTrim = true; 15296 r.queue.processNextBroadcast(false); 15297 } 15298 } 15299 15300 if (rl.app != null) { 15301 rl.app.receivers.remove(rl); 15302 } 15303 removeReceiverLocked(rl); 15304 if (rl.linkedToDeath) { 15305 rl.linkedToDeath = false; 15306 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15307 } 15308 } 15309 } 15310 15311 // If we actually concluded any broadcasts, we might now be able 15312 // to trim the recipients' apps from our working set 15313 if (doTrim) { 15314 trimApplications(); 15315 return; 15316 } 15317 15318 } finally { 15319 Binder.restoreCallingIdentity(origId); 15320 } 15321 } 15322 15323 void removeReceiverLocked(ReceiverList rl) { 15324 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15325 int N = rl.size(); 15326 for (int i=0; i<N; i++) { 15327 mReceiverResolver.removeFilter(rl.get(i)); 15328 } 15329 } 15330 15331 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15332 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15333 ProcessRecord r = mLruProcesses.get(i); 15334 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15335 try { 15336 r.thread.dispatchPackageBroadcast(cmd, packages); 15337 } catch (RemoteException ex) { 15338 } 15339 } 15340 } 15341 } 15342 15343 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15344 int callingUid, int[] users) { 15345 List<ResolveInfo> receivers = null; 15346 try { 15347 HashSet<ComponentName> singleUserReceivers = null; 15348 boolean scannedFirstReceivers = false; 15349 for (int user : users) { 15350 // Skip users that have Shell restrictions 15351 if (callingUid == Process.SHELL_UID 15352 && getUserManagerLocked().hasUserRestriction( 15353 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15354 continue; 15355 } 15356 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15357 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15358 if (user != 0 && newReceivers != null) { 15359 // If this is not the primary user, we need to check for 15360 // any receivers that should be filtered out. 15361 for (int i=0; i<newReceivers.size(); i++) { 15362 ResolveInfo ri = newReceivers.get(i); 15363 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15364 newReceivers.remove(i); 15365 i--; 15366 } 15367 } 15368 } 15369 if (newReceivers != null && newReceivers.size() == 0) { 15370 newReceivers = null; 15371 } 15372 if (receivers == null) { 15373 receivers = newReceivers; 15374 } else if (newReceivers != null) { 15375 // We need to concatenate the additional receivers 15376 // found with what we have do far. This would be easy, 15377 // but we also need to de-dup any receivers that are 15378 // singleUser. 15379 if (!scannedFirstReceivers) { 15380 // Collect any single user receivers we had already retrieved. 15381 scannedFirstReceivers = true; 15382 for (int i=0; i<receivers.size(); i++) { 15383 ResolveInfo ri = receivers.get(i); 15384 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15385 ComponentName cn = new ComponentName( 15386 ri.activityInfo.packageName, ri.activityInfo.name); 15387 if (singleUserReceivers == null) { 15388 singleUserReceivers = new HashSet<ComponentName>(); 15389 } 15390 singleUserReceivers.add(cn); 15391 } 15392 } 15393 } 15394 // Add the new results to the existing results, tracking 15395 // and de-dupping single user receivers. 15396 for (int i=0; i<newReceivers.size(); i++) { 15397 ResolveInfo ri = newReceivers.get(i); 15398 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15399 ComponentName cn = new ComponentName( 15400 ri.activityInfo.packageName, ri.activityInfo.name); 15401 if (singleUserReceivers == null) { 15402 singleUserReceivers = new HashSet<ComponentName>(); 15403 } 15404 if (!singleUserReceivers.contains(cn)) { 15405 singleUserReceivers.add(cn); 15406 receivers.add(ri); 15407 } 15408 } else { 15409 receivers.add(ri); 15410 } 15411 } 15412 } 15413 } 15414 } catch (RemoteException ex) { 15415 // pm is in same process, this will never happen. 15416 } 15417 return receivers; 15418 } 15419 15420 private final int broadcastIntentLocked(ProcessRecord callerApp, 15421 String callerPackage, Intent intent, String resolvedType, 15422 IIntentReceiver resultTo, int resultCode, String resultData, 15423 Bundle map, String requiredPermission, int appOp, 15424 boolean ordered, boolean sticky, int callingPid, int callingUid, 15425 int userId) { 15426 intent = new Intent(intent); 15427 15428 // By default broadcasts do not go to stopped apps. 15429 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15430 15431 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15432 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15433 + " ordered=" + ordered + " userid=" + userId); 15434 if ((resultTo != null) && !ordered) { 15435 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15436 } 15437 15438 userId = handleIncomingUser(callingPid, callingUid, userId, 15439 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15440 15441 // Make sure that the user who is receiving this broadcast is started. 15442 // If not, we will just skip it. 15443 15444 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15445 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15446 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15447 Slog.w(TAG, "Skipping broadcast of " + intent 15448 + ": user " + userId + " is stopped"); 15449 return ActivityManager.BROADCAST_SUCCESS; 15450 } 15451 } 15452 15453 /* 15454 * Prevent non-system code (defined here to be non-persistent 15455 * processes) from sending protected broadcasts. 15456 */ 15457 int callingAppId = UserHandle.getAppId(callingUid); 15458 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15459 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15460 || callingAppId == Process.NFC_UID || callingUid == 0) { 15461 // Always okay. 15462 } else if (callerApp == null || !callerApp.persistent) { 15463 try { 15464 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15465 intent.getAction())) { 15466 String msg = "Permission Denial: not allowed to send broadcast " 15467 + intent.getAction() + " from pid=" 15468 + callingPid + ", uid=" + callingUid; 15469 Slog.w(TAG, msg); 15470 throw new SecurityException(msg); 15471 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15472 // Special case for compatibility: we don't want apps to send this, 15473 // but historically it has not been protected and apps may be using it 15474 // to poke their own app widget. So, instead of making it protected, 15475 // just limit it to the caller. 15476 if (callerApp == null) { 15477 String msg = "Permission Denial: not allowed to send broadcast " 15478 + intent.getAction() + " from unknown caller."; 15479 Slog.w(TAG, msg); 15480 throw new SecurityException(msg); 15481 } else if (intent.getComponent() != null) { 15482 // They are good enough to send to an explicit component... verify 15483 // it is being sent to the calling app. 15484 if (!intent.getComponent().getPackageName().equals( 15485 callerApp.info.packageName)) { 15486 String msg = "Permission Denial: not allowed to send broadcast " 15487 + intent.getAction() + " to " 15488 + intent.getComponent().getPackageName() + " from " 15489 + callerApp.info.packageName; 15490 Slog.w(TAG, msg); 15491 throw new SecurityException(msg); 15492 } 15493 } else { 15494 // Limit broadcast to their own package. 15495 intent.setPackage(callerApp.info.packageName); 15496 } 15497 } 15498 } catch (RemoteException e) { 15499 Slog.w(TAG, "Remote exception", e); 15500 return ActivityManager.BROADCAST_SUCCESS; 15501 } 15502 } 15503 15504 // Handle special intents: if this broadcast is from the package 15505 // manager about a package being removed, we need to remove all of 15506 // its activities from the history stack. 15507 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15508 intent.getAction()); 15509 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15510 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15511 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15512 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15513 || uidRemoved) { 15514 if (checkComponentPermission( 15515 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15516 callingPid, callingUid, -1, true) 15517 == PackageManager.PERMISSION_GRANTED) { 15518 if (uidRemoved) { 15519 final Bundle intentExtras = intent.getExtras(); 15520 final int uid = intentExtras != null 15521 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15522 if (uid >= 0) { 15523 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15524 synchronized (bs) { 15525 bs.removeUidStatsLocked(uid); 15526 } 15527 mAppOpsService.uidRemoved(uid); 15528 } 15529 } else { 15530 // If resources are unavailable just force stop all 15531 // those packages and flush the attribute cache as well. 15532 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15533 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15534 if (list != null && (list.length > 0)) { 15535 for (String pkg : list) { 15536 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15537 "storage unmount"); 15538 } 15539 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15540 sendPackageBroadcastLocked( 15541 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15542 } 15543 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15544 intent.getAction())) { 15545 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15546 } else { 15547 Uri data = intent.getData(); 15548 String ssp; 15549 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15550 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15551 intent.getAction()); 15552 boolean fullUninstall = removed && 15553 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15554 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15555 forceStopPackageLocked(ssp, UserHandle.getAppId( 15556 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15557 false, fullUninstall, userId, 15558 removed ? "pkg removed" : "pkg changed"); 15559 } 15560 if (removed) { 15561 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15562 new String[] {ssp}, userId); 15563 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15564 mAppOpsService.packageRemoved( 15565 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15566 15567 // Remove all permissions granted from/to this package 15568 removeUriPermissionsForPackageLocked(ssp, userId, true); 15569 } 15570 } 15571 } 15572 } 15573 } 15574 } else { 15575 String msg = "Permission Denial: " + intent.getAction() 15576 + " broadcast from " + callerPackage + " (pid=" + callingPid 15577 + ", uid=" + callingUid + ")" 15578 + " requires " 15579 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15580 Slog.w(TAG, msg); 15581 throw new SecurityException(msg); 15582 } 15583 15584 // Special case for adding a package: by default turn on compatibility 15585 // mode. 15586 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15587 Uri data = intent.getData(); 15588 String ssp; 15589 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15590 mCompatModePackages.handlePackageAddedLocked(ssp, 15591 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15592 } 15593 } 15594 15595 /* 15596 * If this is the time zone changed action, queue up a message that will reset the timezone 15597 * of all currently running processes. This message will get queued up before the broadcast 15598 * happens. 15599 */ 15600 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15601 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15602 } 15603 15604 /* 15605 * If the user set the time, let all running processes know. 15606 */ 15607 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15608 final int is24Hour = intent.getBooleanExtra( 15609 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15610 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15611 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15612 synchronized (stats) { 15613 stats.noteCurrentTimeChangedLocked(); 15614 } 15615 } 15616 15617 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15618 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15619 } 15620 15621 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15622 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15623 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15624 } 15625 15626 // Add to the sticky list if requested. 15627 if (sticky) { 15628 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15629 callingPid, callingUid) 15630 != PackageManager.PERMISSION_GRANTED) { 15631 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15632 + callingPid + ", uid=" + callingUid 15633 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15634 Slog.w(TAG, msg); 15635 throw new SecurityException(msg); 15636 } 15637 if (requiredPermission != null) { 15638 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15639 + " and enforce permission " + requiredPermission); 15640 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15641 } 15642 if (intent.getComponent() != null) { 15643 throw new SecurityException( 15644 "Sticky broadcasts can't target a specific component"); 15645 } 15646 // We use userId directly here, since the "all" target is maintained 15647 // as a separate set of sticky broadcasts. 15648 if (userId != UserHandle.USER_ALL) { 15649 // But first, if this is not a broadcast to all users, then 15650 // make sure it doesn't conflict with an existing broadcast to 15651 // all users. 15652 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15653 UserHandle.USER_ALL); 15654 if (stickies != null) { 15655 ArrayList<Intent> list = stickies.get(intent.getAction()); 15656 if (list != null) { 15657 int N = list.size(); 15658 int i; 15659 for (i=0; i<N; i++) { 15660 if (intent.filterEquals(list.get(i))) { 15661 throw new IllegalArgumentException( 15662 "Sticky broadcast " + intent + " for user " 15663 + userId + " conflicts with existing global broadcast"); 15664 } 15665 } 15666 } 15667 } 15668 } 15669 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15670 if (stickies == null) { 15671 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15672 mStickyBroadcasts.put(userId, stickies); 15673 } 15674 ArrayList<Intent> list = stickies.get(intent.getAction()); 15675 if (list == null) { 15676 list = new ArrayList<Intent>(); 15677 stickies.put(intent.getAction(), list); 15678 } 15679 int N = list.size(); 15680 int i; 15681 for (i=0; i<N; i++) { 15682 if (intent.filterEquals(list.get(i))) { 15683 // This sticky already exists, replace it. 15684 list.set(i, new Intent(intent)); 15685 break; 15686 } 15687 } 15688 if (i >= N) { 15689 list.add(new Intent(intent)); 15690 } 15691 } 15692 15693 int[] users; 15694 if (userId == UserHandle.USER_ALL) { 15695 // Caller wants broadcast to go to all started users. 15696 users = mStartedUserArray; 15697 } else { 15698 // Caller wants broadcast to go to one specific user. 15699 users = new int[] {userId}; 15700 } 15701 15702 // Figure out who all will receive this broadcast. 15703 List receivers = null; 15704 List<BroadcastFilter> registeredReceivers = null; 15705 // Need to resolve the intent to interested receivers... 15706 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15707 == 0) { 15708 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15709 } 15710 if (intent.getComponent() == null) { 15711 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15712 // Query one target user at a time, excluding shell-restricted users 15713 UserManagerService ums = getUserManagerLocked(); 15714 for (int i = 0; i < users.length; i++) { 15715 if (ums.hasUserRestriction( 15716 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15717 continue; 15718 } 15719 List<BroadcastFilter> registeredReceiversForUser = 15720 mReceiverResolver.queryIntent(intent, 15721 resolvedType, false, users[i]); 15722 if (registeredReceivers == null) { 15723 registeredReceivers = registeredReceiversForUser; 15724 } else if (registeredReceiversForUser != null) { 15725 registeredReceivers.addAll(registeredReceiversForUser); 15726 } 15727 } 15728 } else { 15729 registeredReceivers = mReceiverResolver.queryIntent(intent, 15730 resolvedType, false, userId); 15731 } 15732 } 15733 15734 final boolean replacePending = 15735 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15736 15737 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15738 + " replacePending=" + replacePending); 15739 15740 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15741 if (!ordered && NR > 0) { 15742 // If we are not serializing this broadcast, then send the 15743 // registered receivers separately so they don't wait for the 15744 // components to be launched. 15745 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15746 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15747 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15748 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15749 ordered, sticky, false, userId); 15750 if (DEBUG_BROADCAST) Slog.v( 15751 TAG, "Enqueueing parallel broadcast " + r); 15752 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15753 if (!replaced) { 15754 queue.enqueueParallelBroadcastLocked(r); 15755 queue.scheduleBroadcastsLocked(); 15756 } 15757 registeredReceivers = null; 15758 NR = 0; 15759 } 15760 15761 // Merge into one list. 15762 int ir = 0; 15763 if (receivers != null) { 15764 // A special case for PACKAGE_ADDED: do not allow the package 15765 // being added to see this broadcast. This prevents them from 15766 // using this as a back door to get run as soon as they are 15767 // installed. Maybe in the future we want to have a special install 15768 // broadcast or such for apps, but we'd like to deliberately make 15769 // this decision. 15770 String skipPackages[] = null; 15771 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15772 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15773 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15774 Uri data = intent.getData(); 15775 if (data != null) { 15776 String pkgName = data.getSchemeSpecificPart(); 15777 if (pkgName != null) { 15778 skipPackages = new String[] { pkgName }; 15779 } 15780 } 15781 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15782 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15783 } 15784 if (skipPackages != null && (skipPackages.length > 0)) { 15785 for (String skipPackage : skipPackages) { 15786 if (skipPackage != null) { 15787 int NT = receivers.size(); 15788 for (int it=0; it<NT; it++) { 15789 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15790 if (curt.activityInfo.packageName.equals(skipPackage)) { 15791 receivers.remove(it); 15792 it--; 15793 NT--; 15794 } 15795 } 15796 } 15797 } 15798 } 15799 15800 int NT = receivers != null ? receivers.size() : 0; 15801 int it = 0; 15802 ResolveInfo curt = null; 15803 BroadcastFilter curr = null; 15804 while (it < NT && ir < NR) { 15805 if (curt == null) { 15806 curt = (ResolveInfo)receivers.get(it); 15807 } 15808 if (curr == null) { 15809 curr = registeredReceivers.get(ir); 15810 } 15811 if (curr.getPriority() >= curt.priority) { 15812 // Insert this broadcast record into the final list. 15813 receivers.add(it, curr); 15814 ir++; 15815 curr = null; 15816 it++; 15817 NT++; 15818 } else { 15819 // Skip to the next ResolveInfo in the final list. 15820 it++; 15821 curt = null; 15822 } 15823 } 15824 } 15825 while (ir < NR) { 15826 if (receivers == null) { 15827 receivers = new ArrayList(); 15828 } 15829 receivers.add(registeredReceivers.get(ir)); 15830 ir++; 15831 } 15832 15833 if ((receivers != null && receivers.size() > 0) 15834 || resultTo != null) { 15835 BroadcastQueue queue = broadcastQueueForIntent(intent); 15836 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15837 callerPackage, callingPid, callingUid, resolvedType, 15838 requiredPermission, appOp, receivers, resultTo, resultCode, 15839 resultData, map, ordered, sticky, false, userId); 15840 if (DEBUG_BROADCAST) Slog.v( 15841 TAG, "Enqueueing ordered broadcast " + r 15842 + ": prev had " + queue.mOrderedBroadcasts.size()); 15843 if (DEBUG_BROADCAST) { 15844 int seq = r.intent.getIntExtra("seq", -1); 15845 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15846 } 15847 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15848 if (!replaced) { 15849 queue.enqueueOrderedBroadcastLocked(r); 15850 queue.scheduleBroadcastsLocked(); 15851 } 15852 } 15853 15854 return ActivityManager.BROADCAST_SUCCESS; 15855 } 15856 15857 final Intent verifyBroadcastLocked(Intent intent) { 15858 // Refuse possible leaked file descriptors 15859 if (intent != null && intent.hasFileDescriptors() == true) { 15860 throw new IllegalArgumentException("File descriptors passed in Intent"); 15861 } 15862 15863 int flags = intent.getFlags(); 15864 15865 if (!mProcessesReady) { 15866 // if the caller really truly claims to know what they're doing, go 15867 // ahead and allow the broadcast without launching any receivers 15868 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15869 intent = new Intent(intent); 15870 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15871 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15872 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15873 + " before boot completion"); 15874 throw new IllegalStateException("Cannot broadcast before boot completed"); 15875 } 15876 } 15877 15878 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15879 throw new IllegalArgumentException( 15880 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15881 } 15882 15883 return intent; 15884 } 15885 15886 public final int broadcastIntent(IApplicationThread caller, 15887 Intent intent, String resolvedType, IIntentReceiver resultTo, 15888 int resultCode, String resultData, Bundle map, 15889 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15890 enforceNotIsolatedCaller("broadcastIntent"); 15891 synchronized(this) { 15892 intent = verifyBroadcastLocked(intent); 15893 15894 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15895 final int callingPid = Binder.getCallingPid(); 15896 final int callingUid = Binder.getCallingUid(); 15897 final long origId = Binder.clearCallingIdentity(); 15898 int res = broadcastIntentLocked(callerApp, 15899 callerApp != null ? callerApp.info.packageName : null, 15900 intent, resolvedType, resultTo, 15901 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15902 callingPid, callingUid, userId); 15903 Binder.restoreCallingIdentity(origId); 15904 return res; 15905 } 15906 } 15907 15908 int broadcastIntentInPackage(String packageName, int uid, 15909 Intent intent, String resolvedType, IIntentReceiver resultTo, 15910 int resultCode, String resultData, Bundle map, 15911 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15912 synchronized(this) { 15913 intent = verifyBroadcastLocked(intent); 15914 15915 final long origId = Binder.clearCallingIdentity(); 15916 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15917 resultTo, resultCode, resultData, map, requiredPermission, 15918 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15919 Binder.restoreCallingIdentity(origId); 15920 return res; 15921 } 15922 } 15923 15924 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15925 // Refuse possible leaked file descriptors 15926 if (intent != null && intent.hasFileDescriptors() == true) { 15927 throw new IllegalArgumentException("File descriptors passed in Intent"); 15928 } 15929 15930 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15931 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15932 15933 synchronized(this) { 15934 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15935 != PackageManager.PERMISSION_GRANTED) { 15936 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15937 + Binder.getCallingPid() 15938 + ", uid=" + Binder.getCallingUid() 15939 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15940 Slog.w(TAG, msg); 15941 throw new SecurityException(msg); 15942 } 15943 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15944 if (stickies != null) { 15945 ArrayList<Intent> list = stickies.get(intent.getAction()); 15946 if (list != null) { 15947 int N = list.size(); 15948 int i; 15949 for (i=0; i<N; i++) { 15950 if (intent.filterEquals(list.get(i))) { 15951 list.remove(i); 15952 break; 15953 } 15954 } 15955 if (list.size() <= 0) { 15956 stickies.remove(intent.getAction()); 15957 } 15958 } 15959 if (stickies.size() <= 0) { 15960 mStickyBroadcasts.remove(userId); 15961 } 15962 } 15963 } 15964 } 15965 15966 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15967 String resultData, Bundle resultExtras, boolean resultAbort) { 15968 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15969 if (r == null) { 15970 Slog.w(TAG, "finishReceiver called but not found on queue"); 15971 return false; 15972 } 15973 15974 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15975 } 15976 15977 void backgroundServicesFinishedLocked(int userId) { 15978 for (BroadcastQueue queue : mBroadcastQueues) { 15979 queue.backgroundServicesFinishedLocked(userId); 15980 } 15981 } 15982 15983 public void finishReceiver(IBinder who, int resultCode, String resultData, 15984 Bundle resultExtras, boolean resultAbort) { 15985 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15986 15987 // Refuse possible leaked file descriptors 15988 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15989 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15990 } 15991 15992 final long origId = Binder.clearCallingIdentity(); 15993 try { 15994 boolean doNext = false; 15995 BroadcastRecord r; 15996 15997 synchronized(this) { 15998 r = broadcastRecordForReceiverLocked(who); 15999 if (r != null) { 16000 doNext = r.queue.finishReceiverLocked(r, resultCode, 16001 resultData, resultExtras, resultAbort, true); 16002 } 16003 } 16004 16005 if (doNext) { 16006 r.queue.processNextBroadcast(false); 16007 } 16008 trimApplications(); 16009 } finally { 16010 Binder.restoreCallingIdentity(origId); 16011 } 16012 } 16013 16014 // ========================================================= 16015 // INSTRUMENTATION 16016 // ========================================================= 16017 16018 public boolean startInstrumentation(ComponentName className, 16019 String profileFile, int flags, Bundle arguments, 16020 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16021 int userId, String abiOverride) { 16022 enforceNotIsolatedCaller("startInstrumentation"); 16023 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16024 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16025 // Refuse possible leaked file descriptors 16026 if (arguments != null && arguments.hasFileDescriptors()) { 16027 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16028 } 16029 16030 synchronized(this) { 16031 InstrumentationInfo ii = null; 16032 ApplicationInfo ai = null; 16033 try { 16034 ii = mContext.getPackageManager().getInstrumentationInfo( 16035 className, STOCK_PM_FLAGS); 16036 ai = AppGlobals.getPackageManager().getApplicationInfo( 16037 ii.targetPackage, STOCK_PM_FLAGS, userId); 16038 } catch (PackageManager.NameNotFoundException e) { 16039 } catch (RemoteException e) { 16040 } 16041 if (ii == null) { 16042 reportStartInstrumentationFailure(watcher, className, 16043 "Unable to find instrumentation info for: " + className); 16044 return false; 16045 } 16046 if (ai == null) { 16047 reportStartInstrumentationFailure(watcher, className, 16048 "Unable to find instrumentation target package: " + ii.targetPackage); 16049 return false; 16050 } 16051 16052 int match = mContext.getPackageManager().checkSignatures( 16053 ii.targetPackage, ii.packageName); 16054 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16055 String msg = "Permission Denial: starting instrumentation " 16056 + className + " from pid=" 16057 + Binder.getCallingPid() 16058 + ", uid=" + Binder.getCallingPid() 16059 + " not allowed because package " + ii.packageName 16060 + " does not have a signature matching the target " 16061 + ii.targetPackage; 16062 reportStartInstrumentationFailure(watcher, className, msg); 16063 throw new SecurityException(msg); 16064 } 16065 16066 final long origId = Binder.clearCallingIdentity(); 16067 // Instrumentation can kill and relaunch even persistent processes 16068 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16069 "start instr"); 16070 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16071 app.instrumentationClass = className; 16072 app.instrumentationInfo = ai; 16073 app.instrumentationProfileFile = profileFile; 16074 app.instrumentationArguments = arguments; 16075 app.instrumentationWatcher = watcher; 16076 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16077 app.instrumentationResultClass = className; 16078 Binder.restoreCallingIdentity(origId); 16079 } 16080 16081 return true; 16082 } 16083 16084 /** 16085 * Report errors that occur while attempting to start Instrumentation. Always writes the 16086 * error to the logs, but if somebody is watching, send the report there too. This enables 16087 * the "am" command to report errors with more information. 16088 * 16089 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16090 * @param cn The component name of the instrumentation. 16091 * @param report The error report. 16092 */ 16093 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16094 ComponentName cn, String report) { 16095 Slog.w(TAG, report); 16096 try { 16097 if (watcher != null) { 16098 Bundle results = new Bundle(); 16099 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16100 results.putString("Error", report); 16101 watcher.instrumentationStatus(cn, -1, results); 16102 } 16103 } catch (RemoteException e) { 16104 Slog.w(TAG, e); 16105 } 16106 } 16107 16108 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16109 if (app.instrumentationWatcher != null) { 16110 try { 16111 // NOTE: IInstrumentationWatcher *must* be oneway here 16112 app.instrumentationWatcher.instrumentationFinished( 16113 app.instrumentationClass, 16114 resultCode, 16115 results); 16116 } catch (RemoteException e) { 16117 } 16118 } 16119 if (app.instrumentationUiAutomationConnection != null) { 16120 try { 16121 app.instrumentationUiAutomationConnection.shutdown(); 16122 } catch (RemoteException re) { 16123 /* ignore */ 16124 } 16125 // Only a UiAutomation can set this flag and now that 16126 // it is finished we make sure it is reset to its default. 16127 mUserIsMonkey = false; 16128 } 16129 app.instrumentationWatcher = null; 16130 app.instrumentationUiAutomationConnection = null; 16131 app.instrumentationClass = null; 16132 app.instrumentationInfo = null; 16133 app.instrumentationProfileFile = null; 16134 app.instrumentationArguments = null; 16135 16136 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16137 "finished inst"); 16138 } 16139 16140 public void finishInstrumentation(IApplicationThread target, 16141 int resultCode, Bundle results) { 16142 int userId = UserHandle.getCallingUserId(); 16143 // Refuse possible leaked file descriptors 16144 if (results != null && results.hasFileDescriptors()) { 16145 throw new IllegalArgumentException("File descriptors passed in Intent"); 16146 } 16147 16148 synchronized(this) { 16149 ProcessRecord app = getRecordForAppLocked(target); 16150 if (app == null) { 16151 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16152 return; 16153 } 16154 final long origId = Binder.clearCallingIdentity(); 16155 finishInstrumentationLocked(app, resultCode, results); 16156 Binder.restoreCallingIdentity(origId); 16157 } 16158 } 16159 16160 // ========================================================= 16161 // CONFIGURATION 16162 // ========================================================= 16163 16164 public ConfigurationInfo getDeviceConfigurationInfo() { 16165 ConfigurationInfo config = new ConfigurationInfo(); 16166 synchronized (this) { 16167 config.reqTouchScreen = mConfiguration.touchscreen; 16168 config.reqKeyboardType = mConfiguration.keyboard; 16169 config.reqNavigation = mConfiguration.navigation; 16170 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16171 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16172 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16173 } 16174 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16175 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16176 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16177 } 16178 config.reqGlEsVersion = GL_ES_VERSION; 16179 } 16180 return config; 16181 } 16182 16183 ActivityStack getFocusedStack() { 16184 return mStackSupervisor.getFocusedStack(); 16185 } 16186 16187 public Configuration getConfiguration() { 16188 Configuration ci; 16189 synchronized(this) { 16190 ci = new Configuration(mConfiguration); 16191 } 16192 return ci; 16193 } 16194 16195 public void updatePersistentConfiguration(Configuration values) { 16196 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16197 "updateConfiguration()"); 16198 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16199 "updateConfiguration()"); 16200 if (values == null) { 16201 throw new NullPointerException("Configuration must not be null"); 16202 } 16203 16204 synchronized(this) { 16205 final long origId = Binder.clearCallingIdentity(); 16206 updateConfigurationLocked(values, null, true, false); 16207 Binder.restoreCallingIdentity(origId); 16208 } 16209 } 16210 16211 public void updateConfiguration(Configuration values) { 16212 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16213 "updateConfiguration()"); 16214 16215 synchronized(this) { 16216 if (values == null && mWindowManager != null) { 16217 // sentinel: fetch the current configuration from the window manager 16218 values = mWindowManager.computeNewConfiguration(); 16219 } 16220 16221 if (mWindowManager != null) { 16222 mProcessList.applyDisplaySize(mWindowManager); 16223 } 16224 16225 final long origId = Binder.clearCallingIdentity(); 16226 if (values != null) { 16227 Settings.System.clearConfiguration(values); 16228 } 16229 updateConfigurationLocked(values, null, false, false); 16230 Binder.restoreCallingIdentity(origId); 16231 } 16232 } 16233 16234 /** 16235 * Do either or both things: (1) change the current configuration, and (2) 16236 * make sure the given activity is running with the (now) current 16237 * configuration. Returns true if the activity has been left running, or 16238 * false if <var>starting</var> is being destroyed to match the new 16239 * configuration. 16240 * @param persistent TODO 16241 */ 16242 boolean updateConfigurationLocked(Configuration values, 16243 ActivityRecord starting, boolean persistent, boolean initLocale) { 16244 int changes = 0; 16245 16246 if (values != null) { 16247 Configuration newConfig = new Configuration(mConfiguration); 16248 changes = newConfig.updateFrom(values); 16249 if (changes != 0) { 16250 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16251 Slog.i(TAG, "Updating configuration to: " + values); 16252 } 16253 16254 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16255 16256 if (values.locale != null && !initLocale) { 16257 saveLocaleLocked(values.locale, 16258 !values.locale.equals(mConfiguration.locale), 16259 values.userSetLocale); 16260 } 16261 16262 mConfigurationSeq++; 16263 if (mConfigurationSeq <= 0) { 16264 mConfigurationSeq = 1; 16265 } 16266 newConfig.seq = mConfigurationSeq; 16267 mConfiguration = newConfig; 16268 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16269 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16270 //mUsageStatsService.noteStartConfig(newConfig); 16271 16272 final Configuration configCopy = new Configuration(mConfiguration); 16273 16274 // TODO: If our config changes, should we auto dismiss any currently 16275 // showing dialogs? 16276 mShowDialogs = shouldShowDialogs(newConfig); 16277 16278 AttributeCache ac = AttributeCache.instance(); 16279 if (ac != null) { 16280 ac.updateConfiguration(configCopy); 16281 } 16282 16283 // Make sure all resources in our process are updated 16284 // right now, so that anyone who is going to retrieve 16285 // resource values after we return will be sure to get 16286 // the new ones. This is especially important during 16287 // boot, where the first config change needs to guarantee 16288 // all resources have that config before following boot 16289 // code is executed. 16290 mSystemThread.applyConfigurationToResources(configCopy); 16291 16292 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16293 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16294 msg.obj = new Configuration(configCopy); 16295 mHandler.sendMessage(msg); 16296 } 16297 16298 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16299 ProcessRecord app = mLruProcesses.get(i); 16300 try { 16301 if (app.thread != null) { 16302 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16303 + app.processName + " new config " + mConfiguration); 16304 app.thread.scheduleConfigurationChanged(configCopy); 16305 } 16306 } catch (Exception e) { 16307 } 16308 } 16309 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16310 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16311 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16312 | Intent.FLAG_RECEIVER_FOREGROUND); 16313 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16314 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16315 Process.SYSTEM_UID, UserHandle.USER_ALL); 16316 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16317 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16318 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16319 broadcastIntentLocked(null, null, intent, 16320 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16321 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16322 } 16323 } 16324 } 16325 16326 boolean kept = true; 16327 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16328 // mainStack is null during startup. 16329 if (mainStack != null) { 16330 if (changes != 0 && starting == null) { 16331 // If the configuration changed, and the caller is not already 16332 // in the process of starting an activity, then find the top 16333 // activity to check if its configuration needs to change. 16334 starting = mainStack.topRunningActivityLocked(null); 16335 } 16336 16337 if (starting != null) { 16338 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16339 // And we need to make sure at this point that all other activities 16340 // are made visible with the correct configuration. 16341 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16342 } 16343 } 16344 16345 if (values != null && mWindowManager != null) { 16346 mWindowManager.setNewConfiguration(mConfiguration); 16347 } 16348 16349 return kept; 16350 } 16351 16352 /** 16353 * Decide based on the configuration whether we should shouw the ANR, 16354 * crash, etc dialogs. The idea is that if there is no affordnace to 16355 * press the on-screen buttons, we shouldn't show the dialog. 16356 * 16357 * A thought: SystemUI might also want to get told about this, the Power 16358 * dialog / global actions also might want different behaviors. 16359 */ 16360 private static final boolean shouldShowDialogs(Configuration config) { 16361 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16362 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16363 } 16364 16365 /** 16366 * Save the locale. You must be inside a synchronized (this) block. 16367 */ 16368 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16369 if(isDiff) { 16370 SystemProperties.set("user.language", l.getLanguage()); 16371 SystemProperties.set("user.region", l.getCountry()); 16372 } 16373 16374 if(isPersist) { 16375 SystemProperties.set("persist.sys.language", l.getLanguage()); 16376 SystemProperties.set("persist.sys.country", l.getCountry()); 16377 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16378 16379 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16380 } 16381 } 16382 16383 @Override 16384 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16385 synchronized (this) { 16386 ActivityRecord srec = ActivityRecord.forToken(token); 16387 if (srec.task != null && srec.task.stack != null) { 16388 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16389 } 16390 } 16391 return false; 16392 } 16393 16394 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16395 Intent resultData) { 16396 16397 synchronized (this) { 16398 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16399 if (stack != null) { 16400 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16401 } 16402 return false; 16403 } 16404 } 16405 16406 public int getLaunchedFromUid(IBinder activityToken) { 16407 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16408 if (srec == null) { 16409 return -1; 16410 } 16411 return srec.launchedFromUid; 16412 } 16413 16414 public String getLaunchedFromPackage(IBinder activityToken) { 16415 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16416 if (srec == null) { 16417 return null; 16418 } 16419 return srec.launchedFromPackage; 16420 } 16421 16422 // ========================================================= 16423 // LIFETIME MANAGEMENT 16424 // ========================================================= 16425 16426 // Returns which broadcast queue the app is the current [or imminent] receiver 16427 // on, or 'null' if the app is not an active broadcast recipient. 16428 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16429 BroadcastRecord r = app.curReceiver; 16430 if (r != null) { 16431 return r.queue; 16432 } 16433 16434 // It's not the current receiver, but it might be starting up to become one 16435 synchronized (this) { 16436 for (BroadcastQueue queue : mBroadcastQueues) { 16437 r = queue.mPendingBroadcast; 16438 if (r != null && r.curApp == app) { 16439 // found it; report which queue it's in 16440 return queue; 16441 } 16442 } 16443 } 16444 16445 return null; 16446 } 16447 16448 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16449 boolean doingAll, long now) { 16450 if (mAdjSeq == app.adjSeq) { 16451 // This adjustment has already been computed. 16452 return app.curRawAdj; 16453 } 16454 16455 if (app.thread == null) { 16456 app.adjSeq = mAdjSeq; 16457 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16458 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16459 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16460 } 16461 16462 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16463 app.adjSource = null; 16464 app.adjTarget = null; 16465 app.empty = false; 16466 app.cached = false; 16467 16468 final int activitiesSize = app.activities.size(); 16469 16470 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16471 // The max adjustment doesn't allow this app to be anything 16472 // below foreground, so it is not worth doing work for it. 16473 app.adjType = "fixed"; 16474 app.adjSeq = mAdjSeq; 16475 app.curRawAdj = app.maxAdj; 16476 app.foregroundActivities = false; 16477 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16478 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16479 // System processes can do UI, and when they do we want to have 16480 // them trim their memory after the user leaves the UI. To 16481 // facilitate this, here we need to determine whether or not it 16482 // is currently showing UI. 16483 app.systemNoUi = true; 16484 if (app == TOP_APP) { 16485 app.systemNoUi = false; 16486 } else if (activitiesSize > 0) { 16487 for (int j = 0; j < activitiesSize; j++) { 16488 final ActivityRecord r = app.activities.get(j); 16489 if (r.visible) { 16490 app.systemNoUi = false; 16491 } 16492 } 16493 } 16494 if (!app.systemNoUi) { 16495 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16496 } 16497 return (app.curAdj=app.maxAdj); 16498 } 16499 16500 app.systemNoUi = false; 16501 16502 // Determine the importance of the process, starting with most 16503 // important to least, and assign an appropriate OOM adjustment. 16504 int adj; 16505 int schedGroup; 16506 int procState; 16507 boolean foregroundActivities = false; 16508 BroadcastQueue queue; 16509 if (app == TOP_APP) { 16510 // The last app on the list is the foreground app. 16511 adj = ProcessList.FOREGROUND_APP_ADJ; 16512 schedGroup = Process.THREAD_GROUP_DEFAULT; 16513 app.adjType = "top-activity"; 16514 foregroundActivities = true; 16515 procState = ActivityManager.PROCESS_STATE_TOP; 16516 } else if (app.instrumentationClass != null) { 16517 // Don't want to kill running instrumentation. 16518 adj = ProcessList.FOREGROUND_APP_ADJ; 16519 schedGroup = Process.THREAD_GROUP_DEFAULT; 16520 app.adjType = "instrumentation"; 16521 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16522 } else if ((queue = isReceivingBroadcast(app)) != null) { 16523 // An app that is currently receiving a broadcast also 16524 // counts as being in the foreground for OOM killer purposes. 16525 // It's placed in a sched group based on the nature of the 16526 // broadcast as reflected by which queue it's active in. 16527 adj = ProcessList.FOREGROUND_APP_ADJ; 16528 schedGroup = (queue == mFgBroadcastQueue) 16529 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16530 app.adjType = "broadcast"; 16531 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16532 } else if (app.executingServices.size() > 0) { 16533 // An app that is currently executing a service callback also 16534 // counts as being in the foreground. 16535 adj = ProcessList.FOREGROUND_APP_ADJ; 16536 schedGroup = app.execServicesFg ? 16537 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16538 app.adjType = "exec-service"; 16539 procState = ActivityManager.PROCESS_STATE_SERVICE; 16540 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16541 } else { 16542 // As far as we know the process is empty. We may change our mind later. 16543 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16544 // At this point we don't actually know the adjustment. Use the cached adj 16545 // value that the caller wants us to. 16546 adj = cachedAdj; 16547 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16548 app.cached = true; 16549 app.empty = true; 16550 app.adjType = "cch-empty"; 16551 } 16552 16553 // Examine all activities if not already foreground. 16554 if (!foregroundActivities && activitiesSize > 0) { 16555 for (int j = 0; j < activitiesSize; j++) { 16556 final ActivityRecord r = app.activities.get(j); 16557 if (r.app != app) { 16558 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16559 + app + "?!?"); 16560 continue; 16561 } 16562 if (r.visible) { 16563 // App has a visible activity; only upgrade adjustment. 16564 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16565 adj = ProcessList.VISIBLE_APP_ADJ; 16566 app.adjType = "visible"; 16567 } 16568 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16569 procState = ActivityManager.PROCESS_STATE_TOP; 16570 } 16571 schedGroup = Process.THREAD_GROUP_DEFAULT; 16572 app.cached = false; 16573 app.empty = false; 16574 foregroundActivities = true; 16575 break; 16576 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16577 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16578 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16579 app.adjType = "pausing"; 16580 } 16581 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16582 procState = ActivityManager.PROCESS_STATE_TOP; 16583 } 16584 schedGroup = Process.THREAD_GROUP_DEFAULT; 16585 app.cached = false; 16586 app.empty = false; 16587 foregroundActivities = true; 16588 } else if (r.state == ActivityState.STOPPING) { 16589 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16590 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16591 app.adjType = "stopping"; 16592 } 16593 // For the process state, we will at this point consider the 16594 // process to be cached. It will be cached either as an activity 16595 // or empty depending on whether the activity is finishing. We do 16596 // this so that we can treat the process as cached for purposes of 16597 // memory trimming (determing current memory level, trim command to 16598 // send to process) since there can be an arbitrary number of stopping 16599 // processes and they should soon all go into the cached state. 16600 if (!r.finishing) { 16601 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16602 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16603 } 16604 } 16605 app.cached = false; 16606 app.empty = false; 16607 foregroundActivities = true; 16608 } else { 16609 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16610 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16611 app.adjType = "cch-act"; 16612 } 16613 } 16614 } 16615 } 16616 16617 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16618 if (app.foregroundServices) { 16619 // The user is aware of this app, so make it visible. 16620 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16621 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16622 app.cached = false; 16623 app.adjType = "fg-service"; 16624 schedGroup = Process.THREAD_GROUP_DEFAULT; 16625 } else if (app.forcingToForeground != null) { 16626 // The user is aware of this app, so make it visible. 16627 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16628 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16629 app.cached = false; 16630 app.adjType = "force-fg"; 16631 app.adjSource = app.forcingToForeground; 16632 schedGroup = Process.THREAD_GROUP_DEFAULT; 16633 } 16634 } 16635 16636 if (app == mHeavyWeightProcess) { 16637 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16638 // We don't want to kill the current heavy-weight process. 16639 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16640 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16641 app.cached = false; 16642 app.adjType = "heavy"; 16643 } 16644 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16645 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16646 } 16647 } 16648 16649 if (app == mHomeProcess) { 16650 if (adj > ProcessList.HOME_APP_ADJ) { 16651 // This process is hosting what we currently consider to be the 16652 // home app, so we don't want to let it go into the background. 16653 adj = ProcessList.HOME_APP_ADJ; 16654 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16655 app.cached = false; 16656 app.adjType = "home"; 16657 } 16658 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16659 procState = ActivityManager.PROCESS_STATE_HOME; 16660 } 16661 } 16662 16663 if (app == mPreviousProcess && app.activities.size() > 0) { 16664 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16665 // This was the previous process that showed UI to the user. 16666 // We want to try to keep it around more aggressively, to give 16667 // a good experience around switching between two apps. 16668 adj = ProcessList.PREVIOUS_APP_ADJ; 16669 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16670 app.cached = false; 16671 app.adjType = "previous"; 16672 } 16673 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16674 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16675 } 16676 } 16677 16678 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16679 + " reason=" + app.adjType); 16680 16681 // By default, we use the computed adjustment. It may be changed if 16682 // there are applications dependent on our services or providers, but 16683 // this gives us a baseline and makes sure we don't get into an 16684 // infinite recursion. 16685 app.adjSeq = mAdjSeq; 16686 app.curRawAdj = adj; 16687 app.hasStartedServices = false; 16688 16689 if (mBackupTarget != null && app == mBackupTarget.app) { 16690 // If possible we want to avoid killing apps while they're being backed up 16691 if (adj > ProcessList.BACKUP_APP_ADJ) { 16692 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16693 adj = ProcessList.BACKUP_APP_ADJ; 16694 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16695 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16696 } 16697 app.adjType = "backup"; 16698 app.cached = false; 16699 } 16700 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16701 procState = ActivityManager.PROCESS_STATE_BACKUP; 16702 } 16703 } 16704 16705 boolean mayBeTop = false; 16706 16707 for (int is = app.services.size()-1; 16708 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16709 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16710 || procState > ActivityManager.PROCESS_STATE_TOP); 16711 is--) { 16712 ServiceRecord s = app.services.valueAt(is); 16713 if (s.startRequested) { 16714 app.hasStartedServices = true; 16715 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16716 procState = ActivityManager.PROCESS_STATE_SERVICE; 16717 } 16718 if (app.hasShownUi && app != mHomeProcess) { 16719 // If this process has shown some UI, let it immediately 16720 // go to the LRU list because it may be pretty heavy with 16721 // UI stuff. We'll tag it with a label just to help 16722 // debug and understand what is going on. 16723 if (adj > ProcessList.SERVICE_ADJ) { 16724 app.adjType = "cch-started-ui-services"; 16725 } 16726 } else { 16727 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16728 // This service has seen some activity within 16729 // recent memory, so we will keep its process ahead 16730 // of the background processes. 16731 if (adj > ProcessList.SERVICE_ADJ) { 16732 adj = ProcessList.SERVICE_ADJ; 16733 app.adjType = "started-services"; 16734 app.cached = false; 16735 } 16736 } 16737 // If we have let the service slide into the background 16738 // state, still have some text describing what it is doing 16739 // even though the service no longer has an impact. 16740 if (adj > ProcessList.SERVICE_ADJ) { 16741 app.adjType = "cch-started-services"; 16742 } 16743 } 16744 } 16745 for (int conni = s.connections.size()-1; 16746 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16747 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16748 || procState > ActivityManager.PROCESS_STATE_TOP); 16749 conni--) { 16750 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16751 for (int i = 0; 16752 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16753 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16754 || procState > ActivityManager.PROCESS_STATE_TOP); 16755 i++) { 16756 // XXX should compute this based on the max of 16757 // all connected clients. 16758 ConnectionRecord cr = clist.get(i); 16759 if (cr.binding.client == app) { 16760 // Binding to ourself is not interesting. 16761 continue; 16762 } 16763 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16764 ProcessRecord client = cr.binding.client; 16765 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16766 TOP_APP, doingAll, now); 16767 int clientProcState = client.curProcState; 16768 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16769 // If the other app is cached for any reason, for purposes here 16770 // we are going to consider it empty. The specific cached state 16771 // doesn't propagate except under certain conditions. 16772 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16773 } 16774 String adjType = null; 16775 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16776 // Not doing bind OOM management, so treat 16777 // this guy more like a started service. 16778 if (app.hasShownUi && app != mHomeProcess) { 16779 // If this process has shown some UI, let it immediately 16780 // go to the LRU list because it may be pretty heavy with 16781 // UI stuff. We'll tag it with a label just to help 16782 // debug and understand what is going on. 16783 if (adj > clientAdj) { 16784 adjType = "cch-bound-ui-services"; 16785 } 16786 app.cached = false; 16787 clientAdj = adj; 16788 clientProcState = procState; 16789 } else { 16790 if (now >= (s.lastActivity 16791 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16792 // This service has not seen activity within 16793 // recent memory, so allow it to drop to the 16794 // LRU list if there is no other reason to keep 16795 // it around. We'll also tag it with a label just 16796 // to help debug and undertand what is going on. 16797 if (adj > clientAdj) { 16798 adjType = "cch-bound-services"; 16799 } 16800 clientAdj = adj; 16801 } 16802 } 16803 } 16804 if (adj > clientAdj) { 16805 // If this process has recently shown UI, and 16806 // the process that is binding to it is less 16807 // important than being visible, then we don't 16808 // care about the binding as much as we care 16809 // about letting this process get into the LRU 16810 // list to be killed and restarted if needed for 16811 // memory. 16812 if (app.hasShownUi && app != mHomeProcess 16813 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16814 adjType = "cch-bound-ui-services"; 16815 } else { 16816 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16817 |Context.BIND_IMPORTANT)) != 0) { 16818 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16819 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16820 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16821 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16822 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16823 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16824 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16825 adj = clientAdj; 16826 } else { 16827 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16828 adj = ProcessList.VISIBLE_APP_ADJ; 16829 } 16830 } 16831 if (!client.cached) { 16832 app.cached = false; 16833 } 16834 adjType = "service"; 16835 } 16836 } 16837 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16838 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16839 schedGroup = Process.THREAD_GROUP_DEFAULT; 16840 } 16841 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16842 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16843 // Special handling of clients who are in the top state. 16844 // We *may* want to consider this process to be in the 16845 // top state as well, but only if there is not another 16846 // reason for it to be running. Being on the top is a 16847 // special state, meaning you are specifically running 16848 // for the current top app. If the process is already 16849 // running in the background for some other reason, it 16850 // is more important to continue considering it to be 16851 // in the background state. 16852 mayBeTop = true; 16853 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16854 } else { 16855 // Special handling for above-top states (persistent 16856 // processes). These should not bring the current process 16857 // into the top state, since they are not on top. Instead 16858 // give them the best state after that. 16859 clientProcState = 16860 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16861 } 16862 } 16863 } else { 16864 if (clientProcState < 16865 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16866 clientProcState = 16867 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16868 } 16869 } 16870 if (procState > clientProcState) { 16871 procState = clientProcState; 16872 } 16873 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16874 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16875 app.pendingUiClean = true; 16876 } 16877 if (adjType != null) { 16878 app.adjType = adjType; 16879 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16880 .REASON_SERVICE_IN_USE; 16881 app.adjSource = cr.binding.client; 16882 app.adjSourceProcState = clientProcState; 16883 app.adjTarget = s.name; 16884 } 16885 } 16886 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16887 app.treatLikeActivity = true; 16888 } 16889 final ActivityRecord a = cr.activity; 16890 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16891 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16892 (a.visible || a.state == ActivityState.RESUMED 16893 || a.state == ActivityState.PAUSING)) { 16894 adj = ProcessList.FOREGROUND_APP_ADJ; 16895 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16896 schedGroup = Process.THREAD_GROUP_DEFAULT; 16897 } 16898 app.cached = false; 16899 app.adjType = "service"; 16900 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16901 .REASON_SERVICE_IN_USE; 16902 app.adjSource = a; 16903 app.adjSourceProcState = procState; 16904 app.adjTarget = s.name; 16905 } 16906 } 16907 } 16908 } 16909 } 16910 16911 for (int provi = app.pubProviders.size()-1; 16912 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16913 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16914 || procState > ActivityManager.PROCESS_STATE_TOP); 16915 provi--) { 16916 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16917 for (int i = cpr.connections.size()-1; 16918 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16919 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16920 || procState > ActivityManager.PROCESS_STATE_TOP); 16921 i--) { 16922 ContentProviderConnection conn = cpr.connections.get(i); 16923 ProcessRecord client = conn.client; 16924 if (client == app) { 16925 // Being our own client is not interesting. 16926 continue; 16927 } 16928 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16929 int clientProcState = client.curProcState; 16930 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16931 // If the other app is cached for any reason, for purposes here 16932 // we are going to consider it empty. 16933 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16934 } 16935 if (adj > clientAdj) { 16936 if (app.hasShownUi && app != mHomeProcess 16937 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16938 app.adjType = "cch-ui-provider"; 16939 } else { 16940 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16941 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16942 app.adjType = "provider"; 16943 } 16944 app.cached &= client.cached; 16945 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16946 .REASON_PROVIDER_IN_USE; 16947 app.adjSource = client; 16948 app.adjSourceProcState = clientProcState; 16949 app.adjTarget = cpr.name; 16950 } 16951 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16952 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16953 // Special handling of clients who are in the top state. 16954 // We *may* want to consider this process to be in the 16955 // top state as well, but only if there is not another 16956 // reason for it to be running. Being on the top is a 16957 // special state, meaning you are specifically running 16958 // for the current top app. If the process is already 16959 // running in the background for some other reason, it 16960 // is more important to continue considering it to be 16961 // in the background state. 16962 mayBeTop = true; 16963 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16964 } else { 16965 // Special handling for above-top states (persistent 16966 // processes). These should not bring the current process 16967 // into the top state, since they are not on top. Instead 16968 // give them the best state after that. 16969 clientProcState = 16970 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16971 } 16972 } 16973 if (procState > clientProcState) { 16974 procState = clientProcState; 16975 } 16976 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16977 schedGroup = Process.THREAD_GROUP_DEFAULT; 16978 } 16979 } 16980 // If the provider has external (non-framework) process 16981 // dependencies, ensure that its adjustment is at least 16982 // FOREGROUND_APP_ADJ. 16983 if (cpr.hasExternalProcessHandles()) { 16984 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16985 adj = ProcessList.FOREGROUND_APP_ADJ; 16986 schedGroup = Process.THREAD_GROUP_DEFAULT; 16987 app.cached = false; 16988 app.adjType = "provider"; 16989 app.adjTarget = cpr.name; 16990 } 16991 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16992 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16993 } 16994 } 16995 } 16996 16997 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16998 // A client of one of our services or providers is in the top state. We 16999 // *may* want to be in the top state, but not if we are already running in 17000 // the background for some other reason. For the decision here, we are going 17001 // to pick out a few specific states that we want to remain in when a client 17002 // is top (states that tend to be longer-term) and otherwise allow it to go 17003 // to the top state. 17004 switch (procState) { 17005 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17006 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17007 case ActivityManager.PROCESS_STATE_SERVICE: 17008 // These all are longer-term states, so pull them up to the top 17009 // of the background states, but not all the way to the top state. 17010 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17011 break; 17012 default: 17013 // Otherwise, top is a better choice, so take it. 17014 procState = ActivityManager.PROCESS_STATE_TOP; 17015 break; 17016 } 17017 } 17018 17019 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17020 if (app.hasClientActivities) { 17021 // This is a cached process, but with client activities. Mark it so. 17022 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17023 app.adjType = "cch-client-act"; 17024 } else if (app.treatLikeActivity) { 17025 // This is a cached process, but somebody wants us to treat it like it has 17026 // an activity, okay! 17027 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17028 app.adjType = "cch-as-act"; 17029 } 17030 } 17031 17032 if (adj == ProcessList.SERVICE_ADJ) { 17033 if (doingAll) { 17034 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17035 mNewNumServiceProcs++; 17036 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17037 if (!app.serviceb) { 17038 // This service isn't far enough down on the LRU list to 17039 // normally be a B service, but if we are low on RAM and it 17040 // is large we want to force it down since we would prefer to 17041 // keep launcher over it. 17042 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17043 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17044 app.serviceHighRam = true; 17045 app.serviceb = true; 17046 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17047 } else { 17048 mNewNumAServiceProcs++; 17049 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17050 } 17051 } else { 17052 app.serviceHighRam = false; 17053 } 17054 } 17055 if (app.serviceb) { 17056 adj = ProcessList.SERVICE_B_ADJ; 17057 } 17058 } 17059 17060 app.curRawAdj = adj; 17061 17062 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17063 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17064 if (adj > app.maxAdj) { 17065 adj = app.maxAdj; 17066 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17067 schedGroup = Process.THREAD_GROUP_DEFAULT; 17068 } 17069 } 17070 17071 // Do final modification to adj. Everything we do between here and applying 17072 // the final setAdj must be done in this function, because we will also use 17073 // it when computing the final cached adj later. Note that we don't need to 17074 // worry about this for max adj above, since max adj will always be used to 17075 // keep it out of the cached vaues. 17076 app.curAdj = app.modifyRawOomAdj(adj); 17077 app.curSchedGroup = schedGroup; 17078 app.curProcState = procState; 17079 app.foregroundActivities = foregroundActivities; 17080 17081 return app.curRawAdj; 17082 } 17083 17084 /** 17085 * Schedule PSS collection of a process. 17086 */ 17087 void requestPssLocked(ProcessRecord proc, int procState) { 17088 if (mPendingPssProcesses.contains(proc)) { 17089 return; 17090 } 17091 if (mPendingPssProcesses.size() == 0) { 17092 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17093 } 17094 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17095 proc.pssProcState = procState; 17096 mPendingPssProcesses.add(proc); 17097 } 17098 17099 /** 17100 * Schedule PSS collection of all processes. 17101 */ 17102 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17103 if (!always) { 17104 if (now < (mLastFullPssTime + 17105 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17106 return; 17107 } 17108 } 17109 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17110 mLastFullPssTime = now; 17111 mFullPssPending = true; 17112 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17113 mPendingPssProcesses.clear(); 17114 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17115 ProcessRecord app = mLruProcesses.get(i); 17116 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17117 app.pssProcState = app.setProcState; 17118 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17119 isSleeping(), now); 17120 mPendingPssProcesses.add(app); 17121 } 17122 } 17123 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17124 } 17125 17126 /** 17127 * Ask a given process to GC right now. 17128 */ 17129 final void performAppGcLocked(ProcessRecord app) { 17130 try { 17131 app.lastRequestedGc = SystemClock.uptimeMillis(); 17132 if (app.thread != null) { 17133 if (app.reportLowMemory) { 17134 app.reportLowMemory = false; 17135 app.thread.scheduleLowMemory(); 17136 } else { 17137 app.thread.processInBackground(); 17138 } 17139 } 17140 } catch (Exception e) { 17141 // whatever. 17142 } 17143 } 17144 17145 /** 17146 * Returns true if things are idle enough to perform GCs. 17147 */ 17148 private final boolean canGcNowLocked() { 17149 boolean processingBroadcasts = false; 17150 for (BroadcastQueue q : mBroadcastQueues) { 17151 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17152 processingBroadcasts = true; 17153 } 17154 } 17155 return !processingBroadcasts 17156 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17157 } 17158 17159 /** 17160 * Perform GCs on all processes that are waiting for it, but only 17161 * if things are idle. 17162 */ 17163 final void performAppGcsLocked() { 17164 final int N = mProcessesToGc.size(); 17165 if (N <= 0) { 17166 return; 17167 } 17168 if (canGcNowLocked()) { 17169 while (mProcessesToGc.size() > 0) { 17170 ProcessRecord proc = mProcessesToGc.remove(0); 17171 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17172 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17173 <= SystemClock.uptimeMillis()) { 17174 // To avoid spamming the system, we will GC processes one 17175 // at a time, waiting a few seconds between each. 17176 performAppGcLocked(proc); 17177 scheduleAppGcsLocked(); 17178 return; 17179 } else { 17180 // It hasn't been long enough since we last GCed this 17181 // process... put it in the list to wait for its time. 17182 addProcessToGcListLocked(proc); 17183 break; 17184 } 17185 } 17186 } 17187 17188 scheduleAppGcsLocked(); 17189 } 17190 } 17191 17192 /** 17193 * If all looks good, perform GCs on all processes waiting for them. 17194 */ 17195 final void performAppGcsIfAppropriateLocked() { 17196 if (canGcNowLocked()) { 17197 performAppGcsLocked(); 17198 return; 17199 } 17200 // Still not idle, wait some more. 17201 scheduleAppGcsLocked(); 17202 } 17203 17204 /** 17205 * Schedule the execution of all pending app GCs. 17206 */ 17207 final void scheduleAppGcsLocked() { 17208 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17209 17210 if (mProcessesToGc.size() > 0) { 17211 // Schedule a GC for the time to the next process. 17212 ProcessRecord proc = mProcessesToGc.get(0); 17213 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17214 17215 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17216 long now = SystemClock.uptimeMillis(); 17217 if (when < (now+GC_TIMEOUT)) { 17218 when = now + GC_TIMEOUT; 17219 } 17220 mHandler.sendMessageAtTime(msg, when); 17221 } 17222 } 17223 17224 /** 17225 * Add a process to the array of processes waiting to be GCed. Keeps the 17226 * list in sorted order by the last GC time. The process can't already be 17227 * on the list. 17228 */ 17229 final void addProcessToGcListLocked(ProcessRecord proc) { 17230 boolean added = false; 17231 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17232 if (mProcessesToGc.get(i).lastRequestedGc < 17233 proc.lastRequestedGc) { 17234 added = true; 17235 mProcessesToGc.add(i+1, proc); 17236 break; 17237 } 17238 } 17239 if (!added) { 17240 mProcessesToGc.add(0, proc); 17241 } 17242 } 17243 17244 /** 17245 * Set up to ask a process to GC itself. This will either do it 17246 * immediately, or put it on the list of processes to gc the next 17247 * time things are idle. 17248 */ 17249 final void scheduleAppGcLocked(ProcessRecord app) { 17250 long now = SystemClock.uptimeMillis(); 17251 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17252 return; 17253 } 17254 if (!mProcessesToGc.contains(app)) { 17255 addProcessToGcListLocked(app); 17256 scheduleAppGcsLocked(); 17257 } 17258 } 17259 17260 final void checkExcessivePowerUsageLocked(boolean doKills) { 17261 updateCpuStatsNow(); 17262 17263 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17264 boolean doWakeKills = doKills; 17265 boolean doCpuKills = doKills; 17266 if (mLastPowerCheckRealtime == 0) { 17267 doWakeKills = false; 17268 } 17269 if (mLastPowerCheckUptime == 0) { 17270 doCpuKills = false; 17271 } 17272 if (stats.isScreenOn()) { 17273 doWakeKills = false; 17274 } 17275 final long curRealtime = SystemClock.elapsedRealtime(); 17276 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17277 final long curUptime = SystemClock.uptimeMillis(); 17278 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17279 mLastPowerCheckRealtime = curRealtime; 17280 mLastPowerCheckUptime = curUptime; 17281 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17282 doWakeKills = false; 17283 } 17284 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17285 doCpuKills = false; 17286 } 17287 int i = mLruProcesses.size(); 17288 while (i > 0) { 17289 i--; 17290 ProcessRecord app = mLruProcesses.get(i); 17291 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17292 long wtime; 17293 synchronized (stats) { 17294 wtime = stats.getProcessWakeTime(app.info.uid, 17295 app.pid, curRealtime); 17296 } 17297 long wtimeUsed = wtime - app.lastWakeTime; 17298 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17299 if (DEBUG_POWER) { 17300 StringBuilder sb = new StringBuilder(128); 17301 sb.append("Wake for "); 17302 app.toShortString(sb); 17303 sb.append(": over "); 17304 TimeUtils.formatDuration(realtimeSince, sb); 17305 sb.append(" used "); 17306 TimeUtils.formatDuration(wtimeUsed, sb); 17307 sb.append(" ("); 17308 sb.append((wtimeUsed*100)/realtimeSince); 17309 sb.append("%)"); 17310 Slog.i(TAG, sb.toString()); 17311 sb.setLength(0); 17312 sb.append("CPU for "); 17313 app.toShortString(sb); 17314 sb.append(": over "); 17315 TimeUtils.formatDuration(uptimeSince, sb); 17316 sb.append(" used "); 17317 TimeUtils.formatDuration(cputimeUsed, sb); 17318 sb.append(" ("); 17319 sb.append((cputimeUsed*100)/uptimeSince); 17320 sb.append("%)"); 17321 Slog.i(TAG, sb.toString()); 17322 } 17323 // If a process has held a wake lock for more 17324 // than 50% of the time during this period, 17325 // that sounds bad. Kill! 17326 if (doWakeKills && realtimeSince > 0 17327 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17328 synchronized (stats) { 17329 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17330 realtimeSince, wtimeUsed); 17331 } 17332 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17333 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17334 } else if (doCpuKills && uptimeSince > 0 17335 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17336 synchronized (stats) { 17337 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17338 uptimeSince, cputimeUsed); 17339 } 17340 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17341 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17342 } else { 17343 app.lastWakeTime = wtime; 17344 app.lastCpuTime = app.curCpuTime; 17345 } 17346 } 17347 } 17348 } 17349 17350 private final boolean applyOomAdjLocked(ProcessRecord app, 17351 ProcessRecord TOP_APP, boolean doingAll, long now) { 17352 boolean success = true; 17353 17354 if (app.curRawAdj != app.setRawAdj) { 17355 app.setRawAdj = app.curRawAdj; 17356 } 17357 17358 int changes = 0; 17359 17360 if (app.curAdj != app.setAdj) { 17361 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17362 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17363 TAG, "Set " + app.pid + " " + app.processName + 17364 " adj " + app.curAdj + ": " + app.adjType); 17365 app.setAdj = app.curAdj; 17366 } 17367 17368 if (app.setSchedGroup != app.curSchedGroup) { 17369 app.setSchedGroup = app.curSchedGroup; 17370 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17371 "Setting process group of " + app.processName 17372 + " to " + app.curSchedGroup); 17373 if (app.waitingToKill != null && 17374 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17375 app.kill(app.waitingToKill, true); 17376 success = false; 17377 } else { 17378 if (true) { 17379 long oldId = Binder.clearCallingIdentity(); 17380 try { 17381 Process.setProcessGroup(app.pid, app.curSchedGroup); 17382 } catch (Exception e) { 17383 Slog.w(TAG, "Failed setting process group of " + app.pid 17384 + " to " + app.curSchedGroup); 17385 e.printStackTrace(); 17386 } finally { 17387 Binder.restoreCallingIdentity(oldId); 17388 } 17389 } else { 17390 if (app.thread != null) { 17391 try { 17392 app.thread.setSchedulingGroup(app.curSchedGroup); 17393 } catch (RemoteException e) { 17394 } 17395 } 17396 } 17397 Process.setSwappiness(app.pid, 17398 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17399 } 17400 } 17401 if (app.repForegroundActivities != app.foregroundActivities) { 17402 app.repForegroundActivities = app.foregroundActivities; 17403 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17404 } 17405 if (app.repProcState != app.curProcState) { 17406 app.repProcState = app.curProcState; 17407 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17408 if (app.thread != null) { 17409 try { 17410 if (false) { 17411 //RuntimeException h = new RuntimeException("here"); 17412 Slog.i(TAG, "Sending new process state " + app.repProcState 17413 + " to " + app /*, h*/); 17414 } 17415 app.thread.setProcessState(app.repProcState); 17416 } catch (RemoteException e) { 17417 } 17418 } 17419 } 17420 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17421 app.setProcState)) { 17422 app.lastStateTime = now; 17423 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17424 isSleeping(), now); 17425 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17426 + ProcessList.makeProcStateString(app.setProcState) + " to " 17427 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17428 + (app.nextPssTime-now) + ": " + app); 17429 } else { 17430 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17431 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17432 requestPssLocked(app, app.setProcState); 17433 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17434 isSleeping(), now); 17435 } else if (false && DEBUG_PSS) { 17436 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17437 } 17438 } 17439 if (app.setProcState != app.curProcState) { 17440 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17441 "Proc state change of " + app.processName 17442 + " to " + app.curProcState); 17443 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17444 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17445 if (setImportant && !curImportant) { 17446 // This app is no longer something we consider important enough to allow to 17447 // use arbitrary amounts of battery power. Note 17448 // its current wake lock time to later know to kill it if 17449 // it is not behaving well. 17450 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17451 synchronized (stats) { 17452 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17453 app.pid, SystemClock.elapsedRealtime()); 17454 } 17455 app.lastCpuTime = app.curCpuTime; 17456 17457 } 17458 app.setProcState = app.curProcState; 17459 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17460 app.notCachedSinceIdle = false; 17461 } 17462 if (!doingAll) { 17463 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17464 } else { 17465 app.procStateChanged = true; 17466 } 17467 } 17468 17469 if (changes != 0) { 17470 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17471 int i = mPendingProcessChanges.size()-1; 17472 ProcessChangeItem item = null; 17473 while (i >= 0) { 17474 item = mPendingProcessChanges.get(i); 17475 if (item.pid == app.pid) { 17476 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17477 break; 17478 } 17479 i--; 17480 } 17481 if (i < 0) { 17482 // No existing item in pending changes; need a new one. 17483 final int NA = mAvailProcessChanges.size(); 17484 if (NA > 0) { 17485 item = mAvailProcessChanges.remove(NA-1); 17486 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17487 } else { 17488 item = new ProcessChangeItem(); 17489 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17490 } 17491 item.changes = 0; 17492 item.pid = app.pid; 17493 item.uid = app.info.uid; 17494 if (mPendingProcessChanges.size() == 0) { 17495 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17496 "*** Enqueueing dispatch processes changed!"); 17497 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17498 } 17499 mPendingProcessChanges.add(item); 17500 } 17501 item.changes |= changes; 17502 item.processState = app.repProcState; 17503 item.foregroundActivities = app.repForegroundActivities; 17504 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17505 + Integer.toHexString(System.identityHashCode(item)) 17506 + " " + app.toShortString() + ": changes=" + item.changes 17507 + " procState=" + item.processState 17508 + " foreground=" + item.foregroundActivities 17509 + " type=" + app.adjType + " source=" + app.adjSource 17510 + " target=" + app.adjTarget); 17511 } 17512 17513 return success; 17514 } 17515 17516 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17517 if (proc.thread != null) { 17518 if (proc.baseProcessTracker != null) { 17519 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17520 } 17521 if (proc.repProcState >= 0) { 17522 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17523 proc.repProcState); 17524 } 17525 } 17526 } 17527 17528 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17529 ProcessRecord TOP_APP, boolean doingAll, long now) { 17530 if (app.thread == null) { 17531 return false; 17532 } 17533 17534 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17535 17536 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17537 } 17538 17539 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17540 boolean oomAdj) { 17541 if (isForeground != proc.foregroundServices) { 17542 proc.foregroundServices = isForeground; 17543 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17544 proc.info.uid); 17545 if (isForeground) { 17546 if (curProcs == null) { 17547 curProcs = new ArrayList<ProcessRecord>(); 17548 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17549 } 17550 if (!curProcs.contains(proc)) { 17551 curProcs.add(proc); 17552 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17553 proc.info.packageName, proc.info.uid); 17554 } 17555 } else { 17556 if (curProcs != null) { 17557 if (curProcs.remove(proc)) { 17558 mBatteryStatsService.noteEvent( 17559 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17560 proc.info.packageName, proc.info.uid); 17561 if (curProcs.size() <= 0) { 17562 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17563 } 17564 } 17565 } 17566 } 17567 if (oomAdj) { 17568 updateOomAdjLocked(); 17569 } 17570 } 17571 } 17572 17573 private final ActivityRecord resumedAppLocked() { 17574 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17575 String pkg; 17576 int uid; 17577 if (act != null) { 17578 pkg = act.packageName; 17579 uid = act.info.applicationInfo.uid; 17580 } else { 17581 pkg = null; 17582 uid = -1; 17583 } 17584 // Has the UID or resumed package name changed? 17585 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17586 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17587 if (mCurResumedPackage != null) { 17588 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17589 mCurResumedPackage, mCurResumedUid); 17590 } 17591 mCurResumedPackage = pkg; 17592 mCurResumedUid = uid; 17593 if (mCurResumedPackage != null) { 17594 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17595 mCurResumedPackage, mCurResumedUid); 17596 } 17597 } 17598 return act; 17599 } 17600 17601 final boolean updateOomAdjLocked(ProcessRecord app) { 17602 final ActivityRecord TOP_ACT = resumedAppLocked(); 17603 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17604 final boolean wasCached = app.cached; 17605 17606 mAdjSeq++; 17607 17608 // This is the desired cached adjusment we want to tell it to use. 17609 // If our app is currently cached, we know it, and that is it. Otherwise, 17610 // we don't know it yet, and it needs to now be cached we will then 17611 // need to do a complete oom adj. 17612 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17613 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17614 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17615 SystemClock.uptimeMillis()); 17616 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17617 // Changed to/from cached state, so apps after it in the LRU 17618 // list may also be changed. 17619 updateOomAdjLocked(); 17620 } 17621 return success; 17622 } 17623 17624 final void updateOomAdjLocked() { 17625 final ActivityRecord TOP_ACT = resumedAppLocked(); 17626 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17627 final long now = SystemClock.uptimeMillis(); 17628 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17629 final int N = mLruProcesses.size(); 17630 17631 if (false) { 17632 RuntimeException e = new RuntimeException(); 17633 e.fillInStackTrace(); 17634 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17635 } 17636 17637 mAdjSeq++; 17638 mNewNumServiceProcs = 0; 17639 mNewNumAServiceProcs = 0; 17640 17641 final int emptyProcessLimit; 17642 final int cachedProcessLimit; 17643 if (mProcessLimit <= 0) { 17644 emptyProcessLimit = cachedProcessLimit = 0; 17645 } else if (mProcessLimit == 1) { 17646 emptyProcessLimit = 1; 17647 cachedProcessLimit = 0; 17648 } else { 17649 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17650 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17651 } 17652 17653 // Let's determine how many processes we have running vs. 17654 // how many slots we have for background processes; we may want 17655 // to put multiple processes in a slot of there are enough of 17656 // them. 17657 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17658 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17659 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17660 if (numEmptyProcs > cachedProcessLimit) { 17661 // If there are more empty processes than our limit on cached 17662 // processes, then use the cached process limit for the factor. 17663 // This ensures that the really old empty processes get pushed 17664 // down to the bottom, so if we are running low on memory we will 17665 // have a better chance at keeping around more cached processes 17666 // instead of a gazillion empty processes. 17667 numEmptyProcs = cachedProcessLimit; 17668 } 17669 int emptyFactor = numEmptyProcs/numSlots; 17670 if (emptyFactor < 1) emptyFactor = 1; 17671 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17672 if (cachedFactor < 1) cachedFactor = 1; 17673 int stepCached = 0; 17674 int stepEmpty = 0; 17675 int numCached = 0; 17676 int numEmpty = 0; 17677 int numTrimming = 0; 17678 17679 mNumNonCachedProcs = 0; 17680 mNumCachedHiddenProcs = 0; 17681 17682 // First update the OOM adjustment for each of the 17683 // application processes based on their current state. 17684 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17685 int nextCachedAdj = curCachedAdj+1; 17686 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17687 int nextEmptyAdj = curEmptyAdj+2; 17688 for (int i=N-1; i>=0; i--) { 17689 ProcessRecord app = mLruProcesses.get(i); 17690 if (!app.killedByAm && app.thread != null) { 17691 app.procStateChanged = false; 17692 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17693 17694 // If we haven't yet assigned the final cached adj 17695 // to the process, do that now. 17696 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17697 switch (app.curProcState) { 17698 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17699 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17700 // This process is a cached process holding activities... 17701 // assign it the next cached value for that type, and then 17702 // step that cached level. 17703 app.curRawAdj = curCachedAdj; 17704 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17705 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17706 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17707 + ")"); 17708 if (curCachedAdj != nextCachedAdj) { 17709 stepCached++; 17710 if (stepCached >= cachedFactor) { 17711 stepCached = 0; 17712 curCachedAdj = nextCachedAdj; 17713 nextCachedAdj += 2; 17714 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17715 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17716 } 17717 } 17718 } 17719 break; 17720 default: 17721 // For everything else, assign next empty cached process 17722 // level and bump that up. Note that this means that 17723 // long-running services that have dropped down to the 17724 // cached level will be treated as empty (since their process 17725 // state is still as a service), which is what we want. 17726 app.curRawAdj = curEmptyAdj; 17727 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17728 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17729 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17730 + ")"); 17731 if (curEmptyAdj != nextEmptyAdj) { 17732 stepEmpty++; 17733 if (stepEmpty >= emptyFactor) { 17734 stepEmpty = 0; 17735 curEmptyAdj = nextEmptyAdj; 17736 nextEmptyAdj += 2; 17737 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17738 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17739 } 17740 } 17741 } 17742 break; 17743 } 17744 } 17745 17746 applyOomAdjLocked(app, TOP_APP, true, now); 17747 17748 // Count the number of process types. 17749 switch (app.curProcState) { 17750 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17751 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17752 mNumCachedHiddenProcs++; 17753 numCached++; 17754 if (numCached > cachedProcessLimit) { 17755 app.kill("cached #" + numCached, true); 17756 } 17757 break; 17758 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17759 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17760 && app.lastActivityTime < oldTime) { 17761 app.kill("empty for " 17762 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17763 / 1000) + "s", true); 17764 } else { 17765 numEmpty++; 17766 if (numEmpty > emptyProcessLimit) { 17767 app.kill("empty #" + numEmpty, true); 17768 } 17769 } 17770 break; 17771 default: 17772 mNumNonCachedProcs++; 17773 break; 17774 } 17775 17776 if (app.isolated && app.services.size() <= 0) { 17777 // If this is an isolated process, and there are no 17778 // services running in it, then the process is no longer 17779 // needed. We agressively kill these because we can by 17780 // definition not re-use the same process again, and it is 17781 // good to avoid having whatever code was running in them 17782 // left sitting around after no longer needed. 17783 app.kill("isolated not needed", true); 17784 } 17785 17786 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17787 && !app.killedByAm) { 17788 numTrimming++; 17789 } 17790 } 17791 } 17792 17793 mNumServiceProcs = mNewNumServiceProcs; 17794 17795 // Now determine the memory trimming level of background processes. 17796 // Unfortunately we need to start at the back of the list to do this 17797 // properly. We only do this if the number of background apps we 17798 // are managing to keep around is less than half the maximum we desire; 17799 // if we are keeping a good number around, we'll let them use whatever 17800 // memory they want. 17801 final int numCachedAndEmpty = numCached + numEmpty; 17802 int memFactor; 17803 if (numCached <= ProcessList.TRIM_CACHED_APPS 17804 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17805 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17806 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17807 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17808 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17809 } else { 17810 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17811 } 17812 } else { 17813 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17814 } 17815 // We always allow the memory level to go up (better). We only allow it to go 17816 // down if we are in a state where that is allowed, *and* the total number of processes 17817 // has gone down since last time. 17818 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17819 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17820 + " last=" + mLastNumProcesses); 17821 if (memFactor > mLastMemoryLevel) { 17822 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17823 memFactor = mLastMemoryLevel; 17824 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17825 } 17826 } 17827 mLastMemoryLevel = memFactor; 17828 mLastNumProcesses = mLruProcesses.size(); 17829 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17830 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17831 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17832 if (mLowRamStartTime == 0) { 17833 mLowRamStartTime = now; 17834 } 17835 int step = 0; 17836 int fgTrimLevel; 17837 switch (memFactor) { 17838 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17839 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17840 break; 17841 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17842 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17843 break; 17844 default: 17845 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17846 break; 17847 } 17848 int factor = numTrimming/3; 17849 int minFactor = 2; 17850 if (mHomeProcess != null) minFactor++; 17851 if (mPreviousProcess != null) minFactor++; 17852 if (factor < minFactor) factor = minFactor; 17853 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17854 for (int i=N-1; i>=0; i--) { 17855 ProcessRecord app = mLruProcesses.get(i); 17856 if (allChanged || app.procStateChanged) { 17857 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17858 app.procStateChanged = false; 17859 } 17860 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17861 && !app.killedByAm) { 17862 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17863 try { 17864 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17865 "Trimming memory of " + app.processName 17866 + " to " + curLevel); 17867 app.thread.scheduleTrimMemory(curLevel); 17868 } catch (RemoteException e) { 17869 } 17870 if (false) { 17871 // For now we won't do this; our memory trimming seems 17872 // to be good enough at this point that destroying 17873 // activities causes more harm than good. 17874 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17875 && app != mHomeProcess && app != mPreviousProcess) { 17876 // Need to do this on its own message because the stack may not 17877 // be in a consistent state at this point. 17878 // For these apps we will also finish their activities 17879 // to help them free memory. 17880 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17881 } 17882 } 17883 } 17884 app.trimMemoryLevel = curLevel; 17885 step++; 17886 if (step >= factor) { 17887 step = 0; 17888 switch (curLevel) { 17889 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17890 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17891 break; 17892 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17893 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17894 break; 17895 } 17896 } 17897 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17898 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17899 && app.thread != null) { 17900 try { 17901 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17902 "Trimming memory of heavy-weight " + app.processName 17903 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17904 app.thread.scheduleTrimMemory( 17905 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17906 } catch (RemoteException e) { 17907 } 17908 } 17909 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17910 } else { 17911 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17912 || app.systemNoUi) && app.pendingUiClean) { 17913 // If this application is now in the background and it 17914 // had done UI, then give it the special trim level to 17915 // have it free UI resources. 17916 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17917 if (app.trimMemoryLevel < level && app.thread != null) { 17918 try { 17919 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17920 "Trimming memory of bg-ui " + app.processName 17921 + " to " + level); 17922 app.thread.scheduleTrimMemory(level); 17923 } catch (RemoteException e) { 17924 } 17925 } 17926 app.pendingUiClean = false; 17927 } 17928 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17929 try { 17930 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17931 "Trimming memory of fg " + app.processName 17932 + " to " + fgTrimLevel); 17933 app.thread.scheduleTrimMemory(fgTrimLevel); 17934 } catch (RemoteException e) { 17935 } 17936 } 17937 app.trimMemoryLevel = fgTrimLevel; 17938 } 17939 } 17940 } else { 17941 if (mLowRamStartTime != 0) { 17942 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17943 mLowRamStartTime = 0; 17944 } 17945 for (int i=N-1; i>=0; i--) { 17946 ProcessRecord app = mLruProcesses.get(i); 17947 if (allChanged || app.procStateChanged) { 17948 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17949 app.procStateChanged = false; 17950 } 17951 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17952 || app.systemNoUi) && app.pendingUiClean) { 17953 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17954 && app.thread != null) { 17955 try { 17956 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17957 "Trimming memory of ui hidden " + app.processName 17958 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17959 app.thread.scheduleTrimMemory( 17960 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17961 } catch (RemoteException e) { 17962 } 17963 } 17964 app.pendingUiClean = false; 17965 } 17966 app.trimMemoryLevel = 0; 17967 } 17968 } 17969 17970 if (mAlwaysFinishActivities) { 17971 // Need to do this on its own message because the stack may not 17972 // be in a consistent state at this point. 17973 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17974 } 17975 17976 if (allChanged) { 17977 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17978 } 17979 17980 if (mProcessStats.shouldWriteNowLocked(now)) { 17981 mHandler.post(new Runnable() { 17982 @Override public void run() { 17983 synchronized (ActivityManagerService.this) { 17984 mProcessStats.writeStateAsyncLocked(); 17985 } 17986 } 17987 }); 17988 } 17989 17990 if (DEBUG_OOM_ADJ) { 17991 if (false) { 17992 RuntimeException here = new RuntimeException("here"); 17993 here.fillInStackTrace(); 17994 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17995 } else { 17996 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17997 } 17998 } 17999 } 18000 18001 final void trimApplications() { 18002 synchronized (this) { 18003 int i; 18004 18005 // First remove any unused application processes whose package 18006 // has been removed. 18007 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18008 final ProcessRecord app = mRemovedProcesses.get(i); 18009 if (app.activities.size() == 0 18010 && app.curReceiver == null && app.services.size() == 0) { 18011 Slog.i( 18012 TAG, "Exiting empty application process " 18013 + app.processName + " (" 18014 + (app.thread != null ? app.thread.asBinder() : null) 18015 + ")\n"); 18016 if (app.pid > 0 && app.pid != MY_PID) { 18017 app.kill("empty", false); 18018 } else { 18019 try { 18020 app.thread.scheduleExit(); 18021 } catch (Exception e) { 18022 // Ignore exceptions. 18023 } 18024 } 18025 cleanUpApplicationRecordLocked(app, false, true, -1); 18026 mRemovedProcesses.remove(i); 18027 18028 if (app.persistent) { 18029 addAppLocked(app.info, false, null /* ABI override */); 18030 } 18031 } 18032 } 18033 18034 // Now update the oom adj for all processes. 18035 updateOomAdjLocked(); 18036 } 18037 } 18038 18039 /** This method sends the specified signal to each of the persistent apps */ 18040 public void signalPersistentProcesses(int sig) throws RemoteException { 18041 if (sig != Process.SIGNAL_USR1) { 18042 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18043 } 18044 18045 synchronized (this) { 18046 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18047 != PackageManager.PERMISSION_GRANTED) { 18048 throw new SecurityException("Requires permission " 18049 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18050 } 18051 18052 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18053 ProcessRecord r = mLruProcesses.get(i); 18054 if (r.thread != null && r.persistent) { 18055 Process.sendSignal(r.pid, sig); 18056 } 18057 } 18058 } 18059 } 18060 18061 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18062 if (proc == null || proc == mProfileProc) { 18063 proc = mProfileProc; 18064 profileType = mProfileType; 18065 clearProfilerLocked(); 18066 } 18067 if (proc == null) { 18068 return; 18069 } 18070 try { 18071 proc.thread.profilerControl(false, null, profileType); 18072 } catch (RemoteException e) { 18073 throw new IllegalStateException("Process disappeared"); 18074 } 18075 } 18076 18077 private void clearProfilerLocked() { 18078 if (mProfileFd != null) { 18079 try { 18080 mProfileFd.close(); 18081 } catch (IOException e) { 18082 } 18083 } 18084 mProfileApp = null; 18085 mProfileProc = null; 18086 mProfileFile = null; 18087 mProfileType = 0; 18088 mAutoStopProfiler = false; 18089 mSamplingInterval = 0; 18090 } 18091 18092 public boolean profileControl(String process, int userId, boolean start, 18093 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18094 18095 try { 18096 synchronized (this) { 18097 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18098 // its own permission. 18099 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18100 != PackageManager.PERMISSION_GRANTED) { 18101 throw new SecurityException("Requires permission " 18102 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18103 } 18104 18105 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18106 throw new IllegalArgumentException("null profile info or fd"); 18107 } 18108 18109 ProcessRecord proc = null; 18110 if (process != null) { 18111 proc = findProcessLocked(process, userId, "profileControl"); 18112 } 18113 18114 if (start && (proc == null || proc.thread == null)) { 18115 throw new IllegalArgumentException("Unknown process: " + process); 18116 } 18117 18118 if (start) { 18119 stopProfilerLocked(null, 0); 18120 setProfileApp(proc.info, proc.processName, profilerInfo); 18121 mProfileProc = proc; 18122 mProfileType = profileType; 18123 ParcelFileDescriptor fd = profilerInfo.profileFd; 18124 try { 18125 fd = fd.dup(); 18126 } catch (IOException e) { 18127 fd = null; 18128 } 18129 profilerInfo.profileFd = fd; 18130 proc.thread.profilerControl(start, profilerInfo, profileType); 18131 fd = null; 18132 mProfileFd = null; 18133 } else { 18134 stopProfilerLocked(proc, profileType); 18135 if (profilerInfo != null && profilerInfo.profileFd != null) { 18136 try { 18137 profilerInfo.profileFd.close(); 18138 } catch (IOException e) { 18139 } 18140 } 18141 } 18142 18143 return true; 18144 } 18145 } catch (RemoteException e) { 18146 throw new IllegalStateException("Process disappeared"); 18147 } finally { 18148 if (profilerInfo != null && profilerInfo.profileFd != null) { 18149 try { 18150 profilerInfo.profileFd.close(); 18151 } catch (IOException e) { 18152 } 18153 } 18154 } 18155 } 18156 18157 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18158 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18159 userId, true, ALLOW_FULL_ONLY, callName, null); 18160 ProcessRecord proc = null; 18161 try { 18162 int pid = Integer.parseInt(process); 18163 synchronized (mPidsSelfLocked) { 18164 proc = mPidsSelfLocked.get(pid); 18165 } 18166 } catch (NumberFormatException e) { 18167 } 18168 18169 if (proc == null) { 18170 ArrayMap<String, SparseArray<ProcessRecord>> all 18171 = mProcessNames.getMap(); 18172 SparseArray<ProcessRecord> procs = all.get(process); 18173 if (procs != null && procs.size() > 0) { 18174 proc = procs.valueAt(0); 18175 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18176 for (int i=1; i<procs.size(); i++) { 18177 ProcessRecord thisProc = procs.valueAt(i); 18178 if (thisProc.userId == userId) { 18179 proc = thisProc; 18180 break; 18181 } 18182 } 18183 } 18184 } 18185 } 18186 18187 return proc; 18188 } 18189 18190 public boolean dumpHeap(String process, int userId, boolean managed, 18191 String path, ParcelFileDescriptor fd) throws RemoteException { 18192 18193 try { 18194 synchronized (this) { 18195 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18196 // its own permission (same as profileControl). 18197 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18198 != PackageManager.PERMISSION_GRANTED) { 18199 throw new SecurityException("Requires permission " 18200 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18201 } 18202 18203 if (fd == null) { 18204 throw new IllegalArgumentException("null fd"); 18205 } 18206 18207 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18208 if (proc == null || proc.thread == null) { 18209 throw new IllegalArgumentException("Unknown process: " + process); 18210 } 18211 18212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18213 if (!isDebuggable) { 18214 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18215 throw new SecurityException("Process not debuggable: " + proc); 18216 } 18217 } 18218 18219 proc.thread.dumpHeap(managed, path, fd); 18220 fd = null; 18221 return true; 18222 } 18223 } catch (RemoteException e) { 18224 throw new IllegalStateException("Process disappeared"); 18225 } finally { 18226 if (fd != null) { 18227 try { 18228 fd.close(); 18229 } catch (IOException e) { 18230 } 18231 } 18232 } 18233 } 18234 18235 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18236 public void monitor() { 18237 synchronized (this) { } 18238 } 18239 18240 void onCoreSettingsChange(Bundle settings) { 18241 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18242 ProcessRecord processRecord = mLruProcesses.get(i); 18243 try { 18244 if (processRecord.thread != null) { 18245 processRecord.thread.setCoreSettings(settings); 18246 } 18247 } catch (RemoteException re) { 18248 /* ignore */ 18249 } 18250 } 18251 } 18252 18253 // Multi-user methods 18254 18255 /** 18256 * Start user, if its not already running, but don't bring it to foreground. 18257 */ 18258 @Override 18259 public boolean startUserInBackground(final int userId) { 18260 return startUser(userId, /* foreground */ false); 18261 } 18262 18263 /** 18264 * Start user, if its not already running, and bring it to foreground. 18265 */ 18266 boolean startUserInForeground(final int userId, Dialog dlg) { 18267 boolean result = startUser(userId, /* foreground */ true); 18268 dlg.dismiss(); 18269 return result; 18270 } 18271 18272 /** 18273 * Refreshes the list of users related to the current user when either a 18274 * user switch happens or when a new related user is started in the 18275 * background. 18276 */ 18277 private void updateCurrentProfileIdsLocked() { 18278 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18279 mCurrentUserId, false /* enabledOnly */); 18280 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18281 for (int i = 0; i < currentProfileIds.length; i++) { 18282 currentProfileIds[i] = profiles.get(i).id; 18283 } 18284 mCurrentProfileIds = currentProfileIds; 18285 18286 synchronized (mUserProfileGroupIdsSelfLocked) { 18287 mUserProfileGroupIdsSelfLocked.clear(); 18288 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18289 for (int i = 0; i < users.size(); i++) { 18290 UserInfo user = users.get(i); 18291 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18292 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18293 } 18294 } 18295 } 18296 } 18297 18298 private Set getProfileIdsLocked(int userId) { 18299 Set userIds = new HashSet<Integer>(); 18300 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18301 userId, false /* enabledOnly */); 18302 for (UserInfo user : profiles) { 18303 userIds.add(Integer.valueOf(user.id)); 18304 } 18305 return userIds; 18306 } 18307 18308 @Override 18309 public boolean switchUser(final int userId) { 18310 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18311 String userName; 18312 synchronized (this) { 18313 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18314 if (userInfo == null) { 18315 Slog.w(TAG, "No user info for user #" + userId); 18316 return false; 18317 } 18318 if (userInfo.isManagedProfile()) { 18319 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18320 return false; 18321 } 18322 userName = userInfo.name; 18323 mTargetUserId = userId; 18324 } 18325 mHandler.removeMessages(START_USER_SWITCH_MSG); 18326 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18327 return true; 18328 } 18329 18330 private void showUserSwitchDialog(int userId, String userName) { 18331 // The dialog will show and then initiate the user switch by calling startUserInForeground 18332 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18333 true /* above system */); 18334 d.show(); 18335 } 18336 18337 private boolean startUser(final int userId, final boolean foreground) { 18338 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18339 != PackageManager.PERMISSION_GRANTED) { 18340 String msg = "Permission Denial: switchUser() from pid=" 18341 + Binder.getCallingPid() 18342 + ", uid=" + Binder.getCallingUid() 18343 + " requires " + INTERACT_ACROSS_USERS_FULL; 18344 Slog.w(TAG, msg); 18345 throw new SecurityException(msg); 18346 } 18347 18348 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18349 18350 final long ident = Binder.clearCallingIdentity(); 18351 try { 18352 synchronized (this) { 18353 final int oldUserId = mCurrentUserId; 18354 if (oldUserId == userId) { 18355 return true; 18356 } 18357 18358 mStackSupervisor.setLockTaskModeLocked(null, false); 18359 18360 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18361 if (userInfo == null) { 18362 Slog.w(TAG, "No user info for user #" + userId); 18363 return false; 18364 } 18365 if (foreground && userInfo.isManagedProfile()) { 18366 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18367 return false; 18368 } 18369 18370 if (foreground) { 18371 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18372 R.anim.screen_user_enter); 18373 } 18374 18375 boolean needStart = false; 18376 18377 // If the user we are switching to is not currently started, then 18378 // we need to start it now. 18379 if (mStartedUsers.get(userId) == null) { 18380 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18381 updateStartedUserArrayLocked(); 18382 needStart = true; 18383 } 18384 18385 final Integer userIdInt = Integer.valueOf(userId); 18386 mUserLru.remove(userIdInt); 18387 mUserLru.add(userIdInt); 18388 18389 if (foreground) { 18390 mCurrentUserId = userId; 18391 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18392 updateCurrentProfileIdsLocked(); 18393 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18394 // Once the internal notion of the active user has switched, we lock the device 18395 // with the option to show the user switcher on the keyguard. 18396 mWindowManager.lockNow(null); 18397 } else { 18398 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18399 updateCurrentProfileIdsLocked(); 18400 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18401 mUserLru.remove(currentUserIdInt); 18402 mUserLru.add(currentUserIdInt); 18403 } 18404 18405 final UserStartedState uss = mStartedUsers.get(userId); 18406 18407 // Make sure user is in the started state. If it is currently 18408 // stopping, we need to knock that off. 18409 if (uss.mState == UserStartedState.STATE_STOPPING) { 18410 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18411 // so we can just fairly silently bring the user back from 18412 // the almost-dead. 18413 uss.mState = UserStartedState.STATE_RUNNING; 18414 updateStartedUserArrayLocked(); 18415 needStart = true; 18416 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18417 // This means ACTION_SHUTDOWN has been sent, so we will 18418 // need to treat this as a new boot of the user. 18419 uss.mState = UserStartedState.STATE_BOOTING; 18420 updateStartedUserArrayLocked(); 18421 needStart = true; 18422 } 18423 18424 if (uss.mState == UserStartedState.STATE_BOOTING) { 18425 // Booting up a new user, need to tell system services about it. 18426 // Note that this is on the same handler as scheduling of broadcasts, 18427 // which is important because it needs to go first. 18428 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18429 } 18430 18431 if (foreground) { 18432 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18433 oldUserId)); 18434 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18435 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18436 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18437 oldUserId, userId, uss)); 18438 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18439 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18440 } 18441 18442 if (needStart) { 18443 // Send USER_STARTED broadcast 18444 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18445 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18446 | Intent.FLAG_RECEIVER_FOREGROUND); 18447 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18448 broadcastIntentLocked(null, null, intent, 18449 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18450 false, false, MY_PID, Process.SYSTEM_UID, userId); 18451 } 18452 18453 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18454 if (userId != UserHandle.USER_OWNER) { 18455 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18456 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18457 broadcastIntentLocked(null, null, intent, null, 18458 new IIntentReceiver.Stub() { 18459 public void performReceive(Intent intent, int resultCode, 18460 String data, Bundle extras, boolean ordered, 18461 boolean sticky, int sendingUser) { 18462 onUserInitialized(uss, foreground, oldUserId, userId); 18463 } 18464 }, 0, null, null, null, AppOpsManager.OP_NONE, 18465 true, false, MY_PID, Process.SYSTEM_UID, 18466 userId); 18467 uss.initializing = true; 18468 } else { 18469 getUserManagerLocked().makeInitialized(userInfo.id); 18470 } 18471 } 18472 18473 if (foreground) { 18474 if (!uss.initializing) { 18475 moveUserToForeground(uss, oldUserId, userId); 18476 } 18477 } else { 18478 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18479 } 18480 18481 if (needStart) { 18482 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18483 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18484 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18485 broadcastIntentLocked(null, null, intent, 18486 null, new IIntentReceiver.Stub() { 18487 @Override 18488 public void performReceive(Intent intent, int resultCode, String data, 18489 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18490 throws RemoteException { 18491 } 18492 }, 0, null, null, 18493 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18494 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18495 } 18496 } 18497 } finally { 18498 Binder.restoreCallingIdentity(ident); 18499 } 18500 18501 return true; 18502 } 18503 18504 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18505 long ident = Binder.clearCallingIdentity(); 18506 try { 18507 Intent intent; 18508 if (oldUserId >= 0) { 18509 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18510 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18511 int count = profiles.size(); 18512 for (int i = 0; i < count; i++) { 18513 int profileUserId = profiles.get(i).id; 18514 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18515 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18516 | Intent.FLAG_RECEIVER_FOREGROUND); 18517 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18518 broadcastIntentLocked(null, null, intent, 18519 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18520 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18521 } 18522 } 18523 if (newUserId >= 0) { 18524 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18525 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18526 int count = profiles.size(); 18527 for (int i = 0; i < count; i++) { 18528 int profileUserId = profiles.get(i).id; 18529 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18530 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18531 | Intent.FLAG_RECEIVER_FOREGROUND); 18532 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18533 broadcastIntentLocked(null, null, intent, 18534 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18535 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18536 } 18537 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18538 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18539 | Intent.FLAG_RECEIVER_FOREGROUND); 18540 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18541 broadcastIntentLocked(null, null, intent, 18542 null, null, 0, null, null, 18543 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18544 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18545 } 18546 } finally { 18547 Binder.restoreCallingIdentity(ident); 18548 } 18549 } 18550 18551 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18552 final int newUserId) { 18553 final int N = mUserSwitchObservers.beginBroadcast(); 18554 if (N > 0) { 18555 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18556 int mCount = 0; 18557 @Override 18558 public void sendResult(Bundle data) throws RemoteException { 18559 synchronized (ActivityManagerService.this) { 18560 if (mCurUserSwitchCallback == this) { 18561 mCount++; 18562 if (mCount == N) { 18563 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18564 } 18565 } 18566 } 18567 } 18568 }; 18569 synchronized (this) { 18570 uss.switching = true; 18571 mCurUserSwitchCallback = callback; 18572 } 18573 for (int i=0; i<N; i++) { 18574 try { 18575 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18576 newUserId, callback); 18577 } catch (RemoteException e) { 18578 } 18579 } 18580 } else { 18581 synchronized (this) { 18582 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18583 } 18584 } 18585 mUserSwitchObservers.finishBroadcast(); 18586 } 18587 18588 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18589 synchronized (this) { 18590 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18591 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18592 } 18593 } 18594 18595 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18596 mCurUserSwitchCallback = null; 18597 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18598 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18599 oldUserId, newUserId, uss)); 18600 } 18601 18602 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18603 synchronized (this) { 18604 if (foreground) { 18605 moveUserToForeground(uss, oldUserId, newUserId); 18606 } 18607 } 18608 18609 completeSwitchAndInitalize(uss, newUserId, true, false); 18610 } 18611 18612 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18613 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18614 if (homeInFront) { 18615 startHomeActivityLocked(newUserId); 18616 } else { 18617 mStackSupervisor.resumeTopActivitiesLocked(); 18618 } 18619 EventLogTags.writeAmSwitchUser(newUserId); 18620 getUserManagerLocked().userForeground(newUserId); 18621 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18622 } 18623 18624 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18625 completeSwitchAndInitalize(uss, newUserId, false, true); 18626 } 18627 18628 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18629 boolean clearInitializing, boolean clearSwitching) { 18630 boolean unfrozen = false; 18631 synchronized (this) { 18632 if (clearInitializing) { 18633 uss.initializing = false; 18634 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18635 } 18636 if (clearSwitching) { 18637 uss.switching = false; 18638 } 18639 if (!uss.switching && !uss.initializing) { 18640 mWindowManager.stopFreezingScreen(); 18641 unfrozen = true; 18642 } 18643 } 18644 if (unfrozen) { 18645 final int N = mUserSwitchObservers.beginBroadcast(); 18646 for (int i=0; i<N; i++) { 18647 try { 18648 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18649 } catch (RemoteException e) { 18650 } 18651 } 18652 mUserSwitchObservers.finishBroadcast(); 18653 } 18654 } 18655 18656 void scheduleStartProfilesLocked() { 18657 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18658 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18659 DateUtils.SECOND_IN_MILLIS); 18660 } 18661 } 18662 18663 void startProfilesLocked() { 18664 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18665 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18666 mCurrentUserId, false /* enabledOnly */); 18667 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18668 for (UserInfo user : profiles) { 18669 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18670 && user.id != mCurrentUserId) { 18671 toStart.add(user); 18672 } 18673 } 18674 final int n = toStart.size(); 18675 int i = 0; 18676 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18677 startUserInBackground(toStart.get(i).id); 18678 } 18679 if (i < n) { 18680 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18681 } 18682 } 18683 18684 void finishUserBoot(UserStartedState uss) { 18685 synchronized (this) { 18686 if (uss.mState == UserStartedState.STATE_BOOTING 18687 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18688 uss.mState = UserStartedState.STATE_RUNNING; 18689 final int userId = uss.mHandle.getIdentifier(); 18690 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18691 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18692 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18693 broadcastIntentLocked(null, null, intent, 18694 null, null, 0, null, null, 18695 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18696 true, false, MY_PID, Process.SYSTEM_UID, userId); 18697 } 18698 } 18699 } 18700 18701 void finishUserSwitch(UserStartedState uss) { 18702 synchronized (this) { 18703 finishUserBoot(uss); 18704 18705 startProfilesLocked(); 18706 18707 int num = mUserLru.size(); 18708 int i = 0; 18709 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18710 Integer oldUserId = mUserLru.get(i); 18711 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18712 if (oldUss == null) { 18713 // Shouldn't happen, but be sane if it does. 18714 mUserLru.remove(i); 18715 num--; 18716 continue; 18717 } 18718 if (oldUss.mState == UserStartedState.STATE_STOPPING 18719 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18720 // This user is already stopping, doesn't count. 18721 num--; 18722 i++; 18723 continue; 18724 } 18725 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18726 // Owner and current can't be stopped, but count as running. 18727 i++; 18728 continue; 18729 } 18730 // This is a user to be stopped. 18731 stopUserLocked(oldUserId, null); 18732 num--; 18733 i++; 18734 } 18735 } 18736 } 18737 18738 @Override 18739 public int stopUser(final int userId, final IStopUserCallback callback) { 18740 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18741 != PackageManager.PERMISSION_GRANTED) { 18742 String msg = "Permission Denial: switchUser() from pid=" 18743 + Binder.getCallingPid() 18744 + ", uid=" + Binder.getCallingUid() 18745 + " requires " + INTERACT_ACROSS_USERS_FULL; 18746 Slog.w(TAG, msg); 18747 throw new SecurityException(msg); 18748 } 18749 if (userId <= 0) { 18750 throw new IllegalArgumentException("Can't stop primary user " + userId); 18751 } 18752 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18753 synchronized (this) { 18754 return stopUserLocked(userId, callback); 18755 } 18756 } 18757 18758 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18759 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18760 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18761 return ActivityManager.USER_OP_IS_CURRENT; 18762 } 18763 18764 final UserStartedState uss = mStartedUsers.get(userId); 18765 if (uss == null) { 18766 // User is not started, nothing to do... but we do need to 18767 // callback if requested. 18768 if (callback != null) { 18769 mHandler.post(new Runnable() { 18770 @Override 18771 public void run() { 18772 try { 18773 callback.userStopped(userId); 18774 } catch (RemoteException e) { 18775 } 18776 } 18777 }); 18778 } 18779 return ActivityManager.USER_OP_SUCCESS; 18780 } 18781 18782 if (callback != null) { 18783 uss.mStopCallbacks.add(callback); 18784 } 18785 18786 if (uss.mState != UserStartedState.STATE_STOPPING 18787 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18788 uss.mState = UserStartedState.STATE_STOPPING; 18789 updateStartedUserArrayLocked(); 18790 18791 long ident = Binder.clearCallingIdentity(); 18792 try { 18793 // We are going to broadcast ACTION_USER_STOPPING and then 18794 // once that is done send a final ACTION_SHUTDOWN and then 18795 // stop the user. 18796 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18797 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18798 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18799 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18800 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18801 // This is the result receiver for the final shutdown broadcast. 18802 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18803 @Override 18804 public void performReceive(Intent intent, int resultCode, String data, 18805 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18806 finishUserStop(uss); 18807 } 18808 }; 18809 // This is the result receiver for the initial stopping broadcast. 18810 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18811 @Override 18812 public void performReceive(Intent intent, int resultCode, String data, 18813 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18814 // On to the next. 18815 synchronized (ActivityManagerService.this) { 18816 if (uss.mState != UserStartedState.STATE_STOPPING) { 18817 // Whoops, we are being started back up. Abort, abort! 18818 return; 18819 } 18820 uss.mState = UserStartedState.STATE_SHUTDOWN; 18821 } 18822 mBatteryStatsService.noteEvent( 18823 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18824 Integer.toString(userId), userId); 18825 mSystemServiceManager.stopUser(userId); 18826 broadcastIntentLocked(null, null, shutdownIntent, 18827 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18828 true, false, MY_PID, Process.SYSTEM_UID, userId); 18829 } 18830 }; 18831 // Kick things off. 18832 broadcastIntentLocked(null, null, stoppingIntent, 18833 null, stoppingReceiver, 0, null, null, 18834 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18835 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18836 } finally { 18837 Binder.restoreCallingIdentity(ident); 18838 } 18839 } 18840 18841 return ActivityManager.USER_OP_SUCCESS; 18842 } 18843 18844 void finishUserStop(UserStartedState uss) { 18845 final int userId = uss.mHandle.getIdentifier(); 18846 boolean stopped; 18847 ArrayList<IStopUserCallback> callbacks; 18848 synchronized (this) { 18849 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18850 if (mStartedUsers.get(userId) != uss) { 18851 stopped = false; 18852 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18853 stopped = false; 18854 } else { 18855 stopped = true; 18856 // User can no longer run. 18857 mStartedUsers.remove(userId); 18858 mUserLru.remove(Integer.valueOf(userId)); 18859 updateStartedUserArrayLocked(); 18860 18861 // Clean up all state and processes associated with the user. 18862 // Kill all the processes for the user. 18863 forceStopUserLocked(userId, "finish user"); 18864 } 18865 18866 // Explicitly remove the old information in mRecentTasks. 18867 removeRecentTasksForUserLocked(userId); 18868 } 18869 18870 for (int i=0; i<callbacks.size(); i++) { 18871 try { 18872 if (stopped) callbacks.get(i).userStopped(userId); 18873 else callbacks.get(i).userStopAborted(userId); 18874 } catch (RemoteException e) { 18875 } 18876 } 18877 18878 if (stopped) { 18879 mSystemServiceManager.cleanupUser(userId); 18880 synchronized (this) { 18881 mStackSupervisor.removeUserLocked(userId); 18882 } 18883 } 18884 } 18885 18886 @Override 18887 public UserInfo getCurrentUser() { 18888 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18889 != PackageManager.PERMISSION_GRANTED) && ( 18890 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18891 != PackageManager.PERMISSION_GRANTED)) { 18892 String msg = "Permission Denial: getCurrentUser() from pid=" 18893 + Binder.getCallingPid() 18894 + ", uid=" + Binder.getCallingUid() 18895 + " requires " + INTERACT_ACROSS_USERS; 18896 Slog.w(TAG, msg); 18897 throw new SecurityException(msg); 18898 } 18899 synchronized (this) { 18900 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18901 return getUserManagerLocked().getUserInfo(userId); 18902 } 18903 } 18904 18905 int getCurrentUserIdLocked() { 18906 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18907 } 18908 18909 @Override 18910 public boolean isUserRunning(int userId, boolean orStopped) { 18911 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18912 != PackageManager.PERMISSION_GRANTED) { 18913 String msg = "Permission Denial: isUserRunning() from pid=" 18914 + Binder.getCallingPid() 18915 + ", uid=" + Binder.getCallingUid() 18916 + " requires " + INTERACT_ACROSS_USERS; 18917 Slog.w(TAG, msg); 18918 throw new SecurityException(msg); 18919 } 18920 synchronized (this) { 18921 return isUserRunningLocked(userId, orStopped); 18922 } 18923 } 18924 18925 boolean isUserRunningLocked(int userId, boolean orStopped) { 18926 UserStartedState state = mStartedUsers.get(userId); 18927 if (state == null) { 18928 return false; 18929 } 18930 if (orStopped) { 18931 return true; 18932 } 18933 return state.mState != UserStartedState.STATE_STOPPING 18934 && state.mState != UserStartedState.STATE_SHUTDOWN; 18935 } 18936 18937 @Override 18938 public int[] getRunningUserIds() { 18939 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18940 != PackageManager.PERMISSION_GRANTED) { 18941 String msg = "Permission Denial: isUserRunning() from pid=" 18942 + Binder.getCallingPid() 18943 + ", uid=" + Binder.getCallingUid() 18944 + " requires " + INTERACT_ACROSS_USERS; 18945 Slog.w(TAG, msg); 18946 throw new SecurityException(msg); 18947 } 18948 synchronized (this) { 18949 return mStartedUserArray; 18950 } 18951 } 18952 18953 private void updateStartedUserArrayLocked() { 18954 int num = 0; 18955 for (int i=0; i<mStartedUsers.size(); i++) { 18956 UserStartedState uss = mStartedUsers.valueAt(i); 18957 // This list does not include stopping users. 18958 if (uss.mState != UserStartedState.STATE_STOPPING 18959 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18960 num++; 18961 } 18962 } 18963 mStartedUserArray = new int[num]; 18964 num = 0; 18965 for (int i=0; i<mStartedUsers.size(); i++) { 18966 UserStartedState uss = mStartedUsers.valueAt(i); 18967 if (uss.mState != UserStartedState.STATE_STOPPING 18968 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18969 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18970 num++; 18971 } 18972 } 18973 } 18974 18975 @Override 18976 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18977 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18978 != PackageManager.PERMISSION_GRANTED) { 18979 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18980 + Binder.getCallingPid() 18981 + ", uid=" + Binder.getCallingUid() 18982 + " requires " + INTERACT_ACROSS_USERS_FULL; 18983 Slog.w(TAG, msg); 18984 throw new SecurityException(msg); 18985 } 18986 18987 mUserSwitchObservers.register(observer); 18988 } 18989 18990 @Override 18991 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18992 mUserSwitchObservers.unregister(observer); 18993 } 18994 18995 private boolean userExists(int userId) { 18996 if (userId == 0) { 18997 return true; 18998 } 18999 UserManagerService ums = getUserManagerLocked(); 19000 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19001 } 19002 19003 int[] getUsersLocked() { 19004 UserManagerService ums = getUserManagerLocked(); 19005 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19006 } 19007 19008 UserManagerService getUserManagerLocked() { 19009 if (mUserManager == null) { 19010 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19011 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19012 } 19013 return mUserManager; 19014 } 19015 19016 private int applyUserId(int uid, int userId) { 19017 return UserHandle.getUid(userId, uid); 19018 } 19019 19020 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19021 if (info == null) return null; 19022 ApplicationInfo newInfo = new ApplicationInfo(info); 19023 newInfo.uid = applyUserId(info.uid, userId); 19024 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19025 + info.packageName; 19026 return newInfo; 19027 } 19028 19029 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19030 if (aInfo == null 19031 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19032 return aInfo; 19033 } 19034 19035 ActivityInfo info = new ActivityInfo(aInfo); 19036 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19037 return info; 19038 } 19039 19040 private final class LocalService extends ActivityManagerInternal { 19041 @Override 19042 public void goingToSleep() { 19043 ActivityManagerService.this.goingToSleep(); 19044 } 19045 19046 @Override 19047 public void wakingUp() { 19048 ActivityManagerService.this.wakingUp(); 19049 } 19050 19051 @Override 19052 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19053 String processName, String abiOverride, int uid, Runnable crashHandler) { 19054 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19055 processName, abiOverride, uid, crashHandler); 19056 } 19057 } 19058 19059 /** 19060 * An implementation of IAppTask, that allows an app to manage its own tasks via 19061 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19062 * only the process that calls getAppTasks() can call the AppTask methods. 19063 */ 19064 class AppTaskImpl extends IAppTask.Stub { 19065 private int mTaskId; 19066 private int mCallingUid; 19067 19068 public AppTaskImpl(int taskId, int callingUid) { 19069 mTaskId = taskId; 19070 mCallingUid = callingUid; 19071 } 19072 19073 private void checkCaller() { 19074 if (mCallingUid != Binder.getCallingUid()) { 19075 throw new SecurityException("Caller " + mCallingUid 19076 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19077 } 19078 } 19079 19080 @Override 19081 public void finishAndRemoveTask() { 19082 checkCaller(); 19083 19084 synchronized (ActivityManagerService.this) { 19085 long origId = Binder.clearCallingIdentity(); 19086 try { 19087 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19088 if (tr == null) { 19089 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19090 } 19091 // Only kill the process if we are not a new document 19092 int flags = tr.getBaseIntent().getFlags(); 19093 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19094 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19095 removeTaskByIdLocked(mTaskId, 19096 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19097 } finally { 19098 Binder.restoreCallingIdentity(origId); 19099 } 19100 } 19101 } 19102 19103 @Override 19104 public ActivityManager.RecentTaskInfo getTaskInfo() { 19105 checkCaller(); 19106 19107 synchronized (ActivityManagerService.this) { 19108 long origId = Binder.clearCallingIdentity(); 19109 try { 19110 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19111 if (tr == null) { 19112 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19113 } 19114 return createRecentTaskInfoFromTaskRecord(tr); 19115 } finally { 19116 Binder.restoreCallingIdentity(origId); 19117 } 19118 } 19119 } 19120 19121 @Override 19122 public void moveToFront() { 19123 checkCaller(); 19124 19125 final TaskRecord tr; 19126 synchronized (ActivityManagerService.this) { 19127 tr = recentTaskForIdLocked(mTaskId); 19128 if (tr == null) { 19129 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19130 } 19131 if (tr.getRootActivity() != null) { 19132 moveTaskToFrontLocked(tr.taskId, 0, null); 19133 return; 19134 } 19135 } 19136 19137 startActivityFromRecentsInner(tr.taskId, null); 19138 } 19139 19140 @Override 19141 public int startActivity(IBinder whoThread, String callingPackage, 19142 Intent intent, String resolvedType, Bundle options) { 19143 checkCaller(); 19144 19145 int callingUser = UserHandle.getCallingUserId(); 19146 TaskRecord tr; 19147 IApplicationThread appThread; 19148 synchronized (ActivityManagerService.this) { 19149 tr = recentTaskForIdLocked(mTaskId); 19150 if (tr == null) { 19151 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19152 } 19153 appThread = ApplicationThreadNative.asInterface(whoThread); 19154 if (appThread == null) { 19155 throw new IllegalArgumentException("Bad app thread " + appThread); 19156 } 19157 } 19158 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19159 resolvedType, null, null, null, null, 0, 0, null, null, 19160 null, options, callingUser, null, tr); 19161 } 19162 19163 @Override 19164 public void setExcludeFromRecents(boolean exclude) { 19165 checkCaller(); 19166 19167 synchronized (ActivityManagerService.this) { 19168 long origId = Binder.clearCallingIdentity(); 19169 try { 19170 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19171 if (tr == null) { 19172 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19173 } 19174 Intent intent = tr.getBaseIntent(); 19175 if (exclude) { 19176 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19177 } else { 19178 intent.setFlags(intent.getFlags() 19179 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19180 } 19181 } finally { 19182 Binder.restoreCallingIdentity(origId); 19183 } 19184 } 19185 } 19186 } 19187} 19188