ActivityManagerService.java revision ab4a81b3c625e33d04ae8070fcce6b6baee6522c
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_BUFFERS]).append(" kB buffers, "); 1738 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1739 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1740 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1741 logBuilder.append(" ZRAM: "); 1742 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1743 logBuilder.append(" kB RAM, "); 1744 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1745 logBuilder.append(" kB swap total, "); 1746 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1747 logBuilder.append(" kB swap free\n"); 1748 } 1749 Slog.i(TAG, logBuilder.toString()); 1750 1751 StringBuilder dropBuilder = new StringBuilder(1024); 1752 /* 1753 StringWriter oomSw = new StringWriter(); 1754 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1755 StringWriter catSw = new StringWriter(); 1756 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1757 String[] emptyArgs = new String[] { }; 1758 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1759 oomPw.flush(); 1760 String oomString = oomSw.toString(); 1761 */ 1762 dropBuilder.append(stack); 1763 dropBuilder.append('\n'); 1764 dropBuilder.append('\n'); 1765 dropBuilder.append(logBuilder); 1766 dropBuilder.append('\n'); 1767 /* 1768 dropBuilder.append(oomString); 1769 dropBuilder.append('\n'); 1770 */ 1771 StringWriter catSw = new StringWriter(); 1772 synchronized (ActivityManagerService.this) { 1773 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1774 String[] emptyArgs = new String[] { }; 1775 catPw.println(); 1776 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1777 catPw.println(); 1778 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1779 false, false, null); 1780 catPw.println(); 1781 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1782 catPw.flush(); 1783 } 1784 dropBuilder.append(catSw.toString()); 1785 addErrorToDropBox("lowmem", null, "system_server", null, 1786 null, tag.toString(), dropBuilder.toString(), null, null); 1787 //Slog.i(TAG, "Sent to dropbox:"); 1788 //Slog.i(TAG, dropBuilder.toString()); 1789 synchronized (ActivityManagerService.this) { 1790 long now = SystemClock.uptimeMillis(); 1791 if (mLastMemUsageReportTime < now) { 1792 mLastMemUsageReportTime = now; 1793 } 1794 } 1795 } 1796 }; 1797 thread.start(); 1798 break; 1799 } 1800 case START_USER_SWITCH_MSG: { 1801 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1802 break; 1803 } 1804 case REPORT_USER_SWITCH_MSG: { 1805 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1806 break; 1807 } 1808 case CONTINUE_USER_SWITCH_MSG: { 1809 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1810 break; 1811 } 1812 case USER_SWITCH_TIMEOUT_MSG: { 1813 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1814 break; 1815 } 1816 case IMMERSIVE_MODE_LOCK_MSG: { 1817 final boolean nextState = (msg.arg1 != 0); 1818 if (mUpdateLock.isHeld() != nextState) { 1819 if (DEBUG_IMMERSIVE) { 1820 final ActivityRecord r = (ActivityRecord) msg.obj; 1821 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1822 } 1823 if (nextState) { 1824 mUpdateLock.acquire(); 1825 } else { 1826 mUpdateLock.release(); 1827 } 1828 } 1829 break; 1830 } 1831 case PERSIST_URI_GRANTS_MSG: { 1832 writeGrantedUriPermissions(); 1833 break; 1834 } 1835 case REQUEST_ALL_PSS_MSG: { 1836 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1837 break; 1838 } 1839 case START_PROFILES_MSG: { 1840 synchronized (ActivityManagerService.this) { 1841 startProfilesLocked(); 1842 } 1843 break; 1844 } 1845 case UPDATE_TIME: { 1846 synchronized (ActivityManagerService.this) { 1847 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1848 ProcessRecord r = mLruProcesses.get(i); 1849 if (r.thread != null) { 1850 try { 1851 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1852 } catch (RemoteException ex) { 1853 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1854 } 1855 } 1856 } 1857 } 1858 break; 1859 } 1860 case SYSTEM_USER_START_MSG: { 1861 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1862 Integer.toString(msg.arg1), msg.arg1); 1863 mSystemServiceManager.startUser(msg.arg1); 1864 break; 1865 } 1866 case SYSTEM_USER_CURRENT_MSG: { 1867 mBatteryStatsService.noteEvent( 1868 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1869 Integer.toString(msg.arg2), msg.arg2); 1870 mBatteryStatsService.noteEvent( 1871 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1872 Integer.toString(msg.arg1), msg.arg1); 1873 mSystemServiceManager.switchUser(msg.arg1); 1874 mLockToAppRequest.clearPrompt(); 1875 break; 1876 } 1877 case ENTER_ANIMATION_COMPLETE_MSG: { 1878 synchronized (ActivityManagerService.this) { 1879 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1880 if (r != null && r.app != null && r.app.thread != null) { 1881 try { 1882 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1883 } catch (RemoteException e) { 1884 } 1885 } 1886 } 1887 break; 1888 } 1889 case FINISH_BOOTING_MSG: { 1890 if (msg.arg1 != 0) { 1891 finishBooting(); 1892 } 1893 if (msg.arg2 != 0) { 1894 enableScreenAfterBoot(); 1895 } 1896 break; 1897 } 1898 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1899 try { 1900 Locale l = (Locale) msg.obj; 1901 IBinder service = ServiceManager.getService("mount"); 1902 IMountService mountService = IMountService.Stub.asInterface(service); 1903 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1904 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1905 } catch (RemoteException e) { 1906 Log.e(TAG, "Error storing locale for decryption UI", e); 1907 } 1908 break; 1909 } 1910 } 1911 } 1912 }; 1913 1914 static final int COLLECT_PSS_BG_MSG = 1; 1915 1916 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1917 @Override 1918 public void handleMessage(Message msg) { 1919 switch (msg.what) { 1920 case COLLECT_PSS_BG_MSG: { 1921 long start = SystemClock.uptimeMillis(); 1922 MemInfoReader memInfo = null; 1923 synchronized (ActivityManagerService.this) { 1924 if (mFullPssPending) { 1925 mFullPssPending = false; 1926 memInfo = new MemInfoReader(); 1927 } 1928 } 1929 if (memInfo != null) { 1930 updateCpuStatsNow(); 1931 long nativeTotalPss = 0; 1932 synchronized (mProcessCpuTracker) { 1933 final int N = mProcessCpuTracker.countStats(); 1934 for (int j=0; j<N; j++) { 1935 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1936 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1937 // This is definitely an application process; skip it. 1938 continue; 1939 } 1940 synchronized (mPidsSelfLocked) { 1941 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1942 // This is one of our own processes; skip it. 1943 continue; 1944 } 1945 } 1946 nativeTotalPss += Debug.getPss(st.pid, null); 1947 } 1948 } 1949 memInfo.readMemInfo(); 1950 synchronized (ActivityManagerService.this) { 1951 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1952 + (SystemClock.uptimeMillis()-start) + "ms"); 1953 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1954 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1955 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1956 +memInfo.getSlabSizeKb(), 1957 nativeTotalPss); 1958 } 1959 } 1960 1961 int i=0, num=0; 1962 long[] tmp = new long[1]; 1963 do { 1964 ProcessRecord proc; 1965 int procState; 1966 int pid; 1967 synchronized (ActivityManagerService.this) { 1968 if (i >= mPendingPssProcesses.size()) { 1969 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1970 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1971 mPendingPssProcesses.clear(); 1972 return; 1973 } 1974 proc = mPendingPssProcesses.get(i); 1975 procState = proc.pssProcState; 1976 if (proc.thread != null && procState == proc.setProcState) { 1977 pid = proc.pid; 1978 } else { 1979 proc = null; 1980 pid = 0; 1981 } 1982 i++; 1983 } 1984 if (proc != null) { 1985 long pss = Debug.getPss(pid, tmp); 1986 synchronized (ActivityManagerService.this) { 1987 if (proc.thread != null && proc.setProcState == procState 1988 && proc.pid == pid) { 1989 num++; 1990 proc.lastPssTime = SystemClock.uptimeMillis(); 1991 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1992 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1993 + ": " + pss + " lastPss=" + proc.lastPss 1994 + " state=" + ProcessList.makeProcStateString(procState)); 1995 if (proc.initialIdlePss == 0) { 1996 proc.initialIdlePss = pss; 1997 } 1998 proc.lastPss = pss; 1999 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2000 proc.lastCachedPss = pss; 2001 } 2002 } 2003 } 2004 } 2005 } while (true); 2006 } 2007 } 2008 } 2009 }; 2010 2011 /** 2012 * Monitor for package changes and update our internal state. 2013 */ 2014 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2015 @Override 2016 public void onPackageRemoved(String packageName, int uid) { 2017 // Remove all tasks with activities in the specified package from the list of recent tasks 2018 final int eventUserId = getChangingUserId(); 2019 synchronized (ActivityManagerService.this) { 2020 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2021 TaskRecord tr = mRecentTasks.get(i); 2022 if (tr.userId != eventUserId) continue; 2023 2024 ComponentName cn = tr.intent.getComponent(); 2025 if (cn != null && cn.getPackageName().equals(packageName)) { 2026 // If the package name matches, remove the task and kill the process 2027 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2028 } 2029 } 2030 } 2031 } 2032 2033 @Override 2034 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2035 onPackageModified(packageName); 2036 return true; 2037 } 2038 2039 @Override 2040 public void onPackageModified(String packageName) { 2041 final int eventUserId = getChangingUserId(); 2042 final IPackageManager pm = AppGlobals.getPackageManager(); 2043 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2044 new ArrayList<Pair<Intent, Integer>>(); 2045 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2046 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2047 // Copy the list of recent tasks so that we don't hold onto the lock on 2048 // ActivityManagerService for long periods while checking if components exist. 2049 synchronized (ActivityManagerService.this) { 2050 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2051 TaskRecord tr = mRecentTasks.get(i); 2052 if (tr.userId != eventUserId) continue; 2053 2054 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2055 } 2056 } 2057 // Check the recent tasks and filter out all tasks with components that no longer exist. 2058 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2059 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2060 ComponentName cn = p.first.getComponent(); 2061 if (cn != null && cn.getPackageName().equals(packageName)) { 2062 if (componentsKnownToExist.contains(cn)) { 2063 // If we know that the component still exists in the package, then skip 2064 continue; 2065 } 2066 try { 2067 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2068 if (info != null) { 2069 componentsKnownToExist.add(cn); 2070 } else { 2071 tasksToRemove.add(p.second); 2072 } 2073 } catch (RemoteException e) { 2074 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2075 } 2076 } 2077 } 2078 // Prune all the tasks with removed components from the list of recent tasks 2079 synchronized (ActivityManagerService.this) { 2080 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2081 // Remove the task but don't kill the process (since other components in that 2082 // package may still be running and in the background) 2083 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2084 } 2085 } 2086 } 2087 2088 @Override 2089 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2090 // Force stop the specified packages 2091 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2092 if (packages != null) { 2093 for (String pkg : packages) { 2094 synchronized (ActivityManagerService.this) { 2095 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2096 userId, "finished booting")) { 2097 return true; 2098 } 2099 } 2100 } 2101 } 2102 return false; 2103 } 2104 }; 2105 2106 public void setSystemProcess() { 2107 try { 2108 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2109 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2110 ServiceManager.addService("meminfo", new MemBinder(this)); 2111 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2112 ServiceManager.addService("dbinfo", new DbBinder(this)); 2113 if (MONITOR_CPU_USAGE) { 2114 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2115 } 2116 ServiceManager.addService("permission", new PermissionController(this)); 2117 2118 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2119 "android", STOCK_PM_FLAGS); 2120 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2121 2122 synchronized (this) { 2123 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2124 app.persistent = true; 2125 app.pid = MY_PID; 2126 app.maxAdj = ProcessList.SYSTEM_ADJ; 2127 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2128 mProcessNames.put(app.processName, app.uid, app); 2129 synchronized (mPidsSelfLocked) { 2130 mPidsSelfLocked.put(app.pid, app); 2131 } 2132 updateLruProcessLocked(app, false, null); 2133 updateOomAdjLocked(); 2134 } 2135 } catch (PackageManager.NameNotFoundException e) { 2136 throw new RuntimeException( 2137 "Unable to find android system package", e); 2138 } 2139 } 2140 2141 public void setWindowManager(WindowManagerService wm) { 2142 mWindowManager = wm; 2143 mStackSupervisor.setWindowManager(wm); 2144 } 2145 2146 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2147 mUsageStatsService = usageStatsManager; 2148 } 2149 2150 public void startObservingNativeCrashes() { 2151 final NativeCrashListener ncl = new NativeCrashListener(this); 2152 ncl.start(); 2153 } 2154 2155 public IAppOpsService getAppOpsService() { 2156 return mAppOpsService; 2157 } 2158 2159 static class MemBinder extends Binder { 2160 ActivityManagerService mActivityManagerService; 2161 MemBinder(ActivityManagerService activityManagerService) { 2162 mActivityManagerService = activityManagerService; 2163 } 2164 2165 @Override 2166 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2167 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2168 != PackageManager.PERMISSION_GRANTED) { 2169 pw.println("Permission Denial: can't dump meminfo from from pid=" 2170 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2171 + " without permission " + android.Manifest.permission.DUMP); 2172 return; 2173 } 2174 2175 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2176 } 2177 } 2178 2179 static class GraphicsBinder extends Binder { 2180 ActivityManagerService mActivityManagerService; 2181 GraphicsBinder(ActivityManagerService activityManagerService) { 2182 mActivityManagerService = activityManagerService; 2183 } 2184 2185 @Override 2186 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2187 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2188 != PackageManager.PERMISSION_GRANTED) { 2189 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2190 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2191 + " without permission " + android.Manifest.permission.DUMP); 2192 return; 2193 } 2194 2195 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2196 } 2197 } 2198 2199 static class DbBinder extends Binder { 2200 ActivityManagerService mActivityManagerService; 2201 DbBinder(ActivityManagerService activityManagerService) { 2202 mActivityManagerService = activityManagerService; 2203 } 2204 2205 @Override 2206 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2207 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2208 != PackageManager.PERMISSION_GRANTED) { 2209 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2210 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2211 + " without permission " + android.Manifest.permission.DUMP); 2212 return; 2213 } 2214 2215 mActivityManagerService.dumpDbInfo(fd, pw, args); 2216 } 2217 } 2218 2219 static class CpuBinder extends Binder { 2220 ActivityManagerService mActivityManagerService; 2221 CpuBinder(ActivityManagerService activityManagerService) { 2222 mActivityManagerService = activityManagerService; 2223 } 2224 2225 @Override 2226 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2227 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2228 != PackageManager.PERMISSION_GRANTED) { 2229 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2230 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2231 + " without permission " + android.Manifest.permission.DUMP); 2232 return; 2233 } 2234 2235 synchronized (mActivityManagerService.mProcessCpuTracker) { 2236 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2237 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2238 SystemClock.uptimeMillis())); 2239 } 2240 } 2241 } 2242 2243 public static final class Lifecycle extends SystemService { 2244 private final ActivityManagerService mService; 2245 2246 public Lifecycle(Context context) { 2247 super(context); 2248 mService = new ActivityManagerService(context); 2249 } 2250 2251 @Override 2252 public void onStart() { 2253 mService.start(); 2254 } 2255 2256 public ActivityManagerService getService() { 2257 return mService; 2258 } 2259 } 2260 2261 // Note: This method is invoked on the main thread but may need to attach various 2262 // handlers to other threads. So take care to be explicit about the looper. 2263 public ActivityManagerService(Context systemContext) { 2264 mContext = systemContext; 2265 mFactoryTest = FactoryTest.getMode(); 2266 mSystemThread = ActivityThread.currentActivityThread(); 2267 2268 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2269 2270 mHandlerThread = new ServiceThread(TAG, 2271 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2272 mHandlerThread.start(); 2273 mHandler = new MainHandler(mHandlerThread.getLooper()); 2274 2275 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2276 "foreground", BROADCAST_FG_TIMEOUT, false); 2277 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2278 "background", BROADCAST_BG_TIMEOUT, true); 2279 mBroadcastQueues[0] = mFgBroadcastQueue; 2280 mBroadcastQueues[1] = mBgBroadcastQueue; 2281 2282 mServices = new ActiveServices(this); 2283 mProviderMap = new ProviderMap(this); 2284 2285 // TODO: Move creation of battery stats service outside of activity manager service. 2286 File dataDir = Environment.getDataDirectory(); 2287 File systemDir = new File(dataDir, "system"); 2288 systemDir.mkdirs(); 2289 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2290 mBatteryStatsService.getActiveStatistics().readLocked(); 2291 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2292 mOnBattery = DEBUG_POWER ? true 2293 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2294 mBatteryStatsService.getActiveStatistics().setCallback(this); 2295 2296 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2297 2298 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2299 2300 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2301 2302 // User 0 is the first and only user that runs at boot. 2303 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2304 mUserLru.add(Integer.valueOf(0)); 2305 updateStartedUserArrayLocked(); 2306 2307 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2308 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2309 2310 mConfiguration.setToDefaults(); 2311 mConfiguration.setLocale(Locale.getDefault()); 2312 2313 mConfigurationSeq = mConfiguration.seq = 1; 2314 mProcessCpuTracker.init(); 2315 2316 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2317 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2318 mStackSupervisor = new ActivityStackSupervisor(this); 2319 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2320 2321 mProcessCpuThread = new Thread("CpuTracker") { 2322 @Override 2323 public void run() { 2324 while (true) { 2325 try { 2326 try { 2327 synchronized(this) { 2328 final long now = SystemClock.uptimeMillis(); 2329 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2330 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2331 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2332 // + ", write delay=" + nextWriteDelay); 2333 if (nextWriteDelay < nextCpuDelay) { 2334 nextCpuDelay = nextWriteDelay; 2335 } 2336 if (nextCpuDelay > 0) { 2337 mProcessCpuMutexFree.set(true); 2338 this.wait(nextCpuDelay); 2339 } 2340 } 2341 } catch (InterruptedException e) { 2342 } 2343 updateCpuStatsNow(); 2344 } catch (Exception e) { 2345 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2346 } 2347 } 2348 } 2349 }; 2350 2351 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2352 2353 Watchdog.getInstance().addMonitor(this); 2354 Watchdog.getInstance().addThread(mHandler); 2355 } 2356 2357 public void setSystemServiceManager(SystemServiceManager mgr) { 2358 mSystemServiceManager = mgr; 2359 } 2360 2361 private void start() { 2362 Process.removeAllProcessGroups(); 2363 mProcessCpuThread.start(); 2364 2365 mBatteryStatsService.publish(mContext); 2366 mAppOpsService.publish(mContext); 2367 Slog.d("AppOps", "AppOpsService published"); 2368 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2369 } 2370 2371 public void initPowerManagement() { 2372 mStackSupervisor.initPowerManagement(); 2373 mBatteryStatsService.initPowerManagement(); 2374 } 2375 2376 @Override 2377 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2378 throws RemoteException { 2379 if (code == SYSPROPS_TRANSACTION) { 2380 // We need to tell all apps about the system property change. 2381 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2382 synchronized(this) { 2383 final int NP = mProcessNames.getMap().size(); 2384 for (int ip=0; ip<NP; ip++) { 2385 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2386 final int NA = apps.size(); 2387 for (int ia=0; ia<NA; ia++) { 2388 ProcessRecord app = apps.valueAt(ia); 2389 if (app.thread != null) { 2390 procs.add(app.thread.asBinder()); 2391 } 2392 } 2393 } 2394 } 2395 2396 int N = procs.size(); 2397 for (int i=0; i<N; i++) { 2398 Parcel data2 = Parcel.obtain(); 2399 try { 2400 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2401 } catch (RemoteException e) { 2402 } 2403 data2.recycle(); 2404 } 2405 } 2406 try { 2407 return super.onTransact(code, data, reply, flags); 2408 } catch (RuntimeException e) { 2409 // The activity manager only throws security exceptions, so let's 2410 // log all others. 2411 if (!(e instanceof SecurityException)) { 2412 Slog.wtf(TAG, "Activity Manager Crash", e); 2413 } 2414 throw e; 2415 } 2416 } 2417 2418 void updateCpuStats() { 2419 final long now = SystemClock.uptimeMillis(); 2420 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2421 return; 2422 } 2423 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2424 synchronized (mProcessCpuThread) { 2425 mProcessCpuThread.notify(); 2426 } 2427 } 2428 } 2429 2430 void updateCpuStatsNow() { 2431 synchronized (mProcessCpuTracker) { 2432 mProcessCpuMutexFree.set(false); 2433 final long now = SystemClock.uptimeMillis(); 2434 boolean haveNewCpuStats = false; 2435 2436 if (MONITOR_CPU_USAGE && 2437 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2438 mLastCpuTime.set(now); 2439 haveNewCpuStats = true; 2440 mProcessCpuTracker.update(); 2441 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2442 //Slog.i(TAG, "Total CPU usage: " 2443 // + mProcessCpu.getTotalCpuPercent() + "%"); 2444 2445 // Slog the cpu usage if the property is set. 2446 if ("true".equals(SystemProperties.get("events.cpu"))) { 2447 int user = mProcessCpuTracker.getLastUserTime(); 2448 int system = mProcessCpuTracker.getLastSystemTime(); 2449 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2450 int irq = mProcessCpuTracker.getLastIrqTime(); 2451 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2452 int idle = mProcessCpuTracker.getLastIdleTime(); 2453 2454 int total = user + system + iowait + irq + softIrq + idle; 2455 if (total == 0) total = 1; 2456 2457 EventLog.writeEvent(EventLogTags.CPU, 2458 ((user+system+iowait+irq+softIrq) * 100) / total, 2459 (user * 100) / total, 2460 (system * 100) / total, 2461 (iowait * 100) / total, 2462 (irq * 100) / total, 2463 (softIrq * 100) / total); 2464 } 2465 } 2466 2467 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2468 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2469 synchronized(bstats) { 2470 synchronized(mPidsSelfLocked) { 2471 if (haveNewCpuStats) { 2472 if (mOnBattery) { 2473 int perc = bstats.startAddingCpuLocked(); 2474 int totalUTime = 0; 2475 int totalSTime = 0; 2476 final int N = mProcessCpuTracker.countStats(); 2477 for (int i=0; i<N; i++) { 2478 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2479 if (!st.working) { 2480 continue; 2481 } 2482 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2483 int otherUTime = (st.rel_utime*perc)/100; 2484 int otherSTime = (st.rel_stime*perc)/100; 2485 totalUTime += otherUTime; 2486 totalSTime += otherSTime; 2487 if (pr != null) { 2488 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2489 if (ps == null || !ps.isActive()) { 2490 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2491 pr.info.uid, pr.processName); 2492 } 2493 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2494 st.rel_stime-otherSTime); 2495 ps.addSpeedStepTimes(cpuSpeedTimes); 2496 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2497 } else { 2498 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2499 if (ps == null || !ps.isActive()) { 2500 st.batteryStats = ps = bstats.getProcessStatsLocked( 2501 bstats.mapUid(st.uid), st.name); 2502 } 2503 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2504 st.rel_stime-otherSTime); 2505 ps.addSpeedStepTimes(cpuSpeedTimes); 2506 } 2507 } 2508 bstats.finishAddingCpuLocked(perc, totalUTime, 2509 totalSTime, cpuSpeedTimes); 2510 } 2511 } 2512 } 2513 2514 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2515 mLastWriteTime = now; 2516 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2517 } 2518 } 2519 } 2520 } 2521 2522 @Override 2523 public void batteryNeedsCpuUpdate() { 2524 updateCpuStatsNow(); 2525 } 2526 2527 @Override 2528 public void batteryPowerChanged(boolean onBattery) { 2529 // When plugging in, update the CPU stats first before changing 2530 // the plug state. 2531 updateCpuStatsNow(); 2532 synchronized (this) { 2533 synchronized(mPidsSelfLocked) { 2534 mOnBattery = DEBUG_POWER ? true : onBattery; 2535 } 2536 } 2537 } 2538 2539 /** 2540 * Initialize the application bind args. These are passed to each 2541 * process when the bindApplication() IPC is sent to the process. They're 2542 * lazily setup to make sure the services are running when they're asked for. 2543 */ 2544 private HashMap<String, IBinder> getCommonServicesLocked() { 2545 if (mAppBindArgs == null) { 2546 mAppBindArgs = new HashMap<String, IBinder>(); 2547 2548 // Setup the application init args 2549 mAppBindArgs.put("package", ServiceManager.getService("package")); 2550 mAppBindArgs.put("window", ServiceManager.getService("window")); 2551 mAppBindArgs.put(Context.ALARM_SERVICE, 2552 ServiceManager.getService(Context.ALARM_SERVICE)); 2553 } 2554 return mAppBindArgs; 2555 } 2556 2557 final void setFocusedActivityLocked(ActivityRecord r) { 2558 if (mFocusedActivity != r) { 2559 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2560 mFocusedActivity = r; 2561 if (r.task != null && r.task.voiceInteractor != null) { 2562 startRunningVoiceLocked(); 2563 } else { 2564 finishRunningVoiceLocked(); 2565 } 2566 mStackSupervisor.setFocusedStack(r); 2567 if (r != null) { 2568 mWindowManager.setFocusedApp(r.appToken, true); 2569 } 2570 applyUpdateLockStateLocked(r); 2571 } 2572 } 2573 2574 final void clearFocusedActivity(ActivityRecord r) { 2575 if (mFocusedActivity == r) { 2576 mFocusedActivity = null; 2577 } 2578 } 2579 2580 @Override 2581 public void setFocusedStack(int stackId) { 2582 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2583 synchronized (ActivityManagerService.this) { 2584 ActivityStack stack = mStackSupervisor.getStack(stackId); 2585 if (stack != null) { 2586 ActivityRecord r = stack.topRunningActivityLocked(null); 2587 if (r != null) { 2588 setFocusedActivityLocked(r); 2589 } 2590 } 2591 } 2592 } 2593 2594 @Override 2595 public void notifyActivityDrawn(IBinder token) { 2596 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2597 synchronized (this) { 2598 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2599 if (r != null) { 2600 r.task.stack.notifyActivityDrawnLocked(r); 2601 } 2602 } 2603 } 2604 2605 final void applyUpdateLockStateLocked(ActivityRecord r) { 2606 // Modifications to the UpdateLock state are done on our handler, outside 2607 // the activity manager's locks. The new state is determined based on the 2608 // state *now* of the relevant activity record. The object is passed to 2609 // the handler solely for logging detail, not to be consulted/modified. 2610 final boolean nextState = r != null && r.immersive; 2611 mHandler.sendMessage( 2612 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2613 } 2614 2615 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2616 Message msg = Message.obtain(); 2617 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2618 msg.obj = r.task.askedCompatMode ? null : r; 2619 mHandler.sendMessage(msg); 2620 } 2621 2622 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2623 String what, Object obj, ProcessRecord srcApp) { 2624 app.lastActivityTime = now; 2625 2626 if (app.activities.size() > 0) { 2627 // Don't want to touch dependent processes that are hosting activities. 2628 return index; 2629 } 2630 2631 int lrui = mLruProcesses.lastIndexOf(app); 2632 if (lrui < 0) { 2633 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2634 + what + " " + obj + " from " + srcApp); 2635 return index; 2636 } 2637 2638 if (lrui >= index) { 2639 // Don't want to cause this to move dependent processes *back* in the 2640 // list as if they were less frequently used. 2641 return index; 2642 } 2643 2644 if (lrui >= mLruProcessActivityStart) { 2645 // Don't want to touch dependent processes that are hosting activities. 2646 return index; 2647 } 2648 2649 mLruProcesses.remove(lrui); 2650 if (index > 0) { 2651 index--; 2652 } 2653 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2654 + " in LRU list: " + app); 2655 mLruProcesses.add(index, app); 2656 return index; 2657 } 2658 2659 final void removeLruProcessLocked(ProcessRecord app) { 2660 int lrui = mLruProcesses.lastIndexOf(app); 2661 if (lrui >= 0) { 2662 if (!app.killed) { 2663 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2664 Process.killProcessQuiet(app.pid); 2665 Process.killProcessGroup(app.info.uid, app.pid); 2666 } 2667 if (lrui <= mLruProcessActivityStart) { 2668 mLruProcessActivityStart--; 2669 } 2670 if (lrui <= mLruProcessServiceStart) { 2671 mLruProcessServiceStart--; 2672 } 2673 mLruProcesses.remove(lrui); 2674 } 2675 } 2676 2677 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2678 ProcessRecord client) { 2679 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2680 || app.treatLikeActivity; 2681 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2682 if (!activityChange && hasActivity) { 2683 // The process has activities, so we are only allowing activity-based adjustments 2684 // to move it. It should be kept in the front of the list with other 2685 // processes that have activities, and we don't want those to change their 2686 // order except due to activity operations. 2687 return; 2688 } 2689 2690 mLruSeq++; 2691 final long now = SystemClock.uptimeMillis(); 2692 app.lastActivityTime = now; 2693 2694 // First a quick reject: if the app is already at the position we will 2695 // put it, then there is nothing to do. 2696 if (hasActivity) { 2697 final int N = mLruProcesses.size(); 2698 if (N > 0 && mLruProcesses.get(N-1) == app) { 2699 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2700 return; 2701 } 2702 } else { 2703 if (mLruProcessServiceStart > 0 2704 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2705 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2706 return; 2707 } 2708 } 2709 2710 int lrui = mLruProcesses.lastIndexOf(app); 2711 2712 if (app.persistent && lrui >= 0) { 2713 // We don't care about the position of persistent processes, as long as 2714 // they are in the list. 2715 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2716 return; 2717 } 2718 2719 /* In progress: compute new position first, so we can avoid doing work 2720 if the process is not actually going to move. Not yet working. 2721 int addIndex; 2722 int nextIndex; 2723 boolean inActivity = false, inService = false; 2724 if (hasActivity) { 2725 // Process has activities, put it at the very tipsy-top. 2726 addIndex = mLruProcesses.size(); 2727 nextIndex = mLruProcessServiceStart; 2728 inActivity = true; 2729 } else if (hasService) { 2730 // Process has services, put it at the top of the service list. 2731 addIndex = mLruProcessActivityStart; 2732 nextIndex = mLruProcessServiceStart; 2733 inActivity = true; 2734 inService = true; 2735 } else { 2736 // Process not otherwise of interest, it goes to the top of the non-service area. 2737 addIndex = mLruProcessServiceStart; 2738 if (client != null) { 2739 int clientIndex = mLruProcesses.lastIndexOf(client); 2740 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2741 + app); 2742 if (clientIndex >= 0 && addIndex > clientIndex) { 2743 addIndex = clientIndex; 2744 } 2745 } 2746 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2747 } 2748 2749 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2750 + mLruProcessActivityStart + "): " + app); 2751 */ 2752 2753 if (lrui >= 0) { 2754 if (lrui < mLruProcessActivityStart) { 2755 mLruProcessActivityStart--; 2756 } 2757 if (lrui < mLruProcessServiceStart) { 2758 mLruProcessServiceStart--; 2759 } 2760 /* 2761 if (addIndex > lrui) { 2762 addIndex--; 2763 } 2764 if (nextIndex > lrui) { 2765 nextIndex--; 2766 } 2767 */ 2768 mLruProcesses.remove(lrui); 2769 } 2770 2771 /* 2772 mLruProcesses.add(addIndex, app); 2773 if (inActivity) { 2774 mLruProcessActivityStart++; 2775 } 2776 if (inService) { 2777 mLruProcessActivityStart++; 2778 } 2779 */ 2780 2781 int nextIndex; 2782 if (hasActivity) { 2783 final int N = mLruProcesses.size(); 2784 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2785 // Process doesn't have activities, but has clients with 2786 // activities... move it up, but one below the top (the top 2787 // should always have a real activity). 2788 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2789 mLruProcesses.add(N-1, app); 2790 // To keep it from spamming the LRU list (by making a bunch of clients), 2791 // we will push down any other entries owned by the app. 2792 final int uid = app.info.uid; 2793 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2794 ProcessRecord subProc = mLruProcesses.get(i); 2795 if (subProc.info.uid == uid) { 2796 // We want to push this one down the list. If the process after 2797 // it is for the same uid, however, don't do so, because we don't 2798 // want them internally to be re-ordered. 2799 if (mLruProcesses.get(i-1).info.uid != uid) { 2800 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2801 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2802 ProcessRecord tmp = mLruProcesses.get(i); 2803 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2804 mLruProcesses.set(i-1, tmp); 2805 i--; 2806 } 2807 } else { 2808 // A gap, we can stop here. 2809 break; 2810 } 2811 } 2812 } else { 2813 // Process has activities, put it at the very tipsy-top. 2814 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2815 mLruProcesses.add(app); 2816 } 2817 nextIndex = mLruProcessServiceStart; 2818 } else if (hasService) { 2819 // Process has services, put it at the top of the service list. 2820 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2821 mLruProcesses.add(mLruProcessActivityStart, app); 2822 nextIndex = mLruProcessServiceStart; 2823 mLruProcessActivityStart++; 2824 } else { 2825 // Process not otherwise of interest, it goes to the top of the non-service area. 2826 int index = mLruProcessServiceStart; 2827 if (client != null) { 2828 // If there is a client, don't allow the process to be moved up higher 2829 // in the list than that client. 2830 int clientIndex = mLruProcesses.lastIndexOf(client); 2831 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2832 + " when updating " + app); 2833 if (clientIndex <= lrui) { 2834 // Don't allow the client index restriction to push it down farther in the 2835 // list than it already is. 2836 clientIndex = lrui; 2837 } 2838 if (clientIndex >= 0 && index > clientIndex) { 2839 index = clientIndex; 2840 } 2841 } 2842 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2843 mLruProcesses.add(index, app); 2844 nextIndex = index-1; 2845 mLruProcessActivityStart++; 2846 mLruProcessServiceStart++; 2847 } 2848 2849 // If the app is currently using a content provider or service, 2850 // bump those processes as well. 2851 for (int j=app.connections.size()-1; j>=0; j--) { 2852 ConnectionRecord cr = app.connections.valueAt(j); 2853 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2854 && cr.binding.service.app != null 2855 && cr.binding.service.app.lruSeq != mLruSeq 2856 && !cr.binding.service.app.persistent) { 2857 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2858 "service connection", cr, app); 2859 } 2860 } 2861 for (int j=app.conProviders.size()-1; j>=0; j--) { 2862 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2863 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2864 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2865 "provider reference", cpr, app); 2866 } 2867 } 2868 } 2869 2870 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2871 if (uid == Process.SYSTEM_UID) { 2872 // The system gets to run in any process. If there are multiple 2873 // processes with the same uid, just pick the first (this 2874 // should never happen). 2875 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2876 if (procs == null) return null; 2877 final int N = procs.size(); 2878 for (int i = 0; i < N; i++) { 2879 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2880 } 2881 } 2882 ProcessRecord proc = mProcessNames.get(processName, uid); 2883 if (false && proc != null && !keepIfLarge 2884 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2885 && proc.lastCachedPss >= 4000) { 2886 // Turn this condition on to cause killing to happen regularly, for testing. 2887 if (proc.baseProcessTracker != null) { 2888 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2889 } 2890 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2891 } else if (proc != null && !keepIfLarge 2892 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2893 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2894 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2895 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2896 if (proc.baseProcessTracker != null) { 2897 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2898 } 2899 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2900 } 2901 } 2902 return proc; 2903 } 2904 2905 void ensurePackageDexOpt(String packageName) { 2906 IPackageManager pm = AppGlobals.getPackageManager(); 2907 try { 2908 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2909 mDidDexOpt = true; 2910 } 2911 } catch (RemoteException e) { 2912 } 2913 } 2914 2915 boolean isNextTransitionForward() { 2916 int transit = mWindowManager.getPendingAppTransition(); 2917 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2918 || transit == AppTransition.TRANSIT_TASK_OPEN 2919 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2920 } 2921 2922 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2923 String processName, String abiOverride, int uid, Runnable crashHandler) { 2924 synchronized(this) { 2925 ApplicationInfo info = new ApplicationInfo(); 2926 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2927 // For isolated processes, the former contains the parent's uid and the latter the 2928 // actual uid of the isolated process. 2929 // In the special case introduced by this method (which is, starting an isolated 2930 // process directly from the SystemServer without an actual parent app process) the 2931 // closest thing to a parent's uid is SYSTEM_UID. 2932 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2933 // the |isolated| logic in the ProcessRecord constructor. 2934 info.uid = Process.SYSTEM_UID; 2935 info.processName = processName; 2936 info.className = entryPoint; 2937 info.packageName = "android"; 2938 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2939 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2940 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2941 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2942 crashHandler); 2943 return proc != null ? proc.pid : 0; 2944 } 2945 } 2946 2947 final ProcessRecord startProcessLocked(String processName, 2948 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2949 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2950 boolean isolated, boolean keepIfLarge) { 2951 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2952 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2953 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2954 null /* crashHandler */); 2955 } 2956 2957 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2958 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2959 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2960 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2961 long startTime = SystemClock.elapsedRealtime(); 2962 ProcessRecord app; 2963 if (!isolated) { 2964 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2965 checkTime(startTime, "startProcess: after getProcessRecord"); 2966 } else { 2967 // If this is an isolated process, it can't re-use an existing process. 2968 app = null; 2969 } 2970 // We don't have to do anything more if: 2971 // (1) There is an existing application record; and 2972 // (2) The caller doesn't think it is dead, OR there is no thread 2973 // object attached to it so we know it couldn't have crashed; and 2974 // (3) There is a pid assigned to it, so it is either starting or 2975 // already running. 2976 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2977 + " app=" + app + " knownToBeDead=" + knownToBeDead 2978 + " thread=" + (app != null ? app.thread : null) 2979 + " pid=" + (app != null ? app.pid : -1)); 2980 if (app != null && app.pid > 0) { 2981 if (!knownToBeDead || app.thread == null) { 2982 // We already have the app running, or are waiting for it to 2983 // come up (we have a pid but not yet its thread), so keep it. 2984 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2985 // If this is a new package in the process, add the package to the list 2986 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2987 checkTime(startTime, "startProcess: done, added package to proc"); 2988 return app; 2989 } 2990 2991 // An application record is attached to a previous process, 2992 // clean it up now. 2993 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2994 checkTime(startTime, "startProcess: bad proc running, killing"); 2995 Process.killProcessGroup(app.info.uid, app.pid); 2996 handleAppDiedLocked(app, true, true); 2997 checkTime(startTime, "startProcess: done killing old proc"); 2998 } 2999 3000 String hostingNameStr = hostingName != null 3001 ? hostingName.flattenToShortString() : null; 3002 3003 if (!isolated) { 3004 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3005 // If we are in the background, then check to see if this process 3006 // is bad. If so, we will just silently fail. 3007 if (mBadProcesses.get(info.processName, info.uid) != null) { 3008 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3009 + "/" + info.processName); 3010 return null; 3011 } 3012 } else { 3013 // When the user is explicitly starting a process, then clear its 3014 // crash count so that we won't make it bad until they see at 3015 // least one crash dialog again, and make the process good again 3016 // if it had been bad. 3017 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3018 + "/" + info.processName); 3019 mProcessCrashTimes.remove(info.processName, info.uid); 3020 if (mBadProcesses.get(info.processName, info.uid) != null) { 3021 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3022 UserHandle.getUserId(info.uid), info.uid, 3023 info.processName); 3024 mBadProcesses.remove(info.processName, info.uid); 3025 if (app != null) { 3026 app.bad = false; 3027 } 3028 } 3029 } 3030 } 3031 3032 if (app == null) { 3033 checkTime(startTime, "startProcess: creating new process record"); 3034 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3035 app.crashHandler = crashHandler; 3036 if (app == null) { 3037 Slog.w(TAG, "Failed making new process record for " 3038 + processName + "/" + info.uid + " isolated=" + isolated); 3039 return null; 3040 } 3041 mProcessNames.put(processName, app.uid, app); 3042 if (isolated) { 3043 mIsolatedProcesses.put(app.uid, app); 3044 } 3045 checkTime(startTime, "startProcess: done creating new process record"); 3046 } else { 3047 // If this is a new package in the process, add the package to the list 3048 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3049 checkTime(startTime, "startProcess: added package to existing proc"); 3050 } 3051 3052 // If the system is not ready yet, then hold off on starting this 3053 // process until it is. 3054 if (!mProcessesReady 3055 && !isAllowedWhileBooting(info) 3056 && !allowWhileBooting) { 3057 if (!mProcessesOnHold.contains(app)) { 3058 mProcessesOnHold.add(app); 3059 } 3060 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3061 checkTime(startTime, "startProcess: returning with proc on hold"); 3062 return app; 3063 } 3064 3065 checkTime(startTime, "startProcess: stepping in to startProcess"); 3066 startProcessLocked( 3067 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3068 checkTime(startTime, "startProcess: done starting proc!"); 3069 return (app.pid != 0) ? app : null; 3070 } 3071 3072 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3073 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3074 } 3075 3076 private final void startProcessLocked(ProcessRecord app, 3077 String hostingType, String hostingNameStr) { 3078 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3079 null /* entryPoint */, null /* entryPointArgs */); 3080 } 3081 3082 private final void startProcessLocked(ProcessRecord app, String hostingType, 3083 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3084 long startTime = SystemClock.elapsedRealtime(); 3085 if (app.pid > 0 && app.pid != MY_PID) { 3086 checkTime(startTime, "startProcess: removing from pids map"); 3087 synchronized (mPidsSelfLocked) { 3088 mPidsSelfLocked.remove(app.pid); 3089 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3090 } 3091 checkTime(startTime, "startProcess: done removing from pids map"); 3092 app.setPid(0); 3093 } 3094 3095 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3096 "startProcessLocked removing on hold: " + app); 3097 mProcessesOnHold.remove(app); 3098 3099 checkTime(startTime, "startProcess: starting to update cpu stats"); 3100 updateCpuStats(); 3101 checkTime(startTime, "startProcess: done updating cpu stats"); 3102 3103 try { 3104 int uid = app.uid; 3105 3106 int[] gids = null; 3107 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3108 if (!app.isolated) { 3109 int[] permGids = null; 3110 try { 3111 checkTime(startTime, "startProcess: getting gids from package manager"); 3112 final PackageManager pm = mContext.getPackageManager(); 3113 permGids = pm.getPackageGids(app.info.packageName); 3114 3115 if (Environment.isExternalStorageEmulated()) { 3116 checkTime(startTime, "startProcess: checking external storage perm"); 3117 if (pm.checkPermission( 3118 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3119 app.info.packageName) == PERMISSION_GRANTED) { 3120 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3121 } else { 3122 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3123 } 3124 } 3125 } catch (PackageManager.NameNotFoundException e) { 3126 Slog.w(TAG, "Unable to retrieve gids", e); 3127 } 3128 3129 /* 3130 * Add shared application and profile GIDs so applications can share some 3131 * resources like shared libraries and access user-wide resources 3132 */ 3133 if (permGids == null) { 3134 gids = new int[2]; 3135 } else { 3136 gids = new int[permGids.length + 2]; 3137 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3138 } 3139 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3140 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3141 } 3142 checkTime(startTime, "startProcess: building args"); 3143 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3144 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3145 && mTopComponent != null 3146 && app.processName.equals(mTopComponent.getPackageName())) { 3147 uid = 0; 3148 } 3149 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3150 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3151 uid = 0; 3152 } 3153 } 3154 int debugFlags = 0; 3155 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3156 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3157 // Also turn on CheckJNI for debuggable apps. It's quite 3158 // awkward to turn on otherwise. 3159 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3160 } 3161 // Run the app in safe mode if its manifest requests so or the 3162 // system is booted in safe mode. 3163 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3164 mSafeMode == true) { 3165 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3166 } 3167 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3168 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3169 } 3170 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3171 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3172 } 3173 if ("1".equals(SystemProperties.get("debug.assert"))) { 3174 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3175 } 3176 3177 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3178 if (requiredAbi == null) { 3179 requiredAbi = Build.SUPPORTED_ABIS[0]; 3180 } 3181 3182 String instructionSet = null; 3183 if (app.info.primaryCpuAbi != null) { 3184 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3185 } 3186 3187 // Start the process. It will either succeed and return a result containing 3188 // the PID of the new process, or else throw a RuntimeException. 3189 boolean isActivityProcess = (entryPoint == null); 3190 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3191 checkTime(startTime, "startProcess: asking zygote to start proc"); 3192 Process.ProcessStartResult startResult = Process.start(entryPoint, 3193 app.processName, uid, uid, gids, debugFlags, mountExternal, 3194 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3195 app.info.dataDir, entryPointArgs); 3196 checkTime(startTime, "startProcess: returned from zygote!"); 3197 3198 if (app.isolated) { 3199 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3200 } 3201 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3202 checkTime(startTime, "startProcess: done updating battery stats"); 3203 3204 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3205 UserHandle.getUserId(uid), startResult.pid, uid, 3206 app.processName, hostingType, 3207 hostingNameStr != null ? hostingNameStr : ""); 3208 3209 if (app.persistent) { 3210 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3211 } 3212 3213 checkTime(startTime, "startProcess: building log message"); 3214 StringBuilder buf = mStringBuilder; 3215 buf.setLength(0); 3216 buf.append("Start proc "); 3217 buf.append(app.processName); 3218 if (!isActivityProcess) { 3219 buf.append(" ["); 3220 buf.append(entryPoint); 3221 buf.append("]"); 3222 } 3223 buf.append(" for "); 3224 buf.append(hostingType); 3225 if (hostingNameStr != null) { 3226 buf.append(" "); 3227 buf.append(hostingNameStr); 3228 } 3229 buf.append(": pid="); 3230 buf.append(startResult.pid); 3231 buf.append(" uid="); 3232 buf.append(uid); 3233 buf.append(" gids={"); 3234 if (gids != null) { 3235 for (int gi=0; gi<gids.length; gi++) { 3236 if (gi != 0) buf.append(", "); 3237 buf.append(gids[gi]); 3238 3239 } 3240 } 3241 buf.append("}"); 3242 if (requiredAbi != null) { 3243 buf.append(" abi="); 3244 buf.append(requiredAbi); 3245 } 3246 Slog.i(TAG, buf.toString()); 3247 app.setPid(startResult.pid); 3248 app.usingWrapper = startResult.usingWrapper; 3249 app.removed = false; 3250 app.killed = false; 3251 app.killedByAm = false; 3252 checkTime(startTime, "startProcess: starting to update pids map"); 3253 synchronized (mPidsSelfLocked) { 3254 this.mPidsSelfLocked.put(startResult.pid, app); 3255 if (isActivityProcess) { 3256 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3257 msg.obj = app; 3258 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3259 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3260 } 3261 } 3262 checkTime(startTime, "startProcess: done updating pids map"); 3263 } catch (RuntimeException e) { 3264 // XXX do better error recovery. 3265 app.setPid(0); 3266 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3267 if (app.isolated) { 3268 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3269 } 3270 Slog.e(TAG, "Failure starting process " + app.processName, e); 3271 } 3272 } 3273 3274 void updateUsageStats(ActivityRecord component, boolean resumed) { 3275 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3276 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3277 if (resumed) { 3278 if (mUsageStatsService != null) { 3279 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3280 UsageEvents.Event.MOVE_TO_FOREGROUND); 3281 } 3282 synchronized (stats) { 3283 stats.noteActivityResumedLocked(component.app.uid); 3284 } 3285 } else { 3286 if (mUsageStatsService != null) { 3287 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3288 UsageEvents.Event.MOVE_TO_BACKGROUND); 3289 } 3290 synchronized (stats) { 3291 stats.noteActivityPausedLocked(component.app.uid); 3292 } 3293 } 3294 } 3295 3296 Intent getHomeIntent() { 3297 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3298 intent.setComponent(mTopComponent); 3299 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3300 intent.addCategory(Intent.CATEGORY_HOME); 3301 } 3302 return intent; 3303 } 3304 3305 boolean startHomeActivityLocked(int userId) { 3306 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3307 && mTopAction == null) { 3308 // We are running in factory test mode, but unable to find 3309 // the factory test app, so just sit around displaying the 3310 // error message and don't try to start anything. 3311 return false; 3312 } 3313 Intent intent = getHomeIntent(); 3314 ActivityInfo aInfo = 3315 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3316 if (aInfo != null) { 3317 intent.setComponent(new ComponentName( 3318 aInfo.applicationInfo.packageName, aInfo.name)); 3319 // Don't do this if the home app is currently being 3320 // instrumented. 3321 aInfo = new ActivityInfo(aInfo); 3322 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3323 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3324 aInfo.applicationInfo.uid, true); 3325 if (app == null || app.instrumentationClass == null) { 3326 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3327 mStackSupervisor.startHomeActivity(intent, aInfo); 3328 } 3329 } 3330 3331 return true; 3332 } 3333 3334 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3335 ActivityInfo ai = null; 3336 ComponentName comp = intent.getComponent(); 3337 try { 3338 if (comp != null) { 3339 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3340 } else { 3341 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3342 intent, 3343 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3344 flags, userId); 3345 3346 if (info != null) { 3347 ai = info.activityInfo; 3348 } 3349 } 3350 } catch (RemoteException e) { 3351 // ignore 3352 } 3353 3354 return ai; 3355 } 3356 3357 /** 3358 * Starts the "new version setup screen" if appropriate. 3359 */ 3360 void startSetupActivityLocked() { 3361 // Only do this once per boot. 3362 if (mCheckedForSetup) { 3363 return; 3364 } 3365 3366 // We will show this screen if the current one is a different 3367 // version than the last one shown, and we are not running in 3368 // low-level factory test mode. 3369 final ContentResolver resolver = mContext.getContentResolver(); 3370 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3371 Settings.Global.getInt(resolver, 3372 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3373 mCheckedForSetup = true; 3374 3375 // See if we should be showing the platform update setup UI. 3376 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3377 List<ResolveInfo> ris = mContext.getPackageManager() 3378 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3379 3380 // We don't allow third party apps to replace this. 3381 ResolveInfo ri = null; 3382 for (int i=0; ris != null && i<ris.size(); i++) { 3383 if ((ris.get(i).activityInfo.applicationInfo.flags 3384 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3385 ri = ris.get(i); 3386 break; 3387 } 3388 } 3389 3390 if (ri != null) { 3391 String vers = ri.activityInfo.metaData != null 3392 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3393 : null; 3394 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3395 vers = ri.activityInfo.applicationInfo.metaData.getString( 3396 Intent.METADATA_SETUP_VERSION); 3397 } 3398 String lastVers = Settings.Secure.getString( 3399 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3400 if (vers != null && !vers.equals(lastVers)) { 3401 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3402 intent.setComponent(new ComponentName( 3403 ri.activityInfo.packageName, ri.activityInfo.name)); 3404 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3405 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3406 null); 3407 } 3408 } 3409 } 3410 } 3411 3412 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3413 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3414 } 3415 3416 void enforceNotIsolatedCaller(String caller) { 3417 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3418 throw new SecurityException("Isolated process not allowed to call " + caller); 3419 } 3420 } 3421 3422 void enforceShellRestriction(String restriction, int userHandle) { 3423 if (Binder.getCallingUid() == Process.SHELL_UID) { 3424 if (userHandle < 0 3425 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3426 throw new SecurityException("Shell does not have permission to access user " 3427 + userHandle); 3428 } 3429 } 3430 } 3431 3432 @Override 3433 public int getFrontActivityScreenCompatMode() { 3434 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3435 synchronized (this) { 3436 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3437 } 3438 } 3439 3440 @Override 3441 public void setFrontActivityScreenCompatMode(int mode) { 3442 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3443 "setFrontActivityScreenCompatMode"); 3444 synchronized (this) { 3445 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3446 } 3447 } 3448 3449 @Override 3450 public int getPackageScreenCompatMode(String packageName) { 3451 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3452 synchronized (this) { 3453 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3454 } 3455 } 3456 3457 @Override 3458 public void setPackageScreenCompatMode(String packageName, int mode) { 3459 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3460 "setPackageScreenCompatMode"); 3461 synchronized (this) { 3462 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3463 } 3464 } 3465 3466 @Override 3467 public boolean getPackageAskScreenCompat(String packageName) { 3468 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3469 synchronized (this) { 3470 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3471 } 3472 } 3473 3474 @Override 3475 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3476 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3477 "setPackageAskScreenCompat"); 3478 synchronized (this) { 3479 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3480 } 3481 } 3482 3483 private void dispatchProcessesChanged() { 3484 int N; 3485 synchronized (this) { 3486 N = mPendingProcessChanges.size(); 3487 if (mActiveProcessChanges.length < N) { 3488 mActiveProcessChanges = new ProcessChangeItem[N]; 3489 } 3490 mPendingProcessChanges.toArray(mActiveProcessChanges); 3491 mAvailProcessChanges.addAll(mPendingProcessChanges); 3492 mPendingProcessChanges.clear(); 3493 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3494 } 3495 3496 int i = mProcessObservers.beginBroadcast(); 3497 while (i > 0) { 3498 i--; 3499 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3500 if (observer != null) { 3501 try { 3502 for (int j=0; j<N; j++) { 3503 ProcessChangeItem item = mActiveProcessChanges[j]; 3504 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3505 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3506 + item.pid + " uid=" + item.uid + ": " 3507 + item.foregroundActivities); 3508 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3509 item.foregroundActivities); 3510 } 3511 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3513 + item.pid + " uid=" + item.uid + ": " + item.processState); 3514 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3515 } 3516 } 3517 } catch (RemoteException e) { 3518 } 3519 } 3520 } 3521 mProcessObservers.finishBroadcast(); 3522 } 3523 3524 private void dispatchProcessDied(int pid, int uid) { 3525 int i = mProcessObservers.beginBroadcast(); 3526 while (i > 0) { 3527 i--; 3528 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3529 if (observer != null) { 3530 try { 3531 observer.onProcessDied(pid, uid); 3532 } catch (RemoteException e) { 3533 } 3534 } 3535 } 3536 mProcessObservers.finishBroadcast(); 3537 } 3538 3539 @Override 3540 public final int startActivity(IApplicationThread caller, String callingPackage, 3541 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3542 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3543 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3544 resultWho, requestCode, startFlags, profilerInfo, options, 3545 UserHandle.getCallingUserId()); 3546 } 3547 3548 @Override 3549 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3550 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3551 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3552 enforceNotIsolatedCaller("startActivity"); 3553 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3554 false, ALLOW_FULL_ONLY, "startActivity", null); 3555 // TODO: Switch to user app stacks here. 3556 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3557 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3558 profilerInfo, null, null, options, userId, null, null); 3559 } 3560 3561 @Override 3562 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3563 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3564 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3565 3566 // This is very dangerous -- it allows you to perform a start activity (including 3567 // permission grants) as any app that may launch one of your own activities. So 3568 // we will only allow this to be done from activities that are part of the core framework, 3569 // and then only when they are running as the system. 3570 final ActivityRecord sourceRecord; 3571 final int targetUid; 3572 final String targetPackage; 3573 synchronized (this) { 3574 if (resultTo == null) { 3575 throw new SecurityException("Must be called from an activity"); 3576 } 3577 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3578 if (sourceRecord == null) { 3579 throw new SecurityException("Called with bad activity token: " + resultTo); 3580 } 3581 if (!sourceRecord.info.packageName.equals("android")) { 3582 throw new SecurityException( 3583 "Must be called from an activity that is declared in the android package"); 3584 } 3585 if (sourceRecord.app == null) { 3586 throw new SecurityException("Called without a process attached to activity"); 3587 } 3588 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3589 // This is still okay, as long as this activity is running under the 3590 // uid of the original calling activity. 3591 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3592 throw new SecurityException( 3593 "Calling activity in uid " + sourceRecord.app.uid 3594 + " must be system uid or original calling uid " 3595 + sourceRecord.launchedFromUid); 3596 } 3597 } 3598 targetUid = sourceRecord.launchedFromUid; 3599 targetPackage = sourceRecord.launchedFromPackage; 3600 } 3601 3602 // TODO: Switch to user app stacks here. 3603 try { 3604 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3605 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3606 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3607 return ret; 3608 } catch (SecurityException e) { 3609 // XXX need to figure out how to propagate to original app. 3610 // A SecurityException here is generally actually a fault of the original 3611 // calling activity (such as a fairly granting permissions), so propagate it 3612 // back to them. 3613 /* 3614 StringBuilder msg = new StringBuilder(); 3615 msg.append("While launching"); 3616 msg.append(intent.toString()); 3617 msg.append(": "); 3618 msg.append(e.getMessage()); 3619 */ 3620 throw e; 3621 } 3622 } 3623 3624 @Override 3625 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3626 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3627 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3628 enforceNotIsolatedCaller("startActivityAndWait"); 3629 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3630 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3631 WaitResult res = new WaitResult(); 3632 // TODO: Switch to user app stacks here. 3633 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3634 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3635 options, userId, null, null); 3636 return res; 3637 } 3638 3639 @Override 3640 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3641 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3642 int startFlags, Configuration config, Bundle options, int userId) { 3643 enforceNotIsolatedCaller("startActivityWithConfig"); 3644 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3645 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3646 // TODO: Switch to user app stacks here. 3647 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3648 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3649 null, null, config, options, userId, null, null); 3650 return ret; 3651 } 3652 3653 @Override 3654 public int startActivityIntentSender(IApplicationThread caller, 3655 IntentSender intent, Intent fillInIntent, String resolvedType, 3656 IBinder resultTo, String resultWho, int requestCode, 3657 int flagsMask, int flagsValues, Bundle options) { 3658 enforceNotIsolatedCaller("startActivityIntentSender"); 3659 // Refuse possible leaked file descriptors 3660 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3661 throw new IllegalArgumentException("File descriptors passed in Intent"); 3662 } 3663 3664 IIntentSender sender = intent.getTarget(); 3665 if (!(sender instanceof PendingIntentRecord)) { 3666 throw new IllegalArgumentException("Bad PendingIntent object"); 3667 } 3668 3669 PendingIntentRecord pir = (PendingIntentRecord)sender; 3670 3671 synchronized (this) { 3672 // If this is coming from the currently resumed activity, it is 3673 // effectively saying that app switches are allowed at this point. 3674 final ActivityStack stack = getFocusedStack(); 3675 if (stack.mResumedActivity != null && 3676 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3677 mAppSwitchesAllowedTime = 0; 3678 } 3679 } 3680 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3681 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3682 return ret; 3683 } 3684 3685 @Override 3686 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3687 Intent intent, String resolvedType, IVoiceInteractionSession session, 3688 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3689 Bundle options, int userId) { 3690 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3691 != PackageManager.PERMISSION_GRANTED) { 3692 String msg = "Permission Denial: startVoiceActivity() from pid=" 3693 + Binder.getCallingPid() 3694 + ", uid=" + Binder.getCallingUid() 3695 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3696 Slog.w(TAG, msg); 3697 throw new SecurityException(msg); 3698 } 3699 if (session == null || interactor == null) { 3700 throw new NullPointerException("null session or interactor"); 3701 } 3702 userId = handleIncomingUser(callingPid, callingUid, userId, 3703 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3704 // TODO: Switch to user app stacks here. 3705 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3706 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3707 null, options, userId, null, null); 3708 } 3709 3710 @Override 3711 public boolean startNextMatchingActivity(IBinder callingActivity, 3712 Intent intent, Bundle options) { 3713 // Refuse possible leaked file descriptors 3714 if (intent != null && intent.hasFileDescriptors() == true) { 3715 throw new IllegalArgumentException("File descriptors passed in Intent"); 3716 } 3717 3718 synchronized (this) { 3719 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3720 if (r == null) { 3721 ActivityOptions.abort(options); 3722 return false; 3723 } 3724 if (r.app == null || r.app.thread == null) { 3725 // The caller is not running... d'oh! 3726 ActivityOptions.abort(options); 3727 return false; 3728 } 3729 intent = new Intent(intent); 3730 // The caller is not allowed to change the data. 3731 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3732 // And we are resetting to find the next component... 3733 intent.setComponent(null); 3734 3735 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3736 3737 ActivityInfo aInfo = null; 3738 try { 3739 List<ResolveInfo> resolves = 3740 AppGlobals.getPackageManager().queryIntentActivities( 3741 intent, r.resolvedType, 3742 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3743 UserHandle.getCallingUserId()); 3744 3745 // Look for the original activity in the list... 3746 final int N = resolves != null ? resolves.size() : 0; 3747 for (int i=0; i<N; i++) { 3748 ResolveInfo rInfo = resolves.get(i); 3749 if (rInfo.activityInfo.packageName.equals(r.packageName) 3750 && rInfo.activityInfo.name.equals(r.info.name)) { 3751 // We found the current one... the next matching is 3752 // after it. 3753 i++; 3754 if (i<N) { 3755 aInfo = resolves.get(i).activityInfo; 3756 } 3757 if (debug) { 3758 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3759 + "/" + r.info.name); 3760 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3761 + "/" + aInfo.name); 3762 } 3763 break; 3764 } 3765 } 3766 } catch (RemoteException e) { 3767 } 3768 3769 if (aInfo == null) { 3770 // Nobody who is next! 3771 ActivityOptions.abort(options); 3772 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3773 return false; 3774 } 3775 3776 intent.setComponent(new ComponentName( 3777 aInfo.applicationInfo.packageName, aInfo.name)); 3778 intent.setFlags(intent.getFlags()&~( 3779 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3780 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3781 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3782 Intent.FLAG_ACTIVITY_NEW_TASK)); 3783 3784 // Okay now we need to start the new activity, replacing the 3785 // currently running activity. This is a little tricky because 3786 // we want to start the new one as if the current one is finished, 3787 // but not finish the current one first so that there is no flicker. 3788 // And thus... 3789 final boolean wasFinishing = r.finishing; 3790 r.finishing = true; 3791 3792 // Propagate reply information over to the new activity. 3793 final ActivityRecord resultTo = r.resultTo; 3794 final String resultWho = r.resultWho; 3795 final int requestCode = r.requestCode; 3796 r.resultTo = null; 3797 if (resultTo != null) { 3798 resultTo.removeResultsLocked(r, resultWho, requestCode); 3799 } 3800 3801 final long origId = Binder.clearCallingIdentity(); 3802 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3803 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3804 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3805 -1, r.launchedFromUid, 0, options, false, null, null, null); 3806 Binder.restoreCallingIdentity(origId); 3807 3808 r.finishing = wasFinishing; 3809 if (res != ActivityManager.START_SUCCESS) { 3810 return false; 3811 } 3812 return true; 3813 } 3814 } 3815 3816 @Override 3817 public final int startActivityFromRecents(int taskId, Bundle options) { 3818 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3819 String msg = "Permission Denial: startActivityFromRecents called without " + 3820 START_TASKS_FROM_RECENTS; 3821 Slog.w(TAG, msg); 3822 throw new SecurityException(msg); 3823 } 3824 return startActivityFromRecentsInner(taskId, options); 3825 } 3826 3827 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3828 final TaskRecord task; 3829 final int callingUid; 3830 final String callingPackage; 3831 final Intent intent; 3832 final int userId; 3833 synchronized (this) { 3834 task = recentTaskForIdLocked(taskId); 3835 if (task == null) { 3836 throw new IllegalArgumentException("Task " + taskId + " not found."); 3837 } 3838 callingUid = task.mCallingUid; 3839 callingPackage = task.mCallingPackage; 3840 intent = task.intent; 3841 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3842 userId = task.userId; 3843 } 3844 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3845 options, userId, null, task); 3846 } 3847 3848 final int startActivityInPackage(int uid, String callingPackage, 3849 Intent intent, String resolvedType, IBinder resultTo, 3850 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3851 IActivityContainer container, TaskRecord inTask) { 3852 3853 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3854 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3855 3856 // TODO: Switch to user app stacks here. 3857 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3858 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3859 null, null, null, options, userId, container, inTask); 3860 return ret; 3861 } 3862 3863 @Override 3864 public final int startActivities(IApplicationThread caller, String callingPackage, 3865 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3866 int userId) { 3867 enforceNotIsolatedCaller("startActivities"); 3868 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3869 false, ALLOW_FULL_ONLY, "startActivity", null); 3870 // TODO: Switch to user app stacks here. 3871 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3872 resolvedTypes, resultTo, options, userId); 3873 return ret; 3874 } 3875 3876 final int startActivitiesInPackage(int uid, String callingPackage, 3877 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3878 Bundle options, int userId) { 3879 3880 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3881 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3882 // TODO: Switch to user app stacks here. 3883 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3884 resultTo, options, userId); 3885 return ret; 3886 } 3887 3888 //explicitly remove thd old information in mRecentTasks when removing existing user. 3889 private void removeRecentTasksForUserLocked(int userId) { 3890 if(userId <= 0) { 3891 Slog.i(TAG, "Can't remove recent task on user " + userId); 3892 return; 3893 } 3894 3895 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3896 TaskRecord tr = mRecentTasks.get(i); 3897 if (tr.userId == userId) { 3898 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3899 + " when finishing user" + userId); 3900 mRecentTasks.remove(i); 3901 tr.removedFromRecents(mTaskPersister); 3902 } 3903 } 3904 3905 // Remove tasks from persistent storage. 3906 mTaskPersister.wakeup(null, true); 3907 } 3908 3909 // Sort by taskId 3910 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3911 @Override 3912 public int compare(TaskRecord lhs, TaskRecord rhs) { 3913 return rhs.taskId - lhs.taskId; 3914 } 3915 }; 3916 3917 // Extract the affiliates of the chain containing mRecentTasks[start]. 3918 private int processNextAffiliateChain(int start) { 3919 final TaskRecord startTask = mRecentTasks.get(start); 3920 final int affiliateId = startTask.mAffiliatedTaskId; 3921 3922 // Quick identification of isolated tasks. I.e. those not launched behind. 3923 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3924 startTask.mNextAffiliate == null) { 3925 // There is still a slim chance that there are other tasks that point to this task 3926 // and that the chain is so messed up that this task no longer points to them but 3927 // the gain of this optimization outweighs the risk. 3928 startTask.inRecents = true; 3929 return start + 1; 3930 } 3931 3932 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3933 mTmpRecents.clear(); 3934 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3935 final TaskRecord task = mRecentTasks.get(i); 3936 if (task.mAffiliatedTaskId == affiliateId) { 3937 mRecentTasks.remove(i); 3938 mTmpRecents.add(task); 3939 } 3940 } 3941 3942 // Sort them all by taskId. That is the order they were create in and that order will 3943 // always be correct. 3944 Collections.sort(mTmpRecents, mTaskRecordComparator); 3945 3946 // Go through and fix up the linked list. 3947 // The first one is the end of the chain and has no next. 3948 final TaskRecord first = mTmpRecents.get(0); 3949 first.inRecents = true; 3950 if (first.mNextAffiliate != null) { 3951 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3952 first.setNextAffiliate(null); 3953 mTaskPersister.wakeup(first, false); 3954 } 3955 // Everything in the middle is doubly linked from next to prev. 3956 final int tmpSize = mTmpRecents.size(); 3957 for (int i = 0; i < tmpSize - 1; ++i) { 3958 final TaskRecord next = mTmpRecents.get(i); 3959 final TaskRecord prev = mTmpRecents.get(i + 1); 3960 if (next.mPrevAffiliate != prev) { 3961 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3962 " setting prev=" + prev); 3963 next.setPrevAffiliate(prev); 3964 mTaskPersister.wakeup(next, false); 3965 } 3966 if (prev.mNextAffiliate != next) { 3967 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3968 " setting next=" + next); 3969 prev.setNextAffiliate(next); 3970 mTaskPersister.wakeup(prev, false); 3971 } 3972 prev.inRecents = true; 3973 } 3974 // The last one is the beginning of the list and has no prev. 3975 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3976 if (last.mPrevAffiliate != null) { 3977 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3978 last.setPrevAffiliate(null); 3979 mTaskPersister.wakeup(last, false); 3980 } 3981 3982 // Insert the group back into mRecentTasks at start. 3983 mRecentTasks.addAll(start, mTmpRecents); 3984 3985 // Let the caller know where we left off. 3986 return start + tmpSize; 3987 } 3988 3989 /** 3990 * Update the recent tasks lists: make sure tasks should still be here (their 3991 * applications / activities still exist), update their availability, fixup ordering 3992 * of affiliations. 3993 */ 3994 void cleanupRecentTasksLocked(int userId) { 3995 if (mRecentTasks == null) { 3996 // Happens when called from the packagemanager broadcast before boot. 3997 return; 3998 } 3999 4000 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4001 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4002 final IPackageManager pm = AppGlobals.getPackageManager(); 4003 final ActivityInfo dummyAct = new ActivityInfo(); 4004 final ApplicationInfo dummyApp = new ApplicationInfo(); 4005 4006 int N = mRecentTasks.size(); 4007 4008 int[] users = userId == UserHandle.USER_ALL 4009 ? getUsersLocked() : new int[] { userId }; 4010 for (int user : users) { 4011 for (int i = 0; i < N; i++) { 4012 TaskRecord task = mRecentTasks.get(i); 4013 if (task.userId != user) { 4014 // Only look at tasks for the user ID of interest. 4015 continue; 4016 } 4017 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4018 // This situation is broken, and we should just get rid of it now. 4019 mRecentTasks.remove(i); 4020 task.removedFromRecents(mTaskPersister); 4021 i--; 4022 N--; 4023 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4024 continue; 4025 } 4026 // Check whether this activity is currently available. 4027 if (task.realActivity != null) { 4028 ActivityInfo ai = availActCache.get(task.realActivity); 4029 if (ai == null) { 4030 try { 4031 ai = pm.getActivityInfo(task.realActivity, 4032 PackageManager.GET_UNINSTALLED_PACKAGES 4033 | PackageManager.GET_DISABLED_COMPONENTS, user); 4034 } catch (RemoteException e) { 4035 // Will never happen. 4036 continue; 4037 } 4038 if (ai == null) { 4039 ai = dummyAct; 4040 } 4041 availActCache.put(task.realActivity, ai); 4042 } 4043 if (ai == dummyAct) { 4044 // This could be either because the activity no longer exists, or the 4045 // app is temporarily gone. For the former we want to remove the recents 4046 // entry; for the latter we want to mark it as unavailable. 4047 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4048 if (app == null) { 4049 try { 4050 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4051 PackageManager.GET_UNINSTALLED_PACKAGES 4052 | PackageManager.GET_DISABLED_COMPONENTS, user); 4053 } catch (RemoteException e) { 4054 // Will never happen. 4055 continue; 4056 } 4057 if (app == null) { 4058 app = dummyApp; 4059 } 4060 availAppCache.put(task.realActivity.getPackageName(), app); 4061 } 4062 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4063 // Doesn't exist any more! Good-bye. 4064 mRecentTasks.remove(i); 4065 task.removedFromRecents(mTaskPersister); 4066 i--; 4067 N--; 4068 Slog.w(TAG, "Removing no longer valid recent: " + task); 4069 continue; 4070 } else { 4071 // Otherwise just not available for now. 4072 if (task.isAvailable) { 4073 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4074 + task); 4075 } 4076 task.isAvailable = false; 4077 } 4078 } else { 4079 if (!ai.enabled || !ai.applicationInfo.enabled 4080 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4081 if (task.isAvailable) { 4082 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4083 + task + " (enabled=" + ai.enabled + "/" 4084 + ai.applicationInfo.enabled + " flags=" 4085 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4086 } 4087 task.isAvailable = false; 4088 } else { 4089 if (!task.isAvailable) { 4090 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4091 + task); 4092 } 4093 task.isAvailable = true; 4094 } 4095 } 4096 } 4097 } 4098 } 4099 4100 // Verify the affiliate chain for each task. 4101 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4102 } 4103 4104 mTmpRecents.clear(); 4105 // mRecentTasks is now in sorted, affiliated order. 4106 } 4107 4108 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4109 int N = mRecentTasks.size(); 4110 TaskRecord top = task; 4111 int topIndex = taskIndex; 4112 while (top.mNextAffiliate != null && topIndex > 0) { 4113 top = top.mNextAffiliate; 4114 topIndex--; 4115 } 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4117 + topIndex + " from intial " + taskIndex); 4118 // Find the end of the chain, doing a sanity check along the way. 4119 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4120 int endIndex = topIndex; 4121 TaskRecord prev = top; 4122 while (endIndex < N) { 4123 TaskRecord cur = mRecentTasks.get(endIndex); 4124 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4125 + endIndex + " " + cur); 4126 if (cur == top) { 4127 // Verify start of the chain. 4128 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4129 Slog.wtf(TAG, "Bad chain @" + endIndex 4130 + ": first task has next affiliate: " + prev); 4131 sane = false; 4132 break; 4133 } 4134 } else { 4135 // Verify middle of the chain's next points back to the one before. 4136 if (cur.mNextAffiliate != prev 4137 || cur.mNextAffiliateTaskId != prev.taskId) { 4138 Slog.wtf(TAG, "Bad chain @" + endIndex 4139 + ": middle task " + cur + " @" + endIndex 4140 + " has bad next affiliate " 4141 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4142 + ", expected " + prev); 4143 sane = false; 4144 break; 4145 } 4146 } 4147 if (cur.mPrevAffiliateTaskId == -1) { 4148 // Chain ends here. 4149 if (cur.mPrevAffiliate != null) { 4150 Slog.wtf(TAG, "Bad chain @" + endIndex 4151 + ": last task " + cur + " has previous affiliate " 4152 + cur.mPrevAffiliate); 4153 sane = false; 4154 } 4155 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4156 break; 4157 } else { 4158 // Verify middle of the chain's prev points to a valid item. 4159 if (cur.mPrevAffiliate == null) { 4160 Slog.wtf(TAG, "Bad chain @" + endIndex 4161 + ": task " + cur + " has previous affiliate " 4162 + cur.mPrevAffiliate + " but should be id " 4163 + cur.mPrevAffiliate); 4164 sane = false; 4165 break; 4166 } 4167 } 4168 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4169 Slog.wtf(TAG, "Bad chain @" + endIndex 4170 + ": task " + cur + " has affiliated id " 4171 + cur.mAffiliatedTaskId + " but should be " 4172 + task.mAffiliatedTaskId); 4173 sane = false; 4174 break; 4175 } 4176 prev = cur; 4177 endIndex++; 4178 if (endIndex >= N) { 4179 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4180 + ": last task " + prev); 4181 sane = false; 4182 break; 4183 } 4184 } 4185 if (sane) { 4186 if (endIndex < taskIndex) { 4187 Slog.wtf(TAG, "Bad chain @" + endIndex 4188 + ": did not extend to task " + task + " @" + taskIndex); 4189 sane = false; 4190 } 4191 } 4192 if (sane) { 4193 // All looks good, we can just move all of the affiliated tasks 4194 // to the top. 4195 for (int i=topIndex; i<=endIndex; i++) { 4196 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4197 + " from " + i + " to " + (i-topIndex)); 4198 TaskRecord cur = mRecentTasks.remove(i); 4199 mRecentTasks.add(i-topIndex, cur); 4200 } 4201 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4202 + " to " + endIndex); 4203 return true; 4204 } 4205 4206 // Whoops, couldn't do it. 4207 return false; 4208 } 4209 4210 final void addRecentTaskLocked(TaskRecord task) { 4211 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4212 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4213 4214 int N = mRecentTasks.size(); 4215 // Quick case: check if the top-most recent task is the same. 4216 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4218 return; 4219 } 4220 // Another quick case: check if this is part of a set of affiliated 4221 // tasks that are at the top. 4222 if (isAffiliated && N > 0 && task.inRecents 4223 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4224 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4225 + " at top when adding " + task); 4226 return; 4227 } 4228 // Another quick case: never add voice sessions. 4229 if (task.voiceSession != null) { 4230 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4231 return; 4232 } 4233 4234 boolean needAffiliationFix = false; 4235 4236 // Slightly less quick case: the task is already in recents, so all we need 4237 // to do is move it. 4238 if (task.inRecents) { 4239 int taskIndex = mRecentTasks.indexOf(task); 4240 if (taskIndex >= 0) { 4241 if (!isAffiliated) { 4242 // Simple case: this is not an affiliated task, so we just move it to the front. 4243 mRecentTasks.remove(taskIndex); 4244 mRecentTasks.add(0, task); 4245 notifyTaskPersisterLocked(task, false); 4246 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4247 + " from " + taskIndex); 4248 return; 4249 } else { 4250 // More complicated: need to keep all affiliated tasks together. 4251 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4252 // All went well. 4253 return; 4254 } 4255 4256 // Uh oh... something bad in the affiliation chain, try to rebuild 4257 // everything and then go through our general path of adding a new task. 4258 needAffiliationFix = true; 4259 } 4260 } else { 4261 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4262 needAffiliationFix = true; 4263 } 4264 } 4265 4266 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4267 trimRecentsForTask(task, true); 4268 4269 N = mRecentTasks.size(); 4270 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4271 final TaskRecord tr = mRecentTasks.remove(N - 1); 4272 tr.removedFromRecents(mTaskPersister); 4273 N--; 4274 } 4275 task.inRecents = true; 4276 if (!isAffiliated || needAffiliationFix) { 4277 // If this is a simple non-affiliated task, or we had some failure trying to 4278 // handle it as part of an affilated task, then just place it at the top. 4279 mRecentTasks.add(0, task); 4280 } else if (isAffiliated) { 4281 // If this is a new affiliated task, then move all of the affiliated tasks 4282 // to the front and insert this new one. 4283 TaskRecord other = task.mNextAffiliate; 4284 if (other == null) { 4285 other = task.mPrevAffiliate; 4286 } 4287 if (other != null) { 4288 int otherIndex = mRecentTasks.indexOf(other); 4289 if (otherIndex >= 0) { 4290 // Insert new task at appropriate location. 4291 int taskIndex; 4292 if (other == task.mNextAffiliate) { 4293 // We found the index of our next affiliation, which is who is 4294 // before us in the list, so add after that point. 4295 taskIndex = otherIndex+1; 4296 } else { 4297 // We found the index of our previous affiliation, which is who is 4298 // after us in the list, so add at their position. 4299 taskIndex = otherIndex; 4300 } 4301 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4302 + taskIndex + ": " + task); 4303 mRecentTasks.add(taskIndex, task); 4304 4305 // Now move everything to the front. 4306 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4307 // All went well. 4308 return; 4309 } 4310 4311 // Uh oh... something bad in the affiliation chain, try to rebuild 4312 // everything and then go through our general path of adding a new task. 4313 needAffiliationFix = true; 4314 } else { 4315 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4316 + other); 4317 needAffiliationFix = true; 4318 } 4319 } else { 4320 if (DEBUG_RECENTS) Slog.d(TAG, 4321 "addRecent: adding affiliated task without next/prev:" + task); 4322 needAffiliationFix = true; 4323 } 4324 } 4325 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4326 4327 if (needAffiliationFix) { 4328 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4329 cleanupRecentTasksLocked(task.userId); 4330 } 4331 } 4332 4333 /** 4334 * If needed, remove oldest existing entries in recents that are for the same kind 4335 * of task as the given one. 4336 */ 4337 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4338 int N = mRecentTasks.size(); 4339 final Intent intent = task.intent; 4340 final boolean document = intent != null && intent.isDocument(); 4341 4342 int maxRecents = task.maxRecents - 1; 4343 for (int i=0; i<N; i++) { 4344 final TaskRecord tr = mRecentTasks.get(i); 4345 if (task != tr) { 4346 if (task.userId != tr.userId) { 4347 continue; 4348 } 4349 if (i > MAX_RECENT_BITMAPS) { 4350 tr.freeLastThumbnail(); 4351 } 4352 final Intent trIntent = tr.intent; 4353 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4354 (intent == null || !intent.filterEquals(trIntent))) { 4355 continue; 4356 } 4357 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4358 if (document && trIsDocument) { 4359 // These are the same document activity (not necessarily the same doc). 4360 if (maxRecents > 0) { 4361 --maxRecents; 4362 continue; 4363 } 4364 // Hit the maximum number of documents for this task. Fall through 4365 // and remove this document from recents. 4366 } else if (document || trIsDocument) { 4367 // Only one of these is a document. Not the droid we're looking for. 4368 continue; 4369 } 4370 } 4371 4372 if (!doTrim) { 4373 // If the caller is not actually asking for a trim, just tell them we reached 4374 // a point where the trim would happen. 4375 return i; 4376 } 4377 4378 // Either task and tr are the same or, their affinities match or their intents match 4379 // and neither of them is a document, or they are documents using the same activity 4380 // and their maxRecents has been reached. 4381 tr.disposeThumbnail(); 4382 mRecentTasks.remove(i); 4383 if (task != tr) { 4384 tr.removedFromRecents(mTaskPersister); 4385 } 4386 i--; 4387 N--; 4388 if (task.intent == null) { 4389 // If the new recent task we are adding is not fully 4390 // specified, then replace it with the existing recent task. 4391 task = tr; 4392 } 4393 notifyTaskPersisterLocked(tr, false); 4394 } 4395 4396 return -1; 4397 } 4398 4399 @Override 4400 public void reportActivityFullyDrawn(IBinder token) { 4401 synchronized (this) { 4402 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4403 if (r == null) { 4404 return; 4405 } 4406 r.reportFullyDrawnLocked(); 4407 } 4408 } 4409 4410 @Override 4411 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4412 synchronized (this) { 4413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4414 if (r == null) { 4415 return; 4416 } 4417 final long origId = Binder.clearCallingIdentity(); 4418 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4419 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4420 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4421 if (config != null) { 4422 r.frozenBeforeDestroy = true; 4423 if (!updateConfigurationLocked(config, r, false, false)) { 4424 mStackSupervisor.resumeTopActivitiesLocked(); 4425 } 4426 } 4427 Binder.restoreCallingIdentity(origId); 4428 } 4429 } 4430 4431 @Override 4432 public int getRequestedOrientation(IBinder token) { 4433 synchronized (this) { 4434 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4435 if (r == null) { 4436 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4437 } 4438 return mWindowManager.getAppOrientation(r.appToken); 4439 } 4440 } 4441 4442 /** 4443 * This is the internal entry point for handling Activity.finish(). 4444 * 4445 * @param token The Binder token referencing the Activity we want to finish. 4446 * @param resultCode Result code, if any, from this Activity. 4447 * @param resultData Result data (Intent), if any, from this Activity. 4448 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4449 * the root Activity in the task. 4450 * 4451 * @return Returns true if the activity successfully finished, or false if it is still running. 4452 */ 4453 @Override 4454 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4455 boolean finishTask) { 4456 // Refuse possible leaked file descriptors 4457 if (resultData != null && resultData.hasFileDescriptors() == true) { 4458 throw new IllegalArgumentException("File descriptors passed in Intent"); 4459 } 4460 4461 synchronized(this) { 4462 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4463 if (r == null) { 4464 return true; 4465 } 4466 // Keep track of the root activity of the task before we finish it 4467 TaskRecord tr = r.task; 4468 ActivityRecord rootR = tr.getRootActivity(); 4469 // Do not allow task to finish in Lock Task mode. 4470 if (tr == mStackSupervisor.mLockTaskModeTask) { 4471 if (rootR == r) { 4472 mStackSupervisor.showLockTaskToast(); 4473 return false; 4474 } 4475 } 4476 if (mController != null) { 4477 // Find the first activity that is not finishing. 4478 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4479 if (next != null) { 4480 // ask watcher if this is allowed 4481 boolean resumeOK = true; 4482 try { 4483 resumeOK = mController.activityResuming(next.packageName); 4484 } catch (RemoteException e) { 4485 mController = null; 4486 Watchdog.getInstance().setActivityController(null); 4487 } 4488 4489 if (!resumeOK) { 4490 return false; 4491 } 4492 } 4493 } 4494 final long origId = Binder.clearCallingIdentity(); 4495 try { 4496 boolean res; 4497 if (finishTask && r == rootR) { 4498 // If requested, remove the task that is associated to this activity only if it 4499 // was the root activity in the task. The result code and data is ignored because 4500 // we don't support returning them across task boundaries. 4501 res = removeTaskByIdLocked(tr.taskId, 0); 4502 } else { 4503 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4504 resultData, "app-request", true); 4505 } 4506 return res; 4507 } finally { 4508 Binder.restoreCallingIdentity(origId); 4509 } 4510 } 4511 } 4512 4513 @Override 4514 public final void finishHeavyWeightApp() { 4515 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4516 != PackageManager.PERMISSION_GRANTED) { 4517 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4518 + Binder.getCallingPid() 4519 + ", uid=" + Binder.getCallingUid() 4520 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4521 Slog.w(TAG, msg); 4522 throw new SecurityException(msg); 4523 } 4524 4525 synchronized(this) { 4526 if (mHeavyWeightProcess == null) { 4527 return; 4528 } 4529 4530 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4531 mHeavyWeightProcess.activities); 4532 for (int i=0; i<activities.size(); i++) { 4533 ActivityRecord r = activities.get(i); 4534 if (!r.finishing) { 4535 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4536 null, "finish-heavy", true); 4537 } 4538 } 4539 4540 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4541 mHeavyWeightProcess.userId, 0)); 4542 mHeavyWeightProcess = null; 4543 } 4544 } 4545 4546 @Override 4547 public void crashApplication(int uid, int initialPid, String packageName, 4548 String message) { 4549 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4550 != PackageManager.PERMISSION_GRANTED) { 4551 String msg = "Permission Denial: crashApplication() from pid=" 4552 + Binder.getCallingPid() 4553 + ", uid=" + Binder.getCallingUid() 4554 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4555 Slog.w(TAG, msg); 4556 throw new SecurityException(msg); 4557 } 4558 4559 synchronized(this) { 4560 ProcessRecord proc = null; 4561 4562 // Figure out which process to kill. We don't trust that initialPid 4563 // still has any relation to current pids, so must scan through the 4564 // list. 4565 synchronized (mPidsSelfLocked) { 4566 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4567 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4568 if (p.uid != uid) { 4569 continue; 4570 } 4571 if (p.pid == initialPid) { 4572 proc = p; 4573 break; 4574 } 4575 if (p.pkgList.containsKey(packageName)) { 4576 proc = p; 4577 } 4578 } 4579 } 4580 4581 if (proc == null) { 4582 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4583 + " initialPid=" + initialPid 4584 + " packageName=" + packageName); 4585 return; 4586 } 4587 4588 if (proc.thread != null) { 4589 if (proc.pid == Process.myPid()) { 4590 Log.w(TAG, "crashApplication: trying to crash self!"); 4591 return; 4592 } 4593 long ident = Binder.clearCallingIdentity(); 4594 try { 4595 proc.thread.scheduleCrash(message); 4596 } catch (RemoteException e) { 4597 } 4598 Binder.restoreCallingIdentity(ident); 4599 } 4600 } 4601 } 4602 4603 @Override 4604 public final void finishSubActivity(IBinder token, String resultWho, 4605 int requestCode) { 4606 synchronized(this) { 4607 final long origId = Binder.clearCallingIdentity(); 4608 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4609 if (r != null) { 4610 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4611 } 4612 Binder.restoreCallingIdentity(origId); 4613 } 4614 } 4615 4616 @Override 4617 public boolean finishActivityAffinity(IBinder token) { 4618 synchronized(this) { 4619 final long origId = Binder.clearCallingIdentity(); 4620 try { 4621 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4622 4623 ActivityRecord rootR = r.task.getRootActivity(); 4624 // Do not allow task to finish in Lock Task mode. 4625 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4626 if (rootR == r) { 4627 mStackSupervisor.showLockTaskToast(); 4628 return false; 4629 } 4630 } 4631 boolean res = false; 4632 if (r != null) { 4633 res = r.task.stack.finishActivityAffinityLocked(r); 4634 } 4635 return res; 4636 } finally { 4637 Binder.restoreCallingIdentity(origId); 4638 } 4639 } 4640 } 4641 4642 @Override 4643 public void finishVoiceTask(IVoiceInteractionSession session) { 4644 synchronized(this) { 4645 final long origId = Binder.clearCallingIdentity(); 4646 try { 4647 mStackSupervisor.finishVoiceTask(session); 4648 } finally { 4649 Binder.restoreCallingIdentity(origId); 4650 } 4651 } 4652 4653 } 4654 4655 @Override 4656 public boolean releaseActivityInstance(IBinder token) { 4657 synchronized(this) { 4658 final long origId = Binder.clearCallingIdentity(); 4659 try { 4660 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4661 if (r.task == null || r.task.stack == null) { 4662 return false; 4663 } 4664 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4665 } finally { 4666 Binder.restoreCallingIdentity(origId); 4667 } 4668 } 4669 } 4670 4671 @Override 4672 public void releaseSomeActivities(IApplicationThread appInt) { 4673 synchronized(this) { 4674 final long origId = Binder.clearCallingIdentity(); 4675 try { 4676 ProcessRecord app = getRecordForAppLocked(appInt); 4677 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4678 } finally { 4679 Binder.restoreCallingIdentity(origId); 4680 } 4681 } 4682 } 4683 4684 @Override 4685 public boolean willActivityBeVisible(IBinder token) { 4686 synchronized(this) { 4687 ActivityStack stack = ActivityRecord.getStackLocked(token); 4688 if (stack != null) { 4689 return stack.willActivityBeVisibleLocked(token); 4690 } 4691 return false; 4692 } 4693 } 4694 4695 @Override 4696 public void overridePendingTransition(IBinder token, String packageName, 4697 int enterAnim, int exitAnim) { 4698 synchronized(this) { 4699 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4700 if (self == null) { 4701 return; 4702 } 4703 4704 final long origId = Binder.clearCallingIdentity(); 4705 4706 if (self.state == ActivityState.RESUMED 4707 || self.state == ActivityState.PAUSING) { 4708 mWindowManager.overridePendingAppTransition(packageName, 4709 enterAnim, exitAnim, null); 4710 } 4711 4712 Binder.restoreCallingIdentity(origId); 4713 } 4714 } 4715 4716 /** 4717 * Main function for removing an existing process from the activity manager 4718 * as a result of that process going away. Clears out all connections 4719 * to the process. 4720 */ 4721 private final void handleAppDiedLocked(ProcessRecord app, 4722 boolean restarting, boolean allowRestart) { 4723 int pid = app.pid; 4724 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4725 if (!kept && !restarting) { 4726 removeLruProcessLocked(app); 4727 if (pid > 0) { 4728 ProcessList.remove(pid); 4729 } 4730 } 4731 4732 if (mProfileProc == app) { 4733 clearProfilerLocked(); 4734 } 4735 4736 // Remove this application's activities from active lists. 4737 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4738 4739 app.activities.clear(); 4740 4741 if (app.instrumentationClass != null) { 4742 Slog.w(TAG, "Crash of app " + app.processName 4743 + " running instrumentation " + app.instrumentationClass); 4744 Bundle info = new Bundle(); 4745 info.putString("shortMsg", "Process crashed."); 4746 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4747 } 4748 4749 if (!restarting) { 4750 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4751 // If there was nothing to resume, and we are not already 4752 // restarting this process, but there is a visible activity that 4753 // is hosted by the process... then make sure all visible 4754 // activities are running, taking care of restarting this 4755 // process. 4756 if (hasVisibleActivities) { 4757 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4758 } 4759 } 4760 } 4761 } 4762 4763 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4764 IBinder threadBinder = thread.asBinder(); 4765 // Find the application record. 4766 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4767 ProcessRecord rec = mLruProcesses.get(i); 4768 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4769 return i; 4770 } 4771 } 4772 return -1; 4773 } 4774 4775 final ProcessRecord getRecordForAppLocked( 4776 IApplicationThread thread) { 4777 if (thread == null) { 4778 return null; 4779 } 4780 4781 int appIndex = getLRURecordIndexForAppLocked(thread); 4782 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4783 } 4784 4785 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4786 // If there are no longer any background processes running, 4787 // and the app that died was not running instrumentation, 4788 // then tell everyone we are now low on memory. 4789 boolean haveBg = false; 4790 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4791 ProcessRecord rec = mLruProcesses.get(i); 4792 if (rec.thread != null 4793 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4794 haveBg = true; 4795 break; 4796 } 4797 } 4798 4799 if (!haveBg) { 4800 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4801 if (doReport) { 4802 long now = SystemClock.uptimeMillis(); 4803 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4804 doReport = false; 4805 } else { 4806 mLastMemUsageReportTime = now; 4807 } 4808 } 4809 final ArrayList<ProcessMemInfo> memInfos 4810 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4811 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4812 long now = SystemClock.uptimeMillis(); 4813 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4814 ProcessRecord rec = mLruProcesses.get(i); 4815 if (rec == dyingProc || rec.thread == null) { 4816 continue; 4817 } 4818 if (doReport) { 4819 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4820 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4821 } 4822 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4823 // The low memory report is overriding any current 4824 // state for a GC request. Make sure to do 4825 // heavy/important/visible/foreground processes first. 4826 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4827 rec.lastRequestedGc = 0; 4828 } else { 4829 rec.lastRequestedGc = rec.lastLowMemory; 4830 } 4831 rec.reportLowMemory = true; 4832 rec.lastLowMemory = now; 4833 mProcessesToGc.remove(rec); 4834 addProcessToGcListLocked(rec); 4835 } 4836 } 4837 if (doReport) { 4838 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4839 mHandler.sendMessage(msg); 4840 } 4841 scheduleAppGcsLocked(); 4842 } 4843 } 4844 4845 final void appDiedLocked(ProcessRecord app) { 4846 appDiedLocked(app, app.pid, app.thread); 4847 } 4848 4849 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4850 // First check if this ProcessRecord is actually active for the pid. 4851 synchronized (mPidsSelfLocked) { 4852 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4853 if (curProc != app) { 4854 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4855 return; 4856 } 4857 } 4858 4859 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4860 synchronized (stats) { 4861 stats.noteProcessDiedLocked(app.info.uid, pid); 4862 } 4863 4864 Process.killProcessQuiet(pid); 4865 Process.killProcessGroup(app.info.uid, pid); 4866 app.killed = true; 4867 4868 // Clean up already done if the process has been re-started. 4869 if (app.pid == pid && app.thread != null && 4870 app.thread.asBinder() == thread.asBinder()) { 4871 boolean doLowMem = app.instrumentationClass == null; 4872 boolean doOomAdj = doLowMem; 4873 if (!app.killedByAm) { 4874 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4875 + ") has died"); 4876 mAllowLowerMemLevel = true; 4877 } else { 4878 // Note that we always want to do oom adj to update our state with the 4879 // new number of procs. 4880 mAllowLowerMemLevel = false; 4881 doLowMem = false; 4882 } 4883 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4884 if (DEBUG_CLEANUP) Slog.v( 4885 TAG, "Dying app: " + app + ", pid: " + pid 4886 + ", thread: " + thread.asBinder()); 4887 handleAppDiedLocked(app, false, true); 4888 4889 if (doOomAdj) { 4890 updateOomAdjLocked(); 4891 } 4892 if (doLowMem) { 4893 doLowMemReportIfNeededLocked(app); 4894 } 4895 } else if (app.pid != pid) { 4896 // A new process has already been started. 4897 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4898 + ") has died and restarted (pid " + app.pid + ")."); 4899 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4900 } else if (DEBUG_PROCESSES) { 4901 Slog.d(TAG, "Received spurious death notification for thread " 4902 + thread.asBinder()); 4903 } 4904 } 4905 4906 /** 4907 * If a stack trace dump file is configured, dump process stack traces. 4908 * @param clearTraces causes the dump file to be erased prior to the new 4909 * traces being written, if true; when false, the new traces will be 4910 * appended to any existing file content. 4911 * @param firstPids of dalvik VM processes to dump stack traces for first 4912 * @param lastPids of dalvik VM processes to dump stack traces for last 4913 * @param nativeProcs optional list of native process names to dump stack crawls 4914 * @return file containing stack traces, or null if no dump file is configured 4915 */ 4916 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4917 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4918 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4919 if (tracesPath == null || tracesPath.length() == 0) { 4920 return null; 4921 } 4922 4923 File tracesFile = new File(tracesPath); 4924 try { 4925 File tracesDir = tracesFile.getParentFile(); 4926 if (!tracesDir.exists()) { 4927 tracesDir.mkdirs(); 4928 if (!SELinux.restorecon(tracesDir)) { 4929 return null; 4930 } 4931 } 4932 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4933 4934 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4935 tracesFile.createNewFile(); 4936 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4937 } catch (IOException e) { 4938 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4939 return null; 4940 } 4941 4942 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4943 return tracesFile; 4944 } 4945 4946 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4947 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4948 // Use a FileObserver to detect when traces finish writing. 4949 // The order of traces is considered important to maintain for legibility. 4950 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4951 @Override 4952 public synchronized void onEvent(int event, String path) { notify(); } 4953 }; 4954 4955 try { 4956 observer.startWatching(); 4957 4958 // First collect all of the stacks of the most important pids. 4959 if (firstPids != null) { 4960 try { 4961 int num = firstPids.size(); 4962 for (int i = 0; i < num; i++) { 4963 synchronized (observer) { 4964 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4965 observer.wait(200); // Wait for write-close, give up after 200msec 4966 } 4967 } 4968 } catch (InterruptedException e) { 4969 Slog.wtf(TAG, e); 4970 } 4971 } 4972 4973 // Next collect the stacks of the native pids 4974 if (nativeProcs != null) { 4975 int[] pids = Process.getPidsForCommands(nativeProcs); 4976 if (pids != null) { 4977 for (int pid : pids) { 4978 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4979 } 4980 } 4981 } 4982 4983 // Lastly, measure CPU usage. 4984 if (processCpuTracker != null) { 4985 processCpuTracker.init(); 4986 System.gc(); 4987 processCpuTracker.update(); 4988 try { 4989 synchronized (processCpuTracker) { 4990 processCpuTracker.wait(500); // measure over 1/2 second. 4991 } 4992 } catch (InterruptedException e) { 4993 } 4994 processCpuTracker.update(); 4995 4996 // We'll take the stack crawls of just the top apps using CPU. 4997 final int N = processCpuTracker.countWorkingStats(); 4998 int numProcs = 0; 4999 for (int i=0; i<N && numProcs<5; i++) { 5000 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5001 if (lastPids.indexOfKey(stats.pid) >= 0) { 5002 numProcs++; 5003 try { 5004 synchronized (observer) { 5005 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5006 observer.wait(200); // Wait for write-close, give up after 200msec 5007 } 5008 } catch (InterruptedException e) { 5009 Slog.wtf(TAG, e); 5010 } 5011 5012 } 5013 } 5014 } 5015 } finally { 5016 observer.stopWatching(); 5017 } 5018 } 5019 5020 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5021 if (true || IS_USER_BUILD) { 5022 return; 5023 } 5024 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5025 if (tracesPath == null || tracesPath.length() == 0) { 5026 return; 5027 } 5028 5029 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5030 StrictMode.allowThreadDiskWrites(); 5031 try { 5032 final File tracesFile = new File(tracesPath); 5033 final File tracesDir = tracesFile.getParentFile(); 5034 final File tracesTmp = new File(tracesDir, "__tmp__"); 5035 try { 5036 if (!tracesDir.exists()) { 5037 tracesDir.mkdirs(); 5038 if (!SELinux.restorecon(tracesDir.getPath())) { 5039 return; 5040 } 5041 } 5042 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5043 5044 if (tracesFile.exists()) { 5045 tracesTmp.delete(); 5046 tracesFile.renameTo(tracesTmp); 5047 } 5048 StringBuilder sb = new StringBuilder(); 5049 Time tobj = new Time(); 5050 tobj.set(System.currentTimeMillis()); 5051 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5052 sb.append(": "); 5053 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5054 sb.append(" since "); 5055 sb.append(msg); 5056 FileOutputStream fos = new FileOutputStream(tracesFile); 5057 fos.write(sb.toString().getBytes()); 5058 if (app == null) { 5059 fos.write("\n*** No application process!".getBytes()); 5060 } 5061 fos.close(); 5062 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5063 } catch (IOException e) { 5064 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5065 return; 5066 } 5067 5068 if (app != null) { 5069 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5070 firstPids.add(app.pid); 5071 dumpStackTraces(tracesPath, firstPids, null, null, null); 5072 } 5073 5074 File lastTracesFile = null; 5075 File curTracesFile = null; 5076 for (int i=9; i>=0; i--) { 5077 String name = String.format(Locale.US, "slow%02d.txt", i); 5078 curTracesFile = new File(tracesDir, name); 5079 if (curTracesFile.exists()) { 5080 if (lastTracesFile != null) { 5081 curTracesFile.renameTo(lastTracesFile); 5082 } else { 5083 curTracesFile.delete(); 5084 } 5085 } 5086 lastTracesFile = curTracesFile; 5087 } 5088 tracesFile.renameTo(curTracesFile); 5089 if (tracesTmp.exists()) { 5090 tracesTmp.renameTo(tracesFile); 5091 } 5092 } finally { 5093 StrictMode.setThreadPolicy(oldPolicy); 5094 } 5095 } 5096 5097 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5098 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5099 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5100 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5101 5102 if (mController != null) { 5103 try { 5104 // 0 == continue, -1 = kill process immediately 5105 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5106 if (res < 0 && app.pid != MY_PID) { 5107 app.kill("anr", true); 5108 } 5109 } catch (RemoteException e) { 5110 mController = null; 5111 Watchdog.getInstance().setActivityController(null); 5112 } 5113 } 5114 5115 long anrTime = SystemClock.uptimeMillis(); 5116 if (MONITOR_CPU_USAGE) { 5117 updateCpuStatsNow(); 5118 } 5119 5120 synchronized (this) { 5121 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5122 if (mShuttingDown) { 5123 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5124 return; 5125 } else if (app.notResponding) { 5126 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5127 return; 5128 } else if (app.crashing) { 5129 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5130 return; 5131 } 5132 5133 // In case we come through here for the same app before completing 5134 // this one, mark as anring now so we will bail out. 5135 app.notResponding = true; 5136 5137 // Log the ANR to the event log. 5138 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5139 app.processName, app.info.flags, annotation); 5140 5141 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5142 firstPids.add(app.pid); 5143 5144 int parentPid = app.pid; 5145 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5146 if (parentPid != app.pid) firstPids.add(parentPid); 5147 5148 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5149 5150 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5151 ProcessRecord r = mLruProcesses.get(i); 5152 if (r != null && r.thread != null) { 5153 int pid = r.pid; 5154 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5155 if (r.persistent) { 5156 firstPids.add(pid); 5157 } else { 5158 lastPids.put(pid, Boolean.TRUE); 5159 } 5160 } 5161 } 5162 } 5163 } 5164 5165 // Log the ANR to the main log. 5166 StringBuilder info = new StringBuilder(); 5167 info.setLength(0); 5168 info.append("ANR in ").append(app.processName); 5169 if (activity != null && activity.shortComponentName != null) { 5170 info.append(" (").append(activity.shortComponentName).append(")"); 5171 } 5172 info.append("\n"); 5173 info.append("PID: ").append(app.pid).append("\n"); 5174 if (annotation != null) { 5175 info.append("Reason: ").append(annotation).append("\n"); 5176 } 5177 if (parent != null && parent != activity) { 5178 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5179 } 5180 5181 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5182 5183 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5184 NATIVE_STACKS_OF_INTEREST); 5185 5186 String cpuInfo = null; 5187 if (MONITOR_CPU_USAGE) { 5188 updateCpuStatsNow(); 5189 synchronized (mProcessCpuTracker) { 5190 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5191 } 5192 info.append(processCpuTracker.printCurrentLoad()); 5193 info.append(cpuInfo); 5194 } 5195 5196 info.append(processCpuTracker.printCurrentState(anrTime)); 5197 5198 Slog.e(TAG, info.toString()); 5199 if (tracesFile == null) { 5200 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5201 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5202 } 5203 5204 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5205 cpuInfo, tracesFile, null); 5206 5207 if (mController != null) { 5208 try { 5209 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5210 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5211 if (res != 0) { 5212 if (res < 0 && app.pid != MY_PID) { 5213 app.kill("anr", true); 5214 } else { 5215 synchronized (this) { 5216 mServices.scheduleServiceTimeoutLocked(app); 5217 } 5218 } 5219 return; 5220 } 5221 } catch (RemoteException e) { 5222 mController = null; 5223 Watchdog.getInstance().setActivityController(null); 5224 } 5225 } 5226 5227 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5228 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5229 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5230 5231 synchronized (this) { 5232 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5233 app.kill("bg anr", true); 5234 return; 5235 } 5236 5237 // Set the app's notResponding state, and look up the errorReportReceiver 5238 makeAppNotRespondingLocked(app, 5239 activity != null ? activity.shortComponentName : null, 5240 annotation != null ? "ANR " + annotation : "ANR", 5241 info.toString()); 5242 5243 // Bring up the infamous App Not Responding dialog 5244 Message msg = Message.obtain(); 5245 HashMap<String, Object> map = new HashMap<String, Object>(); 5246 msg.what = SHOW_NOT_RESPONDING_MSG; 5247 msg.obj = map; 5248 msg.arg1 = aboveSystem ? 1 : 0; 5249 map.put("app", app); 5250 if (activity != null) { 5251 map.put("activity", activity); 5252 } 5253 5254 mHandler.sendMessage(msg); 5255 } 5256 } 5257 5258 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5259 if (!mLaunchWarningShown) { 5260 mLaunchWarningShown = true; 5261 mHandler.post(new Runnable() { 5262 @Override 5263 public void run() { 5264 synchronized (ActivityManagerService.this) { 5265 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5266 d.show(); 5267 mHandler.postDelayed(new Runnable() { 5268 @Override 5269 public void run() { 5270 synchronized (ActivityManagerService.this) { 5271 d.dismiss(); 5272 mLaunchWarningShown = false; 5273 } 5274 } 5275 }, 4000); 5276 } 5277 } 5278 }); 5279 } 5280 } 5281 5282 @Override 5283 public boolean clearApplicationUserData(final String packageName, 5284 final IPackageDataObserver observer, int userId) { 5285 enforceNotIsolatedCaller("clearApplicationUserData"); 5286 int uid = Binder.getCallingUid(); 5287 int pid = Binder.getCallingPid(); 5288 userId = handleIncomingUser(pid, uid, 5289 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5290 long callingId = Binder.clearCallingIdentity(); 5291 try { 5292 IPackageManager pm = AppGlobals.getPackageManager(); 5293 int pkgUid = -1; 5294 synchronized(this) { 5295 try { 5296 pkgUid = pm.getPackageUid(packageName, userId); 5297 } catch (RemoteException e) { 5298 } 5299 if (pkgUid == -1) { 5300 Slog.w(TAG, "Invalid packageName: " + packageName); 5301 if (observer != null) { 5302 try { 5303 observer.onRemoveCompleted(packageName, false); 5304 } catch (RemoteException e) { 5305 Slog.i(TAG, "Observer no longer exists."); 5306 } 5307 } 5308 return false; 5309 } 5310 if (uid == pkgUid || checkComponentPermission( 5311 android.Manifest.permission.CLEAR_APP_USER_DATA, 5312 pid, uid, -1, true) 5313 == PackageManager.PERMISSION_GRANTED) { 5314 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5315 } else { 5316 throw new SecurityException("PID " + pid + " does not have permission " 5317 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5318 + " of package " + packageName); 5319 } 5320 5321 // Remove all tasks match the cleared application package and user 5322 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5323 final TaskRecord tr = mRecentTasks.get(i); 5324 final String taskPackageName = 5325 tr.getBaseIntent().getComponent().getPackageName(); 5326 if (tr.userId != userId) continue; 5327 if (!taskPackageName.equals(packageName)) continue; 5328 removeTaskByIdLocked(tr.taskId, 0); 5329 } 5330 } 5331 5332 try { 5333 // Clear application user data 5334 pm.clearApplicationUserData(packageName, observer, userId); 5335 5336 synchronized(this) { 5337 // Remove all permissions granted from/to this package 5338 removeUriPermissionsForPackageLocked(packageName, userId, true); 5339 } 5340 5341 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5342 Uri.fromParts("package", packageName, null)); 5343 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5344 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5345 null, null, 0, null, null, null, false, false, userId); 5346 } catch (RemoteException e) { 5347 } 5348 } finally { 5349 Binder.restoreCallingIdentity(callingId); 5350 } 5351 return true; 5352 } 5353 5354 @Override 5355 public void killBackgroundProcesses(final String packageName, int userId) { 5356 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5357 != PackageManager.PERMISSION_GRANTED && 5358 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5359 != PackageManager.PERMISSION_GRANTED) { 5360 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5361 + Binder.getCallingPid() 5362 + ", uid=" + Binder.getCallingUid() 5363 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5364 Slog.w(TAG, msg); 5365 throw new SecurityException(msg); 5366 } 5367 5368 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5369 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5370 long callingId = Binder.clearCallingIdentity(); 5371 try { 5372 IPackageManager pm = AppGlobals.getPackageManager(); 5373 synchronized(this) { 5374 int appId = -1; 5375 try { 5376 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5377 } catch (RemoteException e) { 5378 } 5379 if (appId == -1) { 5380 Slog.w(TAG, "Invalid packageName: " + packageName); 5381 return; 5382 } 5383 killPackageProcessesLocked(packageName, appId, userId, 5384 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5385 } 5386 } finally { 5387 Binder.restoreCallingIdentity(callingId); 5388 } 5389 } 5390 5391 @Override 5392 public void killAllBackgroundProcesses() { 5393 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5394 != PackageManager.PERMISSION_GRANTED) { 5395 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5396 + Binder.getCallingPid() 5397 + ", uid=" + Binder.getCallingUid() 5398 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5399 Slog.w(TAG, msg); 5400 throw new SecurityException(msg); 5401 } 5402 5403 long callingId = Binder.clearCallingIdentity(); 5404 try { 5405 synchronized(this) { 5406 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5407 final int NP = mProcessNames.getMap().size(); 5408 for (int ip=0; ip<NP; ip++) { 5409 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5410 final int NA = apps.size(); 5411 for (int ia=0; ia<NA; ia++) { 5412 ProcessRecord app = apps.valueAt(ia); 5413 if (app.persistent) { 5414 // we don't kill persistent processes 5415 continue; 5416 } 5417 if (app.removed) { 5418 procs.add(app); 5419 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5420 app.removed = true; 5421 procs.add(app); 5422 } 5423 } 5424 } 5425 5426 int N = procs.size(); 5427 for (int i=0; i<N; i++) { 5428 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5429 } 5430 mAllowLowerMemLevel = true; 5431 updateOomAdjLocked(); 5432 doLowMemReportIfNeededLocked(null); 5433 } 5434 } finally { 5435 Binder.restoreCallingIdentity(callingId); 5436 } 5437 } 5438 5439 @Override 5440 public void forceStopPackage(final String packageName, int userId) { 5441 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5442 != PackageManager.PERMISSION_GRANTED) { 5443 String msg = "Permission Denial: forceStopPackage() from pid=" 5444 + Binder.getCallingPid() 5445 + ", uid=" + Binder.getCallingUid() 5446 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5447 Slog.w(TAG, msg); 5448 throw new SecurityException(msg); 5449 } 5450 final int callingPid = Binder.getCallingPid(); 5451 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5452 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5453 long callingId = Binder.clearCallingIdentity(); 5454 try { 5455 IPackageManager pm = AppGlobals.getPackageManager(); 5456 synchronized(this) { 5457 int[] users = userId == UserHandle.USER_ALL 5458 ? getUsersLocked() : new int[] { userId }; 5459 for (int user : users) { 5460 int pkgUid = -1; 5461 try { 5462 pkgUid = pm.getPackageUid(packageName, user); 5463 } catch (RemoteException e) { 5464 } 5465 if (pkgUid == -1) { 5466 Slog.w(TAG, "Invalid packageName: " + packageName); 5467 continue; 5468 } 5469 try { 5470 pm.setPackageStoppedState(packageName, true, user); 5471 } catch (RemoteException e) { 5472 } catch (IllegalArgumentException e) { 5473 Slog.w(TAG, "Failed trying to unstop package " 5474 + packageName + ": " + e); 5475 } 5476 if (isUserRunningLocked(user, false)) { 5477 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5478 } 5479 } 5480 } 5481 } finally { 5482 Binder.restoreCallingIdentity(callingId); 5483 } 5484 } 5485 5486 @Override 5487 public void addPackageDependency(String packageName) { 5488 synchronized (this) { 5489 int callingPid = Binder.getCallingPid(); 5490 if (callingPid == Process.myPid()) { 5491 // Yeah, um, no. 5492 Slog.w(TAG, "Can't addPackageDependency on system process"); 5493 return; 5494 } 5495 ProcessRecord proc; 5496 synchronized (mPidsSelfLocked) { 5497 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5498 } 5499 if (proc != null) { 5500 if (proc.pkgDeps == null) { 5501 proc.pkgDeps = new ArraySet<String>(1); 5502 } 5503 proc.pkgDeps.add(packageName); 5504 } 5505 } 5506 } 5507 5508 /* 5509 * The pkg name and app id have to be specified. 5510 */ 5511 @Override 5512 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5513 if (pkg == null) { 5514 return; 5515 } 5516 // Make sure the uid is valid. 5517 if (appid < 0) { 5518 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5519 return; 5520 } 5521 int callerUid = Binder.getCallingUid(); 5522 // Only the system server can kill an application 5523 if (callerUid == Process.SYSTEM_UID) { 5524 // Post an aysnc message to kill the application 5525 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5526 msg.arg1 = appid; 5527 msg.arg2 = 0; 5528 Bundle bundle = new Bundle(); 5529 bundle.putString("pkg", pkg); 5530 bundle.putString("reason", reason); 5531 msg.obj = bundle; 5532 mHandler.sendMessage(msg); 5533 } else { 5534 throw new SecurityException(callerUid + " cannot kill pkg: " + 5535 pkg); 5536 } 5537 } 5538 5539 @Override 5540 public void closeSystemDialogs(String reason) { 5541 enforceNotIsolatedCaller("closeSystemDialogs"); 5542 5543 final int pid = Binder.getCallingPid(); 5544 final int uid = Binder.getCallingUid(); 5545 final long origId = Binder.clearCallingIdentity(); 5546 try { 5547 synchronized (this) { 5548 // Only allow this from foreground processes, so that background 5549 // applications can't abuse it to prevent system UI from being shown. 5550 if (uid >= Process.FIRST_APPLICATION_UID) { 5551 ProcessRecord proc; 5552 synchronized (mPidsSelfLocked) { 5553 proc = mPidsSelfLocked.get(pid); 5554 } 5555 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5556 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5557 + " from background process " + proc); 5558 return; 5559 } 5560 } 5561 closeSystemDialogsLocked(reason); 5562 } 5563 } finally { 5564 Binder.restoreCallingIdentity(origId); 5565 } 5566 } 5567 5568 void closeSystemDialogsLocked(String reason) { 5569 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5570 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5571 | Intent.FLAG_RECEIVER_FOREGROUND); 5572 if (reason != null) { 5573 intent.putExtra("reason", reason); 5574 } 5575 mWindowManager.closeSystemDialogs(reason); 5576 5577 mStackSupervisor.closeSystemDialogsLocked(); 5578 5579 broadcastIntentLocked(null, null, intent, null, 5580 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5581 Process.SYSTEM_UID, UserHandle.USER_ALL); 5582 } 5583 5584 @Override 5585 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5586 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5587 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5588 for (int i=pids.length-1; i>=0; i--) { 5589 ProcessRecord proc; 5590 int oomAdj; 5591 synchronized (this) { 5592 synchronized (mPidsSelfLocked) { 5593 proc = mPidsSelfLocked.get(pids[i]); 5594 oomAdj = proc != null ? proc.setAdj : 0; 5595 } 5596 } 5597 infos[i] = new Debug.MemoryInfo(); 5598 Debug.getMemoryInfo(pids[i], infos[i]); 5599 if (proc != null) { 5600 synchronized (this) { 5601 if (proc.thread != null && proc.setAdj == oomAdj) { 5602 // Record this for posterity if the process has been stable. 5603 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5604 infos[i].getTotalUss(), false, proc.pkgList); 5605 } 5606 } 5607 } 5608 } 5609 return infos; 5610 } 5611 5612 @Override 5613 public long[] getProcessPss(int[] pids) { 5614 enforceNotIsolatedCaller("getProcessPss"); 5615 long[] pss = new long[pids.length]; 5616 for (int i=pids.length-1; i>=0; i--) { 5617 ProcessRecord proc; 5618 int oomAdj; 5619 synchronized (this) { 5620 synchronized (mPidsSelfLocked) { 5621 proc = mPidsSelfLocked.get(pids[i]); 5622 oomAdj = proc != null ? proc.setAdj : 0; 5623 } 5624 } 5625 long[] tmpUss = new long[1]; 5626 pss[i] = Debug.getPss(pids[i], tmpUss); 5627 if (proc != null) { 5628 synchronized (this) { 5629 if (proc.thread != null && proc.setAdj == oomAdj) { 5630 // Record this for posterity if the process has been stable. 5631 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5632 } 5633 } 5634 } 5635 } 5636 return pss; 5637 } 5638 5639 @Override 5640 public void killApplicationProcess(String processName, int uid) { 5641 if (processName == null) { 5642 return; 5643 } 5644 5645 int callerUid = Binder.getCallingUid(); 5646 // Only the system server can kill an application 5647 if (callerUid == Process.SYSTEM_UID) { 5648 synchronized (this) { 5649 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5650 if (app != null && app.thread != null) { 5651 try { 5652 app.thread.scheduleSuicide(); 5653 } catch (RemoteException e) { 5654 // If the other end already died, then our work here is done. 5655 } 5656 } else { 5657 Slog.w(TAG, "Process/uid not found attempting kill of " 5658 + processName + " / " + uid); 5659 } 5660 } 5661 } else { 5662 throw new SecurityException(callerUid + " cannot kill app process: " + 5663 processName); 5664 } 5665 } 5666 5667 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5668 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5669 false, true, false, false, UserHandle.getUserId(uid), reason); 5670 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5671 Uri.fromParts("package", packageName, null)); 5672 if (!mProcessesReady) { 5673 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5674 | Intent.FLAG_RECEIVER_FOREGROUND); 5675 } 5676 intent.putExtra(Intent.EXTRA_UID, uid); 5677 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5678 broadcastIntentLocked(null, null, intent, 5679 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5680 false, false, 5681 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5682 } 5683 5684 private void forceStopUserLocked(int userId, String reason) { 5685 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5686 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5687 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5688 | Intent.FLAG_RECEIVER_FOREGROUND); 5689 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5690 broadcastIntentLocked(null, null, intent, 5691 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5692 false, false, 5693 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5694 } 5695 5696 private final boolean killPackageProcessesLocked(String packageName, int appId, 5697 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5698 boolean doit, boolean evenPersistent, String reason) { 5699 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5700 5701 // Remove all processes this package may have touched: all with the 5702 // same UID (except for the system or root user), and all whose name 5703 // matches the package name. 5704 final int NP = mProcessNames.getMap().size(); 5705 for (int ip=0; ip<NP; ip++) { 5706 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5707 final int NA = apps.size(); 5708 for (int ia=0; ia<NA; ia++) { 5709 ProcessRecord app = apps.valueAt(ia); 5710 if (app.persistent && !evenPersistent) { 5711 // we don't kill persistent processes 5712 continue; 5713 } 5714 if (app.removed) { 5715 if (doit) { 5716 procs.add(app); 5717 } 5718 continue; 5719 } 5720 5721 // Skip process if it doesn't meet our oom adj requirement. 5722 if (app.setAdj < minOomAdj) { 5723 continue; 5724 } 5725 5726 // If no package is specified, we call all processes under the 5727 // give user id. 5728 if (packageName == null) { 5729 if (app.userId != userId) { 5730 continue; 5731 } 5732 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5733 continue; 5734 } 5735 // Package has been specified, we want to hit all processes 5736 // that match it. We need to qualify this by the processes 5737 // that are running under the specified app and user ID. 5738 } else { 5739 final boolean isDep = app.pkgDeps != null 5740 && app.pkgDeps.contains(packageName); 5741 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5742 continue; 5743 } 5744 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5745 continue; 5746 } 5747 if (!app.pkgList.containsKey(packageName) && !isDep) { 5748 continue; 5749 } 5750 } 5751 5752 // Process has passed all conditions, kill it! 5753 if (!doit) { 5754 return true; 5755 } 5756 app.removed = true; 5757 procs.add(app); 5758 } 5759 } 5760 5761 int N = procs.size(); 5762 for (int i=0; i<N; i++) { 5763 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5764 } 5765 updateOomAdjLocked(); 5766 return N > 0; 5767 } 5768 5769 private final boolean forceStopPackageLocked(String name, int appId, 5770 boolean callerWillRestart, boolean purgeCache, boolean doit, 5771 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5772 int i; 5773 int N; 5774 5775 if (userId == UserHandle.USER_ALL && name == null) { 5776 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5777 } 5778 5779 if (appId < 0 && name != null) { 5780 try { 5781 appId = UserHandle.getAppId( 5782 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5783 } catch (RemoteException e) { 5784 } 5785 } 5786 5787 if (doit) { 5788 if (name != null) { 5789 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5790 + " user=" + userId + ": " + reason); 5791 } else { 5792 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5793 } 5794 5795 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5796 for (int ip=pmap.size()-1; ip>=0; ip--) { 5797 SparseArray<Long> ba = pmap.valueAt(ip); 5798 for (i=ba.size()-1; i>=0; i--) { 5799 boolean remove = false; 5800 final int entUid = ba.keyAt(i); 5801 if (name != null) { 5802 if (userId == UserHandle.USER_ALL) { 5803 if (UserHandle.getAppId(entUid) == appId) { 5804 remove = true; 5805 } 5806 } else { 5807 if (entUid == UserHandle.getUid(userId, appId)) { 5808 remove = true; 5809 } 5810 } 5811 } else if (UserHandle.getUserId(entUid) == userId) { 5812 remove = true; 5813 } 5814 if (remove) { 5815 ba.removeAt(i); 5816 } 5817 } 5818 if (ba.size() == 0) { 5819 pmap.removeAt(ip); 5820 } 5821 } 5822 } 5823 5824 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5825 -100, callerWillRestart, true, doit, evenPersistent, 5826 name == null ? ("stop user " + userId) : ("stop " + name)); 5827 5828 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5829 if (!doit) { 5830 return true; 5831 } 5832 didSomething = true; 5833 } 5834 5835 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5836 if (!doit) { 5837 return true; 5838 } 5839 didSomething = true; 5840 } 5841 5842 if (name == null) { 5843 // Remove all sticky broadcasts from this user. 5844 mStickyBroadcasts.remove(userId); 5845 } 5846 5847 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5848 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5849 userId, providers)) { 5850 if (!doit) { 5851 return true; 5852 } 5853 didSomething = true; 5854 } 5855 N = providers.size(); 5856 for (i=0; i<N; i++) { 5857 removeDyingProviderLocked(null, providers.get(i), true); 5858 } 5859 5860 // Remove transient permissions granted from/to this package/user 5861 removeUriPermissionsForPackageLocked(name, userId, false); 5862 5863 if (name == null || uninstalling) { 5864 // Remove pending intents. For now we only do this when force 5865 // stopping users, because we have some problems when doing this 5866 // for packages -- app widgets are not currently cleaned up for 5867 // such packages, so they can be left with bad pending intents. 5868 if (mIntentSenderRecords.size() > 0) { 5869 Iterator<WeakReference<PendingIntentRecord>> it 5870 = mIntentSenderRecords.values().iterator(); 5871 while (it.hasNext()) { 5872 WeakReference<PendingIntentRecord> wpir = it.next(); 5873 if (wpir == null) { 5874 it.remove(); 5875 continue; 5876 } 5877 PendingIntentRecord pir = wpir.get(); 5878 if (pir == null) { 5879 it.remove(); 5880 continue; 5881 } 5882 if (name == null) { 5883 // Stopping user, remove all objects for the user. 5884 if (pir.key.userId != userId) { 5885 // Not the same user, skip it. 5886 continue; 5887 } 5888 } else { 5889 if (UserHandle.getAppId(pir.uid) != appId) { 5890 // Different app id, skip it. 5891 continue; 5892 } 5893 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5894 // Different user, skip it. 5895 continue; 5896 } 5897 if (!pir.key.packageName.equals(name)) { 5898 // Different package, skip it. 5899 continue; 5900 } 5901 } 5902 if (!doit) { 5903 return true; 5904 } 5905 didSomething = true; 5906 it.remove(); 5907 pir.canceled = true; 5908 if (pir.key.activity != null) { 5909 pir.key.activity.pendingResults.remove(pir.ref); 5910 } 5911 } 5912 } 5913 } 5914 5915 if (doit) { 5916 if (purgeCache && name != null) { 5917 AttributeCache ac = AttributeCache.instance(); 5918 if (ac != null) { 5919 ac.removePackage(name); 5920 } 5921 } 5922 if (mBooted) { 5923 mStackSupervisor.resumeTopActivitiesLocked(); 5924 mStackSupervisor.scheduleIdleLocked(); 5925 } 5926 } 5927 5928 return didSomething; 5929 } 5930 5931 private final boolean removeProcessLocked(ProcessRecord app, 5932 boolean callerWillRestart, boolean allowRestart, String reason) { 5933 final String name = app.processName; 5934 final int uid = app.uid; 5935 if (DEBUG_PROCESSES) Slog.d( 5936 TAG, "Force removing proc " + app.toShortString() + " (" + name 5937 + "/" + uid + ")"); 5938 5939 mProcessNames.remove(name, uid); 5940 mIsolatedProcesses.remove(app.uid); 5941 if (mHeavyWeightProcess == app) { 5942 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5943 mHeavyWeightProcess.userId, 0)); 5944 mHeavyWeightProcess = null; 5945 } 5946 boolean needRestart = false; 5947 if (app.pid > 0 && app.pid != MY_PID) { 5948 int pid = app.pid; 5949 synchronized (mPidsSelfLocked) { 5950 mPidsSelfLocked.remove(pid); 5951 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5952 } 5953 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5954 if (app.isolated) { 5955 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5956 } 5957 app.kill(reason, true); 5958 handleAppDiedLocked(app, true, allowRestart); 5959 removeLruProcessLocked(app); 5960 5961 if (app.persistent && !app.isolated) { 5962 if (!callerWillRestart) { 5963 addAppLocked(app.info, false, null /* ABI override */); 5964 } else { 5965 needRestart = true; 5966 } 5967 } 5968 } else { 5969 mRemovedProcesses.add(app); 5970 } 5971 5972 return needRestart; 5973 } 5974 5975 private final void processStartTimedOutLocked(ProcessRecord app) { 5976 final int pid = app.pid; 5977 boolean gone = false; 5978 synchronized (mPidsSelfLocked) { 5979 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5980 if (knownApp != null && knownApp.thread == null) { 5981 mPidsSelfLocked.remove(pid); 5982 gone = true; 5983 } 5984 } 5985 5986 if (gone) { 5987 Slog.w(TAG, "Process " + app + " failed to attach"); 5988 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5989 pid, app.uid, app.processName); 5990 mProcessNames.remove(app.processName, app.uid); 5991 mIsolatedProcesses.remove(app.uid); 5992 if (mHeavyWeightProcess == app) { 5993 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5994 mHeavyWeightProcess.userId, 0)); 5995 mHeavyWeightProcess = null; 5996 } 5997 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5998 if (app.isolated) { 5999 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6000 } 6001 // Take care of any launching providers waiting for this process. 6002 checkAppInLaunchingProvidersLocked(app, true); 6003 // Take care of any services that are waiting for the process. 6004 mServices.processStartTimedOutLocked(app); 6005 app.kill("start timeout", true); 6006 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6007 Slog.w(TAG, "Unattached app died before backup, skipping"); 6008 try { 6009 IBackupManager bm = IBackupManager.Stub.asInterface( 6010 ServiceManager.getService(Context.BACKUP_SERVICE)); 6011 bm.agentDisconnected(app.info.packageName); 6012 } catch (RemoteException e) { 6013 // Can't happen; the backup manager is local 6014 } 6015 } 6016 if (isPendingBroadcastProcessLocked(pid)) { 6017 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6018 skipPendingBroadcastLocked(pid); 6019 } 6020 } else { 6021 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6022 } 6023 } 6024 6025 private final boolean attachApplicationLocked(IApplicationThread thread, 6026 int pid) { 6027 6028 // Find the application record that is being attached... either via 6029 // the pid if we are running in multiple processes, or just pull the 6030 // next app record if we are emulating process with anonymous threads. 6031 ProcessRecord app; 6032 if (pid != MY_PID && pid >= 0) { 6033 synchronized (mPidsSelfLocked) { 6034 app = mPidsSelfLocked.get(pid); 6035 } 6036 } else { 6037 app = null; 6038 } 6039 6040 if (app == null) { 6041 Slog.w(TAG, "No pending application record for pid " + pid 6042 + " (IApplicationThread " + thread + "); dropping process"); 6043 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6044 if (pid > 0 && pid != MY_PID) { 6045 Process.killProcessQuiet(pid); 6046 //TODO: Process.killProcessGroup(app.info.uid, pid); 6047 } else { 6048 try { 6049 thread.scheduleExit(); 6050 } catch (Exception e) { 6051 // Ignore exceptions. 6052 } 6053 } 6054 return false; 6055 } 6056 6057 // If this application record is still attached to a previous 6058 // process, clean it up now. 6059 if (app.thread != null) { 6060 handleAppDiedLocked(app, true, true); 6061 } 6062 6063 // Tell the process all about itself. 6064 6065 if (localLOGV) Slog.v( 6066 TAG, "Binding process pid " + pid + " to record " + app); 6067 6068 final String processName = app.processName; 6069 try { 6070 AppDeathRecipient adr = new AppDeathRecipient( 6071 app, pid, thread); 6072 thread.asBinder().linkToDeath(adr, 0); 6073 app.deathRecipient = adr; 6074 } catch (RemoteException e) { 6075 app.resetPackageList(mProcessStats); 6076 startProcessLocked(app, "link fail", processName); 6077 return false; 6078 } 6079 6080 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6081 6082 app.makeActive(thread, mProcessStats); 6083 app.curAdj = app.setAdj = -100; 6084 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6085 app.forcingToForeground = null; 6086 updateProcessForegroundLocked(app, false, false); 6087 app.hasShownUi = false; 6088 app.debugging = false; 6089 app.cached = false; 6090 6091 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6092 6093 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6094 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6095 6096 if (!normalMode) { 6097 Slog.i(TAG, "Launching preboot mode app: " + app); 6098 } 6099 6100 if (localLOGV) Slog.v( 6101 TAG, "New app record " + app 6102 + " thread=" + thread.asBinder() + " pid=" + pid); 6103 try { 6104 int testMode = IApplicationThread.DEBUG_OFF; 6105 if (mDebugApp != null && mDebugApp.equals(processName)) { 6106 testMode = mWaitForDebugger 6107 ? IApplicationThread.DEBUG_WAIT 6108 : IApplicationThread.DEBUG_ON; 6109 app.debugging = true; 6110 if (mDebugTransient) { 6111 mDebugApp = mOrigDebugApp; 6112 mWaitForDebugger = mOrigWaitForDebugger; 6113 } 6114 } 6115 String profileFile = app.instrumentationProfileFile; 6116 ParcelFileDescriptor profileFd = null; 6117 int samplingInterval = 0; 6118 boolean profileAutoStop = false; 6119 if (mProfileApp != null && mProfileApp.equals(processName)) { 6120 mProfileProc = app; 6121 profileFile = mProfileFile; 6122 profileFd = mProfileFd; 6123 samplingInterval = mSamplingInterval; 6124 profileAutoStop = mAutoStopProfiler; 6125 } 6126 boolean enableOpenGlTrace = false; 6127 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6128 enableOpenGlTrace = true; 6129 mOpenGlTraceApp = null; 6130 } 6131 6132 // If the app is being launched for restore or full backup, set it up specially 6133 boolean isRestrictedBackupMode = false; 6134 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6135 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6136 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6137 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6138 } 6139 6140 ensurePackageDexOpt(app.instrumentationInfo != null 6141 ? app.instrumentationInfo.packageName 6142 : app.info.packageName); 6143 if (app.instrumentationClass != null) { 6144 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6145 } 6146 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6147 + processName + " with config " + mConfiguration); 6148 ApplicationInfo appInfo = app.instrumentationInfo != null 6149 ? app.instrumentationInfo : app.info; 6150 app.compat = compatibilityInfoForPackageLocked(appInfo); 6151 if (profileFd != null) { 6152 profileFd = profileFd.dup(); 6153 } 6154 ProfilerInfo profilerInfo = profileFile == null ? null 6155 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6156 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6157 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6158 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6159 isRestrictedBackupMode || !normalMode, app.persistent, 6160 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6161 mCoreSettingsObserver.getCoreSettingsLocked()); 6162 updateLruProcessLocked(app, false, null); 6163 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6164 } catch (Exception e) { 6165 // todo: Yikes! What should we do? For now we will try to 6166 // start another process, but that could easily get us in 6167 // an infinite loop of restarting processes... 6168 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6169 6170 app.resetPackageList(mProcessStats); 6171 app.unlinkDeathRecipient(); 6172 startProcessLocked(app, "bind fail", processName); 6173 return false; 6174 } 6175 6176 // Remove this record from the list of starting applications. 6177 mPersistentStartingProcesses.remove(app); 6178 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6179 "Attach application locked removing on hold: " + app); 6180 mProcessesOnHold.remove(app); 6181 6182 boolean badApp = false; 6183 boolean didSomething = false; 6184 6185 // See if the top visible activity is waiting to run in this process... 6186 if (normalMode) { 6187 try { 6188 if (mStackSupervisor.attachApplicationLocked(app)) { 6189 didSomething = true; 6190 } 6191 } catch (Exception e) { 6192 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6193 badApp = true; 6194 } 6195 } 6196 6197 // Find any services that should be running in this process... 6198 if (!badApp) { 6199 try { 6200 didSomething |= mServices.attachApplicationLocked(app, processName); 6201 } catch (Exception e) { 6202 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6203 badApp = true; 6204 } 6205 } 6206 6207 // Check if a next-broadcast receiver is in this process... 6208 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6209 try { 6210 didSomething |= sendPendingBroadcastsLocked(app); 6211 } catch (Exception e) { 6212 // If the app died trying to launch the receiver we declare it 'bad' 6213 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6214 badApp = true; 6215 } 6216 } 6217 6218 // Check whether the next backup agent is in this process... 6219 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6220 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6221 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6222 try { 6223 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6224 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6225 mBackupTarget.backupMode); 6226 } catch (Exception e) { 6227 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6228 badApp = true; 6229 } 6230 } 6231 6232 if (badApp) { 6233 app.kill("error during init", true); 6234 handleAppDiedLocked(app, false, true); 6235 return false; 6236 } 6237 6238 if (!didSomething) { 6239 updateOomAdjLocked(); 6240 } 6241 6242 return true; 6243 } 6244 6245 @Override 6246 public final void attachApplication(IApplicationThread thread) { 6247 synchronized (this) { 6248 int callingPid = Binder.getCallingPid(); 6249 final long origId = Binder.clearCallingIdentity(); 6250 attachApplicationLocked(thread, callingPid); 6251 Binder.restoreCallingIdentity(origId); 6252 } 6253 } 6254 6255 @Override 6256 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6257 final long origId = Binder.clearCallingIdentity(); 6258 synchronized (this) { 6259 ActivityStack stack = ActivityRecord.getStackLocked(token); 6260 if (stack != null) { 6261 ActivityRecord r = 6262 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6263 if (stopProfiling) { 6264 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6265 try { 6266 mProfileFd.close(); 6267 } catch (IOException e) { 6268 } 6269 clearProfilerLocked(); 6270 } 6271 } 6272 } 6273 } 6274 Binder.restoreCallingIdentity(origId); 6275 } 6276 6277 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6278 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6279 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6280 } 6281 6282 void enableScreenAfterBoot() { 6283 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6284 SystemClock.uptimeMillis()); 6285 mWindowManager.enableScreenAfterBoot(); 6286 6287 synchronized (this) { 6288 updateEventDispatchingLocked(); 6289 } 6290 } 6291 6292 @Override 6293 public void showBootMessage(final CharSequence msg, final boolean always) { 6294 enforceNotIsolatedCaller("showBootMessage"); 6295 mWindowManager.showBootMessage(msg, always); 6296 } 6297 6298 @Override 6299 public void keyguardWaitingForActivityDrawn() { 6300 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6301 final long token = Binder.clearCallingIdentity(); 6302 try { 6303 synchronized (this) { 6304 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6305 mWindowManager.keyguardWaitingForActivityDrawn(); 6306 if (mLockScreenShown) { 6307 mLockScreenShown = false; 6308 comeOutOfSleepIfNeededLocked(); 6309 } 6310 } 6311 } finally { 6312 Binder.restoreCallingIdentity(token); 6313 } 6314 } 6315 6316 final void finishBooting() { 6317 synchronized (this) { 6318 if (!mBootAnimationComplete) { 6319 mCallFinishBooting = true; 6320 return; 6321 } 6322 mCallFinishBooting = false; 6323 } 6324 6325 // Register receivers to handle package update events 6326 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6327 6328 // Let system services know. 6329 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6330 6331 synchronized (this) { 6332 // Ensure that any processes we had put on hold are now started 6333 // up. 6334 final int NP = mProcessesOnHold.size(); 6335 if (NP > 0) { 6336 ArrayList<ProcessRecord> procs = 6337 new ArrayList<ProcessRecord>(mProcessesOnHold); 6338 for (int ip=0; ip<NP; ip++) { 6339 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6340 + procs.get(ip)); 6341 startProcessLocked(procs.get(ip), "on-hold", null); 6342 } 6343 } 6344 6345 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6346 // Start looking for apps that are abusing wake locks. 6347 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6348 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6349 // Tell anyone interested that we are done booting! 6350 SystemProperties.set("sys.boot_completed", "1"); 6351 6352 // And trigger dev.bootcomplete if we are not showing encryption progress 6353 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6354 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6355 SystemProperties.set("dev.bootcomplete", "1"); 6356 } 6357 for (int i=0; i<mStartedUsers.size(); i++) { 6358 UserStartedState uss = mStartedUsers.valueAt(i); 6359 if (uss.mState == UserStartedState.STATE_BOOTING) { 6360 uss.mState = UserStartedState.STATE_RUNNING; 6361 final int userId = mStartedUsers.keyAt(i); 6362 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6363 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6364 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6365 broadcastIntentLocked(null, null, intent, null, 6366 new IIntentReceiver.Stub() { 6367 @Override 6368 public void performReceive(Intent intent, int resultCode, 6369 String data, Bundle extras, boolean ordered, 6370 boolean sticky, int sendingUser) { 6371 synchronized (ActivityManagerService.this) { 6372 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6373 true, false); 6374 } 6375 } 6376 }, 6377 0, null, null, 6378 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6379 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6380 userId); 6381 } 6382 } 6383 scheduleStartProfilesLocked(); 6384 } 6385 } 6386 } 6387 6388 @Override 6389 public void bootAnimationComplete() { 6390 final boolean callFinishBooting; 6391 synchronized (this) { 6392 callFinishBooting = mCallFinishBooting; 6393 mBootAnimationComplete = true; 6394 } 6395 if (callFinishBooting) { 6396 finishBooting(); 6397 } 6398 } 6399 6400 final void ensureBootCompleted() { 6401 boolean booting; 6402 boolean enableScreen; 6403 synchronized (this) { 6404 booting = mBooting; 6405 mBooting = false; 6406 enableScreen = !mBooted; 6407 mBooted = true; 6408 } 6409 6410 if (booting) { 6411 finishBooting(); 6412 } 6413 6414 if (enableScreen) { 6415 enableScreenAfterBoot(); 6416 } 6417 } 6418 6419 @Override 6420 public final void activityResumed(IBinder token) { 6421 final long origId = Binder.clearCallingIdentity(); 6422 synchronized(this) { 6423 ActivityStack stack = ActivityRecord.getStackLocked(token); 6424 if (stack != null) { 6425 ActivityRecord.activityResumedLocked(token); 6426 } 6427 } 6428 Binder.restoreCallingIdentity(origId); 6429 } 6430 6431 @Override 6432 public final void activityPaused(IBinder token) { 6433 final long origId = Binder.clearCallingIdentity(); 6434 synchronized(this) { 6435 ActivityStack stack = ActivityRecord.getStackLocked(token); 6436 if (stack != null) { 6437 stack.activityPausedLocked(token, false); 6438 } 6439 } 6440 Binder.restoreCallingIdentity(origId); 6441 } 6442 6443 @Override 6444 public final void activityStopped(IBinder token, Bundle icicle, 6445 PersistableBundle persistentState, CharSequence description) { 6446 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6447 6448 // Refuse possible leaked file descriptors 6449 if (icicle != null && icicle.hasFileDescriptors()) { 6450 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6451 } 6452 6453 final long origId = Binder.clearCallingIdentity(); 6454 6455 synchronized (this) { 6456 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6457 if (r != null) { 6458 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6459 } 6460 } 6461 6462 trimApplications(); 6463 6464 Binder.restoreCallingIdentity(origId); 6465 } 6466 6467 @Override 6468 public final void activityDestroyed(IBinder token) { 6469 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6470 synchronized (this) { 6471 ActivityStack stack = ActivityRecord.getStackLocked(token); 6472 if (stack != null) { 6473 stack.activityDestroyedLocked(token); 6474 } 6475 } 6476 } 6477 6478 @Override 6479 public final void backgroundResourcesReleased(IBinder token) { 6480 final long origId = Binder.clearCallingIdentity(); 6481 try { 6482 synchronized (this) { 6483 ActivityStack stack = ActivityRecord.getStackLocked(token); 6484 if (stack != null) { 6485 stack.backgroundResourcesReleased(token); 6486 } 6487 } 6488 } finally { 6489 Binder.restoreCallingIdentity(origId); 6490 } 6491 } 6492 6493 @Override 6494 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6495 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6496 } 6497 6498 @Override 6499 public final void notifyEnterAnimationComplete(IBinder token) { 6500 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6501 } 6502 6503 @Override 6504 public String getCallingPackage(IBinder token) { 6505 synchronized (this) { 6506 ActivityRecord r = getCallingRecordLocked(token); 6507 return r != null ? r.info.packageName : null; 6508 } 6509 } 6510 6511 @Override 6512 public ComponentName getCallingActivity(IBinder token) { 6513 synchronized (this) { 6514 ActivityRecord r = getCallingRecordLocked(token); 6515 return r != null ? r.intent.getComponent() : null; 6516 } 6517 } 6518 6519 private ActivityRecord getCallingRecordLocked(IBinder token) { 6520 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6521 if (r == null) { 6522 return null; 6523 } 6524 return r.resultTo; 6525 } 6526 6527 @Override 6528 public ComponentName getActivityClassForToken(IBinder token) { 6529 synchronized(this) { 6530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6531 if (r == null) { 6532 return null; 6533 } 6534 return r.intent.getComponent(); 6535 } 6536 } 6537 6538 @Override 6539 public String getPackageForToken(IBinder token) { 6540 synchronized(this) { 6541 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6542 if (r == null) { 6543 return null; 6544 } 6545 return r.packageName; 6546 } 6547 } 6548 6549 @Override 6550 public IIntentSender getIntentSender(int type, 6551 String packageName, IBinder token, String resultWho, 6552 int requestCode, Intent[] intents, String[] resolvedTypes, 6553 int flags, Bundle options, int userId) { 6554 enforceNotIsolatedCaller("getIntentSender"); 6555 // Refuse possible leaked file descriptors 6556 if (intents != null) { 6557 if (intents.length < 1) { 6558 throw new IllegalArgumentException("Intents array length must be >= 1"); 6559 } 6560 for (int i=0; i<intents.length; i++) { 6561 Intent intent = intents[i]; 6562 if (intent != null) { 6563 if (intent.hasFileDescriptors()) { 6564 throw new IllegalArgumentException("File descriptors passed in Intent"); 6565 } 6566 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6567 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6568 throw new IllegalArgumentException( 6569 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6570 } 6571 intents[i] = new Intent(intent); 6572 } 6573 } 6574 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6575 throw new IllegalArgumentException( 6576 "Intent array length does not match resolvedTypes length"); 6577 } 6578 } 6579 if (options != null) { 6580 if (options.hasFileDescriptors()) { 6581 throw new IllegalArgumentException("File descriptors passed in options"); 6582 } 6583 } 6584 6585 synchronized(this) { 6586 int callingUid = Binder.getCallingUid(); 6587 int origUserId = userId; 6588 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6589 type == ActivityManager.INTENT_SENDER_BROADCAST, 6590 ALLOW_NON_FULL, "getIntentSender", null); 6591 if (origUserId == UserHandle.USER_CURRENT) { 6592 // We don't want to evaluate this until the pending intent is 6593 // actually executed. However, we do want to always do the 6594 // security checking for it above. 6595 userId = UserHandle.USER_CURRENT; 6596 } 6597 try { 6598 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6599 int uid = AppGlobals.getPackageManager() 6600 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6601 if (!UserHandle.isSameApp(callingUid, uid)) { 6602 String msg = "Permission Denial: getIntentSender() from pid=" 6603 + Binder.getCallingPid() 6604 + ", uid=" + Binder.getCallingUid() 6605 + ", (need uid=" + uid + ")" 6606 + " is not allowed to send as package " + packageName; 6607 Slog.w(TAG, msg); 6608 throw new SecurityException(msg); 6609 } 6610 } 6611 6612 return getIntentSenderLocked(type, packageName, callingUid, userId, 6613 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6614 6615 } catch (RemoteException e) { 6616 throw new SecurityException(e); 6617 } 6618 } 6619 } 6620 6621 IIntentSender getIntentSenderLocked(int type, String packageName, 6622 int callingUid, int userId, IBinder token, String resultWho, 6623 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6624 Bundle options) { 6625 if (DEBUG_MU) 6626 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6627 ActivityRecord activity = null; 6628 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6629 activity = ActivityRecord.isInStackLocked(token); 6630 if (activity == null) { 6631 return null; 6632 } 6633 if (activity.finishing) { 6634 return null; 6635 } 6636 } 6637 6638 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6639 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6640 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6641 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6642 |PendingIntent.FLAG_UPDATE_CURRENT); 6643 6644 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6645 type, packageName, activity, resultWho, 6646 requestCode, intents, resolvedTypes, flags, options, userId); 6647 WeakReference<PendingIntentRecord> ref; 6648 ref = mIntentSenderRecords.get(key); 6649 PendingIntentRecord rec = ref != null ? ref.get() : null; 6650 if (rec != null) { 6651 if (!cancelCurrent) { 6652 if (updateCurrent) { 6653 if (rec.key.requestIntent != null) { 6654 rec.key.requestIntent.replaceExtras(intents != null ? 6655 intents[intents.length - 1] : null); 6656 } 6657 if (intents != null) { 6658 intents[intents.length-1] = rec.key.requestIntent; 6659 rec.key.allIntents = intents; 6660 rec.key.allResolvedTypes = resolvedTypes; 6661 } else { 6662 rec.key.allIntents = null; 6663 rec.key.allResolvedTypes = null; 6664 } 6665 } 6666 return rec; 6667 } 6668 rec.canceled = true; 6669 mIntentSenderRecords.remove(key); 6670 } 6671 if (noCreate) { 6672 return rec; 6673 } 6674 rec = new PendingIntentRecord(this, key, callingUid); 6675 mIntentSenderRecords.put(key, rec.ref); 6676 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6677 if (activity.pendingResults == null) { 6678 activity.pendingResults 6679 = new HashSet<WeakReference<PendingIntentRecord>>(); 6680 } 6681 activity.pendingResults.add(rec.ref); 6682 } 6683 return rec; 6684 } 6685 6686 @Override 6687 public void cancelIntentSender(IIntentSender sender) { 6688 if (!(sender instanceof PendingIntentRecord)) { 6689 return; 6690 } 6691 synchronized(this) { 6692 PendingIntentRecord rec = (PendingIntentRecord)sender; 6693 try { 6694 int uid = AppGlobals.getPackageManager() 6695 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6696 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6697 String msg = "Permission Denial: cancelIntentSender() from pid=" 6698 + Binder.getCallingPid() 6699 + ", uid=" + Binder.getCallingUid() 6700 + " is not allowed to cancel packges " 6701 + rec.key.packageName; 6702 Slog.w(TAG, msg); 6703 throw new SecurityException(msg); 6704 } 6705 } catch (RemoteException e) { 6706 throw new SecurityException(e); 6707 } 6708 cancelIntentSenderLocked(rec, true); 6709 } 6710 } 6711 6712 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6713 rec.canceled = true; 6714 mIntentSenderRecords.remove(rec.key); 6715 if (cleanActivity && rec.key.activity != null) { 6716 rec.key.activity.pendingResults.remove(rec.ref); 6717 } 6718 } 6719 6720 @Override 6721 public String getPackageForIntentSender(IIntentSender pendingResult) { 6722 if (!(pendingResult instanceof PendingIntentRecord)) { 6723 return null; 6724 } 6725 try { 6726 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6727 return res.key.packageName; 6728 } catch (ClassCastException e) { 6729 } 6730 return null; 6731 } 6732 6733 @Override 6734 public int getUidForIntentSender(IIntentSender sender) { 6735 if (sender instanceof PendingIntentRecord) { 6736 try { 6737 PendingIntentRecord res = (PendingIntentRecord)sender; 6738 return res.uid; 6739 } catch (ClassCastException e) { 6740 } 6741 } 6742 return -1; 6743 } 6744 6745 @Override 6746 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6747 if (!(pendingResult instanceof PendingIntentRecord)) { 6748 return false; 6749 } 6750 try { 6751 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6752 if (res.key.allIntents == null) { 6753 return false; 6754 } 6755 for (int i=0; i<res.key.allIntents.length; i++) { 6756 Intent intent = res.key.allIntents[i]; 6757 if (intent.getPackage() != null && intent.getComponent() != null) { 6758 return false; 6759 } 6760 } 6761 return true; 6762 } catch (ClassCastException e) { 6763 } 6764 return false; 6765 } 6766 6767 @Override 6768 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6769 if (!(pendingResult instanceof PendingIntentRecord)) { 6770 return false; 6771 } 6772 try { 6773 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6774 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6775 return true; 6776 } 6777 return false; 6778 } catch (ClassCastException e) { 6779 } 6780 return false; 6781 } 6782 6783 @Override 6784 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6785 if (!(pendingResult instanceof PendingIntentRecord)) { 6786 return null; 6787 } 6788 try { 6789 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6790 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6791 } catch (ClassCastException e) { 6792 } 6793 return null; 6794 } 6795 6796 @Override 6797 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6798 if (!(pendingResult instanceof PendingIntentRecord)) { 6799 return null; 6800 } 6801 try { 6802 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6803 Intent intent = res.key.requestIntent; 6804 if (intent != null) { 6805 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6806 || res.lastTagPrefix.equals(prefix))) { 6807 return res.lastTag; 6808 } 6809 res.lastTagPrefix = prefix; 6810 StringBuilder sb = new StringBuilder(128); 6811 if (prefix != null) { 6812 sb.append(prefix); 6813 } 6814 if (intent.getAction() != null) { 6815 sb.append(intent.getAction()); 6816 } else if (intent.getComponent() != null) { 6817 intent.getComponent().appendShortString(sb); 6818 } else { 6819 sb.append("?"); 6820 } 6821 return res.lastTag = sb.toString(); 6822 } 6823 } catch (ClassCastException e) { 6824 } 6825 return null; 6826 } 6827 6828 @Override 6829 public void setProcessLimit(int max) { 6830 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6831 "setProcessLimit()"); 6832 synchronized (this) { 6833 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6834 mProcessLimitOverride = max; 6835 } 6836 trimApplications(); 6837 } 6838 6839 @Override 6840 public int getProcessLimit() { 6841 synchronized (this) { 6842 return mProcessLimitOverride; 6843 } 6844 } 6845 6846 void foregroundTokenDied(ForegroundToken token) { 6847 synchronized (ActivityManagerService.this) { 6848 synchronized (mPidsSelfLocked) { 6849 ForegroundToken cur 6850 = mForegroundProcesses.get(token.pid); 6851 if (cur != token) { 6852 return; 6853 } 6854 mForegroundProcesses.remove(token.pid); 6855 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6856 if (pr == null) { 6857 return; 6858 } 6859 pr.forcingToForeground = null; 6860 updateProcessForegroundLocked(pr, false, false); 6861 } 6862 updateOomAdjLocked(); 6863 } 6864 } 6865 6866 @Override 6867 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6868 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6869 "setProcessForeground()"); 6870 synchronized(this) { 6871 boolean changed = false; 6872 6873 synchronized (mPidsSelfLocked) { 6874 ProcessRecord pr = mPidsSelfLocked.get(pid); 6875 if (pr == null && isForeground) { 6876 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6877 return; 6878 } 6879 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6880 if (oldToken != null) { 6881 oldToken.token.unlinkToDeath(oldToken, 0); 6882 mForegroundProcesses.remove(pid); 6883 if (pr != null) { 6884 pr.forcingToForeground = null; 6885 } 6886 changed = true; 6887 } 6888 if (isForeground && token != null) { 6889 ForegroundToken newToken = new ForegroundToken() { 6890 @Override 6891 public void binderDied() { 6892 foregroundTokenDied(this); 6893 } 6894 }; 6895 newToken.pid = pid; 6896 newToken.token = token; 6897 try { 6898 token.linkToDeath(newToken, 0); 6899 mForegroundProcesses.put(pid, newToken); 6900 pr.forcingToForeground = token; 6901 changed = true; 6902 } catch (RemoteException e) { 6903 // If the process died while doing this, we will later 6904 // do the cleanup with the process death link. 6905 } 6906 } 6907 } 6908 6909 if (changed) { 6910 updateOomAdjLocked(); 6911 } 6912 } 6913 } 6914 6915 // ========================================================= 6916 // PERMISSIONS 6917 // ========================================================= 6918 6919 static class PermissionController extends IPermissionController.Stub { 6920 ActivityManagerService mActivityManagerService; 6921 PermissionController(ActivityManagerService activityManagerService) { 6922 mActivityManagerService = activityManagerService; 6923 } 6924 6925 @Override 6926 public boolean checkPermission(String permission, int pid, int uid) { 6927 return mActivityManagerService.checkPermission(permission, pid, 6928 uid) == PackageManager.PERMISSION_GRANTED; 6929 } 6930 } 6931 6932 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6933 @Override 6934 public int checkComponentPermission(String permission, int pid, int uid, 6935 int owningUid, boolean exported) { 6936 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6937 owningUid, exported); 6938 } 6939 6940 @Override 6941 public Object getAMSLock() { 6942 return ActivityManagerService.this; 6943 } 6944 } 6945 6946 /** 6947 * This can be called with or without the global lock held. 6948 */ 6949 int checkComponentPermission(String permission, int pid, int uid, 6950 int owningUid, boolean exported) { 6951 // We might be performing an operation on behalf of an indirect binder 6952 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6953 // client identity accordingly before proceeding. 6954 Identity tlsIdentity = sCallerIdentity.get(); 6955 if (tlsIdentity != null) { 6956 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6957 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6958 uid = tlsIdentity.uid; 6959 pid = tlsIdentity.pid; 6960 } 6961 6962 if (pid == MY_PID) { 6963 return PackageManager.PERMISSION_GRANTED; 6964 } 6965 6966 return ActivityManager.checkComponentPermission(permission, uid, 6967 owningUid, exported); 6968 } 6969 6970 /** 6971 * As the only public entry point for permissions checking, this method 6972 * can enforce the semantic that requesting a check on a null global 6973 * permission is automatically denied. (Internally a null permission 6974 * string is used when calling {@link #checkComponentPermission} in cases 6975 * when only uid-based security is needed.) 6976 * 6977 * This can be called with or without the global lock held. 6978 */ 6979 @Override 6980 public int checkPermission(String permission, int pid, int uid) { 6981 if (permission == null) { 6982 return PackageManager.PERMISSION_DENIED; 6983 } 6984 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6985 } 6986 6987 /** 6988 * Binder IPC calls go through the public entry point. 6989 * This can be called with or without the global lock held. 6990 */ 6991 int checkCallingPermission(String permission) { 6992 return checkPermission(permission, 6993 Binder.getCallingPid(), 6994 UserHandle.getAppId(Binder.getCallingUid())); 6995 } 6996 6997 /** 6998 * This can be called with or without the global lock held. 6999 */ 7000 void enforceCallingPermission(String permission, String func) { 7001 if (checkCallingPermission(permission) 7002 == PackageManager.PERMISSION_GRANTED) { 7003 return; 7004 } 7005 7006 String msg = "Permission Denial: " + func + " from pid=" 7007 + Binder.getCallingPid() 7008 + ", uid=" + Binder.getCallingUid() 7009 + " requires " + permission; 7010 Slog.w(TAG, msg); 7011 throw new SecurityException(msg); 7012 } 7013 7014 /** 7015 * Determine if UID is holding permissions required to access {@link Uri} in 7016 * the given {@link ProviderInfo}. Final permission checking is always done 7017 * in {@link ContentProvider}. 7018 */ 7019 private final boolean checkHoldingPermissionsLocked( 7020 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7021 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7022 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7023 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7024 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7025 != PERMISSION_GRANTED) { 7026 return false; 7027 } 7028 } 7029 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7030 } 7031 7032 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7033 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7034 if (pi.applicationInfo.uid == uid) { 7035 return true; 7036 } else if (!pi.exported) { 7037 return false; 7038 } 7039 7040 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7041 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7042 try { 7043 // check if target holds top-level <provider> permissions 7044 if (!readMet && pi.readPermission != null && considerUidPermissions 7045 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7046 readMet = true; 7047 } 7048 if (!writeMet && pi.writePermission != null && considerUidPermissions 7049 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7050 writeMet = true; 7051 } 7052 7053 // track if unprotected read/write is allowed; any denied 7054 // <path-permission> below removes this ability 7055 boolean allowDefaultRead = pi.readPermission == null; 7056 boolean allowDefaultWrite = pi.writePermission == null; 7057 7058 // check if target holds any <path-permission> that match uri 7059 final PathPermission[] pps = pi.pathPermissions; 7060 if (pps != null) { 7061 final String path = grantUri.uri.getPath(); 7062 int i = pps.length; 7063 while (i > 0 && (!readMet || !writeMet)) { 7064 i--; 7065 PathPermission pp = pps[i]; 7066 if (pp.match(path)) { 7067 if (!readMet) { 7068 final String pprperm = pp.getReadPermission(); 7069 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7070 + pprperm + " for " + pp.getPath() 7071 + ": match=" + pp.match(path) 7072 + " check=" + pm.checkUidPermission(pprperm, uid)); 7073 if (pprperm != null) { 7074 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7075 == PERMISSION_GRANTED) { 7076 readMet = true; 7077 } else { 7078 allowDefaultRead = false; 7079 } 7080 } 7081 } 7082 if (!writeMet) { 7083 final String ppwperm = pp.getWritePermission(); 7084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7085 + ppwperm + " for " + pp.getPath() 7086 + ": match=" + pp.match(path) 7087 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7088 if (ppwperm != null) { 7089 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7090 == PERMISSION_GRANTED) { 7091 writeMet = true; 7092 } else { 7093 allowDefaultWrite = false; 7094 } 7095 } 7096 } 7097 } 7098 } 7099 } 7100 7101 // grant unprotected <provider> read/write, if not blocked by 7102 // <path-permission> above 7103 if (allowDefaultRead) readMet = true; 7104 if (allowDefaultWrite) writeMet = true; 7105 7106 } catch (RemoteException e) { 7107 return false; 7108 } 7109 7110 return readMet && writeMet; 7111 } 7112 7113 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7114 ProviderInfo pi = null; 7115 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7116 if (cpr != null) { 7117 pi = cpr.info; 7118 } else { 7119 try { 7120 pi = AppGlobals.getPackageManager().resolveContentProvider( 7121 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7122 } catch (RemoteException ex) { 7123 } 7124 } 7125 return pi; 7126 } 7127 7128 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7129 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7130 if (targetUris != null) { 7131 return targetUris.get(grantUri); 7132 } 7133 return null; 7134 } 7135 7136 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7137 String targetPkg, int targetUid, GrantUri grantUri) { 7138 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7139 if (targetUris == null) { 7140 targetUris = Maps.newArrayMap(); 7141 mGrantedUriPermissions.put(targetUid, targetUris); 7142 } 7143 7144 UriPermission perm = targetUris.get(grantUri); 7145 if (perm == null) { 7146 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7147 targetUris.put(grantUri, perm); 7148 } 7149 7150 return perm; 7151 } 7152 7153 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7154 final int modeFlags) { 7155 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7156 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7157 : UriPermission.STRENGTH_OWNED; 7158 7159 // Root gets to do everything. 7160 if (uid == 0) { 7161 return true; 7162 } 7163 7164 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7165 if (perms == null) return false; 7166 7167 // First look for exact match 7168 final UriPermission exactPerm = perms.get(grantUri); 7169 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7170 return true; 7171 } 7172 7173 // No exact match, look for prefixes 7174 final int N = perms.size(); 7175 for (int i = 0; i < N; i++) { 7176 final UriPermission perm = perms.valueAt(i); 7177 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7178 && perm.getStrength(modeFlags) >= minStrength) { 7179 return true; 7180 } 7181 } 7182 7183 return false; 7184 } 7185 7186 /** 7187 * @param uri This uri must NOT contain an embedded userId. 7188 * @param userId The userId in which the uri is to be resolved. 7189 */ 7190 @Override 7191 public int checkUriPermission(Uri uri, int pid, int uid, 7192 final int modeFlags, int userId) { 7193 enforceNotIsolatedCaller("checkUriPermission"); 7194 7195 // Another redirected-binder-call permissions check as in 7196 // {@link checkComponentPermission}. 7197 Identity tlsIdentity = sCallerIdentity.get(); 7198 if (tlsIdentity != null) { 7199 uid = tlsIdentity.uid; 7200 pid = tlsIdentity.pid; 7201 } 7202 7203 // Our own process gets to do everything. 7204 if (pid == MY_PID) { 7205 return PackageManager.PERMISSION_GRANTED; 7206 } 7207 synchronized (this) { 7208 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7209 ? PackageManager.PERMISSION_GRANTED 7210 : PackageManager.PERMISSION_DENIED; 7211 } 7212 } 7213 7214 /** 7215 * Check if the targetPkg can be granted permission to access uri by 7216 * the callingUid using the given modeFlags. Throws a security exception 7217 * if callingUid is not allowed to do this. Returns the uid of the target 7218 * if the URI permission grant should be performed; returns -1 if it is not 7219 * needed (for example targetPkg already has permission to access the URI). 7220 * If you already know the uid of the target, you can supply it in 7221 * lastTargetUid else set that to -1. 7222 */ 7223 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7224 final int modeFlags, int lastTargetUid) { 7225 if (!Intent.isAccessUriMode(modeFlags)) { 7226 return -1; 7227 } 7228 7229 if (targetPkg != null) { 7230 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7231 "Checking grant " + targetPkg + " permission to " + grantUri); 7232 } 7233 7234 final IPackageManager pm = AppGlobals.getPackageManager(); 7235 7236 // If this is not a content: uri, we can't do anything with it. 7237 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7238 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7239 "Can't grant URI permission for non-content URI: " + grantUri); 7240 return -1; 7241 } 7242 7243 final String authority = grantUri.uri.getAuthority(); 7244 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7245 if (pi == null) { 7246 Slog.w(TAG, "No content provider found for permission check: " + 7247 grantUri.uri.toSafeString()); 7248 return -1; 7249 } 7250 7251 int targetUid = lastTargetUid; 7252 if (targetUid < 0 && targetPkg != null) { 7253 try { 7254 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7255 if (targetUid < 0) { 7256 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7257 "Can't grant URI permission no uid for: " + targetPkg); 7258 return -1; 7259 } 7260 } catch (RemoteException ex) { 7261 return -1; 7262 } 7263 } 7264 7265 if (targetUid >= 0) { 7266 // First... does the target actually need this permission? 7267 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7268 // No need to grant the target this permission. 7269 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7270 "Target " + targetPkg + " already has full permission to " + grantUri); 7271 return -1; 7272 } 7273 } else { 7274 // First... there is no target package, so can anyone access it? 7275 boolean allowed = pi.exported; 7276 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7277 if (pi.readPermission != null) { 7278 allowed = false; 7279 } 7280 } 7281 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7282 if (pi.writePermission != null) { 7283 allowed = false; 7284 } 7285 } 7286 if (allowed) { 7287 return -1; 7288 } 7289 } 7290 7291 /* There is a special cross user grant if: 7292 * - The target is on another user. 7293 * - Apps on the current user can access the uri without any uid permissions. 7294 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7295 * grant uri permissions. 7296 */ 7297 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7298 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7299 modeFlags, false /*without considering the uid permissions*/); 7300 7301 // Second... is the provider allowing granting of URI permissions? 7302 if (!specialCrossUserGrant) { 7303 if (!pi.grantUriPermissions) { 7304 throw new SecurityException("Provider " + pi.packageName 7305 + "/" + pi.name 7306 + " does not allow granting of Uri permissions (uri " 7307 + grantUri + ")"); 7308 } 7309 if (pi.uriPermissionPatterns != null) { 7310 final int N = pi.uriPermissionPatterns.length; 7311 boolean allowed = false; 7312 for (int i=0; i<N; i++) { 7313 if (pi.uriPermissionPatterns[i] != null 7314 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7315 allowed = true; 7316 break; 7317 } 7318 } 7319 if (!allowed) { 7320 throw new SecurityException("Provider " + pi.packageName 7321 + "/" + pi.name 7322 + " does not allow granting of permission to path of Uri " 7323 + grantUri); 7324 } 7325 } 7326 } 7327 7328 // Third... does the caller itself have permission to access 7329 // this uri? 7330 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7331 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7332 // Require they hold a strong enough Uri permission 7333 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7334 throw new SecurityException("Uid " + callingUid 7335 + " does not have permission to uri " + grantUri); 7336 } 7337 } 7338 } 7339 return targetUid; 7340 } 7341 7342 /** 7343 * @param uri This uri must NOT contain an embedded userId. 7344 * @param userId The userId in which the uri is to be resolved. 7345 */ 7346 @Override 7347 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7348 final int modeFlags, int userId) { 7349 enforceNotIsolatedCaller("checkGrantUriPermission"); 7350 synchronized(this) { 7351 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7352 new GrantUri(userId, uri, false), modeFlags, -1); 7353 } 7354 } 7355 7356 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7357 final int modeFlags, UriPermissionOwner owner) { 7358 if (!Intent.isAccessUriMode(modeFlags)) { 7359 return; 7360 } 7361 7362 // So here we are: the caller has the assumed permission 7363 // to the uri, and the target doesn't. Let's now give this to 7364 // the target. 7365 7366 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7367 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7368 7369 final String authority = grantUri.uri.getAuthority(); 7370 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7371 if (pi == null) { 7372 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7373 return; 7374 } 7375 7376 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7377 grantUri.prefix = true; 7378 } 7379 final UriPermission perm = findOrCreateUriPermissionLocked( 7380 pi.packageName, targetPkg, targetUid, grantUri); 7381 perm.grantModes(modeFlags, owner); 7382 } 7383 7384 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7385 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7386 if (targetPkg == null) { 7387 throw new NullPointerException("targetPkg"); 7388 } 7389 int targetUid; 7390 final IPackageManager pm = AppGlobals.getPackageManager(); 7391 try { 7392 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7393 } catch (RemoteException ex) { 7394 return; 7395 } 7396 7397 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7398 targetUid); 7399 if (targetUid < 0) { 7400 return; 7401 } 7402 7403 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7404 owner); 7405 } 7406 7407 static class NeededUriGrants extends ArrayList<GrantUri> { 7408 final String targetPkg; 7409 final int targetUid; 7410 final int flags; 7411 7412 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7413 this.targetPkg = targetPkg; 7414 this.targetUid = targetUid; 7415 this.flags = flags; 7416 } 7417 } 7418 7419 /** 7420 * Like checkGrantUriPermissionLocked, but takes an Intent. 7421 */ 7422 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7423 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7424 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7425 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7426 + " clip=" + (intent != null ? intent.getClipData() : null) 7427 + " from " + intent + "; flags=0x" 7428 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7429 7430 if (targetPkg == null) { 7431 throw new NullPointerException("targetPkg"); 7432 } 7433 7434 if (intent == null) { 7435 return null; 7436 } 7437 Uri data = intent.getData(); 7438 ClipData clip = intent.getClipData(); 7439 if (data == null && clip == null) { 7440 return null; 7441 } 7442 // Default userId for uris in the intent (if they don't specify it themselves) 7443 int contentUserHint = intent.getContentUserHint(); 7444 if (contentUserHint == UserHandle.USER_CURRENT) { 7445 contentUserHint = UserHandle.getUserId(callingUid); 7446 } 7447 final IPackageManager pm = AppGlobals.getPackageManager(); 7448 int targetUid; 7449 if (needed != null) { 7450 targetUid = needed.targetUid; 7451 } else { 7452 try { 7453 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7454 } catch (RemoteException ex) { 7455 return null; 7456 } 7457 if (targetUid < 0) { 7458 if (DEBUG_URI_PERMISSION) { 7459 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7460 + " on user " + targetUserId); 7461 } 7462 return null; 7463 } 7464 } 7465 if (data != null) { 7466 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7467 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7468 targetUid); 7469 if (targetUid > 0) { 7470 if (needed == null) { 7471 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7472 } 7473 needed.add(grantUri); 7474 } 7475 } 7476 if (clip != null) { 7477 for (int i=0; i<clip.getItemCount(); i++) { 7478 Uri uri = clip.getItemAt(i).getUri(); 7479 if (uri != null) { 7480 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7481 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7482 targetUid); 7483 if (targetUid > 0) { 7484 if (needed == null) { 7485 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7486 } 7487 needed.add(grantUri); 7488 } 7489 } else { 7490 Intent clipIntent = clip.getItemAt(i).getIntent(); 7491 if (clipIntent != null) { 7492 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7493 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7494 if (newNeeded != null) { 7495 needed = newNeeded; 7496 } 7497 } 7498 } 7499 } 7500 } 7501 7502 return needed; 7503 } 7504 7505 /** 7506 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7507 */ 7508 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7509 UriPermissionOwner owner) { 7510 if (needed != null) { 7511 for (int i=0; i<needed.size(); i++) { 7512 GrantUri grantUri = needed.get(i); 7513 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7514 grantUri, needed.flags, owner); 7515 } 7516 } 7517 } 7518 7519 void grantUriPermissionFromIntentLocked(int callingUid, 7520 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7521 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7522 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7523 if (needed == null) { 7524 return; 7525 } 7526 7527 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7528 } 7529 7530 /** 7531 * @param uri This uri must NOT contain an embedded userId. 7532 * @param userId The userId in which the uri is to be resolved. 7533 */ 7534 @Override 7535 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7536 final int modeFlags, int userId) { 7537 enforceNotIsolatedCaller("grantUriPermission"); 7538 GrantUri grantUri = new GrantUri(userId, uri, false); 7539 synchronized(this) { 7540 final ProcessRecord r = getRecordForAppLocked(caller); 7541 if (r == null) { 7542 throw new SecurityException("Unable to find app for caller " 7543 + caller 7544 + " when granting permission to uri " + grantUri); 7545 } 7546 if (targetPkg == null) { 7547 throw new IllegalArgumentException("null target"); 7548 } 7549 if (grantUri == null) { 7550 throw new IllegalArgumentException("null uri"); 7551 } 7552 7553 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7554 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7555 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7556 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7557 7558 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7559 UserHandle.getUserId(r.uid)); 7560 } 7561 } 7562 7563 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7564 if (perm.modeFlags == 0) { 7565 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7566 perm.targetUid); 7567 if (perms != null) { 7568 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7569 "Removing " + perm.targetUid + " permission to " + perm.uri); 7570 7571 perms.remove(perm.uri); 7572 if (perms.isEmpty()) { 7573 mGrantedUriPermissions.remove(perm.targetUid); 7574 } 7575 } 7576 } 7577 } 7578 7579 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7580 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7581 7582 final IPackageManager pm = AppGlobals.getPackageManager(); 7583 final String authority = grantUri.uri.getAuthority(); 7584 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7585 if (pi == null) { 7586 Slog.w(TAG, "No content provider found for permission revoke: " 7587 + grantUri.toSafeString()); 7588 return; 7589 } 7590 7591 // Does the caller have this permission on the URI? 7592 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7593 // If they don't have direct access to the URI, then revoke any 7594 // ownerless URI permissions that have been granted to them. 7595 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7596 if (perms != null) { 7597 boolean persistChanged = false; 7598 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7599 final UriPermission perm = it.next(); 7600 if (perm.uri.sourceUserId == grantUri.sourceUserId 7601 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7602 if (DEBUG_URI_PERMISSION) 7603 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7604 " permission to " + perm.uri); 7605 persistChanged |= perm.revokeModes( 7606 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7607 if (perm.modeFlags == 0) { 7608 it.remove(); 7609 } 7610 } 7611 } 7612 if (perms.isEmpty()) { 7613 mGrantedUriPermissions.remove(callingUid); 7614 } 7615 if (persistChanged) { 7616 schedulePersistUriGrants(); 7617 } 7618 } 7619 return; 7620 } 7621 7622 boolean persistChanged = false; 7623 7624 // Go through all of the permissions and remove any that match. 7625 int N = mGrantedUriPermissions.size(); 7626 for (int i = 0; i < N; i++) { 7627 final int targetUid = mGrantedUriPermissions.keyAt(i); 7628 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7629 7630 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7631 final UriPermission perm = it.next(); 7632 if (perm.uri.sourceUserId == grantUri.sourceUserId 7633 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7634 if (DEBUG_URI_PERMISSION) 7635 Slog.v(TAG, 7636 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7637 persistChanged |= perm.revokeModes( 7638 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7639 if (perm.modeFlags == 0) { 7640 it.remove(); 7641 } 7642 } 7643 } 7644 7645 if (perms.isEmpty()) { 7646 mGrantedUriPermissions.remove(targetUid); 7647 N--; 7648 i--; 7649 } 7650 } 7651 7652 if (persistChanged) { 7653 schedulePersistUriGrants(); 7654 } 7655 } 7656 7657 /** 7658 * @param uri This uri must NOT contain an embedded userId. 7659 * @param userId The userId in which the uri is to be resolved. 7660 */ 7661 @Override 7662 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7663 int userId) { 7664 enforceNotIsolatedCaller("revokeUriPermission"); 7665 synchronized(this) { 7666 final ProcessRecord r = getRecordForAppLocked(caller); 7667 if (r == null) { 7668 throw new SecurityException("Unable to find app for caller " 7669 + caller 7670 + " when revoking permission to uri " + uri); 7671 } 7672 if (uri == null) { 7673 Slog.w(TAG, "revokeUriPermission: null uri"); 7674 return; 7675 } 7676 7677 if (!Intent.isAccessUriMode(modeFlags)) { 7678 return; 7679 } 7680 7681 final IPackageManager pm = AppGlobals.getPackageManager(); 7682 final String authority = uri.getAuthority(); 7683 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7684 if (pi == null) { 7685 Slog.w(TAG, "No content provider found for permission revoke: " 7686 + uri.toSafeString()); 7687 return; 7688 } 7689 7690 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7691 } 7692 } 7693 7694 /** 7695 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7696 * given package. 7697 * 7698 * @param packageName Package name to match, or {@code null} to apply to all 7699 * packages. 7700 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7701 * to all users. 7702 * @param persistable If persistable grants should be removed. 7703 */ 7704 private void removeUriPermissionsForPackageLocked( 7705 String packageName, int userHandle, boolean persistable) { 7706 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7707 throw new IllegalArgumentException("Must narrow by either package or user"); 7708 } 7709 7710 boolean persistChanged = false; 7711 7712 int N = mGrantedUriPermissions.size(); 7713 for (int i = 0; i < N; i++) { 7714 final int targetUid = mGrantedUriPermissions.keyAt(i); 7715 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7716 7717 // Only inspect grants matching user 7718 if (userHandle == UserHandle.USER_ALL 7719 || userHandle == UserHandle.getUserId(targetUid)) { 7720 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7721 final UriPermission perm = it.next(); 7722 7723 // Only inspect grants matching package 7724 if (packageName == null || perm.sourcePkg.equals(packageName) 7725 || perm.targetPkg.equals(packageName)) { 7726 persistChanged |= perm.revokeModes(persistable 7727 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7728 7729 // Only remove when no modes remain; any persisted grants 7730 // will keep this alive. 7731 if (perm.modeFlags == 0) { 7732 it.remove(); 7733 } 7734 } 7735 } 7736 7737 if (perms.isEmpty()) { 7738 mGrantedUriPermissions.remove(targetUid); 7739 N--; 7740 i--; 7741 } 7742 } 7743 } 7744 7745 if (persistChanged) { 7746 schedulePersistUriGrants(); 7747 } 7748 } 7749 7750 @Override 7751 public IBinder newUriPermissionOwner(String name) { 7752 enforceNotIsolatedCaller("newUriPermissionOwner"); 7753 synchronized(this) { 7754 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7755 return owner.getExternalTokenLocked(); 7756 } 7757 } 7758 7759 /** 7760 * @param uri This uri must NOT contain an embedded userId. 7761 * @param sourceUserId The userId in which the uri is to be resolved. 7762 * @param targetUserId The userId of the app that receives the grant. 7763 */ 7764 @Override 7765 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7766 final int modeFlags, int sourceUserId, int targetUserId) { 7767 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7768 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7769 synchronized(this) { 7770 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7771 if (owner == null) { 7772 throw new IllegalArgumentException("Unknown owner: " + token); 7773 } 7774 if (fromUid != Binder.getCallingUid()) { 7775 if (Binder.getCallingUid() != Process.myUid()) { 7776 // Only system code can grant URI permissions on behalf 7777 // of other users. 7778 throw new SecurityException("nice try"); 7779 } 7780 } 7781 if (targetPkg == null) { 7782 throw new IllegalArgumentException("null target"); 7783 } 7784 if (uri == null) { 7785 throw new IllegalArgumentException("null uri"); 7786 } 7787 7788 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7789 modeFlags, owner, targetUserId); 7790 } 7791 } 7792 7793 /** 7794 * @param uri This uri must NOT contain an embedded userId. 7795 * @param userId The userId in which the uri is to be resolved. 7796 */ 7797 @Override 7798 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7799 synchronized(this) { 7800 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7801 if (owner == null) { 7802 throw new IllegalArgumentException("Unknown owner: " + token); 7803 } 7804 7805 if (uri == null) { 7806 owner.removeUriPermissionsLocked(mode); 7807 } else { 7808 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7809 } 7810 } 7811 } 7812 7813 private void schedulePersistUriGrants() { 7814 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7815 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7816 10 * DateUtils.SECOND_IN_MILLIS); 7817 } 7818 } 7819 7820 private void writeGrantedUriPermissions() { 7821 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7822 7823 // Snapshot permissions so we can persist without lock 7824 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7825 synchronized (this) { 7826 final int size = mGrantedUriPermissions.size(); 7827 for (int i = 0; i < size; i++) { 7828 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7829 for (UriPermission perm : perms.values()) { 7830 if (perm.persistedModeFlags != 0) { 7831 persist.add(perm.snapshot()); 7832 } 7833 } 7834 } 7835 } 7836 7837 FileOutputStream fos = null; 7838 try { 7839 fos = mGrantFile.startWrite(); 7840 7841 XmlSerializer out = new FastXmlSerializer(); 7842 out.setOutput(fos, "utf-8"); 7843 out.startDocument(null, true); 7844 out.startTag(null, TAG_URI_GRANTS); 7845 for (UriPermission.Snapshot perm : persist) { 7846 out.startTag(null, TAG_URI_GRANT); 7847 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7848 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7849 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7850 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7851 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7852 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7853 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7854 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7855 out.endTag(null, TAG_URI_GRANT); 7856 } 7857 out.endTag(null, TAG_URI_GRANTS); 7858 out.endDocument(); 7859 7860 mGrantFile.finishWrite(fos); 7861 } catch (IOException e) { 7862 if (fos != null) { 7863 mGrantFile.failWrite(fos); 7864 } 7865 } 7866 } 7867 7868 private void readGrantedUriPermissionsLocked() { 7869 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7870 7871 final long now = System.currentTimeMillis(); 7872 7873 FileInputStream fis = null; 7874 try { 7875 fis = mGrantFile.openRead(); 7876 final XmlPullParser in = Xml.newPullParser(); 7877 in.setInput(fis, null); 7878 7879 int type; 7880 while ((type = in.next()) != END_DOCUMENT) { 7881 final String tag = in.getName(); 7882 if (type == START_TAG) { 7883 if (TAG_URI_GRANT.equals(tag)) { 7884 final int sourceUserId; 7885 final int targetUserId; 7886 final int userHandle = readIntAttribute(in, 7887 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7888 if (userHandle != UserHandle.USER_NULL) { 7889 // For backwards compatibility. 7890 sourceUserId = userHandle; 7891 targetUserId = userHandle; 7892 } else { 7893 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7894 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7895 } 7896 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7897 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7898 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7899 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7900 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7901 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7902 7903 // Sanity check that provider still belongs to source package 7904 final ProviderInfo pi = getProviderInfoLocked( 7905 uri.getAuthority(), sourceUserId); 7906 if (pi != null && sourcePkg.equals(pi.packageName)) { 7907 int targetUid = -1; 7908 try { 7909 targetUid = AppGlobals.getPackageManager() 7910 .getPackageUid(targetPkg, targetUserId); 7911 } catch (RemoteException e) { 7912 } 7913 if (targetUid != -1) { 7914 final UriPermission perm = findOrCreateUriPermissionLocked( 7915 sourcePkg, targetPkg, targetUid, 7916 new GrantUri(sourceUserId, uri, prefix)); 7917 perm.initPersistedModes(modeFlags, createdTime); 7918 } 7919 } else { 7920 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7921 + " but instead found " + pi); 7922 } 7923 } 7924 } 7925 } 7926 } catch (FileNotFoundException e) { 7927 // Missing grants is okay 7928 } catch (IOException e) { 7929 Slog.wtf(TAG, "Failed reading Uri grants", e); 7930 } catch (XmlPullParserException e) { 7931 Slog.wtf(TAG, "Failed reading Uri grants", e); 7932 } finally { 7933 IoUtils.closeQuietly(fis); 7934 } 7935 } 7936 7937 /** 7938 * @param uri This uri must NOT contain an embedded userId. 7939 * @param userId The userId in which the uri is to be resolved. 7940 */ 7941 @Override 7942 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7943 enforceNotIsolatedCaller("takePersistableUriPermission"); 7944 7945 Preconditions.checkFlagsArgument(modeFlags, 7946 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7947 7948 synchronized (this) { 7949 final int callingUid = Binder.getCallingUid(); 7950 boolean persistChanged = false; 7951 GrantUri grantUri = new GrantUri(userId, uri, false); 7952 7953 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7954 new GrantUri(userId, uri, false)); 7955 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7956 new GrantUri(userId, uri, true)); 7957 7958 final boolean exactValid = (exactPerm != null) 7959 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7960 final boolean prefixValid = (prefixPerm != null) 7961 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7962 7963 if (!(exactValid || prefixValid)) { 7964 throw new SecurityException("No persistable permission grants found for UID " 7965 + callingUid + " and Uri " + grantUri.toSafeString()); 7966 } 7967 7968 if (exactValid) { 7969 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7970 } 7971 if (prefixValid) { 7972 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7973 } 7974 7975 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7976 7977 if (persistChanged) { 7978 schedulePersistUriGrants(); 7979 } 7980 } 7981 } 7982 7983 /** 7984 * @param uri This uri must NOT contain an embedded userId. 7985 * @param userId The userId in which the uri is to be resolved. 7986 */ 7987 @Override 7988 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7989 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7990 7991 Preconditions.checkFlagsArgument(modeFlags, 7992 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7993 7994 synchronized (this) { 7995 final int callingUid = Binder.getCallingUid(); 7996 boolean persistChanged = false; 7997 7998 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7999 new GrantUri(userId, uri, false)); 8000 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8001 new GrantUri(userId, uri, true)); 8002 if (exactPerm == null && prefixPerm == null) { 8003 throw new SecurityException("No permission grants found for UID " + callingUid 8004 + " and Uri " + uri.toSafeString()); 8005 } 8006 8007 if (exactPerm != null) { 8008 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8009 removeUriPermissionIfNeededLocked(exactPerm); 8010 } 8011 if (prefixPerm != null) { 8012 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8013 removeUriPermissionIfNeededLocked(prefixPerm); 8014 } 8015 8016 if (persistChanged) { 8017 schedulePersistUriGrants(); 8018 } 8019 } 8020 } 8021 8022 /** 8023 * Prune any older {@link UriPermission} for the given UID until outstanding 8024 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8025 * 8026 * @return if any mutations occured that require persisting. 8027 */ 8028 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8029 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8030 if (perms == null) return false; 8031 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8032 8033 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8034 for (UriPermission perm : perms.values()) { 8035 if (perm.persistedModeFlags != 0) { 8036 persisted.add(perm); 8037 } 8038 } 8039 8040 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8041 if (trimCount <= 0) return false; 8042 8043 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8044 for (int i = 0; i < trimCount; i++) { 8045 final UriPermission perm = persisted.get(i); 8046 8047 if (DEBUG_URI_PERMISSION) { 8048 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8049 } 8050 8051 perm.releasePersistableModes(~0); 8052 removeUriPermissionIfNeededLocked(perm); 8053 } 8054 8055 return true; 8056 } 8057 8058 @Override 8059 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8060 String packageName, boolean incoming) { 8061 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8062 Preconditions.checkNotNull(packageName, "packageName"); 8063 8064 final int callingUid = Binder.getCallingUid(); 8065 final IPackageManager pm = AppGlobals.getPackageManager(); 8066 try { 8067 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8068 if (packageUid != callingUid) { 8069 throw new SecurityException( 8070 "Package " + packageName + " does not belong to calling UID " + callingUid); 8071 } 8072 } catch (RemoteException e) { 8073 throw new SecurityException("Failed to verify package name ownership"); 8074 } 8075 8076 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8077 synchronized (this) { 8078 if (incoming) { 8079 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8080 callingUid); 8081 if (perms == null) { 8082 Slog.w(TAG, "No permission grants found for " + packageName); 8083 } else { 8084 for (UriPermission perm : perms.values()) { 8085 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8086 result.add(perm.buildPersistedPublicApiObject()); 8087 } 8088 } 8089 } 8090 } else { 8091 final int size = mGrantedUriPermissions.size(); 8092 for (int i = 0; i < size; i++) { 8093 final ArrayMap<GrantUri, UriPermission> perms = 8094 mGrantedUriPermissions.valueAt(i); 8095 for (UriPermission perm : perms.values()) { 8096 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8097 result.add(perm.buildPersistedPublicApiObject()); 8098 } 8099 } 8100 } 8101 } 8102 } 8103 return new ParceledListSlice<android.content.UriPermission>(result); 8104 } 8105 8106 @Override 8107 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8108 synchronized (this) { 8109 ProcessRecord app = 8110 who != null ? getRecordForAppLocked(who) : null; 8111 if (app == null) return; 8112 8113 Message msg = Message.obtain(); 8114 msg.what = WAIT_FOR_DEBUGGER_MSG; 8115 msg.obj = app; 8116 msg.arg1 = waiting ? 1 : 0; 8117 mHandler.sendMessage(msg); 8118 } 8119 } 8120 8121 @Override 8122 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8123 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8124 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8125 outInfo.availMem = Process.getFreeMemory(); 8126 outInfo.totalMem = Process.getTotalMemory(); 8127 outInfo.threshold = homeAppMem; 8128 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8129 outInfo.hiddenAppThreshold = cachedAppMem; 8130 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8131 ProcessList.SERVICE_ADJ); 8132 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8133 ProcessList.VISIBLE_APP_ADJ); 8134 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8135 ProcessList.FOREGROUND_APP_ADJ); 8136 } 8137 8138 // ========================================================= 8139 // TASK MANAGEMENT 8140 // ========================================================= 8141 8142 @Override 8143 public List<IAppTask> getAppTasks(String callingPackage) { 8144 int callingUid = Binder.getCallingUid(); 8145 long ident = Binder.clearCallingIdentity(); 8146 8147 synchronized(this) { 8148 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8149 try { 8150 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8151 8152 final int N = mRecentTasks.size(); 8153 for (int i = 0; i < N; i++) { 8154 TaskRecord tr = mRecentTasks.get(i); 8155 // Skip tasks that do not match the caller. We don't need to verify 8156 // callingPackage, because we are also limiting to callingUid and know 8157 // that will limit to the correct security sandbox. 8158 if (tr.effectiveUid != callingUid) { 8159 continue; 8160 } 8161 Intent intent = tr.getBaseIntent(); 8162 if (intent == null || 8163 !callingPackage.equals(intent.getComponent().getPackageName())) { 8164 continue; 8165 } 8166 ActivityManager.RecentTaskInfo taskInfo = 8167 createRecentTaskInfoFromTaskRecord(tr); 8168 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8169 list.add(taskImpl); 8170 } 8171 } finally { 8172 Binder.restoreCallingIdentity(ident); 8173 } 8174 return list; 8175 } 8176 } 8177 8178 @Override 8179 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8180 final int callingUid = Binder.getCallingUid(); 8181 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8182 8183 synchronized(this) { 8184 if (localLOGV) Slog.v( 8185 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8186 8187 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8188 callingUid); 8189 8190 // TODO: Improve with MRU list from all ActivityStacks. 8191 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8192 } 8193 8194 return list; 8195 } 8196 8197 TaskRecord getMostRecentTask() { 8198 return mRecentTasks.get(0); 8199 } 8200 8201 /** 8202 * Creates a new RecentTaskInfo from a TaskRecord. 8203 */ 8204 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8205 // Update the task description to reflect any changes in the task stack 8206 tr.updateTaskDescription(); 8207 8208 // Compose the recent task info 8209 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8210 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8211 rti.persistentId = tr.taskId; 8212 rti.baseIntent = new Intent(tr.getBaseIntent()); 8213 rti.origActivity = tr.origActivity; 8214 rti.description = tr.lastDescription; 8215 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8216 rti.userId = tr.userId; 8217 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8218 rti.firstActiveTime = tr.firstActiveTime; 8219 rti.lastActiveTime = tr.lastActiveTime; 8220 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8221 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8222 return rti; 8223 } 8224 8225 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8226 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8227 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8228 if (!allowed) { 8229 if (checkPermission(android.Manifest.permission.GET_TASKS, 8230 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8231 // Temporary compatibility: some existing apps on the system image may 8232 // still be requesting the old permission and not switched to the new 8233 // one; if so, we'll still allow them full access. This means we need 8234 // to see if they are holding the old permission and are a system app. 8235 try { 8236 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8237 allowed = true; 8238 Slog.w(TAG, caller + ": caller " + callingUid 8239 + " is using old GET_TASKS but privileged; allowing"); 8240 } 8241 } catch (RemoteException e) { 8242 } 8243 } 8244 } 8245 if (!allowed) { 8246 Slog.w(TAG, caller + ": caller " + callingUid 8247 + " does not hold GET_TASKS; limiting output"); 8248 } 8249 return allowed; 8250 } 8251 8252 @Override 8253 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8254 final int callingUid = Binder.getCallingUid(); 8255 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8256 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8257 8258 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8259 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8260 synchronized (this) { 8261 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8262 callingUid); 8263 final boolean detailed = checkCallingPermission( 8264 android.Manifest.permission.GET_DETAILED_TASKS) 8265 == PackageManager.PERMISSION_GRANTED; 8266 8267 final int N = mRecentTasks.size(); 8268 ArrayList<ActivityManager.RecentTaskInfo> res 8269 = new ArrayList<ActivityManager.RecentTaskInfo>( 8270 maxNum < N ? maxNum : N); 8271 8272 final Set<Integer> includedUsers; 8273 if (includeProfiles) { 8274 includedUsers = getProfileIdsLocked(userId); 8275 } else { 8276 includedUsers = new HashSet<Integer>(); 8277 } 8278 includedUsers.add(Integer.valueOf(userId)); 8279 8280 for (int i=0; i<N && maxNum > 0; i++) { 8281 TaskRecord tr = mRecentTasks.get(i); 8282 // Only add calling user or related users recent tasks 8283 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8284 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8285 continue; 8286 } 8287 8288 // Return the entry if desired by the caller. We always return 8289 // the first entry, because callers always expect this to be the 8290 // foreground app. We may filter others if the caller has 8291 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8292 // we should exclude the entry. 8293 8294 if (i == 0 8295 || withExcluded 8296 || (tr.intent == null) 8297 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8298 == 0)) { 8299 if (!allowed) { 8300 // If the caller doesn't have the GET_TASKS permission, then only 8301 // allow them to see a small subset of tasks -- their own and home. 8302 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8303 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8304 continue; 8305 } 8306 } 8307 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8308 if (tr.stack != null && tr.stack.isHomeStack()) { 8309 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8310 continue; 8311 } 8312 } 8313 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8314 // Don't include auto remove tasks that are finished or finishing. 8315 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8316 + tr); 8317 continue; 8318 } 8319 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8320 && !tr.isAvailable) { 8321 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8322 continue; 8323 } 8324 8325 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8326 if (!detailed) { 8327 rti.baseIntent.replaceExtras((Bundle)null); 8328 } 8329 8330 res.add(rti); 8331 maxNum--; 8332 } 8333 } 8334 return res; 8335 } 8336 } 8337 8338 private TaskRecord recentTaskForIdLocked(int id) { 8339 final int N = mRecentTasks.size(); 8340 for (int i=0; i<N; i++) { 8341 TaskRecord tr = mRecentTasks.get(i); 8342 if (tr.taskId == id) { 8343 return tr; 8344 } 8345 } 8346 return null; 8347 } 8348 8349 @Override 8350 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8351 synchronized (this) { 8352 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8353 "getTaskThumbnail()"); 8354 TaskRecord tr = recentTaskForIdLocked(id); 8355 if (tr != null) { 8356 return tr.getTaskThumbnailLocked(); 8357 } 8358 } 8359 return null; 8360 } 8361 8362 @Override 8363 public int addAppTask(IBinder activityToken, Intent intent, 8364 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8365 final int callingUid = Binder.getCallingUid(); 8366 final long callingIdent = Binder.clearCallingIdentity(); 8367 8368 try { 8369 synchronized (this) { 8370 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8371 if (r == null) { 8372 throw new IllegalArgumentException("Activity does not exist; token=" 8373 + activityToken); 8374 } 8375 ComponentName comp = intent.getComponent(); 8376 if (comp == null) { 8377 throw new IllegalArgumentException("Intent " + intent 8378 + " must specify explicit component"); 8379 } 8380 if (thumbnail.getWidth() != mThumbnailWidth 8381 || thumbnail.getHeight() != mThumbnailHeight) { 8382 throw new IllegalArgumentException("Bad thumbnail size: got " 8383 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8384 + mThumbnailWidth + "x" + mThumbnailHeight); 8385 } 8386 if (intent.getSelector() != null) { 8387 intent.setSelector(null); 8388 } 8389 if (intent.getSourceBounds() != null) { 8390 intent.setSourceBounds(null); 8391 } 8392 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8393 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8394 // The caller has added this as an auto-remove task... that makes no 8395 // sense, so turn off auto-remove. 8396 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8397 } 8398 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8399 // Must be a new task. 8400 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8401 } 8402 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8403 mLastAddedTaskActivity = null; 8404 } 8405 ActivityInfo ainfo = mLastAddedTaskActivity; 8406 if (ainfo == null) { 8407 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8408 comp, 0, UserHandle.getUserId(callingUid)); 8409 if (ainfo.applicationInfo.uid != callingUid) { 8410 throw new SecurityException( 8411 "Can't add task for another application: target uid=" 8412 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8413 } 8414 } 8415 8416 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8417 intent, description); 8418 8419 int trimIdx = trimRecentsForTask(task, false); 8420 if (trimIdx >= 0) { 8421 // If this would have caused a trim, then we'll abort because that 8422 // means it would be added at the end of the list but then just removed. 8423 return -1; 8424 } 8425 8426 final int N = mRecentTasks.size(); 8427 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8428 final TaskRecord tr = mRecentTasks.remove(N - 1); 8429 tr.removedFromRecents(mTaskPersister); 8430 } 8431 8432 task.inRecents = true; 8433 mRecentTasks.add(task); 8434 r.task.stack.addTask(task, false, false); 8435 8436 task.setLastThumbnail(thumbnail); 8437 task.freeLastThumbnail(); 8438 8439 return task.taskId; 8440 } 8441 } finally { 8442 Binder.restoreCallingIdentity(callingIdent); 8443 } 8444 } 8445 8446 @Override 8447 public Point getAppTaskThumbnailSize() { 8448 synchronized (this) { 8449 return new Point(mThumbnailWidth, mThumbnailHeight); 8450 } 8451 } 8452 8453 @Override 8454 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8455 synchronized (this) { 8456 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8457 if (r != null) { 8458 r.setTaskDescription(td); 8459 r.task.updateTaskDescription(); 8460 } 8461 } 8462 } 8463 8464 @Override 8465 public Bitmap getTaskDescriptionIcon(String filename) { 8466 if (!FileUtils.isValidExtFilename(filename) 8467 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8468 throw new IllegalArgumentException("Bad filename: " + filename); 8469 } 8470 return mTaskPersister.getTaskDescriptionIcon(filename); 8471 } 8472 8473 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8474 mRecentTasks.remove(tr); 8475 tr.removedFromRecents(mTaskPersister); 8476 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8477 Intent baseIntent = new Intent( 8478 tr.intent != null ? tr.intent : tr.affinityIntent); 8479 ComponentName component = baseIntent.getComponent(); 8480 if (component == null) { 8481 Slog.w(TAG, "Now component for base intent of task: " + tr); 8482 return; 8483 } 8484 8485 // Find any running services associated with this app. 8486 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8487 8488 if (killProcesses) { 8489 // Find any running processes associated with this app. 8490 final String pkg = component.getPackageName(); 8491 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8492 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8493 for (int i=0; i<pmap.size(); i++) { 8494 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8495 for (int j=0; j<uids.size(); j++) { 8496 ProcessRecord proc = uids.valueAt(j); 8497 if (proc.userId != tr.userId) { 8498 continue; 8499 } 8500 if (!proc.pkgList.containsKey(pkg)) { 8501 continue; 8502 } 8503 procs.add(proc); 8504 } 8505 } 8506 8507 // Kill the running processes. 8508 for (int i=0; i<procs.size(); i++) { 8509 ProcessRecord pr = procs.get(i); 8510 if (pr == mHomeProcess) { 8511 // Don't kill the home process along with tasks from the same package. 8512 continue; 8513 } 8514 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8515 pr.kill("remove task", true); 8516 } else { 8517 pr.waitingToKill = "remove task"; 8518 } 8519 } 8520 } 8521 } 8522 8523 /** 8524 * Removes the task with the specified task id. 8525 * 8526 * @param taskId Identifier of the task to be removed. 8527 * @param flags Additional operational flags. May be 0 or 8528 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8529 * @return Returns true if the given task was found and removed. 8530 */ 8531 private boolean removeTaskByIdLocked(int taskId, int flags) { 8532 TaskRecord tr = recentTaskForIdLocked(taskId); 8533 if (tr != null) { 8534 tr.removeTaskActivitiesLocked(); 8535 cleanUpRemovedTaskLocked(tr, flags); 8536 if (tr.isPersistable) { 8537 notifyTaskPersisterLocked(null, true); 8538 } 8539 return true; 8540 } 8541 return false; 8542 } 8543 8544 @Override 8545 public boolean removeTask(int taskId, int flags) { 8546 synchronized (this) { 8547 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8548 "removeTask()"); 8549 long ident = Binder.clearCallingIdentity(); 8550 try { 8551 return removeTaskByIdLocked(taskId, flags); 8552 } finally { 8553 Binder.restoreCallingIdentity(ident); 8554 } 8555 } 8556 } 8557 8558 /** 8559 * TODO: Add mController hook 8560 */ 8561 @Override 8562 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8563 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8564 "moveTaskToFront()"); 8565 8566 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8567 synchronized(this) { 8568 moveTaskToFrontLocked(taskId, flags, options); 8569 } 8570 } 8571 8572 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8573 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8574 Binder.getCallingUid(), -1, -1, "Task to front")) { 8575 ActivityOptions.abort(options); 8576 return; 8577 } 8578 final long origId = Binder.clearCallingIdentity(); 8579 try { 8580 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8581 if (task == null) { 8582 return; 8583 } 8584 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8585 mStackSupervisor.showLockTaskToast(); 8586 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8587 return; 8588 } 8589 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8590 if (prev != null && prev.isRecentsActivity()) { 8591 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8592 } 8593 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8594 } finally { 8595 Binder.restoreCallingIdentity(origId); 8596 } 8597 ActivityOptions.abort(options); 8598 } 8599 8600 @Override 8601 public void moveTaskToBack(int taskId) { 8602 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8603 "moveTaskToBack()"); 8604 8605 synchronized(this) { 8606 TaskRecord tr = recentTaskForIdLocked(taskId); 8607 if (tr != null) { 8608 if (tr == mStackSupervisor.mLockTaskModeTask) { 8609 mStackSupervisor.showLockTaskToast(); 8610 return; 8611 } 8612 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8613 ActivityStack stack = tr.stack; 8614 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8615 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8616 Binder.getCallingUid(), -1, -1, "Task to back")) { 8617 return; 8618 } 8619 } 8620 final long origId = Binder.clearCallingIdentity(); 8621 try { 8622 stack.moveTaskToBackLocked(taskId, null); 8623 } finally { 8624 Binder.restoreCallingIdentity(origId); 8625 } 8626 } 8627 } 8628 } 8629 8630 /** 8631 * Moves an activity, and all of the other activities within the same task, to the bottom 8632 * of the history stack. The activity's order within the task is unchanged. 8633 * 8634 * @param token A reference to the activity we wish to move 8635 * @param nonRoot If false then this only works if the activity is the root 8636 * of a task; if true it will work for any activity in a task. 8637 * @return Returns true if the move completed, false if not. 8638 */ 8639 @Override 8640 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8641 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8642 synchronized(this) { 8643 final long origId = Binder.clearCallingIdentity(); 8644 try { 8645 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8646 if (taskId >= 0) { 8647 if ((mStackSupervisor.mLockTaskModeTask != null) 8648 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8649 mStackSupervisor.showLockTaskToast(); 8650 return false; 8651 } 8652 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8653 } 8654 } finally { 8655 Binder.restoreCallingIdentity(origId); 8656 } 8657 } 8658 return false; 8659 } 8660 8661 @Override 8662 public void moveTaskBackwards(int task) { 8663 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8664 "moveTaskBackwards()"); 8665 8666 synchronized(this) { 8667 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8668 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8669 return; 8670 } 8671 final long origId = Binder.clearCallingIdentity(); 8672 moveTaskBackwardsLocked(task); 8673 Binder.restoreCallingIdentity(origId); 8674 } 8675 } 8676 8677 private final void moveTaskBackwardsLocked(int task) { 8678 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8679 } 8680 8681 @Override 8682 public IBinder getHomeActivityToken() throws RemoteException { 8683 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8684 "getHomeActivityToken()"); 8685 synchronized (this) { 8686 return mStackSupervisor.getHomeActivityToken(); 8687 } 8688 } 8689 8690 @Override 8691 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8692 IActivityContainerCallback callback) throws RemoteException { 8693 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8694 "createActivityContainer()"); 8695 synchronized (this) { 8696 if (parentActivityToken == null) { 8697 throw new IllegalArgumentException("parent token must not be null"); 8698 } 8699 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8700 if (r == null) { 8701 return null; 8702 } 8703 if (callback == null) { 8704 throw new IllegalArgumentException("callback must not be null"); 8705 } 8706 return mStackSupervisor.createActivityContainer(r, callback); 8707 } 8708 } 8709 8710 @Override 8711 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8712 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8713 "deleteActivityContainer()"); 8714 synchronized (this) { 8715 mStackSupervisor.deleteActivityContainer(container); 8716 } 8717 } 8718 8719 @Override 8720 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8721 throws RemoteException { 8722 synchronized (this) { 8723 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8724 if (stack != null) { 8725 return stack.mActivityContainer; 8726 } 8727 return null; 8728 } 8729 } 8730 8731 @Override 8732 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8733 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8734 "moveTaskToStack()"); 8735 if (stackId == HOME_STACK_ID) { 8736 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8737 new RuntimeException("here").fillInStackTrace()); 8738 } 8739 synchronized (this) { 8740 long ident = Binder.clearCallingIdentity(); 8741 try { 8742 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8743 + stackId + " toTop=" + toTop); 8744 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8745 } finally { 8746 Binder.restoreCallingIdentity(ident); 8747 } 8748 } 8749 } 8750 8751 @Override 8752 public void resizeStack(int stackBoxId, Rect bounds) { 8753 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8754 "resizeStackBox()"); 8755 long ident = Binder.clearCallingIdentity(); 8756 try { 8757 mWindowManager.resizeStack(stackBoxId, bounds); 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 } 8762 8763 @Override 8764 public List<StackInfo> getAllStackInfos() { 8765 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8766 "getAllStackInfos()"); 8767 long ident = Binder.clearCallingIdentity(); 8768 try { 8769 synchronized (this) { 8770 return mStackSupervisor.getAllStackInfosLocked(); 8771 } 8772 } finally { 8773 Binder.restoreCallingIdentity(ident); 8774 } 8775 } 8776 8777 @Override 8778 public StackInfo getStackInfo(int stackId) { 8779 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8780 "getStackInfo()"); 8781 long ident = Binder.clearCallingIdentity(); 8782 try { 8783 synchronized (this) { 8784 return mStackSupervisor.getStackInfoLocked(stackId); 8785 } 8786 } finally { 8787 Binder.restoreCallingIdentity(ident); 8788 } 8789 } 8790 8791 @Override 8792 public boolean isInHomeStack(int taskId) { 8793 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8794 "getStackInfo()"); 8795 long ident = Binder.clearCallingIdentity(); 8796 try { 8797 synchronized (this) { 8798 TaskRecord tr = recentTaskForIdLocked(taskId); 8799 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8800 } 8801 } finally { 8802 Binder.restoreCallingIdentity(ident); 8803 } 8804 } 8805 8806 @Override 8807 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8808 synchronized(this) { 8809 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8810 } 8811 } 8812 8813 private boolean isLockTaskAuthorized(String pkg) { 8814 final DevicePolicyManager dpm = (DevicePolicyManager) 8815 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8816 try { 8817 int uid = mContext.getPackageManager().getPackageUid(pkg, 8818 Binder.getCallingUserHandle().getIdentifier()); 8819 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8820 } catch (NameNotFoundException e) { 8821 return false; 8822 } 8823 } 8824 8825 void startLockTaskMode(TaskRecord task) { 8826 final String pkg; 8827 synchronized (this) { 8828 pkg = task.intent.getComponent().getPackageName(); 8829 } 8830 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8831 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8832 final TaskRecord taskRecord = task; 8833 mHandler.post(new Runnable() { 8834 @Override 8835 public void run() { 8836 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8837 } 8838 }); 8839 return; 8840 } 8841 long ident = Binder.clearCallingIdentity(); 8842 try { 8843 synchronized (this) { 8844 // Since we lost lock on task, make sure it is still there. 8845 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8846 if (task != null) { 8847 if (!isSystemInitiated 8848 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8849 throw new IllegalArgumentException("Invalid task, not in foreground"); 8850 } 8851 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8852 } 8853 } 8854 } finally { 8855 Binder.restoreCallingIdentity(ident); 8856 } 8857 } 8858 8859 @Override 8860 public void startLockTaskMode(int taskId) { 8861 final TaskRecord task; 8862 long ident = Binder.clearCallingIdentity(); 8863 try { 8864 synchronized (this) { 8865 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8866 } 8867 } finally { 8868 Binder.restoreCallingIdentity(ident); 8869 } 8870 if (task != null) { 8871 startLockTaskMode(task); 8872 } 8873 } 8874 8875 @Override 8876 public void startLockTaskMode(IBinder token) { 8877 final TaskRecord task; 8878 long ident = Binder.clearCallingIdentity(); 8879 try { 8880 synchronized (this) { 8881 final ActivityRecord r = ActivityRecord.forToken(token); 8882 if (r == null) { 8883 return; 8884 } 8885 task = r.task; 8886 } 8887 } finally { 8888 Binder.restoreCallingIdentity(ident); 8889 } 8890 if (task != null) { 8891 startLockTaskMode(task); 8892 } 8893 } 8894 8895 @Override 8896 public void startLockTaskModeOnCurrent() throws RemoteException { 8897 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8898 "startLockTaskModeOnCurrent"); 8899 ActivityRecord r = null; 8900 synchronized (this) { 8901 r = mStackSupervisor.topRunningActivityLocked(); 8902 } 8903 startLockTaskMode(r.task); 8904 } 8905 8906 @Override 8907 public void stopLockTaskMode() { 8908 // Verify that the user matches the package of the intent for the TaskRecord 8909 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8910 // and stopLockTaskMode. 8911 final int callingUid = Binder.getCallingUid(); 8912 if (callingUid != Process.SYSTEM_UID) { 8913 try { 8914 String pkg = 8915 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8916 int uid = mContext.getPackageManager().getPackageUid(pkg, 8917 Binder.getCallingUserHandle().getIdentifier()); 8918 if (uid != callingUid) { 8919 throw new SecurityException("Invalid uid, expected " + uid); 8920 } 8921 } catch (NameNotFoundException e) { 8922 Log.d(TAG, "stopLockTaskMode " + e); 8923 return; 8924 } 8925 } 8926 long ident = Binder.clearCallingIdentity(); 8927 try { 8928 Log.d(TAG, "stopLockTaskMode"); 8929 // Stop lock task 8930 synchronized (this) { 8931 mStackSupervisor.setLockTaskModeLocked(null, false); 8932 } 8933 } finally { 8934 Binder.restoreCallingIdentity(ident); 8935 } 8936 } 8937 8938 @Override 8939 public void stopLockTaskModeOnCurrent() throws RemoteException { 8940 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8941 "stopLockTaskModeOnCurrent"); 8942 long ident = Binder.clearCallingIdentity(); 8943 try { 8944 stopLockTaskMode(); 8945 } finally { 8946 Binder.restoreCallingIdentity(ident); 8947 } 8948 } 8949 8950 @Override 8951 public boolean isInLockTaskMode() { 8952 synchronized (this) { 8953 return mStackSupervisor.isInLockTaskMode(); 8954 } 8955 } 8956 8957 // ========================================================= 8958 // CONTENT PROVIDERS 8959 // ========================================================= 8960 8961 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8962 List<ProviderInfo> providers = null; 8963 try { 8964 providers = AppGlobals.getPackageManager(). 8965 queryContentProviders(app.processName, app.uid, 8966 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8967 } catch (RemoteException ex) { 8968 } 8969 if (DEBUG_MU) 8970 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8971 int userId = app.userId; 8972 if (providers != null) { 8973 int N = providers.size(); 8974 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8975 for (int i=0; i<N; i++) { 8976 ProviderInfo cpi = 8977 (ProviderInfo)providers.get(i); 8978 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8979 cpi.name, cpi.flags); 8980 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8981 // This is a singleton provider, but a user besides the 8982 // default user is asking to initialize a process it runs 8983 // in... well, no, it doesn't actually run in this process, 8984 // it runs in the process of the default user. Get rid of it. 8985 providers.remove(i); 8986 N--; 8987 i--; 8988 continue; 8989 } 8990 8991 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8992 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8993 if (cpr == null) { 8994 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8995 mProviderMap.putProviderByClass(comp, cpr); 8996 } 8997 if (DEBUG_MU) 8998 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8999 app.pubProviders.put(cpi.name, cpr); 9000 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9001 // Don't add this if it is a platform component that is marked 9002 // to run in multiple processes, because this is actually 9003 // part of the framework so doesn't make sense to track as a 9004 // separate apk in the process. 9005 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9006 mProcessStats); 9007 } 9008 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9009 } 9010 } 9011 return providers; 9012 } 9013 9014 /** 9015 * Check if {@link ProcessRecord} has a possible chance at accessing the 9016 * given {@link ProviderInfo}. Final permission checking is always done 9017 * in {@link ContentProvider}. 9018 */ 9019 private final String checkContentProviderPermissionLocked( 9020 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9021 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9022 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9023 boolean checkedGrants = false; 9024 if (checkUser) { 9025 // Looking for cross-user grants before enforcing the typical cross-users permissions 9026 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9027 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9028 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9029 return null; 9030 } 9031 checkedGrants = true; 9032 } 9033 userId = handleIncomingUser(callingPid, callingUid, userId, 9034 false, ALLOW_NON_FULL, 9035 "checkContentProviderPermissionLocked " + cpi.authority, null); 9036 if (userId != tmpTargetUserId) { 9037 // When we actually went to determine the final targer user ID, this ended 9038 // up different than our initial check for the authority. This is because 9039 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9040 // SELF. So we need to re-check the grants again. 9041 checkedGrants = false; 9042 } 9043 } 9044 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9045 cpi.applicationInfo.uid, cpi.exported) 9046 == PackageManager.PERMISSION_GRANTED) { 9047 return null; 9048 } 9049 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9050 cpi.applicationInfo.uid, cpi.exported) 9051 == PackageManager.PERMISSION_GRANTED) { 9052 return null; 9053 } 9054 9055 PathPermission[] pps = cpi.pathPermissions; 9056 if (pps != null) { 9057 int i = pps.length; 9058 while (i > 0) { 9059 i--; 9060 PathPermission pp = pps[i]; 9061 String pprperm = pp.getReadPermission(); 9062 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9063 cpi.applicationInfo.uid, cpi.exported) 9064 == PackageManager.PERMISSION_GRANTED) { 9065 return null; 9066 } 9067 String ppwperm = pp.getWritePermission(); 9068 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9069 cpi.applicationInfo.uid, cpi.exported) 9070 == PackageManager.PERMISSION_GRANTED) { 9071 return null; 9072 } 9073 } 9074 } 9075 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9076 return null; 9077 } 9078 9079 String msg; 9080 if (!cpi.exported) { 9081 msg = "Permission Denial: opening provider " + cpi.name 9082 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9083 + ", uid=" + callingUid + ") that is not exported from uid " 9084 + cpi.applicationInfo.uid; 9085 } else { 9086 msg = "Permission Denial: opening provider " + cpi.name 9087 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9088 + ", uid=" + callingUid + ") requires " 9089 + cpi.readPermission + " or " + cpi.writePermission; 9090 } 9091 Slog.w(TAG, msg); 9092 return msg; 9093 } 9094 9095 /** 9096 * Returns if the ContentProvider has granted a uri to callingUid 9097 */ 9098 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9099 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9100 if (perms != null) { 9101 for (int i=perms.size()-1; i>=0; i--) { 9102 GrantUri grantUri = perms.keyAt(i); 9103 if (grantUri.sourceUserId == userId || !checkUser) { 9104 if (matchesProvider(grantUri.uri, cpi)) { 9105 return true; 9106 } 9107 } 9108 } 9109 } 9110 return false; 9111 } 9112 9113 /** 9114 * Returns true if the uri authority is one of the authorities specified in the provider. 9115 */ 9116 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9117 String uriAuth = uri.getAuthority(); 9118 String cpiAuth = cpi.authority; 9119 if (cpiAuth.indexOf(';') == -1) { 9120 return cpiAuth.equals(uriAuth); 9121 } 9122 String[] cpiAuths = cpiAuth.split(";"); 9123 int length = cpiAuths.length; 9124 for (int i = 0; i < length; i++) { 9125 if (cpiAuths[i].equals(uriAuth)) return true; 9126 } 9127 return false; 9128 } 9129 9130 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9131 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9132 if (r != null) { 9133 for (int i=0; i<r.conProviders.size(); i++) { 9134 ContentProviderConnection conn = r.conProviders.get(i); 9135 if (conn.provider == cpr) { 9136 if (DEBUG_PROVIDER) Slog.v(TAG, 9137 "Adding provider requested by " 9138 + r.processName + " from process " 9139 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9140 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9141 if (stable) { 9142 conn.stableCount++; 9143 conn.numStableIncs++; 9144 } else { 9145 conn.unstableCount++; 9146 conn.numUnstableIncs++; 9147 } 9148 return conn; 9149 } 9150 } 9151 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9152 if (stable) { 9153 conn.stableCount = 1; 9154 conn.numStableIncs = 1; 9155 } else { 9156 conn.unstableCount = 1; 9157 conn.numUnstableIncs = 1; 9158 } 9159 cpr.connections.add(conn); 9160 r.conProviders.add(conn); 9161 return conn; 9162 } 9163 cpr.addExternalProcessHandleLocked(externalProcessToken); 9164 return null; 9165 } 9166 9167 boolean decProviderCountLocked(ContentProviderConnection conn, 9168 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9169 if (conn != null) { 9170 cpr = conn.provider; 9171 if (DEBUG_PROVIDER) Slog.v(TAG, 9172 "Removing provider requested by " 9173 + conn.client.processName + " from process " 9174 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9175 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9176 if (stable) { 9177 conn.stableCount--; 9178 } else { 9179 conn.unstableCount--; 9180 } 9181 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9182 cpr.connections.remove(conn); 9183 conn.client.conProviders.remove(conn); 9184 return true; 9185 } 9186 return false; 9187 } 9188 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9189 return false; 9190 } 9191 9192 private void checkTime(long startTime, String where) { 9193 long now = SystemClock.elapsedRealtime(); 9194 if ((now-startTime) > 1000) { 9195 // If we are taking more than a second, log about it. 9196 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9197 } 9198 } 9199 9200 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9201 String name, IBinder token, boolean stable, int userId) { 9202 ContentProviderRecord cpr; 9203 ContentProviderConnection conn = null; 9204 ProviderInfo cpi = null; 9205 9206 synchronized(this) { 9207 long startTime = SystemClock.elapsedRealtime(); 9208 9209 ProcessRecord r = null; 9210 if (caller != null) { 9211 r = getRecordForAppLocked(caller); 9212 if (r == null) { 9213 throw new SecurityException( 9214 "Unable to find app for caller " + caller 9215 + " (pid=" + Binder.getCallingPid() 9216 + ") when getting content provider " + name); 9217 } 9218 } 9219 9220 boolean checkCrossUser = true; 9221 9222 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9223 9224 // First check if this content provider has been published... 9225 cpr = mProviderMap.getProviderByName(name, userId); 9226 // If that didn't work, check if it exists for user 0 and then 9227 // verify that it's a singleton provider before using it. 9228 if (cpr == null && userId != UserHandle.USER_OWNER) { 9229 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9230 if (cpr != null) { 9231 cpi = cpr.info; 9232 if (isSingleton(cpi.processName, cpi.applicationInfo, 9233 cpi.name, cpi.flags) 9234 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9235 userId = UserHandle.USER_OWNER; 9236 checkCrossUser = false; 9237 } else { 9238 cpr = null; 9239 cpi = null; 9240 } 9241 } 9242 } 9243 9244 boolean providerRunning = cpr != null; 9245 if (providerRunning) { 9246 cpi = cpr.info; 9247 String msg; 9248 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9249 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9250 != null) { 9251 throw new SecurityException(msg); 9252 } 9253 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9254 9255 if (r != null && cpr.canRunHere(r)) { 9256 // This provider has been published or is in the process 9257 // of being published... but it is also allowed to run 9258 // in the caller's process, so don't make a connection 9259 // and just let the caller instantiate its own instance. 9260 ContentProviderHolder holder = cpr.newHolder(null); 9261 // don't give caller the provider object, it needs 9262 // to make its own. 9263 holder.provider = null; 9264 return holder; 9265 } 9266 9267 final long origId = Binder.clearCallingIdentity(); 9268 9269 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9270 9271 // In this case the provider instance already exists, so we can 9272 // return it right away. 9273 conn = incProviderCountLocked(r, cpr, token, stable); 9274 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9275 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9276 // If this is a perceptible app accessing the provider, 9277 // make sure to count it as being accessed and thus 9278 // back up on the LRU list. This is good because 9279 // content providers are often expensive to start. 9280 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9281 updateLruProcessLocked(cpr.proc, false, null); 9282 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9283 } 9284 } 9285 9286 if (cpr.proc != null) { 9287 if (false) { 9288 if (cpr.name.flattenToShortString().equals( 9289 "com.android.providers.calendar/.CalendarProvider2")) { 9290 Slog.v(TAG, "****************** KILLING " 9291 + cpr.name.flattenToShortString()); 9292 Process.killProcess(cpr.proc.pid); 9293 } 9294 } 9295 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9296 boolean success = updateOomAdjLocked(cpr.proc); 9297 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9298 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9299 // NOTE: there is still a race here where a signal could be 9300 // pending on the process even though we managed to update its 9301 // adj level. Not sure what to do about this, but at least 9302 // the race is now smaller. 9303 if (!success) { 9304 // Uh oh... it looks like the provider's process 9305 // has been killed on us. We need to wait for a new 9306 // process to be started, and make sure its death 9307 // doesn't kill our process. 9308 Slog.i(TAG, 9309 "Existing provider " + cpr.name.flattenToShortString() 9310 + " is crashing; detaching " + r); 9311 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9312 checkTime(startTime, "getContentProviderImpl: before appDied"); 9313 appDiedLocked(cpr.proc); 9314 checkTime(startTime, "getContentProviderImpl: after appDied"); 9315 if (!lastRef) { 9316 // This wasn't the last ref our process had on 9317 // the provider... we have now been killed, bail. 9318 return null; 9319 } 9320 providerRunning = false; 9321 conn = null; 9322 } 9323 } 9324 9325 Binder.restoreCallingIdentity(origId); 9326 } 9327 9328 boolean singleton; 9329 if (!providerRunning) { 9330 try { 9331 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9332 cpi = AppGlobals.getPackageManager(). 9333 resolveContentProvider(name, 9334 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9335 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9336 } catch (RemoteException ex) { 9337 } 9338 if (cpi == null) { 9339 return null; 9340 } 9341 // If the provider is a singleton AND 9342 // (it's a call within the same user || the provider is a 9343 // privileged app) 9344 // Then allow connecting to the singleton provider 9345 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9346 cpi.name, cpi.flags) 9347 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9348 if (singleton) { 9349 userId = UserHandle.USER_OWNER; 9350 } 9351 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9352 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9353 9354 String msg; 9355 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9356 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9357 != null) { 9358 throw new SecurityException(msg); 9359 } 9360 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9361 9362 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9363 && !cpi.processName.equals("system")) { 9364 // If this content provider does not run in the system 9365 // process, and the system is not yet ready to run other 9366 // processes, then fail fast instead of hanging. 9367 throw new IllegalArgumentException( 9368 "Attempt to launch content provider before system ready"); 9369 } 9370 9371 // Make sure that the user who owns this provider is started. If not, 9372 // we don't want to allow it to run. 9373 if (mStartedUsers.get(userId) == null) { 9374 Slog.w(TAG, "Unable to launch app " 9375 + cpi.applicationInfo.packageName + "/" 9376 + cpi.applicationInfo.uid + " for provider " 9377 + name + ": user " + userId + " is stopped"); 9378 return null; 9379 } 9380 9381 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9382 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9383 cpr = mProviderMap.getProviderByClass(comp, userId); 9384 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9385 final boolean firstClass = cpr == null; 9386 if (firstClass) { 9387 final long ident = Binder.clearCallingIdentity(); 9388 try { 9389 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9390 ApplicationInfo ai = 9391 AppGlobals.getPackageManager(). 9392 getApplicationInfo( 9393 cpi.applicationInfo.packageName, 9394 STOCK_PM_FLAGS, userId); 9395 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9396 if (ai == null) { 9397 Slog.w(TAG, "No package info for content provider " 9398 + cpi.name); 9399 return null; 9400 } 9401 ai = getAppInfoForUser(ai, userId); 9402 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9403 } catch (RemoteException ex) { 9404 // pm is in same process, this will never happen. 9405 } finally { 9406 Binder.restoreCallingIdentity(ident); 9407 } 9408 } 9409 9410 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9411 9412 if (r != null && cpr.canRunHere(r)) { 9413 // If this is a multiprocess provider, then just return its 9414 // info and allow the caller to instantiate it. Only do 9415 // this if the provider is the same user as the caller's 9416 // process, or can run as root (so can be in any process). 9417 return cpr.newHolder(null); 9418 } 9419 9420 if (DEBUG_PROVIDER) { 9421 RuntimeException e = new RuntimeException("here"); 9422 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9423 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9424 } 9425 9426 // This is single process, and our app is now connecting to it. 9427 // See if we are already in the process of launching this 9428 // provider. 9429 final int N = mLaunchingProviders.size(); 9430 int i; 9431 for (i=0; i<N; i++) { 9432 if (mLaunchingProviders.get(i) == cpr) { 9433 break; 9434 } 9435 } 9436 9437 // If the provider is not already being launched, then get it 9438 // started. 9439 if (i >= N) { 9440 final long origId = Binder.clearCallingIdentity(); 9441 9442 try { 9443 // Content provider is now in use, its package can't be stopped. 9444 try { 9445 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9446 AppGlobals.getPackageManager().setPackageStoppedState( 9447 cpr.appInfo.packageName, false, userId); 9448 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9449 } catch (RemoteException e) { 9450 } catch (IllegalArgumentException e) { 9451 Slog.w(TAG, "Failed trying to unstop package " 9452 + cpr.appInfo.packageName + ": " + e); 9453 } 9454 9455 // Use existing process if already started 9456 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9457 ProcessRecord proc = getProcessRecordLocked( 9458 cpi.processName, cpr.appInfo.uid, false); 9459 if (proc != null && proc.thread != null) { 9460 if (DEBUG_PROVIDER) { 9461 Slog.d(TAG, "Installing in existing process " + proc); 9462 } 9463 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9464 proc.pubProviders.put(cpi.name, cpr); 9465 try { 9466 proc.thread.scheduleInstallProvider(cpi); 9467 } catch (RemoteException e) { 9468 } 9469 } else { 9470 checkTime(startTime, "getContentProviderImpl: before start process"); 9471 proc = startProcessLocked(cpi.processName, 9472 cpr.appInfo, false, 0, "content provider", 9473 new ComponentName(cpi.applicationInfo.packageName, 9474 cpi.name), false, false, false); 9475 checkTime(startTime, "getContentProviderImpl: after start process"); 9476 if (proc == null) { 9477 Slog.w(TAG, "Unable to launch app " 9478 + cpi.applicationInfo.packageName + "/" 9479 + cpi.applicationInfo.uid + " for provider " 9480 + name + ": process is bad"); 9481 return null; 9482 } 9483 } 9484 cpr.launchingApp = proc; 9485 mLaunchingProviders.add(cpr); 9486 } finally { 9487 Binder.restoreCallingIdentity(origId); 9488 } 9489 } 9490 9491 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9492 9493 // Make sure the provider is published (the same provider class 9494 // may be published under multiple names). 9495 if (firstClass) { 9496 mProviderMap.putProviderByClass(comp, cpr); 9497 } 9498 9499 mProviderMap.putProviderByName(name, cpr); 9500 conn = incProviderCountLocked(r, cpr, token, stable); 9501 if (conn != null) { 9502 conn.waiting = true; 9503 } 9504 } 9505 checkTime(startTime, "getContentProviderImpl: done!"); 9506 } 9507 9508 // Wait for the provider to be published... 9509 synchronized (cpr) { 9510 while (cpr.provider == null) { 9511 if (cpr.launchingApp == null) { 9512 Slog.w(TAG, "Unable to launch app " 9513 + cpi.applicationInfo.packageName + "/" 9514 + cpi.applicationInfo.uid + " for provider " 9515 + name + ": launching app became null"); 9516 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9517 UserHandle.getUserId(cpi.applicationInfo.uid), 9518 cpi.applicationInfo.packageName, 9519 cpi.applicationInfo.uid, name); 9520 return null; 9521 } 9522 try { 9523 if (DEBUG_MU) { 9524 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9525 + cpr.launchingApp); 9526 } 9527 if (conn != null) { 9528 conn.waiting = true; 9529 } 9530 cpr.wait(); 9531 } catch (InterruptedException ex) { 9532 } finally { 9533 if (conn != null) { 9534 conn.waiting = false; 9535 } 9536 } 9537 } 9538 } 9539 return cpr != null ? cpr.newHolder(conn) : null; 9540 } 9541 9542 @Override 9543 public final ContentProviderHolder getContentProvider( 9544 IApplicationThread caller, String name, int userId, boolean stable) { 9545 enforceNotIsolatedCaller("getContentProvider"); 9546 if (caller == null) { 9547 String msg = "null IApplicationThread when getting content provider " 9548 + name; 9549 Slog.w(TAG, msg); 9550 throw new SecurityException(msg); 9551 } 9552 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9553 // with cross-user grant. 9554 return getContentProviderImpl(caller, name, null, stable, userId); 9555 } 9556 9557 public ContentProviderHolder getContentProviderExternal( 9558 String name, int userId, IBinder token) { 9559 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9560 "Do not have permission in call getContentProviderExternal()"); 9561 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9562 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9563 return getContentProviderExternalUnchecked(name, token, userId); 9564 } 9565 9566 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9567 IBinder token, int userId) { 9568 return getContentProviderImpl(null, name, token, true, userId); 9569 } 9570 9571 /** 9572 * Drop a content provider from a ProcessRecord's bookkeeping 9573 */ 9574 public void removeContentProvider(IBinder connection, boolean stable) { 9575 enforceNotIsolatedCaller("removeContentProvider"); 9576 long ident = Binder.clearCallingIdentity(); 9577 try { 9578 synchronized (this) { 9579 ContentProviderConnection conn; 9580 try { 9581 conn = (ContentProviderConnection)connection; 9582 } catch (ClassCastException e) { 9583 String msg ="removeContentProvider: " + connection 9584 + " not a ContentProviderConnection"; 9585 Slog.w(TAG, msg); 9586 throw new IllegalArgumentException(msg); 9587 } 9588 if (conn == null) { 9589 throw new NullPointerException("connection is null"); 9590 } 9591 if (decProviderCountLocked(conn, null, null, stable)) { 9592 updateOomAdjLocked(); 9593 } 9594 } 9595 } finally { 9596 Binder.restoreCallingIdentity(ident); 9597 } 9598 } 9599 9600 public void removeContentProviderExternal(String name, IBinder token) { 9601 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9602 "Do not have permission in call removeContentProviderExternal()"); 9603 int userId = UserHandle.getCallingUserId(); 9604 long ident = Binder.clearCallingIdentity(); 9605 try { 9606 removeContentProviderExternalUnchecked(name, token, userId); 9607 } finally { 9608 Binder.restoreCallingIdentity(ident); 9609 } 9610 } 9611 9612 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9613 synchronized (this) { 9614 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9615 if(cpr == null) { 9616 //remove from mProvidersByClass 9617 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9618 return; 9619 } 9620 9621 //update content provider record entry info 9622 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9623 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9624 if (localCpr.hasExternalProcessHandles()) { 9625 if (localCpr.removeExternalProcessHandleLocked(token)) { 9626 updateOomAdjLocked(); 9627 } else { 9628 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9629 + " with no external reference for token: " 9630 + token + "."); 9631 } 9632 } else { 9633 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9634 + " with no external references."); 9635 } 9636 } 9637 } 9638 9639 public final void publishContentProviders(IApplicationThread caller, 9640 List<ContentProviderHolder> providers) { 9641 if (providers == null) { 9642 return; 9643 } 9644 9645 enforceNotIsolatedCaller("publishContentProviders"); 9646 synchronized (this) { 9647 final ProcessRecord r = getRecordForAppLocked(caller); 9648 if (DEBUG_MU) 9649 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9650 if (r == null) { 9651 throw new SecurityException( 9652 "Unable to find app for caller " + caller 9653 + " (pid=" + Binder.getCallingPid() 9654 + ") when publishing content providers"); 9655 } 9656 9657 final long origId = Binder.clearCallingIdentity(); 9658 9659 final int N = providers.size(); 9660 for (int i=0; i<N; i++) { 9661 ContentProviderHolder src = providers.get(i); 9662 if (src == null || src.info == null || src.provider == null) { 9663 continue; 9664 } 9665 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9666 if (DEBUG_MU) 9667 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9668 if (dst != null) { 9669 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9670 mProviderMap.putProviderByClass(comp, dst); 9671 String names[] = dst.info.authority.split(";"); 9672 for (int j = 0; j < names.length; j++) { 9673 mProviderMap.putProviderByName(names[j], dst); 9674 } 9675 9676 int NL = mLaunchingProviders.size(); 9677 int j; 9678 for (j=0; j<NL; j++) { 9679 if (mLaunchingProviders.get(j) == dst) { 9680 mLaunchingProviders.remove(j); 9681 j--; 9682 NL--; 9683 } 9684 } 9685 synchronized (dst) { 9686 dst.provider = src.provider; 9687 dst.proc = r; 9688 dst.notifyAll(); 9689 } 9690 updateOomAdjLocked(r); 9691 } 9692 } 9693 9694 Binder.restoreCallingIdentity(origId); 9695 } 9696 } 9697 9698 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9699 ContentProviderConnection conn; 9700 try { 9701 conn = (ContentProviderConnection)connection; 9702 } catch (ClassCastException e) { 9703 String msg ="refContentProvider: " + connection 9704 + " not a ContentProviderConnection"; 9705 Slog.w(TAG, msg); 9706 throw new IllegalArgumentException(msg); 9707 } 9708 if (conn == null) { 9709 throw new NullPointerException("connection is null"); 9710 } 9711 9712 synchronized (this) { 9713 if (stable > 0) { 9714 conn.numStableIncs += stable; 9715 } 9716 stable = conn.stableCount + stable; 9717 if (stable < 0) { 9718 throw new IllegalStateException("stableCount < 0: " + stable); 9719 } 9720 9721 if (unstable > 0) { 9722 conn.numUnstableIncs += unstable; 9723 } 9724 unstable = conn.unstableCount + unstable; 9725 if (unstable < 0) { 9726 throw new IllegalStateException("unstableCount < 0: " + unstable); 9727 } 9728 9729 if ((stable+unstable) <= 0) { 9730 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9731 + stable + " unstable=" + unstable); 9732 } 9733 conn.stableCount = stable; 9734 conn.unstableCount = unstable; 9735 return !conn.dead; 9736 } 9737 } 9738 9739 public void unstableProviderDied(IBinder connection) { 9740 ContentProviderConnection conn; 9741 try { 9742 conn = (ContentProviderConnection)connection; 9743 } catch (ClassCastException e) { 9744 String msg ="refContentProvider: " + connection 9745 + " not a ContentProviderConnection"; 9746 Slog.w(TAG, msg); 9747 throw new IllegalArgumentException(msg); 9748 } 9749 if (conn == null) { 9750 throw new NullPointerException("connection is null"); 9751 } 9752 9753 // Safely retrieve the content provider associated with the connection. 9754 IContentProvider provider; 9755 synchronized (this) { 9756 provider = conn.provider.provider; 9757 } 9758 9759 if (provider == null) { 9760 // Um, yeah, we're way ahead of you. 9761 return; 9762 } 9763 9764 // Make sure the caller is being honest with us. 9765 if (provider.asBinder().pingBinder()) { 9766 // Er, no, still looks good to us. 9767 synchronized (this) { 9768 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9769 + " says " + conn + " died, but we don't agree"); 9770 return; 9771 } 9772 } 9773 9774 // Well look at that! It's dead! 9775 synchronized (this) { 9776 if (conn.provider.provider != provider) { 9777 // But something changed... good enough. 9778 return; 9779 } 9780 9781 ProcessRecord proc = conn.provider.proc; 9782 if (proc == null || proc.thread == null) { 9783 // Seems like the process is already cleaned up. 9784 return; 9785 } 9786 9787 // As far as we're concerned, this is just like receiving a 9788 // death notification... just a bit prematurely. 9789 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9790 + ") early provider death"); 9791 final long ident = Binder.clearCallingIdentity(); 9792 try { 9793 appDiedLocked(proc); 9794 } finally { 9795 Binder.restoreCallingIdentity(ident); 9796 } 9797 } 9798 } 9799 9800 @Override 9801 public void appNotRespondingViaProvider(IBinder connection) { 9802 enforceCallingPermission( 9803 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9804 9805 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9806 if (conn == null) { 9807 Slog.w(TAG, "ContentProviderConnection is null"); 9808 return; 9809 } 9810 9811 final ProcessRecord host = conn.provider.proc; 9812 if (host == null) { 9813 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9814 return; 9815 } 9816 9817 final long token = Binder.clearCallingIdentity(); 9818 try { 9819 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9820 } finally { 9821 Binder.restoreCallingIdentity(token); 9822 } 9823 } 9824 9825 public final void installSystemProviders() { 9826 List<ProviderInfo> providers; 9827 synchronized (this) { 9828 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9829 providers = generateApplicationProvidersLocked(app); 9830 if (providers != null) { 9831 for (int i=providers.size()-1; i>=0; i--) { 9832 ProviderInfo pi = (ProviderInfo)providers.get(i); 9833 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9834 Slog.w(TAG, "Not installing system proc provider " + pi.name 9835 + ": not system .apk"); 9836 providers.remove(i); 9837 } 9838 } 9839 } 9840 } 9841 if (providers != null) { 9842 mSystemThread.installSystemProviders(providers); 9843 } 9844 9845 mCoreSettingsObserver = new CoreSettingsObserver(this); 9846 9847 //mUsageStatsService.monitorPackages(); 9848 } 9849 9850 /** 9851 * Allows apps to retrieve the MIME type of a URI. 9852 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9853 * users, then it does not need permission to access the ContentProvider. 9854 * Either, it needs cross-user uri grants. 9855 * 9856 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9857 * 9858 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9859 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9860 */ 9861 public String getProviderMimeType(Uri uri, int userId) { 9862 enforceNotIsolatedCaller("getProviderMimeType"); 9863 final String name = uri.getAuthority(); 9864 int callingUid = Binder.getCallingUid(); 9865 int callingPid = Binder.getCallingPid(); 9866 long ident = 0; 9867 boolean clearedIdentity = false; 9868 userId = unsafeConvertIncomingUser(userId); 9869 if (canClearIdentity(callingPid, callingUid, userId)) { 9870 clearedIdentity = true; 9871 ident = Binder.clearCallingIdentity(); 9872 } 9873 ContentProviderHolder holder = null; 9874 try { 9875 holder = getContentProviderExternalUnchecked(name, null, userId); 9876 if (holder != null) { 9877 return holder.provider.getType(uri); 9878 } 9879 } catch (RemoteException e) { 9880 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9881 return null; 9882 } finally { 9883 // We need to clear the identity to call removeContentProviderExternalUnchecked 9884 if (!clearedIdentity) { 9885 ident = Binder.clearCallingIdentity(); 9886 } 9887 try { 9888 if (holder != null) { 9889 removeContentProviderExternalUnchecked(name, null, userId); 9890 } 9891 } finally { 9892 Binder.restoreCallingIdentity(ident); 9893 } 9894 } 9895 9896 return null; 9897 } 9898 9899 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9900 if (UserHandle.getUserId(callingUid) == userId) { 9901 return true; 9902 } 9903 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9904 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9905 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9906 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9907 return true; 9908 } 9909 return false; 9910 } 9911 9912 // ========================================================= 9913 // GLOBAL MANAGEMENT 9914 // ========================================================= 9915 9916 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9917 boolean isolated, int isolatedUid) { 9918 String proc = customProcess != null ? customProcess : info.processName; 9919 BatteryStatsImpl.Uid.Proc ps = null; 9920 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9921 int uid = info.uid; 9922 if (isolated) { 9923 if (isolatedUid == 0) { 9924 int userId = UserHandle.getUserId(uid); 9925 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9926 while (true) { 9927 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9928 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9929 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9930 } 9931 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9932 mNextIsolatedProcessUid++; 9933 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9934 // No process for this uid, use it. 9935 break; 9936 } 9937 stepsLeft--; 9938 if (stepsLeft <= 0) { 9939 return null; 9940 } 9941 } 9942 } else { 9943 // Special case for startIsolatedProcess (internal only), where 9944 // the uid of the isolated process is specified by the caller. 9945 uid = isolatedUid; 9946 } 9947 } 9948 return new ProcessRecord(stats, info, proc, uid); 9949 } 9950 9951 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9952 String abiOverride) { 9953 ProcessRecord app; 9954 if (!isolated) { 9955 app = getProcessRecordLocked(info.processName, info.uid, true); 9956 } else { 9957 app = null; 9958 } 9959 9960 if (app == null) { 9961 app = newProcessRecordLocked(info, null, isolated, 0); 9962 mProcessNames.put(info.processName, app.uid, app); 9963 if (isolated) { 9964 mIsolatedProcesses.put(app.uid, app); 9965 } 9966 updateLruProcessLocked(app, false, null); 9967 updateOomAdjLocked(); 9968 } 9969 9970 // This package really, really can not be stopped. 9971 try { 9972 AppGlobals.getPackageManager().setPackageStoppedState( 9973 info.packageName, false, UserHandle.getUserId(app.uid)); 9974 } catch (RemoteException e) { 9975 } catch (IllegalArgumentException e) { 9976 Slog.w(TAG, "Failed trying to unstop package " 9977 + info.packageName + ": " + e); 9978 } 9979 9980 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9981 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9982 app.persistent = true; 9983 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9984 } 9985 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9986 mPersistentStartingProcesses.add(app); 9987 startProcessLocked(app, "added application", app.processName, abiOverride, 9988 null /* entryPoint */, null /* entryPointArgs */); 9989 } 9990 9991 return app; 9992 } 9993 9994 public void unhandledBack() { 9995 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9996 "unhandledBack()"); 9997 9998 synchronized(this) { 9999 final long origId = Binder.clearCallingIdentity(); 10000 try { 10001 getFocusedStack().unhandledBackLocked(); 10002 } finally { 10003 Binder.restoreCallingIdentity(origId); 10004 } 10005 } 10006 } 10007 10008 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10009 enforceNotIsolatedCaller("openContentUri"); 10010 final int userId = UserHandle.getCallingUserId(); 10011 String name = uri.getAuthority(); 10012 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10013 ParcelFileDescriptor pfd = null; 10014 if (cph != null) { 10015 // We record the binder invoker's uid in thread-local storage before 10016 // going to the content provider to open the file. Later, in the code 10017 // that handles all permissions checks, we look for this uid and use 10018 // that rather than the Activity Manager's own uid. The effect is that 10019 // we do the check against the caller's permissions even though it looks 10020 // to the content provider like the Activity Manager itself is making 10021 // the request. 10022 sCallerIdentity.set(new Identity( 10023 Binder.getCallingPid(), Binder.getCallingUid())); 10024 try { 10025 pfd = cph.provider.openFile(null, uri, "r", null); 10026 } catch (FileNotFoundException e) { 10027 // do nothing; pfd will be returned null 10028 } finally { 10029 // Ensure that whatever happens, we clean up the identity state 10030 sCallerIdentity.remove(); 10031 } 10032 10033 // We've got the fd now, so we're done with the provider. 10034 removeContentProviderExternalUnchecked(name, null, userId); 10035 } else { 10036 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10037 } 10038 return pfd; 10039 } 10040 10041 // Actually is sleeping or shutting down or whatever else in the future 10042 // is an inactive state. 10043 public boolean isSleepingOrShuttingDown() { 10044 return isSleeping() || mShuttingDown; 10045 } 10046 10047 public boolean isSleeping() { 10048 return mSleeping; 10049 } 10050 10051 void goingToSleep() { 10052 synchronized(this) { 10053 mWentToSleep = true; 10054 goToSleepIfNeededLocked(); 10055 } 10056 } 10057 10058 void finishRunningVoiceLocked() { 10059 if (mRunningVoice) { 10060 mRunningVoice = false; 10061 goToSleepIfNeededLocked(); 10062 } 10063 } 10064 10065 void goToSleepIfNeededLocked() { 10066 if (mWentToSleep && !mRunningVoice) { 10067 if (!mSleeping) { 10068 mSleeping = true; 10069 mStackSupervisor.goingToSleepLocked(); 10070 10071 // Initialize the wake times of all processes. 10072 checkExcessivePowerUsageLocked(false); 10073 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10074 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10075 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10076 } 10077 } 10078 } 10079 10080 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10081 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10082 // Never persist the home stack. 10083 return; 10084 } 10085 mTaskPersister.wakeup(task, flush); 10086 } 10087 10088 @Override 10089 public boolean shutdown(int timeout) { 10090 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10091 != PackageManager.PERMISSION_GRANTED) { 10092 throw new SecurityException("Requires permission " 10093 + android.Manifest.permission.SHUTDOWN); 10094 } 10095 10096 boolean timedout = false; 10097 10098 synchronized(this) { 10099 mShuttingDown = true; 10100 updateEventDispatchingLocked(); 10101 timedout = mStackSupervisor.shutdownLocked(timeout); 10102 } 10103 10104 mAppOpsService.shutdown(); 10105 if (mUsageStatsService != null) { 10106 mUsageStatsService.prepareShutdown(); 10107 } 10108 mBatteryStatsService.shutdown(); 10109 synchronized (this) { 10110 mProcessStats.shutdownLocked(); 10111 } 10112 notifyTaskPersisterLocked(null, true); 10113 10114 return timedout; 10115 } 10116 10117 public final void activitySlept(IBinder token) { 10118 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10119 10120 final long origId = Binder.clearCallingIdentity(); 10121 10122 synchronized (this) { 10123 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10124 if (r != null) { 10125 mStackSupervisor.activitySleptLocked(r); 10126 } 10127 } 10128 10129 Binder.restoreCallingIdentity(origId); 10130 } 10131 10132 void logLockScreen(String msg) { 10133 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10134 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10135 mWentToSleep + " mSleeping=" + mSleeping); 10136 } 10137 10138 private void comeOutOfSleepIfNeededLocked() { 10139 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10140 if (mSleeping) { 10141 mSleeping = false; 10142 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10143 } 10144 } 10145 } 10146 10147 void wakingUp() { 10148 synchronized(this) { 10149 mWentToSleep = false; 10150 comeOutOfSleepIfNeededLocked(); 10151 } 10152 } 10153 10154 void startRunningVoiceLocked() { 10155 if (!mRunningVoice) { 10156 mRunningVoice = true; 10157 comeOutOfSleepIfNeededLocked(); 10158 } 10159 } 10160 10161 private void updateEventDispatchingLocked() { 10162 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10163 } 10164 10165 public void setLockScreenShown(boolean shown) { 10166 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10167 != PackageManager.PERMISSION_GRANTED) { 10168 throw new SecurityException("Requires permission " 10169 + android.Manifest.permission.DEVICE_POWER); 10170 } 10171 10172 synchronized(this) { 10173 long ident = Binder.clearCallingIdentity(); 10174 try { 10175 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10176 mLockScreenShown = shown; 10177 comeOutOfSleepIfNeededLocked(); 10178 } finally { 10179 Binder.restoreCallingIdentity(ident); 10180 } 10181 } 10182 } 10183 10184 @Override 10185 public void stopAppSwitches() { 10186 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10187 != PackageManager.PERMISSION_GRANTED) { 10188 throw new SecurityException("Requires permission " 10189 + android.Manifest.permission.STOP_APP_SWITCHES); 10190 } 10191 10192 synchronized(this) { 10193 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10194 + APP_SWITCH_DELAY_TIME; 10195 mDidAppSwitch = false; 10196 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10197 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10198 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10199 } 10200 } 10201 10202 public void resumeAppSwitches() { 10203 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10204 != PackageManager.PERMISSION_GRANTED) { 10205 throw new SecurityException("Requires permission " 10206 + android.Manifest.permission.STOP_APP_SWITCHES); 10207 } 10208 10209 synchronized(this) { 10210 // Note that we don't execute any pending app switches... we will 10211 // let those wait until either the timeout, or the next start 10212 // activity request. 10213 mAppSwitchesAllowedTime = 0; 10214 } 10215 } 10216 10217 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10218 int callingPid, int callingUid, String name) { 10219 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10220 return true; 10221 } 10222 10223 int perm = checkComponentPermission( 10224 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10225 sourceUid, -1, true); 10226 if (perm == PackageManager.PERMISSION_GRANTED) { 10227 return true; 10228 } 10229 10230 // If the actual IPC caller is different from the logical source, then 10231 // also see if they are allowed to control app switches. 10232 if (callingUid != -1 && callingUid != sourceUid) { 10233 perm = checkComponentPermission( 10234 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10235 callingUid, -1, true); 10236 if (perm == PackageManager.PERMISSION_GRANTED) { 10237 return true; 10238 } 10239 } 10240 10241 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10242 return false; 10243 } 10244 10245 public void setDebugApp(String packageName, boolean waitForDebugger, 10246 boolean persistent) { 10247 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10248 "setDebugApp()"); 10249 10250 long ident = Binder.clearCallingIdentity(); 10251 try { 10252 // Note that this is not really thread safe if there are multiple 10253 // callers into it at the same time, but that's not a situation we 10254 // care about. 10255 if (persistent) { 10256 final ContentResolver resolver = mContext.getContentResolver(); 10257 Settings.Global.putString( 10258 resolver, Settings.Global.DEBUG_APP, 10259 packageName); 10260 Settings.Global.putInt( 10261 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10262 waitForDebugger ? 1 : 0); 10263 } 10264 10265 synchronized (this) { 10266 if (!persistent) { 10267 mOrigDebugApp = mDebugApp; 10268 mOrigWaitForDebugger = mWaitForDebugger; 10269 } 10270 mDebugApp = packageName; 10271 mWaitForDebugger = waitForDebugger; 10272 mDebugTransient = !persistent; 10273 if (packageName != null) { 10274 forceStopPackageLocked(packageName, -1, false, false, true, true, 10275 false, UserHandle.USER_ALL, "set debug app"); 10276 } 10277 } 10278 } finally { 10279 Binder.restoreCallingIdentity(ident); 10280 } 10281 } 10282 10283 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10284 synchronized (this) { 10285 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10286 if (!isDebuggable) { 10287 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10288 throw new SecurityException("Process not debuggable: " + app.packageName); 10289 } 10290 } 10291 10292 mOpenGlTraceApp = processName; 10293 } 10294 } 10295 10296 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10297 synchronized (this) { 10298 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10299 if (!isDebuggable) { 10300 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10301 throw new SecurityException("Process not debuggable: " + app.packageName); 10302 } 10303 } 10304 mProfileApp = processName; 10305 mProfileFile = profilerInfo.profileFile; 10306 if (mProfileFd != null) { 10307 try { 10308 mProfileFd.close(); 10309 } catch (IOException e) { 10310 } 10311 mProfileFd = null; 10312 } 10313 mProfileFd = profilerInfo.profileFd; 10314 mSamplingInterval = profilerInfo.samplingInterval; 10315 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10316 mProfileType = 0; 10317 } 10318 } 10319 10320 @Override 10321 public void setAlwaysFinish(boolean enabled) { 10322 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10323 "setAlwaysFinish()"); 10324 10325 Settings.Global.putInt( 10326 mContext.getContentResolver(), 10327 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10328 10329 synchronized (this) { 10330 mAlwaysFinishActivities = enabled; 10331 } 10332 } 10333 10334 @Override 10335 public void setActivityController(IActivityController controller) { 10336 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10337 "setActivityController()"); 10338 synchronized (this) { 10339 mController = controller; 10340 Watchdog.getInstance().setActivityController(controller); 10341 } 10342 } 10343 10344 @Override 10345 public void setUserIsMonkey(boolean userIsMonkey) { 10346 synchronized (this) { 10347 synchronized (mPidsSelfLocked) { 10348 final int callingPid = Binder.getCallingPid(); 10349 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10350 if (precessRecord == null) { 10351 throw new SecurityException("Unknown process: " + callingPid); 10352 } 10353 if (precessRecord.instrumentationUiAutomationConnection == null) { 10354 throw new SecurityException("Only an instrumentation process " 10355 + "with a UiAutomation can call setUserIsMonkey"); 10356 } 10357 } 10358 mUserIsMonkey = userIsMonkey; 10359 } 10360 } 10361 10362 @Override 10363 public boolean isUserAMonkey() { 10364 synchronized (this) { 10365 // If there is a controller also implies the user is a monkey. 10366 return (mUserIsMonkey || mController != null); 10367 } 10368 } 10369 10370 public void requestBugReport() { 10371 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10372 SystemProperties.set("ctl.start", "bugreport"); 10373 } 10374 10375 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10376 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10377 } 10378 10379 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10380 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10381 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10382 } 10383 return KEY_DISPATCHING_TIMEOUT; 10384 } 10385 10386 @Override 10387 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10388 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10389 != PackageManager.PERMISSION_GRANTED) { 10390 throw new SecurityException("Requires permission " 10391 + android.Manifest.permission.FILTER_EVENTS); 10392 } 10393 ProcessRecord proc; 10394 long timeout; 10395 synchronized (this) { 10396 synchronized (mPidsSelfLocked) { 10397 proc = mPidsSelfLocked.get(pid); 10398 } 10399 timeout = getInputDispatchingTimeoutLocked(proc); 10400 } 10401 10402 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10403 return -1; 10404 } 10405 10406 return timeout; 10407 } 10408 10409 /** 10410 * Handle input dispatching timeouts. 10411 * Returns whether input dispatching should be aborted or not. 10412 */ 10413 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10414 final ActivityRecord activity, final ActivityRecord parent, 10415 final boolean aboveSystem, String reason) { 10416 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10417 != PackageManager.PERMISSION_GRANTED) { 10418 throw new SecurityException("Requires permission " 10419 + android.Manifest.permission.FILTER_EVENTS); 10420 } 10421 10422 final String annotation; 10423 if (reason == null) { 10424 annotation = "Input dispatching timed out"; 10425 } else { 10426 annotation = "Input dispatching timed out (" + reason + ")"; 10427 } 10428 10429 if (proc != null) { 10430 synchronized (this) { 10431 if (proc.debugging) { 10432 return false; 10433 } 10434 10435 if (mDidDexOpt) { 10436 // Give more time since we were dexopting. 10437 mDidDexOpt = false; 10438 return false; 10439 } 10440 10441 if (proc.instrumentationClass != null) { 10442 Bundle info = new Bundle(); 10443 info.putString("shortMsg", "keyDispatchingTimedOut"); 10444 info.putString("longMsg", annotation); 10445 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10446 return true; 10447 } 10448 } 10449 mHandler.post(new Runnable() { 10450 @Override 10451 public void run() { 10452 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10453 } 10454 }); 10455 } 10456 10457 return true; 10458 } 10459 10460 public Bundle getAssistContextExtras(int requestType) { 10461 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10462 UserHandle.getCallingUserId()); 10463 if (pae == null) { 10464 return null; 10465 } 10466 synchronized (pae) { 10467 while (!pae.haveResult) { 10468 try { 10469 pae.wait(); 10470 } catch (InterruptedException e) { 10471 } 10472 } 10473 if (pae.result != null) { 10474 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10475 } 10476 } 10477 synchronized (this) { 10478 mPendingAssistExtras.remove(pae); 10479 mHandler.removeCallbacks(pae); 10480 } 10481 return pae.extras; 10482 } 10483 10484 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10485 int userHandle) { 10486 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10487 "getAssistContextExtras()"); 10488 PendingAssistExtras pae; 10489 Bundle extras = new Bundle(); 10490 synchronized (this) { 10491 ActivityRecord activity = getFocusedStack().mResumedActivity; 10492 if (activity == null) { 10493 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10494 return null; 10495 } 10496 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10497 if (activity.app == null || activity.app.thread == null) { 10498 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10499 return null; 10500 } 10501 if (activity.app.pid == Binder.getCallingPid()) { 10502 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10503 return null; 10504 } 10505 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10506 try { 10507 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10508 requestType); 10509 mPendingAssistExtras.add(pae); 10510 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10511 } catch (RemoteException e) { 10512 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10513 return null; 10514 } 10515 return pae; 10516 } 10517 } 10518 10519 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10520 PendingAssistExtras pae = (PendingAssistExtras)token; 10521 synchronized (pae) { 10522 pae.result = extras; 10523 pae.haveResult = true; 10524 pae.notifyAll(); 10525 if (pae.intent == null) { 10526 // Caller is just waiting for the result. 10527 return; 10528 } 10529 } 10530 10531 // We are now ready to launch the assist activity. 10532 synchronized (this) { 10533 boolean exists = mPendingAssistExtras.remove(pae); 10534 mHandler.removeCallbacks(pae); 10535 if (!exists) { 10536 // Timed out. 10537 return; 10538 } 10539 } 10540 pae.intent.replaceExtras(extras); 10541 if (pae.hint != null) { 10542 pae.intent.putExtra(pae.hint, true); 10543 } 10544 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10545 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10546 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10547 closeSystemDialogs("assist"); 10548 try { 10549 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10550 } catch (ActivityNotFoundException e) { 10551 Slog.w(TAG, "No activity to handle assist action.", e); 10552 } 10553 } 10554 10555 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10556 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10557 } 10558 10559 public void registerProcessObserver(IProcessObserver observer) { 10560 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10561 "registerProcessObserver()"); 10562 synchronized (this) { 10563 mProcessObservers.register(observer); 10564 } 10565 } 10566 10567 @Override 10568 public void unregisterProcessObserver(IProcessObserver observer) { 10569 synchronized (this) { 10570 mProcessObservers.unregister(observer); 10571 } 10572 } 10573 10574 @Override 10575 public boolean convertFromTranslucent(IBinder token) { 10576 final long origId = Binder.clearCallingIdentity(); 10577 try { 10578 synchronized (this) { 10579 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10580 if (r == null) { 10581 return false; 10582 } 10583 final boolean translucentChanged = r.changeWindowTranslucency(true); 10584 if (translucentChanged) { 10585 r.task.stack.releaseBackgroundResources(); 10586 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10587 } 10588 mWindowManager.setAppFullscreen(token, true); 10589 return translucentChanged; 10590 } 10591 } finally { 10592 Binder.restoreCallingIdentity(origId); 10593 } 10594 } 10595 10596 @Override 10597 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10598 final long origId = Binder.clearCallingIdentity(); 10599 try { 10600 synchronized (this) { 10601 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10602 if (r == null) { 10603 return false; 10604 } 10605 int index = r.task.mActivities.lastIndexOf(r); 10606 if (index > 0) { 10607 ActivityRecord under = r.task.mActivities.get(index - 1); 10608 under.returningOptions = options; 10609 } 10610 final boolean translucentChanged = r.changeWindowTranslucency(false); 10611 if (translucentChanged) { 10612 r.task.stack.convertToTranslucent(r); 10613 } 10614 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10615 mWindowManager.setAppFullscreen(token, false); 10616 return translucentChanged; 10617 } 10618 } finally { 10619 Binder.restoreCallingIdentity(origId); 10620 } 10621 } 10622 10623 @Override 10624 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10625 final long origId = Binder.clearCallingIdentity(); 10626 try { 10627 synchronized (this) { 10628 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10629 if (r != null) { 10630 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10631 } 10632 } 10633 return false; 10634 } finally { 10635 Binder.restoreCallingIdentity(origId); 10636 } 10637 } 10638 10639 @Override 10640 public boolean isBackgroundVisibleBehind(IBinder token) { 10641 final long origId = Binder.clearCallingIdentity(); 10642 try { 10643 synchronized (this) { 10644 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10645 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10646 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10647 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10648 return visible; 10649 } 10650 } finally { 10651 Binder.restoreCallingIdentity(origId); 10652 } 10653 } 10654 10655 @Override 10656 public ActivityOptions getActivityOptions(IBinder token) { 10657 final long origId = Binder.clearCallingIdentity(); 10658 try { 10659 synchronized (this) { 10660 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10661 if (r != null) { 10662 final ActivityOptions activityOptions = r.pendingOptions; 10663 r.pendingOptions = null; 10664 return activityOptions; 10665 } 10666 return null; 10667 } 10668 } finally { 10669 Binder.restoreCallingIdentity(origId); 10670 } 10671 } 10672 10673 @Override 10674 public void setImmersive(IBinder token, boolean immersive) { 10675 synchronized(this) { 10676 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10677 if (r == null) { 10678 throw new IllegalArgumentException(); 10679 } 10680 r.immersive = immersive; 10681 10682 // update associated state if we're frontmost 10683 if (r == mFocusedActivity) { 10684 if (DEBUG_IMMERSIVE) { 10685 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10686 } 10687 applyUpdateLockStateLocked(r); 10688 } 10689 } 10690 } 10691 10692 @Override 10693 public boolean isImmersive(IBinder token) { 10694 synchronized (this) { 10695 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10696 if (r == null) { 10697 throw new IllegalArgumentException(); 10698 } 10699 return r.immersive; 10700 } 10701 } 10702 10703 public boolean isTopActivityImmersive() { 10704 enforceNotIsolatedCaller("startActivity"); 10705 synchronized (this) { 10706 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10707 return (r != null) ? r.immersive : false; 10708 } 10709 } 10710 10711 @Override 10712 public boolean isTopOfTask(IBinder token) { 10713 synchronized (this) { 10714 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10715 if (r == null) { 10716 throw new IllegalArgumentException(); 10717 } 10718 return r.task.getTopActivity() == r; 10719 } 10720 } 10721 10722 public final void enterSafeMode() { 10723 synchronized(this) { 10724 // It only makes sense to do this before the system is ready 10725 // and started launching other packages. 10726 if (!mSystemReady) { 10727 try { 10728 AppGlobals.getPackageManager().enterSafeMode(); 10729 } catch (RemoteException e) { 10730 } 10731 } 10732 10733 mSafeMode = true; 10734 } 10735 } 10736 10737 public final void showSafeModeOverlay() { 10738 View v = LayoutInflater.from(mContext).inflate( 10739 com.android.internal.R.layout.safe_mode, null); 10740 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10741 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10742 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10743 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10744 lp.gravity = Gravity.BOTTOM | Gravity.START; 10745 lp.format = v.getBackground().getOpacity(); 10746 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10747 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10748 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10749 ((WindowManager)mContext.getSystemService( 10750 Context.WINDOW_SERVICE)).addView(v, lp); 10751 } 10752 10753 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10754 if (!(sender instanceof PendingIntentRecord)) { 10755 return; 10756 } 10757 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10758 synchronized (stats) { 10759 if (mBatteryStatsService.isOnBattery()) { 10760 mBatteryStatsService.enforceCallingPermission(); 10761 PendingIntentRecord rec = (PendingIntentRecord)sender; 10762 int MY_UID = Binder.getCallingUid(); 10763 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10764 BatteryStatsImpl.Uid.Pkg pkg = 10765 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10766 sourcePkg != null ? sourcePkg : rec.key.packageName); 10767 pkg.incWakeupsLocked(); 10768 } 10769 } 10770 } 10771 10772 public boolean killPids(int[] pids, String pReason, boolean secure) { 10773 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10774 throw new SecurityException("killPids only available to the system"); 10775 } 10776 String reason = (pReason == null) ? "Unknown" : pReason; 10777 // XXX Note: don't acquire main activity lock here, because the window 10778 // manager calls in with its locks held. 10779 10780 boolean killed = false; 10781 synchronized (mPidsSelfLocked) { 10782 int[] types = new int[pids.length]; 10783 int worstType = 0; 10784 for (int i=0; i<pids.length; i++) { 10785 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10786 if (proc != null) { 10787 int type = proc.setAdj; 10788 types[i] = type; 10789 if (type > worstType) { 10790 worstType = type; 10791 } 10792 } 10793 } 10794 10795 // If the worst oom_adj is somewhere in the cached proc LRU range, 10796 // then constrain it so we will kill all cached procs. 10797 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10798 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10799 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10800 } 10801 10802 // If this is not a secure call, don't let it kill processes that 10803 // are important. 10804 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10805 worstType = ProcessList.SERVICE_ADJ; 10806 } 10807 10808 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10809 for (int i=0; i<pids.length; i++) { 10810 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10811 if (proc == null) { 10812 continue; 10813 } 10814 int adj = proc.setAdj; 10815 if (adj >= worstType && !proc.killedByAm) { 10816 proc.kill(reason, true); 10817 killed = true; 10818 } 10819 } 10820 } 10821 return killed; 10822 } 10823 10824 @Override 10825 public void killUid(int uid, String reason) { 10826 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10827 throw new SecurityException("killUid only available to the system"); 10828 } 10829 synchronized (this) { 10830 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10831 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10832 reason != null ? reason : "kill uid"); 10833 } 10834 } 10835 10836 @Override 10837 public boolean killProcessesBelowForeground(String reason) { 10838 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10839 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10840 } 10841 10842 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10843 } 10844 10845 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10846 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10847 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10848 } 10849 10850 boolean killed = false; 10851 synchronized (mPidsSelfLocked) { 10852 final int size = mPidsSelfLocked.size(); 10853 for (int i = 0; i < size; i++) { 10854 final int pid = mPidsSelfLocked.keyAt(i); 10855 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10856 if (proc == null) continue; 10857 10858 final int adj = proc.setAdj; 10859 if (adj > belowAdj && !proc.killedByAm) { 10860 proc.kill(reason, true); 10861 killed = true; 10862 } 10863 } 10864 } 10865 return killed; 10866 } 10867 10868 @Override 10869 public void hang(final IBinder who, boolean allowRestart) { 10870 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10871 != PackageManager.PERMISSION_GRANTED) { 10872 throw new SecurityException("Requires permission " 10873 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10874 } 10875 10876 final IBinder.DeathRecipient death = new DeathRecipient() { 10877 @Override 10878 public void binderDied() { 10879 synchronized (this) { 10880 notifyAll(); 10881 } 10882 } 10883 }; 10884 10885 try { 10886 who.linkToDeath(death, 0); 10887 } catch (RemoteException e) { 10888 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10889 return; 10890 } 10891 10892 synchronized (this) { 10893 Watchdog.getInstance().setAllowRestart(allowRestart); 10894 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10895 synchronized (death) { 10896 while (who.isBinderAlive()) { 10897 try { 10898 death.wait(); 10899 } catch (InterruptedException e) { 10900 } 10901 } 10902 } 10903 Watchdog.getInstance().setAllowRestart(true); 10904 } 10905 } 10906 10907 @Override 10908 public void restart() { 10909 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10910 != PackageManager.PERMISSION_GRANTED) { 10911 throw new SecurityException("Requires permission " 10912 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10913 } 10914 10915 Log.i(TAG, "Sending shutdown broadcast..."); 10916 10917 BroadcastReceiver br = new BroadcastReceiver() { 10918 @Override public void onReceive(Context context, Intent intent) { 10919 // Now the broadcast is done, finish up the low-level shutdown. 10920 Log.i(TAG, "Shutting down activity manager..."); 10921 shutdown(10000); 10922 Log.i(TAG, "Shutdown complete, restarting!"); 10923 Process.killProcess(Process.myPid()); 10924 System.exit(10); 10925 } 10926 }; 10927 10928 // First send the high-level shut down broadcast. 10929 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10930 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10931 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10932 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10933 mContext.sendOrderedBroadcastAsUser(intent, 10934 UserHandle.ALL, null, br, mHandler, 0, null, null); 10935 */ 10936 br.onReceive(mContext, intent); 10937 } 10938 10939 private long getLowRamTimeSinceIdle(long now) { 10940 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10941 } 10942 10943 @Override 10944 public void performIdleMaintenance() { 10945 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10946 != PackageManager.PERMISSION_GRANTED) { 10947 throw new SecurityException("Requires permission " 10948 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10949 } 10950 10951 synchronized (this) { 10952 final long now = SystemClock.uptimeMillis(); 10953 final long timeSinceLastIdle = now - mLastIdleTime; 10954 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10955 mLastIdleTime = now; 10956 mLowRamTimeSinceLastIdle = 0; 10957 if (mLowRamStartTime != 0) { 10958 mLowRamStartTime = now; 10959 } 10960 10961 StringBuilder sb = new StringBuilder(128); 10962 sb.append("Idle maintenance over "); 10963 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10964 sb.append(" low RAM for "); 10965 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10966 Slog.i(TAG, sb.toString()); 10967 10968 // If at least 1/3 of our time since the last idle period has been spent 10969 // with RAM low, then we want to kill processes. 10970 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10971 10972 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10973 ProcessRecord proc = mLruProcesses.get(i); 10974 if (proc.notCachedSinceIdle) { 10975 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10976 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10977 if (doKilling && proc.initialIdlePss != 0 10978 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10979 proc.kill("idle maint (pss " + proc.lastPss 10980 + " from " + proc.initialIdlePss + ")", true); 10981 } 10982 } 10983 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10984 proc.notCachedSinceIdle = true; 10985 proc.initialIdlePss = 0; 10986 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10987 isSleeping(), now); 10988 } 10989 } 10990 10991 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10992 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10993 } 10994 } 10995 10996 private void retrieveSettings() { 10997 final ContentResolver resolver = mContext.getContentResolver(); 10998 String debugApp = Settings.Global.getString( 10999 resolver, Settings.Global.DEBUG_APP); 11000 boolean waitForDebugger = Settings.Global.getInt( 11001 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11002 boolean alwaysFinishActivities = Settings.Global.getInt( 11003 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11004 boolean forceRtl = Settings.Global.getInt( 11005 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11006 // Transfer any global setting for forcing RTL layout, into a System Property 11007 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11008 11009 Configuration configuration = new Configuration(); 11010 Settings.System.getConfiguration(resolver, configuration); 11011 if (forceRtl) { 11012 // This will take care of setting the correct layout direction flags 11013 configuration.setLayoutDirection(configuration.locale); 11014 } 11015 11016 synchronized (this) { 11017 mDebugApp = mOrigDebugApp = debugApp; 11018 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11019 mAlwaysFinishActivities = alwaysFinishActivities; 11020 // This happens before any activities are started, so we can 11021 // change mConfiguration in-place. 11022 updateConfigurationLocked(configuration, null, false, true); 11023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11024 } 11025 } 11026 11027 /** Loads resources after the current configuration has been set. */ 11028 private void loadResourcesOnSystemReady() { 11029 final Resources res = mContext.getResources(); 11030 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11031 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11032 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11033 } 11034 11035 public boolean testIsSystemReady() { 11036 // no need to synchronize(this) just to read & return the value 11037 return mSystemReady; 11038 } 11039 11040 private static File getCalledPreBootReceiversFile() { 11041 File dataDir = Environment.getDataDirectory(); 11042 File systemDir = new File(dataDir, "system"); 11043 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11044 return fname; 11045 } 11046 11047 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11048 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11049 File file = getCalledPreBootReceiversFile(); 11050 FileInputStream fis = null; 11051 try { 11052 fis = new FileInputStream(file); 11053 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11054 int fvers = dis.readInt(); 11055 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11056 String vers = dis.readUTF(); 11057 String codename = dis.readUTF(); 11058 String build = dis.readUTF(); 11059 if (android.os.Build.VERSION.RELEASE.equals(vers) 11060 && android.os.Build.VERSION.CODENAME.equals(codename) 11061 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11062 int num = dis.readInt(); 11063 while (num > 0) { 11064 num--; 11065 String pkg = dis.readUTF(); 11066 String cls = dis.readUTF(); 11067 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11068 } 11069 } 11070 } 11071 } catch (FileNotFoundException e) { 11072 } catch (IOException e) { 11073 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11074 } finally { 11075 if (fis != null) { 11076 try { 11077 fis.close(); 11078 } catch (IOException e) { 11079 } 11080 } 11081 } 11082 return lastDoneReceivers; 11083 } 11084 11085 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11086 File file = getCalledPreBootReceiversFile(); 11087 FileOutputStream fos = null; 11088 DataOutputStream dos = null; 11089 try { 11090 fos = new FileOutputStream(file); 11091 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11092 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11093 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11094 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11095 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11096 dos.writeInt(list.size()); 11097 for (int i=0; i<list.size(); i++) { 11098 dos.writeUTF(list.get(i).getPackageName()); 11099 dos.writeUTF(list.get(i).getClassName()); 11100 } 11101 } catch (IOException e) { 11102 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11103 file.delete(); 11104 } finally { 11105 FileUtils.sync(fos); 11106 if (dos != null) { 11107 try { 11108 dos.close(); 11109 } catch (IOException e) { 11110 // TODO Auto-generated catch block 11111 e.printStackTrace(); 11112 } 11113 } 11114 } 11115 } 11116 11117 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11118 ArrayList<ComponentName> doneReceivers, int userId) { 11119 boolean waitingUpdate = false; 11120 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11121 List<ResolveInfo> ris = null; 11122 try { 11123 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11124 intent, null, 0, userId); 11125 } catch (RemoteException e) { 11126 } 11127 if (ris != null) { 11128 for (int i=ris.size()-1; i>=0; i--) { 11129 if ((ris.get(i).activityInfo.applicationInfo.flags 11130 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11131 ris.remove(i); 11132 } 11133 } 11134 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11135 11136 // For User 0, load the version number. When delivering to a new user, deliver 11137 // to all receivers. 11138 if (userId == UserHandle.USER_OWNER) { 11139 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11140 for (int i=0; i<ris.size(); i++) { 11141 ActivityInfo ai = ris.get(i).activityInfo; 11142 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11143 if (lastDoneReceivers.contains(comp)) { 11144 // We already did the pre boot receiver for this app with the current 11145 // platform version, so don't do it again... 11146 ris.remove(i); 11147 i--; 11148 // ...however, do keep it as one that has been done, so we don't 11149 // forget about it when rewriting the file of last done receivers. 11150 doneReceivers.add(comp); 11151 } 11152 } 11153 } 11154 11155 // If primary user, send broadcast to all available users, else just to userId 11156 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11157 : new int[] { userId }; 11158 for (int i = 0; i < ris.size(); i++) { 11159 ActivityInfo ai = ris.get(i).activityInfo; 11160 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11161 doneReceivers.add(comp); 11162 intent.setComponent(comp); 11163 for (int j=0; j<users.length; j++) { 11164 IIntentReceiver finisher = null; 11165 // On last receiver and user, set up a completion callback 11166 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11167 finisher = new IIntentReceiver.Stub() { 11168 public void performReceive(Intent intent, int resultCode, 11169 String data, Bundle extras, boolean ordered, 11170 boolean sticky, int sendingUser) { 11171 // The raw IIntentReceiver interface is called 11172 // with the AM lock held, so redispatch to 11173 // execute our code without the lock. 11174 mHandler.post(onFinishCallback); 11175 } 11176 }; 11177 } 11178 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11179 + " for user " + users[j]); 11180 broadcastIntentLocked(null, null, intent, null, finisher, 11181 0, null, null, null, AppOpsManager.OP_NONE, 11182 true, false, MY_PID, Process.SYSTEM_UID, 11183 users[j]); 11184 if (finisher != null) { 11185 waitingUpdate = true; 11186 } 11187 } 11188 } 11189 } 11190 11191 return waitingUpdate; 11192 } 11193 11194 public void systemReady(final Runnable goingCallback) { 11195 synchronized(this) { 11196 if (mSystemReady) { 11197 // If we're done calling all the receivers, run the next "boot phase" passed in 11198 // by the SystemServer 11199 if (goingCallback != null) { 11200 goingCallback.run(); 11201 } 11202 return; 11203 } 11204 11205 // Make sure we have the current profile info, since it is needed for 11206 // security checks. 11207 updateCurrentProfileIdsLocked(); 11208 11209 if (mRecentTasks == null) { 11210 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11211 if (!mRecentTasks.isEmpty()) { 11212 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11213 } 11214 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11215 mTaskPersister.startPersisting(); 11216 } 11217 11218 // Check to see if there are any update receivers to run. 11219 if (!mDidUpdate) { 11220 if (mWaitingUpdate) { 11221 return; 11222 } 11223 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11224 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11225 public void run() { 11226 synchronized (ActivityManagerService.this) { 11227 mDidUpdate = true; 11228 } 11229 writeLastDonePreBootReceivers(doneReceivers); 11230 showBootMessage(mContext.getText( 11231 R.string.android_upgrading_complete), 11232 false); 11233 systemReady(goingCallback); 11234 } 11235 }, doneReceivers, UserHandle.USER_OWNER); 11236 11237 if (mWaitingUpdate) { 11238 return; 11239 } 11240 mDidUpdate = true; 11241 } 11242 11243 mAppOpsService.systemReady(); 11244 mSystemReady = true; 11245 } 11246 11247 ArrayList<ProcessRecord> procsToKill = null; 11248 synchronized(mPidsSelfLocked) { 11249 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11250 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11251 if (!isAllowedWhileBooting(proc.info)){ 11252 if (procsToKill == null) { 11253 procsToKill = new ArrayList<ProcessRecord>(); 11254 } 11255 procsToKill.add(proc); 11256 } 11257 } 11258 } 11259 11260 synchronized(this) { 11261 if (procsToKill != null) { 11262 for (int i=procsToKill.size()-1; i>=0; i--) { 11263 ProcessRecord proc = procsToKill.get(i); 11264 Slog.i(TAG, "Removing system update proc: " + proc); 11265 removeProcessLocked(proc, true, false, "system update done"); 11266 } 11267 } 11268 11269 // Now that we have cleaned up any update processes, we 11270 // are ready to start launching real processes and know that 11271 // we won't trample on them any more. 11272 mProcessesReady = true; 11273 } 11274 11275 Slog.i(TAG, "System now ready"); 11276 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11277 SystemClock.uptimeMillis()); 11278 11279 synchronized(this) { 11280 // Make sure we have no pre-ready processes sitting around. 11281 11282 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11283 ResolveInfo ri = mContext.getPackageManager() 11284 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11285 STOCK_PM_FLAGS); 11286 CharSequence errorMsg = null; 11287 if (ri != null) { 11288 ActivityInfo ai = ri.activityInfo; 11289 ApplicationInfo app = ai.applicationInfo; 11290 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11291 mTopAction = Intent.ACTION_FACTORY_TEST; 11292 mTopData = null; 11293 mTopComponent = new ComponentName(app.packageName, 11294 ai.name); 11295 } else { 11296 errorMsg = mContext.getResources().getText( 11297 com.android.internal.R.string.factorytest_not_system); 11298 } 11299 } else { 11300 errorMsg = mContext.getResources().getText( 11301 com.android.internal.R.string.factorytest_no_action); 11302 } 11303 if (errorMsg != null) { 11304 mTopAction = null; 11305 mTopData = null; 11306 mTopComponent = null; 11307 Message msg = Message.obtain(); 11308 msg.what = SHOW_FACTORY_ERROR_MSG; 11309 msg.getData().putCharSequence("msg", errorMsg); 11310 mHandler.sendMessage(msg); 11311 } 11312 } 11313 } 11314 11315 retrieveSettings(); 11316 loadResourcesOnSystemReady(); 11317 11318 synchronized (this) { 11319 readGrantedUriPermissionsLocked(); 11320 } 11321 11322 if (goingCallback != null) goingCallback.run(); 11323 11324 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11325 Integer.toString(mCurrentUserId), mCurrentUserId); 11326 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11327 Integer.toString(mCurrentUserId), mCurrentUserId); 11328 mSystemServiceManager.startUser(mCurrentUserId); 11329 11330 synchronized (this) { 11331 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11332 try { 11333 List apps = AppGlobals.getPackageManager(). 11334 getPersistentApplications(STOCK_PM_FLAGS); 11335 if (apps != null) { 11336 int N = apps.size(); 11337 int i; 11338 for (i=0; i<N; i++) { 11339 ApplicationInfo info 11340 = (ApplicationInfo)apps.get(i); 11341 if (info != null && 11342 !info.packageName.equals("android")) { 11343 addAppLocked(info, false, null /* ABI override */); 11344 } 11345 } 11346 } 11347 } catch (RemoteException ex) { 11348 // pm is in same process, this will never happen. 11349 } 11350 } 11351 11352 // Start up initial activity. 11353 mBooting = true; 11354 startHomeActivityLocked(mCurrentUserId); 11355 11356 try { 11357 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11358 Message msg = Message.obtain(); 11359 msg.what = SHOW_UID_ERROR_MSG; 11360 mHandler.sendMessage(msg); 11361 } 11362 } catch (RemoteException e) { 11363 } 11364 11365 long ident = Binder.clearCallingIdentity(); 11366 try { 11367 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11369 | Intent.FLAG_RECEIVER_FOREGROUND); 11370 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11371 broadcastIntentLocked(null, null, intent, 11372 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11373 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11374 intent = new Intent(Intent.ACTION_USER_STARTING); 11375 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11376 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11377 broadcastIntentLocked(null, null, intent, 11378 null, new IIntentReceiver.Stub() { 11379 @Override 11380 public void performReceive(Intent intent, int resultCode, String data, 11381 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11382 throws RemoteException { 11383 } 11384 }, 0, null, null, 11385 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11386 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11387 } catch (Throwable t) { 11388 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11389 } finally { 11390 Binder.restoreCallingIdentity(ident); 11391 } 11392 mStackSupervisor.resumeTopActivitiesLocked(); 11393 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11394 } 11395 } 11396 11397 private boolean makeAppCrashingLocked(ProcessRecord app, 11398 String shortMsg, String longMsg, String stackTrace) { 11399 app.crashing = true; 11400 app.crashingReport = generateProcessError(app, 11401 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11402 startAppProblemLocked(app); 11403 app.stopFreezingAllLocked(); 11404 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11405 } 11406 11407 private void makeAppNotRespondingLocked(ProcessRecord app, 11408 String activity, String shortMsg, String longMsg) { 11409 app.notResponding = true; 11410 app.notRespondingReport = generateProcessError(app, 11411 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11412 activity, shortMsg, longMsg, null); 11413 startAppProblemLocked(app); 11414 app.stopFreezingAllLocked(); 11415 } 11416 11417 /** 11418 * Generate a process error record, suitable for attachment to a ProcessRecord. 11419 * 11420 * @param app The ProcessRecord in which the error occurred. 11421 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11422 * ActivityManager.AppErrorStateInfo 11423 * @param activity The activity associated with the crash, if known. 11424 * @param shortMsg Short message describing the crash. 11425 * @param longMsg Long message describing the crash. 11426 * @param stackTrace Full crash stack trace, may be null. 11427 * 11428 * @return Returns a fully-formed AppErrorStateInfo record. 11429 */ 11430 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11431 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11432 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11433 11434 report.condition = condition; 11435 report.processName = app.processName; 11436 report.pid = app.pid; 11437 report.uid = app.info.uid; 11438 report.tag = activity; 11439 report.shortMsg = shortMsg; 11440 report.longMsg = longMsg; 11441 report.stackTrace = stackTrace; 11442 11443 return report; 11444 } 11445 11446 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11447 synchronized (this) { 11448 app.crashing = false; 11449 app.crashingReport = null; 11450 app.notResponding = false; 11451 app.notRespondingReport = null; 11452 if (app.anrDialog == fromDialog) { 11453 app.anrDialog = null; 11454 } 11455 if (app.waitDialog == fromDialog) { 11456 app.waitDialog = null; 11457 } 11458 if (app.pid > 0 && app.pid != MY_PID) { 11459 handleAppCrashLocked(app, null, null, null); 11460 app.kill("user request after error", true); 11461 } 11462 } 11463 } 11464 11465 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11466 String stackTrace) { 11467 long now = SystemClock.uptimeMillis(); 11468 11469 Long crashTime; 11470 if (!app.isolated) { 11471 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11472 } else { 11473 crashTime = null; 11474 } 11475 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11476 // This process loses! 11477 Slog.w(TAG, "Process " + app.info.processName 11478 + " has crashed too many times: killing!"); 11479 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11480 app.userId, app.info.processName, app.uid); 11481 mStackSupervisor.handleAppCrashLocked(app); 11482 if (!app.persistent) { 11483 // We don't want to start this process again until the user 11484 // explicitly does so... but for persistent process, we really 11485 // need to keep it running. If a persistent process is actually 11486 // repeatedly crashing, then badness for everyone. 11487 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11488 app.info.processName); 11489 if (!app.isolated) { 11490 // XXX We don't have a way to mark isolated processes 11491 // as bad, since they don't have a peristent identity. 11492 mBadProcesses.put(app.info.processName, app.uid, 11493 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11494 mProcessCrashTimes.remove(app.info.processName, app.uid); 11495 } 11496 app.bad = true; 11497 app.removed = true; 11498 // Don't let services in this process be restarted and potentially 11499 // annoy the user repeatedly. Unless it is persistent, since those 11500 // processes run critical code. 11501 removeProcessLocked(app, false, false, "crash"); 11502 mStackSupervisor.resumeTopActivitiesLocked(); 11503 return false; 11504 } 11505 mStackSupervisor.resumeTopActivitiesLocked(); 11506 } else { 11507 mStackSupervisor.finishTopRunningActivityLocked(app); 11508 } 11509 11510 // Bump up the crash count of any services currently running in the proc. 11511 for (int i=app.services.size()-1; i>=0; i--) { 11512 // Any services running in the application need to be placed 11513 // back in the pending list. 11514 ServiceRecord sr = app.services.valueAt(i); 11515 sr.crashCount++; 11516 } 11517 11518 // If the crashing process is what we consider to be the "home process" and it has been 11519 // replaced by a third-party app, clear the package preferred activities from packages 11520 // with a home activity running in the process to prevent a repeatedly crashing app 11521 // from blocking the user to manually clear the list. 11522 final ArrayList<ActivityRecord> activities = app.activities; 11523 if (app == mHomeProcess && activities.size() > 0 11524 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11525 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11526 final ActivityRecord r = activities.get(activityNdx); 11527 if (r.isHomeActivity()) { 11528 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11529 try { 11530 ActivityThread.getPackageManager() 11531 .clearPackagePreferredActivities(r.packageName); 11532 } catch (RemoteException c) { 11533 // pm is in same process, this will never happen. 11534 } 11535 } 11536 } 11537 } 11538 11539 if (!app.isolated) { 11540 // XXX Can't keep track of crash times for isolated processes, 11541 // because they don't have a perisistent identity. 11542 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11543 } 11544 11545 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11546 return true; 11547 } 11548 11549 void startAppProblemLocked(ProcessRecord app) { 11550 // If this app is not running under the current user, then we 11551 // can't give it a report button because that would require 11552 // launching the report UI under a different user. 11553 app.errorReportReceiver = null; 11554 11555 for (int userId : mCurrentProfileIds) { 11556 if (app.userId == userId) { 11557 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11558 mContext, app.info.packageName, app.info.flags); 11559 } 11560 } 11561 skipCurrentReceiverLocked(app); 11562 } 11563 11564 void skipCurrentReceiverLocked(ProcessRecord app) { 11565 for (BroadcastQueue queue : mBroadcastQueues) { 11566 queue.skipCurrentReceiverLocked(app); 11567 } 11568 } 11569 11570 /** 11571 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11572 * The application process will exit immediately after this call returns. 11573 * @param app object of the crashing app, null for the system server 11574 * @param crashInfo describing the exception 11575 */ 11576 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11577 ProcessRecord r = findAppProcess(app, "Crash"); 11578 final String processName = app == null ? "system_server" 11579 : (r == null ? "unknown" : r.processName); 11580 11581 handleApplicationCrashInner("crash", r, processName, crashInfo); 11582 } 11583 11584 /* Native crash reporting uses this inner version because it needs to be somewhat 11585 * decoupled from the AM-managed cleanup lifecycle 11586 */ 11587 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11588 ApplicationErrorReport.CrashInfo crashInfo) { 11589 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11590 UserHandle.getUserId(Binder.getCallingUid()), processName, 11591 r == null ? -1 : r.info.flags, 11592 crashInfo.exceptionClassName, 11593 crashInfo.exceptionMessage, 11594 crashInfo.throwFileName, 11595 crashInfo.throwLineNumber); 11596 11597 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11598 11599 crashApplication(r, crashInfo); 11600 } 11601 11602 public void handleApplicationStrictModeViolation( 11603 IBinder app, 11604 int violationMask, 11605 StrictMode.ViolationInfo info) { 11606 ProcessRecord r = findAppProcess(app, "StrictMode"); 11607 if (r == null) { 11608 return; 11609 } 11610 11611 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11612 Integer stackFingerprint = info.hashCode(); 11613 boolean logIt = true; 11614 synchronized (mAlreadyLoggedViolatedStacks) { 11615 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11616 logIt = false; 11617 // TODO: sub-sample into EventLog for these, with 11618 // the info.durationMillis? Then we'd get 11619 // the relative pain numbers, without logging all 11620 // the stack traces repeatedly. We'd want to do 11621 // likewise in the client code, which also does 11622 // dup suppression, before the Binder call. 11623 } else { 11624 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11625 mAlreadyLoggedViolatedStacks.clear(); 11626 } 11627 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11628 } 11629 } 11630 if (logIt) { 11631 logStrictModeViolationToDropBox(r, info); 11632 } 11633 } 11634 11635 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11636 AppErrorResult result = new AppErrorResult(); 11637 synchronized (this) { 11638 final long origId = Binder.clearCallingIdentity(); 11639 11640 Message msg = Message.obtain(); 11641 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11642 HashMap<String, Object> data = new HashMap<String, Object>(); 11643 data.put("result", result); 11644 data.put("app", r); 11645 data.put("violationMask", violationMask); 11646 data.put("info", info); 11647 msg.obj = data; 11648 mHandler.sendMessage(msg); 11649 11650 Binder.restoreCallingIdentity(origId); 11651 } 11652 int res = result.get(); 11653 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11654 } 11655 } 11656 11657 // Depending on the policy in effect, there could be a bunch of 11658 // these in quick succession so we try to batch these together to 11659 // minimize disk writes, number of dropbox entries, and maximize 11660 // compression, by having more fewer, larger records. 11661 private void logStrictModeViolationToDropBox( 11662 ProcessRecord process, 11663 StrictMode.ViolationInfo info) { 11664 if (info == null) { 11665 return; 11666 } 11667 final boolean isSystemApp = process == null || 11668 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11669 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11670 final String processName = process == null ? "unknown" : process.processName; 11671 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11672 final DropBoxManager dbox = (DropBoxManager) 11673 mContext.getSystemService(Context.DROPBOX_SERVICE); 11674 11675 // Exit early if the dropbox isn't configured to accept this report type. 11676 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11677 11678 boolean bufferWasEmpty; 11679 boolean needsFlush; 11680 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11681 synchronized (sb) { 11682 bufferWasEmpty = sb.length() == 0; 11683 appendDropBoxProcessHeaders(process, processName, sb); 11684 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11685 sb.append("System-App: ").append(isSystemApp).append("\n"); 11686 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11687 if (info.violationNumThisLoop != 0) { 11688 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11689 } 11690 if (info.numAnimationsRunning != 0) { 11691 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11692 } 11693 if (info.broadcastIntentAction != null) { 11694 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11695 } 11696 if (info.durationMillis != -1) { 11697 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11698 } 11699 if (info.numInstances != -1) { 11700 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11701 } 11702 if (info.tags != null) { 11703 for (String tag : info.tags) { 11704 sb.append("Span-Tag: ").append(tag).append("\n"); 11705 } 11706 } 11707 sb.append("\n"); 11708 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11709 sb.append(info.crashInfo.stackTrace); 11710 } 11711 sb.append("\n"); 11712 11713 // Only buffer up to ~64k. Various logging bits truncate 11714 // things at 128k. 11715 needsFlush = (sb.length() > 64 * 1024); 11716 } 11717 11718 // Flush immediately if the buffer's grown too large, or this 11719 // is a non-system app. Non-system apps are isolated with a 11720 // different tag & policy and not batched. 11721 // 11722 // Batching is useful during internal testing with 11723 // StrictMode settings turned up high. Without batching, 11724 // thousands of separate files could be created on boot. 11725 if (!isSystemApp || needsFlush) { 11726 new Thread("Error dump: " + dropboxTag) { 11727 @Override 11728 public void run() { 11729 String report; 11730 synchronized (sb) { 11731 report = sb.toString(); 11732 sb.delete(0, sb.length()); 11733 sb.trimToSize(); 11734 } 11735 if (report.length() != 0) { 11736 dbox.addText(dropboxTag, report); 11737 } 11738 } 11739 }.start(); 11740 return; 11741 } 11742 11743 // System app batching: 11744 if (!bufferWasEmpty) { 11745 // An existing dropbox-writing thread is outstanding, so 11746 // we don't need to start it up. The existing thread will 11747 // catch the buffer appends we just did. 11748 return; 11749 } 11750 11751 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11752 // (After this point, we shouldn't access AMS internal data structures.) 11753 new Thread("Error dump: " + dropboxTag) { 11754 @Override 11755 public void run() { 11756 // 5 second sleep to let stacks arrive and be batched together 11757 try { 11758 Thread.sleep(5000); // 5 seconds 11759 } catch (InterruptedException e) {} 11760 11761 String errorReport; 11762 synchronized (mStrictModeBuffer) { 11763 errorReport = mStrictModeBuffer.toString(); 11764 if (errorReport.length() == 0) { 11765 return; 11766 } 11767 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11768 mStrictModeBuffer.trimToSize(); 11769 } 11770 dbox.addText(dropboxTag, errorReport); 11771 } 11772 }.start(); 11773 } 11774 11775 /** 11776 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11777 * @param app object of the crashing app, null for the system server 11778 * @param tag reported by the caller 11779 * @param system whether this wtf is coming from the system 11780 * @param crashInfo describing the context of the error 11781 * @return true if the process should exit immediately (WTF is fatal) 11782 */ 11783 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11784 final ApplicationErrorReport.CrashInfo crashInfo) { 11785 final int callingUid = Binder.getCallingUid(); 11786 final int callingPid = Binder.getCallingPid(); 11787 11788 if (system) { 11789 // If this is coming from the system, we could very well have low-level 11790 // system locks held, so we want to do this all asynchronously. And we 11791 // never want this to become fatal, so there is that too. 11792 mHandler.post(new Runnable() { 11793 @Override public void run() { 11794 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11795 } 11796 }); 11797 return false; 11798 } 11799 11800 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11801 crashInfo); 11802 11803 if (r != null && r.pid != Process.myPid() && 11804 Settings.Global.getInt(mContext.getContentResolver(), 11805 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11806 crashApplication(r, crashInfo); 11807 return true; 11808 } else { 11809 return false; 11810 } 11811 } 11812 11813 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11814 final ApplicationErrorReport.CrashInfo crashInfo) { 11815 final ProcessRecord r = findAppProcess(app, "WTF"); 11816 final String processName = app == null ? "system_server" 11817 : (r == null ? "unknown" : r.processName); 11818 11819 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11820 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11821 11822 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11823 11824 return r; 11825 } 11826 11827 /** 11828 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11829 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11830 */ 11831 private ProcessRecord findAppProcess(IBinder app, String reason) { 11832 if (app == null) { 11833 return null; 11834 } 11835 11836 synchronized (this) { 11837 final int NP = mProcessNames.getMap().size(); 11838 for (int ip=0; ip<NP; ip++) { 11839 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11840 final int NA = apps.size(); 11841 for (int ia=0; ia<NA; ia++) { 11842 ProcessRecord p = apps.valueAt(ia); 11843 if (p.thread != null && p.thread.asBinder() == app) { 11844 return p; 11845 } 11846 } 11847 } 11848 11849 Slog.w(TAG, "Can't find mystery application for " + reason 11850 + " from pid=" + Binder.getCallingPid() 11851 + " uid=" + Binder.getCallingUid() + ": " + app); 11852 return null; 11853 } 11854 } 11855 11856 /** 11857 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11858 * to append various headers to the dropbox log text. 11859 */ 11860 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11861 StringBuilder sb) { 11862 // Watchdog thread ends up invoking this function (with 11863 // a null ProcessRecord) to add the stack file to dropbox. 11864 // Do not acquire a lock on this (am) in such cases, as it 11865 // could cause a potential deadlock, if and when watchdog 11866 // is invoked due to unavailability of lock on am and it 11867 // would prevent watchdog from killing system_server. 11868 if (process == null) { 11869 sb.append("Process: ").append(processName).append("\n"); 11870 return; 11871 } 11872 // Note: ProcessRecord 'process' is guarded by the service 11873 // instance. (notably process.pkgList, which could otherwise change 11874 // concurrently during execution of this method) 11875 synchronized (this) { 11876 sb.append("Process: ").append(processName).append("\n"); 11877 int flags = process.info.flags; 11878 IPackageManager pm = AppGlobals.getPackageManager(); 11879 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11880 for (int ip=0; ip<process.pkgList.size(); ip++) { 11881 String pkg = process.pkgList.keyAt(ip); 11882 sb.append("Package: ").append(pkg); 11883 try { 11884 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11885 if (pi != null) { 11886 sb.append(" v").append(pi.versionCode); 11887 if (pi.versionName != null) { 11888 sb.append(" (").append(pi.versionName).append(")"); 11889 } 11890 } 11891 } catch (RemoteException e) { 11892 Slog.e(TAG, "Error getting package info: " + pkg, e); 11893 } 11894 sb.append("\n"); 11895 } 11896 } 11897 } 11898 11899 private static String processClass(ProcessRecord process) { 11900 if (process == null || process.pid == MY_PID) { 11901 return "system_server"; 11902 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11903 return "system_app"; 11904 } else { 11905 return "data_app"; 11906 } 11907 } 11908 11909 /** 11910 * Write a description of an error (crash, WTF, ANR) to the drop box. 11911 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11912 * @param process which caused the error, null means the system server 11913 * @param activity which triggered the error, null if unknown 11914 * @param parent activity related to the error, null if unknown 11915 * @param subject line related to the error, null if absent 11916 * @param report in long form describing the error, null if absent 11917 * @param logFile to include in the report, null if none 11918 * @param crashInfo giving an application stack trace, null if absent 11919 */ 11920 public void addErrorToDropBox(String eventType, 11921 ProcessRecord process, String processName, ActivityRecord activity, 11922 ActivityRecord parent, String subject, 11923 final String report, final File logFile, 11924 final ApplicationErrorReport.CrashInfo crashInfo) { 11925 // NOTE -- this must never acquire the ActivityManagerService lock, 11926 // otherwise the watchdog may be prevented from resetting the system. 11927 11928 final String dropboxTag = processClass(process) + "_" + eventType; 11929 final DropBoxManager dbox = (DropBoxManager) 11930 mContext.getSystemService(Context.DROPBOX_SERVICE); 11931 11932 // Exit early if the dropbox isn't configured to accept this report type. 11933 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11934 11935 final StringBuilder sb = new StringBuilder(1024); 11936 appendDropBoxProcessHeaders(process, processName, sb); 11937 if (activity != null) { 11938 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11939 } 11940 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11941 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11942 } 11943 if (parent != null && parent != activity) { 11944 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11945 } 11946 if (subject != null) { 11947 sb.append("Subject: ").append(subject).append("\n"); 11948 } 11949 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11950 if (Debug.isDebuggerConnected()) { 11951 sb.append("Debugger: Connected\n"); 11952 } 11953 sb.append("\n"); 11954 11955 // Do the rest in a worker thread to avoid blocking the caller on I/O 11956 // (After this point, we shouldn't access AMS internal data structures.) 11957 Thread worker = new Thread("Error dump: " + dropboxTag) { 11958 @Override 11959 public void run() { 11960 if (report != null) { 11961 sb.append(report); 11962 } 11963 if (logFile != null) { 11964 try { 11965 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11966 "\n\n[[TRUNCATED]]")); 11967 } catch (IOException e) { 11968 Slog.e(TAG, "Error reading " + logFile, e); 11969 } 11970 } 11971 if (crashInfo != null && crashInfo.stackTrace != null) { 11972 sb.append(crashInfo.stackTrace); 11973 } 11974 11975 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11976 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11977 if (lines > 0) { 11978 sb.append("\n"); 11979 11980 // Merge several logcat streams, and take the last N lines 11981 InputStreamReader input = null; 11982 try { 11983 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11984 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11985 "-b", "crash", 11986 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11987 11988 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11989 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11990 input = new InputStreamReader(logcat.getInputStream()); 11991 11992 int num; 11993 char[] buf = new char[8192]; 11994 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11995 } catch (IOException e) { 11996 Slog.e(TAG, "Error running logcat", e); 11997 } finally { 11998 if (input != null) try { input.close(); } catch (IOException e) {} 11999 } 12000 } 12001 12002 dbox.addText(dropboxTag, sb.toString()); 12003 } 12004 }; 12005 12006 if (process == null) { 12007 // If process is null, we are being called from some internal code 12008 // and may be about to die -- run this synchronously. 12009 worker.run(); 12010 } else { 12011 worker.start(); 12012 } 12013 } 12014 12015 /** 12016 * Bring up the "unexpected error" dialog box for a crashing app. 12017 * Deal with edge cases (intercepts from instrumented applications, 12018 * ActivityController, error intent receivers, that sort of thing). 12019 * @param r the application crashing 12020 * @param crashInfo describing the failure 12021 */ 12022 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12023 long timeMillis = System.currentTimeMillis(); 12024 String shortMsg = crashInfo.exceptionClassName; 12025 String longMsg = crashInfo.exceptionMessage; 12026 String stackTrace = crashInfo.stackTrace; 12027 if (shortMsg != null && longMsg != null) { 12028 longMsg = shortMsg + ": " + longMsg; 12029 } else if (shortMsg != null) { 12030 longMsg = shortMsg; 12031 } 12032 12033 AppErrorResult result = new AppErrorResult(); 12034 synchronized (this) { 12035 if (mController != null) { 12036 try { 12037 String name = r != null ? r.processName : null; 12038 int pid = r != null ? r.pid : Binder.getCallingPid(); 12039 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12040 if (!mController.appCrashed(name, pid, 12041 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12042 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12043 && "Native crash".equals(crashInfo.exceptionClassName)) { 12044 Slog.w(TAG, "Skip killing native crashed app " + name 12045 + "(" + pid + ") during testing"); 12046 } else { 12047 Slog.w(TAG, "Force-killing crashed app " + name 12048 + " at watcher's request"); 12049 if (r != null) { 12050 r.kill("crash", true); 12051 } else { 12052 // Huh. 12053 Process.killProcess(pid); 12054 Process.killProcessGroup(uid, pid); 12055 } 12056 } 12057 return; 12058 } 12059 } catch (RemoteException e) { 12060 mController = null; 12061 Watchdog.getInstance().setActivityController(null); 12062 } 12063 } 12064 12065 final long origId = Binder.clearCallingIdentity(); 12066 12067 // If this process is running instrumentation, finish it. 12068 if (r != null && r.instrumentationClass != null) { 12069 Slog.w(TAG, "Error in app " + r.processName 12070 + " running instrumentation " + r.instrumentationClass + ":"); 12071 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12072 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12073 Bundle info = new Bundle(); 12074 info.putString("shortMsg", shortMsg); 12075 info.putString("longMsg", longMsg); 12076 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12077 Binder.restoreCallingIdentity(origId); 12078 return; 12079 } 12080 12081 // If we can't identify the process or it's already exceeded its crash quota, 12082 // quit right away without showing a crash dialog. 12083 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12084 Binder.restoreCallingIdentity(origId); 12085 return; 12086 } 12087 12088 Message msg = Message.obtain(); 12089 msg.what = SHOW_ERROR_MSG; 12090 HashMap data = new HashMap(); 12091 data.put("result", result); 12092 data.put("app", r); 12093 msg.obj = data; 12094 mHandler.sendMessage(msg); 12095 12096 Binder.restoreCallingIdentity(origId); 12097 } 12098 12099 int res = result.get(); 12100 12101 Intent appErrorIntent = null; 12102 synchronized (this) { 12103 if (r != null && !r.isolated) { 12104 // XXX Can't keep track of crash time for isolated processes, 12105 // since they don't have a persistent identity. 12106 mProcessCrashTimes.put(r.info.processName, r.uid, 12107 SystemClock.uptimeMillis()); 12108 } 12109 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12110 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12111 } 12112 } 12113 12114 if (appErrorIntent != null) { 12115 try { 12116 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12117 } catch (ActivityNotFoundException e) { 12118 Slog.w(TAG, "bug report receiver dissappeared", e); 12119 } 12120 } 12121 } 12122 12123 Intent createAppErrorIntentLocked(ProcessRecord r, 12124 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12125 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12126 if (report == null) { 12127 return null; 12128 } 12129 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12130 result.setComponent(r.errorReportReceiver); 12131 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12132 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12133 return result; 12134 } 12135 12136 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12137 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12138 if (r.errorReportReceiver == null) { 12139 return null; 12140 } 12141 12142 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12143 return null; 12144 } 12145 12146 ApplicationErrorReport report = new ApplicationErrorReport(); 12147 report.packageName = r.info.packageName; 12148 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12149 report.processName = r.processName; 12150 report.time = timeMillis; 12151 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12152 12153 if (r.crashing || r.forceCrashReport) { 12154 report.type = ApplicationErrorReport.TYPE_CRASH; 12155 report.crashInfo = crashInfo; 12156 } else if (r.notResponding) { 12157 report.type = ApplicationErrorReport.TYPE_ANR; 12158 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12159 12160 report.anrInfo.activity = r.notRespondingReport.tag; 12161 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12162 report.anrInfo.info = r.notRespondingReport.longMsg; 12163 } 12164 12165 return report; 12166 } 12167 12168 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12169 enforceNotIsolatedCaller("getProcessesInErrorState"); 12170 // assume our apps are happy - lazy create the list 12171 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12172 12173 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12174 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12175 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12176 12177 synchronized (this) { 12178 12179 // iterate across all processes 12180 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12181 ProcessRecord app = mLruProcesses.get(i); 12182 if (!allUsers && app.userId != userId) { 12183 continue; 12184 } 12185 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12186 // This one's in trouble, so we'll generate a report for it 12187 // crashes are higher priority (in case there's a crash *and* an anr) 12188 ActivityManager.ProcessErrorStateInfo report = null; 12189 if (app.crashing) { 12190 report = app.crashingReport; 12191 } else if (app.notResponding) { 12192 report = app.notRespondingReport; 12193 } 12194 12195 if (report != null) { 12196 if (errList == null) { 12197 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12198 } 12199 errList.add(report); 12200 } else { 12201 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12202 " crashing = " + app.crashing + 12203 " notResponding = " + app.notResponding); 12204 } 12205 } 12206 } 12207 } 12208 12209 return errList; 12210 } 12211 12212 static int procStateToImportance(int procState, int memAdj, 12213 ActivityManager.RunningAppProcessInfo currApp) { 12214 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12215 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12216 currApp.lru = memAdj; 12217 } else { 12218 currApp.lru = 0; 12219 } 12220 return imp; 12221 } 12222 12223 private void fillInProcMemInfo(ProcessRecord app, 12224 ActivityManager.RunningAppProcessInfo outInfo) { 12225 outInfo.pid = app.pid; 12226 outInfo.uid = app.info.uid; 12227 if (mHeavyWeightProcess == app) { 12228 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12229 } 12230 if (app.persistent) { 12231 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12232 } 12233 if (app.activities.size() > 0) { 12234 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12235 } 12236 outInfo.lastTrimLevel = app.trimMemoryLevel; 12237 int adj = app.curAdj; 12238 int procState = app.curProcState; 12239 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12240 outInfo.importanceReasonCode = app.adjTypeCode; 12241 outInfo.processState = app.curProcState; 12242 } 12243 12244 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12245 enforceNotIsolatedCaller("getRunningAppProcesses"); 12246 // Lazy instantiation of list 12247 List<ActivityManager.RunningAppProcessInfo> runList = null; 12248 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12249 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12250 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12251 synchronized (this) { 12252 // Iterate across all processes 12253 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12254 ProcessRecord app = mLruProcesses.get(i); 12255 if (!allUsers && app.userId != userId) { 12256 continue; 12257 } 12258 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12259 // Generate process state info for running application 12260 ActivityManager.RunningAppProcessInfo currApp = 12261 new ActivityManager.RunningAppProcessInfo(app.processName, 12262 app.pid, app.getPackageList()); 12263 fillInProcMemInfo(app, currApp); 12264 if (app.adjSource instanceof ProcessRecord) { 12265 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12266 currApp.importanceReasonImportance = 12267 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12268 app.adjSourceProcState); 12269 } else if (app.adjSource instanceof ActivityRecord) { 12270 ActivityRecord r = (ActivityRecord)app.adjSource; 12271 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12272 } 12273 if (app.adjTarget instanceof ComponentName) { 12274 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12275 } 12276 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12277 // + " lru=" + currApp.lru); 12278 if (runList == null) { 12279 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12280 } 12281 runList.add(currApp); 12282 } 12283 } 12284 } 12285 return runList; 12286 } 12287 12288 public List<ApplicationInfo> getRunningExternalApplications() { 12289 enforceNotIsolatedCaller("getRunningExternalApplications"); 12290 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12291 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12292 if (runningApps != null && runningApps.size() > 0) { 12293 Set<String> extList = new HashSet<String>(); 12294 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12295 if (app.pkgList != null) { 12296 for (String pkg : app.pkgList) { 12297 extList.add(pkg); 12298 } 12299 } 12300 } 12301 IPackageManager pm = AppGlobals.getPackageManager(); 12302 for (String pkg : extList) { 12303 try { 12304 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12305 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12306 retList.add(info); 12307 } 12308 } catch (RemoteException e) { 12309 } 12310 } 12311 } 12312 return retList; 12313 } 12314 12315 @Override 12316 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12317 enforceNotIsolatedCaller("getMyMemoryState"); 12318 synchronized (this) { 12319 ProcessRecord proc; 12320 synchronized (mPidsSelfLocked) { 12321 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12322 } 12323 fillInProcMemInfo(proc, outInfo); 12324 } 12325 } 12326 12327 @Override 12328 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12329 if (checkCallingPermission(android.Manifest.permission.DUMP) 12330 != PackageManager.PERMISSION_GRANTED) { 12331 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12332 + Binder.getCallingPid() 12333 + ", uid=" + Binder.getCallingUid() 12334 + " without permission " 12335 + android.Manifest.permission.DUMP); 12336 return; 12337 } 12338 12339 boolean dumpAll = false; 12340 boolean dumpClient = false; 12341 String dumpPackage = null; 12342 12343 int opti = 0; 12344 while (opti < args.length) { 12345 String opt = args[opti]; 12346 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12347 break; 12348 } 12349 opti++; 12350 if ("-a".equals(opt)) { 12351 dumpAll = true; 12352 } else if ("-c".equals(opt)) { 12353 dumpClient = true; 12354 } else if ("-h".equals(opt)) { 12355 pw.println("Activity manager dump options:"); 12356 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12357 pw.println(" cmd may be one of:"); 12358 pw.println(" a[ctivities]: activity stack state"); 12359 pw.println(" r[recents]: recent activities state"); 12360 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12361 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12362 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12363 pw.println(" o[om]: out of memory management"); 12364 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12365 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12366 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12367 pw.println(" service [COMP_SPEC]: service client-side state"); 12368 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12369 pw.println(" all: dump all activities"); 12370 pw.println(" top: dump the top activity"); 12371 pw.println(" write: write all pending state to storage"); 12372 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12373 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12374 pw.println(" a partial substring in a component name, a"); 12375 pw.println(" hex object identifier."); 12376 pw.println(" -a: include all available server state."); 12377 pw.println(" -c: include client state."); 12378 return; 12379 } else { 12380 pw.println("Unknown argument: " + opt + "; use -h for help"); 12381 } 12382 } 12383 12384 long origId = Binder.clearCallingIdentity(); 12385 boolean more = false; 12386 // Is the caller requesting to dump a particular piece of data? 12387 if (opti < args.length) { 12388 String cmd = args[opti]; 12389 opti++; 12390 if ("activities".equals(cmd) || "a".equals(cmd)) { 12391 synchronized (this) { 12392 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12393 } 12394 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12395 synchronized (this) { 12396 dumpRecentsLocked(fd, pw, args, opti, true, null); 12397 } 12398 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12399 String[] newArgs; 12400 String name; 12401 if (opti >= args.length) { 12402 name = null; 12403 newArgs = EMPTY_STRING_ARRAY; 12404 } else { 12405 name = args[opti]; 12406 opti++; 12407 newArgs = new String[args.length - opti]; 12408 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12409 args.length - opti); 12410 } 12411 synchronized (this) { 12412 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12413 } 12414 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12415 String[] newArgs; 12416 String name; 12417 if (opti >= args.length) { 12418 name = null; 12419 newArgs = EMPTY_STRING_ARRAY; 12420 } else { 12421 name = args[opti]; 12422 opti++; 12423 newArgs = new String[args.length - opti]; 12424 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12425 args.length - opti); 12426 } 12427 synchronized (this) { 12428 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12429 } 12430 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12431 String[] newArgs; 12432 String name; 12433 if (opti >= args.length) { 12434 name = null; 12435 newArgs = EMPTY_STRING_ARRAY; 12436 } else { 12437 name = args[opti]; 12438 opti++; 12439 newArgs = new String[args.length - opti]; 12440 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12441 args.length - opti); 12442 } 12443 synchronized (this) { 12444 dumpProcessesLocked(fd, pw, args, opti, true, name); 12445 } 12446 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12447 synchronized (this) { 12448 dumpOomLocked(fd, pw, args, opti, true); 12449 } 12450 } else if ("provider".equals(cmd)) { 12451 String[] newArgs; 12452 String name; 12453 if (opti >= args.length) { 12454 name = null; 12455 newArgs = EMPTY_STRING_ARRAY; 12456 } else { 12457 name = args[opti]; 12458 opti++; 12459 newArgs = new String[args.length - opti]; 12460 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12461 } 12462 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12463 pw.println("No providers match: " + name); 12464 pw.println("Use -h for help."); 12465 } 12466 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12467 synchronized (this) { 12468 dumpProvidersLocked(fd, pw, args, opti, true, null); 12469 } 12470 } else if ("service".equals(cmd)) { 12471 String[] newArgs; 12472 String name; 12473 if (opti >= args.length) { 12474 name = null; 12475 newArgs = EMPTY_STRING_ARRAY; 12476 } else { 12477 name = args[opti]; 12478 opti++; 12479 newArgs = new String[args.length - opti]; 12480 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12481 args.length - opti); 12482 } 12483 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12484 pw.println("No services match: " + name); 12485 pw.println("Use -h for help."); 12486 } 12487 } else if ("package".equals(cmd)) { 12488 String[] newArgs; 12489 if (opti >= args.length) { 12490 pw.println("package: no package name specified"); 12491 pw.println("Use -h for help."); 12492 } else { 12493 dumpPackage = args[opti]; 12494 opti++; 12495 newArgs = new String[args.length - opti]; 12496 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12497 args.length - opti); 12498 args = newArgs; 12499 opti = 0; 12500 more = true; 12501 } 12502 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12503 synchronized (this) { 12504 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12505 } 12506 } else if ("write".equals(cmd)) { 12507 mTaskPersister.flush(); 12508 pw.println("All tasks persisted."); 12509 return; 12510 } else { 12511 // Dumping a single activity? 12512 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12513 pw.println("Bad activity command, or no activities match: " + cmd); 12514 pw.println("Use -h for help."); 12515 } 12516 } 12517 if (!more) { 12518 Binder.restoreCallingIdentity(origId); 12519 return; 12520 } 12521 } 12522 12523 // No piece of data specified, dump everything. 12524 synchronized (this) { 12525 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12526 pw.println(); 12527 if (dumpAll) { 12528 pw.println("-------------------------------------------------------------------------------"); 12529 } 12530 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12531 pw.println(); 12532 if (dumpAll) { 12533 pw.println("-------------------------------------------------------------------------------"); 12534 } 12535 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12536 pw.println(); 12537 if (dumpAll) { 12538 pw.println("-------------------------------------------------------------------------------"); 12539 } 12540 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12541 pw.println(); 12542 if (dumpAll) { 12543 pw.println("-------------------------------------------------------------------------------"); 12544 } 12545 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12546 pw.println(); 12547 if (dumpAll) { 12548 pw.println("-------------------------------------------------------------------------------"); 12549 } 12550 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12551 pw.println(); 12552 if (dumpAll) { 12553 pw.println("-------------------------------------------------------------------------------"); 12554 } 12555 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12556 } 12557 Binder.restoreCallingIdentity(origId); 12558 } 12559 12560 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12561 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12562 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12563 12564 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12565 dumpPackage); 12566 boolean needSep = printedAnything; 12567 12568 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12569 dumpPackage, needSep, " mFocusedActivity: "); 12570 if (printed) { 12571 printedAnything = true; 12572 needSep = false; 12573 } 12574 12575 if (dumpPackage == null) { 12576 if (needSep) { 12577 pw.println(); 12578 } 12579 needSep = true; 12580 printedAnything = true; 12581 mStackSupervisor.dump(pw, " "); 12582 } 12583 12584 if (!printedAnything) { 12585 pw.println(" (nothing)"); 12586 } 12587 } 12588 12589 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12590 int opti, boolean dumpAll, String dumpPackage) { 12591 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12592 12593 boolean printedAnything = false; 12594 12595 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12596 boolean printedHeader = false; 12597 12598 final int N = mRecentTasks.size(); 12599 for (int i=0; i<N; i++) { 12600 TaskRecord tr = mRecentTasks.get(i); 12601 if (dumpPackage != null) { 12602 if (tr.realActivity == null || 12603 !dumpPackage.equals(tr.realActivity)) { 12604 continue; 12605 } 12606 } 12607 if (!printedHeader) { 12608 pw.println(" Recent tasks:"); 12609 printedHeader = true; 12610 printedAnything = true; 12611 } 12612 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12613 pw.println(tr); 12614 if (dumpAll) { 12615 mRecentTasks.get(i).dump(pw, " "); 12616 } 12617 } 12618 } 12619 12620 if (!printedAnything) { 12621 pw.println(" (nothing)"); 12622 } 12623 } 12624 12625 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12626 int opti, boolean dumpAll, String dumpPackage) { 12627 boolean needSep = false; 12628 boolean printedAnything = false; 12629 int numPers = 0; 12630 12631 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12632 12633 if (dumpAll) { 12634 final int NP = mProcessNames.getMap().size(); 12635 for (int ip=0; ip<NP; ip++) { 12636 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12637 final int NA = procs.size(); 12638 for (int ia=0; ia<NA; ia++) { 12639 ProcessRecord r = procs.valueAt(ia); 12640 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12641 continue; 12642 } 12643 if (!needSep) { 12644 pw.println(" All known processes:"); 12645 needSep = true; 12646 printedAnything = true; 12647 } 12648 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12649 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12650 pw.print(" "); pw.println(r); 12651 r.dump(pw, " "); 12652 if (r.persistent) { 12653 numPers++; 12654 } 12655 } 12656 } 12657 } 12658 12659 if (mIsolatedProcesses.size() > 0) { 12660 boolean printed = false; 12661 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12662 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12663 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12664 continue; 12665 } 12666 if (!printed) { 12667 if (needSep) { 12668 pw.println(); 12669 } 12670 pw.println(" Isolated process list (sorted by uid):"); 12671 printedAnything = true; 12672 printed = true; 12673 needSep = true; 12674 } 12675 pw.println(String.format("%sIsolated #%2d: %s", 12676 " ", i, r.toString())); 12677 } 12678 } 12679 12680 if (mLruProcesses.size() > 0) { 12681 if (needSep) { 12682 pw.println(); 12683 } 12684 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12685 pw.print(" total, non-act at "); 12686 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12687 pw.print(", non-svc at "); 12688 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12689 pw.println("):"); 12690 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12691 needSep = true; 12692 printedAnything = true; 12693 } 12694 12695 if (dumpAll || dumpPackage != null) { 12696 synchronized (mPidsSelfLocked) { 12697 boolean printed = false; 12698 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12699 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12700 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12701 continue; 12702 } 12703 if (!printed) { 12704 if (needSep) pw.println(); 12705 needSep = true; 12706 pw.println(" PID mappings:"); 12707 printed = true; 12708 printedAnything = true; 12709 } 12710 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12711 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12712 } 12713 } 12714 } 12715 12716 if (mForegroundProcesses.size() > 0) { 12717 synchronized (mPidsSelfLocked) { 12718 boolean printed = false; 12719 for (int i=0; i<mForegroundProcesses.size(); i++) { 12720 ProcessRecord r = mPidsSelfLocked.get( 12721 mForegroundProcesses.valueAt(i).pid); 12722 if (dumpPackage != null && (r == null 12723 || !r.pkgList.containsKey(dumpPackage))) { 12724 continue; 12725 } 12726 if (!printed) { 12727 if (needSep) pw.println(); 12728 needSep = true; 12729 pw.println(" Foreground Processes:"); 12730 printed = true; 12731 printedAnything = true; 12732 } 12733 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12734 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12735 } 12736 } 12737 } 12738 12739 if (mPersistentStartingProcesses.size() > 0) { 12740 if (needSep) pw.println(); 12741 needSep = true; 12742 printedAnything = true; 12743 pw.println(" Persisent processes that are starting:"); 12744 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12745 "Starting Norm", "Restarting PERS", dumpPackage); 12746 } 12747 12748 if (mRemovedProcesses.size() > 0) { 12749 if (needSep) pw.println(); 12750 needSep = true; 12751 printedAnything = true; 12752 pw.println(" Processes that are being removed:"); 12753 dumpProcessList(pw, this, mRemovedProcesses, " ", 12754 "Removed Norm", "Removed PERS", dumpPackage); 12755 } 12756 12757 if (mProcessesOnHold.size() > 0) { 12758 if (needSep) pw.println(); 12759 needSep = true; 12760 printedAnything = true; 12761 pw.println(" Processes that are on old until the system is ready:"); 12762 dumpProcessList(pw, this, mProcessesOnHold, " ", 12763 "OnHold Norm", "OnHold PERS", dumpPackage); 12764 } 12765 12766 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12767 12768 if (mProcessCrashTimes.getMap().size() > 0) { 12769 boolean printed = false; 12770 long now = SystemClock.uptimeMillis(); 12771 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12772 final int NP = pmap.size(); 12773 for (int ip=0; ip<NP; ip++) { 12774 String pname = pmap.keyAt(ip); 12775 SparseArray<Long> uids = pmap.valueAt(ip); 12776 final int N = uids.size(); 12777 for (int i=0; i<N; i++) { 12778 int puid = uids.keyAt(i); 12779 ProcessRecord r = mProcessNames.get(pname, puid); 12780 if (dumpPackage != null && (r == null 12781 || !r.pkgList.containsKey(dumpPackage))) { 12782 continue; 12783 } 12784 if (!printed) { 12785 if (needSep) pw.println(); 12786 needSep = true; 12787 pw.println(" Time since processes crashed:"); 12788 printed = true; 12789 printedAnything = true; 12790 } 12791 pw.print(" Process "); pw.print(pname); 12792 pw.print(" uid "); pw.print(puid); 12793 pw.print(": last crashed "); 12794 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12795 pw.println(" ago"); 12796 } 12797 } 12798 } 12799 12800 if (mBadProcesses.getMap().size() > 0) { 12801 boolean printed = false; 12802 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12803 final int NP = pmap.size(); 12804 for (int ip=0; ip<NP; ip++) { 12805 String pname = pmap.keyAt(ip); 12806 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12807 final int N = uids.size(); 12808 for (int i=0; i<N; i++) { 12809 int puid = uids.keyAt(i); 12810 ProcessRecord r = mProcessNames.get(pname, puid); 12811 if (dumpPackage != null && (r == null 12812 || !r.pkgList.containsKey(dumpPackage))) { 12813 continue; 12814 } 12815 if (!printed) { 12816 if (needSep) pw.println(); 12817 needSep = true; 12818 pw.println(" Bad processes:"); 12819 printedAnything = true; 12820 } 12821 BadProcessInfo info = uids.valueAt(i); 12822 pw.print(" Bad process "); pw.print(pname); 12823 pw.print(" uid "); pw.print(puid); 12824 pw.print(": crashed at time "); pw.println(info.time); 12825 if (info.shortMsg != null) { 12826 pw.print(" Short msg: "); pw.println(info.shortMsg); 12827 } 12828 if (info.longMsg != null) { 12829 pw.print(" Long msg: "); pw.println(info.longMsg); 12830 } 12831 if (info.stack != null) { 12832 pw.println(" Stack:"); 12833 int lastPos = 0; 12834 for (int pos=0; pos<info.stack.length(); pos++) { 12835 if (info.stack.charAt(pos) == '\n') { 12836 pw.print(" "); 12837 pw.write(info.stack, lastPos, pos-lastPos); 12838 pw.println(); 12839 lastPos = pos+1; 12840 } 12841 } 12842 if (lastPos < info.stack.length()) { 12843 pw.print(" "); 12844 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12845 pw.println(); 12846 } 12847 } 12848 } 12849 } 12850 } 12851 12852 if (dumpPackage == null) { 12853 pw.println(); 12854 needSep = false; 12855 pw.println(" mStartedUsers:"); 12856 for (int i=0; i<mStartedUsers.size(); i++) { 12857 UserStartedState uss = mStartedUsers.valueAt(i); 12858 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12859 pw.print(": "); uss.dump("", pw); 12860 } 12861 pw.print(" mStartedUserArray: ["); 12862 for (int i=0; i<mStartedUserArray.length; i++) { 12863 if (i > 0) pw.print(", "); 12864 pw.print(mStartedUserArray[i]); 12865 } 12866 pw.println("]"); 12867 pw.print(" mUserLru: ["); 12868 for (int i=0; i<mUserLru.size(); i++) { 12869 if (i > 0) pw.print(", "); 12870 pw.print(mUserLru.get(i)); 12871 } 12872 pw.println("]"); 12873 if (dumpAll) { 12874 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12875 } 12876 synchronized (mUserProfileGroupIdsSelfLocked) { 12877 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12878 pw.println(" mUserProfileGroupIds:"); 12879 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12880 pw.print(" User #"); 12881 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12882 pw.print(" -> profile #"); 12883 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12884 } 12885 } 12886 } 12887 } 12888 if (mHomeProcess != null && (dumpPackage == null 12889 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12890 if (needSep) { 12891 pw.println(); 12892 needSep = false; 12893 } 12894 pw.println(" mHomeProcess: " + mHomeProcess); 12895 } 12896 if (mPreviousProcess != null && (dumpPackage == null 12897 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12898 if (needSep) { 12899 pw.println(); 12900 needSep = false; 12901 } 12902 pw.println(" mPreviousProcess: " + mPreviousProcess); 12903 } 12904 if (dumpAll) { 12905 StringBuilder sb = new StringBuilder(128); 12906 sb.append(" mPreviousProcessVisibleTime: "); 12907 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12908 pw.println(sb); 12909 } 12910 if (mHeavyWeightProcess != null && (dumpPackage == null 12911 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12912 if (needSep) { 12913 pw.println(); 12914 needSep = false; 12915 } 12916 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12917 } 12918 if (dumpPackage == null) { 12919 pw.println(" mConfiguration: " + mConfiguration); 12920 } 12921 if (dumpAll) { 12922 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12923 if (mCompatModePackages.getPackages().size() > 0) { 12924 boolean printed = false; 12925 for (Map.Entry<String, Integer> entry 12926 : mCompatModePackages.getPackages().entrySet()) { 12927 String pkg = entry.getKey(); 12928 int mode = entry.getValue(); 12929 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12930 continue; 12931 } 12932 if (!printed) { 12933 pw.println(" mScreenCompatPackages:"); 12934 printed = true; 12935 } 12936 pw.print(" "); pw.print(pkg); pw.print(": "); 12937 pw.print(mode); pw.println(); 12938 } 12939 } 12940 } 12941 if (dumpPackage == null) { 12942 if (mSleeping || mWentToSleep || mLockScreenShown) { 12943 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12944 + " mLockScreenShown " + mLockScreenShown); 12945 } 12946 if (mShuttingDown || mRunningVoice) { 12947 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12948 } 12949 } 12950 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12951 || mOrigWaitForDebugger) { 12952 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12953 || dumpPackage.equals(mOrigDebugApp)) { 12954 if (needSep) { 12955 pw.println(); 12956 needSep = false; 12957 } 12958 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12959 + " mDebugTransient=" + mDebugTransient 12960 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12961 } 12962 } 12963 if (mOpenGlTraceApp != null) { 12964 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12965 if (needSep) { 12966 pw.println(); 12967 needSep = false; 12968 } 12969 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12970 } 12971 } 12972 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12973 || mProfileFd != null) { 12974 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12975 if (needSep) { 12976 pw.println(); 12977 needSep = false; 12978 } 12979 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12980 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12981 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12982 + mAutoStopProfiler); 12983 pw.println(" mProfileType=" + mProfileType); 12984 } 12985 } 12986 if (dumpPackage == null) { 12987 if (mAlwaysFinishActivities || mController != null) { 12988 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12989 + " mController=" + mController); 12990 } 12991 if (dumpAll) { 12992 pw.println(" Total persistent processes: " + numPers); 12993 pw.println(" mProcessesReady=" + mProcessesReady 12994 + " mSystemReady=" + mSystemReady 12995 + " mBooted=" + mBooted 12996 + " mFactoryTest=" + mFactoryTest); 12997 pw.println(" mBooting=" + mBooting 12998 + " mCallFinishBooting=" + mCallFinishBooting 12999 + " mBootAnimationComplete=" + mBootAnimationComplete); 13000 pw.print(" mLastPowerCheckRealtime="); 13001 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13002 pw.println(""); 13003 pw.print(" mLastPowerCheckUptime="); 13004 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13005 pw.println(""); 13006 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13007 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13008 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13009 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13010 + " (" + mLruProcesses.size() + " total)" 13011 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13012 + " mNumServiceProcs=" + mNumServiceProcs 13013 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13014 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13015 + " mLastMemoryLevel" + mLastMemoryLevel 13016 + " mLastNumProcesses" + mLastNumProcesses); 13017 long now = SystemClock.uptimeMillis(); 13018 pw.print(" mLastIdleTime="); 13019 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13020 pw.print(" mLowRamSinceLastIdle="); 13021 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13022 pw.println(); 13023 } 13024 } 13025 13026 if (!printedAnything) { 13027 pw.println(" (nothing)"); 13028 } 13029 } 13030 13031 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13032 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13033 if (mProcessesToGc.size() > 0) { 13034 boolean printed = false; 13035 long now = SystemClock.uptimeMillis(); 13036 for (int i=0; i<mProcessesToGc.size(); i++) { 13037 ProcessRecord proc = mProcessesToGc.get(i); 13038 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13039 continue; 13040 } 13041 if (!printed) { 13042 if (needSep) pw.println(); 13043 needSep = true; 13044 pw.println(" Processes that are waiting to GC:"); 13045 printed = true; 13046 } 13047 pw.print(" Process "); pw.println(proc); 13048 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13049 pw.print(", last gced="); 13050 pw.print(now-proc.lastRequestedGc); 13051 pw.print(" ms ago, last lowMem="); 13052 pw.print(now-proc.lastLowMemory); 13053 pw.println(" ms ago"); 13054 13055 } 13056 } 13057 return needSep; 13058 } 13059 13060 void printOomLevel(PrintWriter pw, String name, int adj) { 13061 pw.print(" "); 13062 if (adj >= 0) { 13063 pw.print(' '); 13064 if (adj < 10) pw.print(' '); 13065 } else { 13066 if (adj > -10) pw.print(' '); 13067 } 13068 pw.print(adj); 13069 pw.print(": "); 13070 pw.print(name); 13071 pw.print(" ("); 13072 pw.print(mProcessList.getMemLevel(adj)/1024); 13073 pw.println(" kB)"); 13074 } 13075 13076 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13077 int opti, boolean dumpAll) { 13078 boolean needSep = false; 13079 13080 if (mLruProcesses.size() > 0) { 13081 if (needSep) pw.println(); 13082 needSep = true; 13083 pw.println(" OOM levels:"); 13084 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13085 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13086 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13087 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13088 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13089 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13090 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13091 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13092 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13093 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13094 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13095 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13096 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13097 13098 if (needSep) pw.println(); 13099 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13100 pw.print(" total, non-act at "); 13101 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13102 pw.print(", non-svc at "); 13103 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13104 pw.println("):"); 13105 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13106 needSep = true; 13107 } 13108 13109 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13110 13111 pw.println(); 13112 pw.println(" mHomeProcess: " + mHomeProcess); 13113 pw.println(" mPreviousProcess: " + mPreviousProcess); 13114 if (mHeavyWeightProcess != null) { 13115 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13116 } 13117 13118 return true; 13119 } 13120 13121 /** 13122 * There are three ways to call this: 13123 * - no provider specified: dump all the providers 13124 * - a flattened component name that matched an existing provider was specified as the 13125 * first arg: dump that one provider 13126 * - the first arg isn't the flattened component name of an existing provider: 13127 * dump all providers whose component contains the first arg as a substring 13128 */ 13129 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13130 int opti, boolean dumpAll) { 13131 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13132 } 13133 13134 static class ItemMatcher { 13135 ArrayList<ComponentName> components; 13136 ArrayList<String> strings; 13137 ArrayList<Integer> objects; 13138 boolean all; 13139 13140 ItemMatcher() { 13141 all = true; 13142 } 13143 13144 void build(String name) { 13145 ComponentName componentName = ComponentName.unflattenFromString(name); 13146 if (componentName != null) { 13147 if (components == null) { 13148 components = new ArrayList<ComponentName>(); 13149 } 13150 components.add(componentName); 13151 all = false; 13152 } else { 13153 int objectId = 0; 13154 // Not a '/' separated full component name; maybe an object ID? 13155 try { 13156 objectId = Integer.parseInt(name, 16); 13157 if (objects == null) { 13158 objects = new ArrayList<Integer>(); 13159 } 13160 objects.add(objectId); 13161 all = false; 13162 } catch (RuntimeException e) { 13163 // Not an integer; just do string match. 13164 if (strings == null) { 13165 strings = new ArrayList<String>(); 13166 } 13167 strings.add(name); 13168 all = false; 13169 } 13170 } 13171 } 13172 13173 int build(String[] args, int opti) { 13174 for (; opti<args.length; opti++) { 13175 String name = args[opti]; 13176 if ("--".equals(name)) { 13177 return opti+1; 13178 } 13179 build(name); 13180 } 13181 return opti; 13182 } 13183 13184 boolean match(Object object, ComponentName comp) { 13185 if (all) { 13186 return true; 13187 } 13188 if (components != null) { 13189 for (int i=0; i<components.size(); i++) { 13190 if (components.get(i).equals(comp)) { 13191 return true; 13192 } 13193 } 13194 } 13195 if (objects != null) { 13196 for (int i=0; i<objects.size(); i++) { 13197 if (System.identityHashCode(object) == objects.get(i)) { 13198 return true; 13199 } 13200 } 13201 } 13202 if (strings != null) { 13203 String flat = comp.flattenToString(); 13204 for (int i=0; i<strings.size(); i++) { 13205 if (flat.contains(strings.get(i))) { 13206 return true; 13207 } 13208 } 13209 } 13210 return false; 13211 } 13212 } 13213 13214 /** 13215 * There are three things that cmd can be: 13216 * - a flattened component name that matches an existing activity 13217 * - the cmd arg isn't the flattened component name of an existing activity: 13218 * dump all activity whose component contains the cmd as a substring 13219 * - A hex number of the ActivityRecord object instance. 13220 */ 13221 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13222 int opti, boolean dumpAll) { 13223 ArrayList<ActivityRecord> activities; 13224 13225 synchronized (this) { 13226 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13227 } 13228 13229 if (activities.size() <= 0) { 13230 return false; 13231 } 13232 13233 String[] newArgs = new String[args.length - opti]; 13234 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13235 13236 TaskRecord lastTask = null; 13237 boolean needSep = false; 13238 for (int i=activities.size()-1; i>=0; i--) { 13239 ActivityRecord r = activities.get(i); 13240 if (needSep) { 13241 pw.println(); 13242 } 13243 needSep = true; 13244 synchronized (this) { 13245 if (lastTask != r.task) { 13246 lastTask = r.task; 13247 pw.print("TASK "); pw.print(lastTask.affinity); 13248 pw.print(" id="); pw.println(lastTask.taskId); 13249 if (dumpAll) { 13250 lastTask.dump(pw, " "); 13251 } 13252 } 13253 } 13254 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13255 } 13256 return true; 13257 } 13258 13259 /** 13260 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13261 * there is a thread associated with the activity. 13262 */ 13263 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13264 final ActivityRecord r, String[] args, boolean dumpAll) { 13265 String innerPrefix = prefix + " "; 13266 synchronized (this) { 13267 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13268 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13269 pw.print(" pid="); 13270 if (r.app != null) pw.println(r.app.pid); 13271 else pw.println("(not running)"); 13272 if (dumpAll) { 13273 r.dump(pw, innerPrefix); 13274 } 13275 } 13276 if (r.app != null && r.app.thread != null) { 13277 // flush anything that is already in the PrintWriter since the thread is going 13278 // to write to the file descriptor directly 13279 pw.flush(); 13280 try { 13281 TransferPipe tp = new TransferPipe(); 13282 try { 13283 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13284 r.appToken, innerPrefix, args); 13285 tp.go(fd); 13286 } finally { 13287 tp.kill(); 13288 } 13289 } catch (IOException e) { 13290 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13291 } catch (RemoteException e) { 13292 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13293 } 13294 } 13295 } 13296 13297 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13298 int opti, boolean dumpAll, String dumpPackage) { 13299 boolean needSep = false; 13300 boolean onlyHistory = false; 13301 boolean printedAnything = false; 13302 13303 if ("history".equals(dumpPackage)) { 13304 if (opti < args.length && "-s".equals(args[opti])) { 13305 dumpAll = false; 13306 } 13307 onlyHistory = true; 13308 dumpPackage = null; 13309 } 13310 13311 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13312 if (!onlyHistory && dumpAll) { 13313 if (mRegisteredReceivers.size() > 0) { 13314 boolean printed = false; 13315 Iterator it = mRegisteredReceivers.values().iterator(); 13316 while (it.hasNext()) { 13317 ReceiverList r = (ReceiverList)it.next(); 13318 if (dumpPackage != null && (r.app == null || 13319 !dumpPackage.equals(r.app.info.packageName))) { 13320 continue; 13321 } 13322 if (!printed) { 13323 pw.println(" Registered Receivers:"); 13324 needSep = true; 13325 printed = true; 13326 printedAnything = true; 13327 } 13328 pw.print(" * "); pw.println(r); 13329 r.dump(pw, " "); 13330 } 13331 } 13332 13333 if (mReceiverResolver.dump(pw, needSep ? 13334 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13335 " ", dumpPackage, false)) { 13336 needSep = true; 13337 printedAnything = true; 13338 } 13339 } 13340 13341 for (BroadcastQueue q : mBroadcastQueues) { 13342 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13343 printedAnything |= needSep; 13344 } 13345 13346 needSep = true; 13347 13348 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13349 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13350 if (needSep) { 13351 pw.println(); 13352 } 13353 needSep = true; 13354 printedAnything = true; 13355 pw.print(" Sticky broadcasts for user "); 13356 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13357 StringBuilder sb = new StringBuilder(128); 13358 for (Map.Entry<String, ArrayList<Intent>> ent 13359 : mStickyBroadcasts.valueAt(user).entrySet()) { 13360 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13361 if (dumpAll) { 13362 pw.println(":"); 13363 ArrayList<Intent> intents = ent.getValue(); 13364 final int N = intents.size(); 13365 for (int i=0; i<N; i++) { 13366 sb.setLength(0); 13367 sb.append(" Intent: "); 13368 intents.get(i).toShortString(sb, false, true, false, false); 13369 pw.println(sb.toString()); 13370 Bundle bundle = intents.get(i).getExtras(); 13371 if (bundle != null) { 13372 pw.print(" "); 13373 pw.println(bundle.toString()); 13374 } 13375 } 13376 } else { 13377 pw.println(""); 13378 } 13379 } 13380 } 13381 } 13382 13383 if (!onlyHistory && dumpAll) { 13384 pw.println(); 13385 for (BroadcastQueue queue : mBroadcastQueues) { 13386 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13387 + queue.mBroadcastsScheduled); 13388 } 13389 pw.println(" mHandler:"); 13390 mHandler.dump(new PrintWriterPrinter(pw), " "); 13391 needSep = true; 13392 printedAnything = true; 13393 } 13394 13395 if (!printedAnything) { 13396 pw.println(" (nothing)"); 13397 } 13398 } 13399 13400 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13401 int opti, boolean dumpAll, String dumpPackage) { 13402 boolean needSep; 13403 boolean printedAnything = false; 13404 13405 ItemMatcher matcher = new ItemMatcher(); 13406 matcher.build(args, opti); 13407 13408 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13409 13410 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13411 printedAnything |= needSep; 13412 13413 if (mLaunchingProviders.size() > 0) { 13414 boolean printed = false; 13415 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13416 ContentProviderRecord r = mLaunchingProviders.get(i); 13417 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13418 continue; 13419 } 13420 if (!printed) { 13421 if (needSep) pw.println(); 13422 needSep = true; 13423 pw.println(" Launching content providers:"); 13424 printed = true; 13425 printedAnything = true; 13426 } 13427 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13428 pw.println(r); 13429 } 13430 } 13431 13432 if (mGrantedUriPermissions.size() > 0) { 13433 boolean printed = false; 13434 int dumpUid = -2; 13435 if (dumpPackage != null) { 13436 try { 13437 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13438 } catch (NameNotFoundException e) { 13439 dumpUid = -1; 13440 } 13441 } 13442 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13443 int uid = mGrantedUriPermissions.keyAt(i); 13444 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13445 continue; 13446 } 13447 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13448 if (!printed) { 13449 if (needSep) pw.println(); 13450 needSep = true; 13451 pw.println(" Granted Uri Permissions:"); 13452 printed = true; 13453 printedAnything = true; 13454 } 13455 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13456 for (UriPermission perm : perms.values()) { 13457 pw.print(" "); pw.println(perm); 13458 if (dumpAll) { 13459 perm.dump(pw, " "); 13460 } 13461 } 13462 } 13463 } 13464 13465 if (!printedAnything) { 13466 pw.println(" (nothing)"); 13467 } 13468 } 13469 13470 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13471 int opti, boolean dumpAll, String dumpPackage) { 13472 boolean printed = false; 13473 13474 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13475 13476 if (mIntentSenderRecords.size() > 0) { 13477 Iterator<WeakReference<PendingIntentRecord>> it 13478 = mIntentSenderRecords.values().iterator(); 13479 while (it.hasNext()) { 13480 WeakReference<PendingIntentRecord> ref = it.next(); 13481 PendingIntentRecord rec = ref != null ? ref.get(): null; 13482 if (dumpPackage != null && (rec == null 13483 || !dumpPackage.equals(rec.key.packageName))) { 13484 continue; 13485 } 13486 printed = true; 13487 if (rec != null) { 13488 pw.print(" * "); pw.println(rec); 13489 if (dumpAll) { 13490 rec.dump(pw, " "); 13491 } 13492 } else { 13493 pw.print(" * "); pw.println(ref); 13494 } 13495 } 13496 } 13497 13498 if (!printed) { 13499 pw.println(" (nothing)"); 13500 } 13501 } 13502 13503 private static final int dumpProcessList(PrintWriter pw, 13504 ActivityManagerService service, List list, 13505 String prefix, String normalLabel, String persistentLabel, 13506 String dumpPackage) { 13507 int numPers = 0; 13508 final int N = list.size()-1; 13509 for (int i=N; i>=0; i--) { 13510 ProcessRecord r = (ProcessRecord)list.get(i); 13511 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13512 continue; 13513 } 13514 pw.println(String.format("%s%s #%2d: %s", 13515 prefix, (r.persistent ? persistentLabel : normalLabel), 13516 i, r.toString())); 13517 if (r.persistent) { 13518 numPers++; 13519 } 13520 } 13521 return numPers; 13522 } 13523 13524 private static final boolean dumpProcessOomList(PrintWriter pw, 13525 ActivityManagerService service, List<ProcessRecord> origList, 13526 String prefix, String normalLabel, String persistentLabel, 13527 boolean inclDetails, String dumpPackage) { 13528 13529 ArrayList<Pair<ProcessRecord, Integer>> list 13530 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13531 for (int i=0; i<origList.size(); i++) { 13532 ProcessRecord r = origList.get(i); 13533 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13534 continue; 13535 } 13536 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13537 } 13538 13539 if (list.size() <= 0) { 13540 return false; 13541 } 13542 13543 Comparator<Pair<ProcessRecord, Integer>> comparator 13544 = new Comparator<Pair<ProcessRecord, Integer>>() { 13545 @Override 13546 public int compare(Pair<ProcessRecord, Integer> object1, 13547 Pair<ProcessRecord, Integer> object2) { 13548 if (object1.first.setAdj != object2.first.setAdj) { 13549 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13550 } 13551 if (object1.second.intValue() != object2.second.intValue()) { 13552 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13553 } 13554 return 0; 13555 } 13556 }; 13557 13558 Collections.sort(list, comparator); 13559 13560 final long curRealtime = SystemClock.elapsedRealtime(); 13561 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13562 final long curUptime = SystemClock.uptimeMillis(); 13563 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13564 13565 for (int i=list.size()-1; i>=0; i--) { 13566 ProcessRecord r = list.get(i).first; 13567 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13568 char schedGroup; 13569 switch (r.setSchedGroup) { 13570 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13571 schedGroup = 'B'; 13572 break; 13573 case Process.THREAD_GROUP_DEFAULT: 13574 schedGroup = 'F'; 13575 break; 13576 default: 13577 schedGroup = '?'; 13578 break; 13579 } 13580 char foreground; 13581 if (r.foregroundActivities) { 13582 foreground = 'A'; 13583 } else if (r.foregroundServices) { 13584 foreground = 'S'; 13585 } else { 13586 foreground = ' '; 13587 } 13588 String procState = ProcessList.makeProcStateString(r.curProcState); 13589 pw.print(prefix); 13590 pw.print(r.persistent ? persistentLabel : normalLabel); 13591 pw.print(" #"); 13592 int num = (origList.size()-1)-list.get(i).second; 13593 if (num < 10) pw.print(' '); 13594 pw.print(num); 13595 pw.print(": "); 13596 pw.print(oomAdj); 13597 pw.print(' '); 13598 pw.print(schedGroup); 13599 pw.print('/'); 13600 pw.print(foreground); 13601 pw.print('/'); 13602 pw.print(procState); 13603 pw.print(" trm:"); 13604 if (r.trimMemoryLevel < 10) pw.print(' '); 13605 pw.print(r.trimMemoryLevel); 13606 pw.print(' '); 13607 pw.print(r.toShortString()); 13608 pw.print(" ("); 13609 pw.print(r.adjType); 13610 pw.println(')'); 13611 if (r.adjSource != null || r.adjTarget != null) { 13612 pw.print(prefix); 13613 pw.print(" "); 13614 if (r.adjTarget instanceof ComponentName) { 13615 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13616 } else if (r.adjTarget != null) { 13617 pw.print(r.adjTarget.toString()); 13618 } else { 13619 pw.print("{null}"); 13620 } 13621 pw.print("<="); 13622 if (r.adjSource instanceof ProcessRecord) { 13623 pw.print("Proc{"); 13624 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13625 pw.println("}"); 13626 } else if (r.adjSource != null) { 13627 pw.println(r.adjSource.toString()); 13628 } else { 13629 pw.println("{null}"); 13630 } 13631 } 13632 if (inclDetails) { 13633 pw.print(prefix); 13634 pw.print(" "); 13635 pw.print("oom: max="); pw.print(r.maxAdj); 13636 pw.print(" curRaw="); pw.print(r.curRawAdj); 13637 pw.print(" setRaw="); pw.print(r.setRawAdj); 13638 pw.print(" cur="); pw.print(r.curAdj); 13639 pw.print(" set="); pw.println(r.setAdj); 13640 pw.print(prefix); 13641 pw.print(" "); 13642 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13643 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13644 pw.print(" lastPss="); pw.print(r.lastPss); 13645 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13646 pw.print(prefix); 13647 pw.print(" "); 13648 pw.print("cached="); pw.print(r.cached); 13649 pw.print(" empty="); pw.print(r.empty); 13650 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13651 13652 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13653 if (r.lastWakeTime != 0) { 13654 long wtime; 13655 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13656 synchronized (stats) { 13657 wtime = stats.getProcessWakeTime(r.info.uid, 13658 r.pid, curRealtime); 13659 } 13660 long timeUsed = wtime - r.lastWakeTime; 13661 pw.print(prefix); 13662 pw.print(" "); 13663 pw.print("keep awake over "); 13664 TimeUtils.formatDuration(realtimeSince, pw); 13665 pw.print(" used "); 13666 TimeUtils.formatDuration(timeUsed, pw); 13667 pw.print(" ("); 13668 pw.print((timeUsed*100)/realtimeSince); 13669 pw.println("%)"); 13670 } 13671 if (r.lastCpuTime != 0) { 13672 long timeUsed = r.curCpuTime - r.lastCpuTime; 13673 pw.print(prefix); 13674 pw.print(" "); 13675 pw.print("run cpu over "); 13676 TimeUtils.formatDuration(uptimeSince, pw); 13677 pw.print(" used "); 13678 TimeUtils.formatDuration(timeUsed, pw); 13679 pw.print(" ("); 13680 pw.print((timeUsed*100)/uptimeSince); 13681 pw.println("%)"); 13682 } 13683 } 13684 } 13685 } 13686 return true; 13687 } 13688 13689 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13690 String[] args) { 13691 ArrayList<ProcessRecord> procs; 13692 synchronized (this) { 13693 if (args != null && args.length > start 13694 && args[start].charAt(0) != '-') { 13695 procs = new ArrayList<ProcessRecord>(); 13696 int pid = -1; 13697 try { 13698 pid = Integer.parseInt(args[start]); 13699 } catch (NumberFormatException e) { 13700 } 13701 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13702 ProcessRecord proc = mLruProcesses.get(i); 13703 if (proc.pid == pid) { 13704 procs.add(proc); 13705 } else if (allPkgs && proc.pkgList != null 13706 && proc.pkgList.containsKey(args[start])) { 13707 procs.add(proc); 13708 } else if (proc.processName.equals(args[start])) { 13709 procs.add(proc); 13710 } 13711 } 13712 if (procs.size() <= 0) { 13713 return null; 13714 } 13715 } else { 13716 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13717 } 13718 } 13719 return procs; 13720 } 13721 13722 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13723 PrintWriter pw, String[] args) { 13724 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13725 if (procs == null) { 13726 pw.println("No process found for: " + args[0]); 13727 return; 13728 } 13729 13730 long uptime = SystemClock.uptimeMillis(); 13731 long realtime = SystemClock.elapsedRealtime(); 13732 pw.println("Applications Graphics Acceleration Info:"); 13733 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13734 13735 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13736 ProcessRecord r = procs.get(i); 13737 if (r.thread != null) { 13738 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13739 pw.flush(); 13740 try { 13741 TransferPipe tp = new TransferPipe(); 13742 try { 13743 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13744 tp.go(fd); 13745 } finally { 13746 tp.kill(); 13747 } 13748 } catch (IOException e) { 13749 pw.println("Failure while dumping the app: " + r); 13750 pw.flush(); 13751 } catch (RemoteException e) { 13752 pw.println("Got a RemoteException while dumping the app " + r); 13753 pw.flush(); 13754 } 13755 } 13756 } 13757 } 13758 13759 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13760 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13761 if (procs == null) { 13762 pw.println("No process found for: " + args[0]); 13763 return; 13764 } 13765 13766 pw.println("Applications Database Info:"); 13767 13768 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13769 ProcessRecord r = procs.get(i); 13770 if (r.thread != null) { 13771 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13772 pw.flush(); 13773 try { 13774 TransferPipe tp = new TransferPipe(); 13775 try { 13776 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13777 tp.go(fd); 13778 } finally { 13779 tp.kill(); 13780 } 13781 } catch (IOException e) { 13782 pw.println("Failure while dumping the app: " + r); 13783 pw.flush(); 13784 } catch (RemoteException e) { 13785 pw.println("Got a RemoteException while dumping the app " + r); 13786 pw.flush(); 13787 } 13788 } 13789 } 13790 } 13791 13792 final static class MemItem { 13793 final boolean isProc; 13794 final String label; 13795 final String shortLabel; 13796 final long pss; 13797 final int id; 13798 final boolean hasActivities; 13799 ArrayList<MemItem> subitems; 13800 13801 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13802 boolean _hasActivities) { 13803 isProc = true; 13804 label = _label; 13805 shortLabel = _shortLabel; 13806 pss = _pss; 13807 id = _id; 13808 hasActivities = _hasActivities; 13809 } 13810 13811 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13812 isProc = false; 13813 label = _label; 13814 shortLabel = _shortLabel; 13815 pss = _pss; 13816 id = _id; 13817 hasActivities = false; 13818 } 13819 } 13820 13821 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13822 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13823 if (sort && !isCompact) { 13824 Collections.sort(items, new Comparator<MemItem>() { 13825 @Override 13826 public int compare(MemItem lhs, MemItem rhs) { 13827 if (lhs.pss < rhs.pss) { 13828 return 1; 13829 } else if (lhs.pss > rhs.pss) { 13830 return -1; 13831 } 13832 return 0; 13833 } 13834 }); 13835 } 13836 13837 for (int i=0; i<items.size(); i++) { 13838 MemItem mi = items.get(i); 13839 if (!isCompact) { 13840 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13841 } else if (mi.isProc) { 13842 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13843 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13844 pw.println(mi.hasActivities ? ",a" : ",e"); 13845 } else { 13846 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13847 pw.println(mi.pss); 13848 } 13849 if (mi.subitems != null) { 13850 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13851 true, isCompact); 13852 } 13853 } 13854 } 13855 13856 // These are in KB. 13857 static final long[] DUMP_MEM_BUCKETS = new long[] { 13858 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13859 120*1024, 160*1024, 200*1024, 13860 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13861 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13862 }; 13863 13864 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13865 boolean stackLike) { 13866 int start = label.lastIndexOf('.'); 13867 if (start >= 0) start++; 13868 else start = 0; 13869 int end = label.length(); 13870 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13871 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13872 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13873 out.append(bucket); 13874 out.append(stackLike ? "MB." : "MB "); 13875 out.append(label, start, end); 13876 return; 13877 } 13878 } 13879 out.append(memKB/1024); 13880 out.append(stackLike ? "MB." : "MB "); 13881 out.append(label, start, end); 13882 } 13883 13884 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13885 ProcessList.NATIVE_ADJ, 13886 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13887 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13888 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13889 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13890 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13891 }; 13892 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13893 "Native", 13894 "System", "Persistent", "Foreground", 13895 "Visible", "Perceptible", 13896 "Heavy Weight", "Backup", 13897 "A Services", "Home", 13898 "Previous", "B Services", "Cached" 13899 }; 13900 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13901 "native", 13902 "sys", "pers", "fore", 13903 "vis", "percept", 13904 "heavy", "backup", 13905 "servicea", "home", 13906 "prev", "serviceb", "cached" 13907 }; 13908 13909 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13910 long realtime, boolean isCheckinRequest, boolean isCompact) { 13911 if (isCheckinRequest || isCompact) { 13912 // short checkin version 13913 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13914 } else { 13915 pw.println("Applications Memory Usage (kB):"); 13916 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13917 } 13918 } 13919 13920 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13921 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13922 boolean dumpDetails = false; 13923 boolean dumpFullDetails = false; 13924 boolean dumpDalvik = false; 13925 boolean oomOnly = false; 13926 boolean isCompact = false; 13927 boolean localOnly = false; 13928 boolean packages = false; 13929 13930 int opti = 0; 13931 while (opti < args.length) { 13932 String opt = args[opti]; 13933 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13934 break; 13935 } 13936 opti++; 13937 if ("-a".equals(opt)) { 13938 dumpDetails = true; 13939 dumpFullDetails = true; 13940 dumpDalvik = true; 13941 } else if ("-d".equals(opt)) { 13942 dumpDalvik = true; 13943 } else if ("-c".equals(opt)) { 13944 isCompact = true; 13945 } else if ("--oom".equals(opt)) { 13946 oomOnly = true; 13947 } else if ("--local".equals(opt)) { 13948 localOnly = true; 13949 } else if ("--package".equals(opt)) { 13950 packages = true; 13951 } else if ("-h".equals(opt)) { 13952 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13953 pw.println(" -a: include all available information for each process."); 13954 pw.println(" -d: include dalvik details when dumping process details."); 13955 pw.println(" -c: dump in a compact machine-parseable representation."); 13956 pw.println(" --oom: only show processes organized by oom adj."); 13957 pw.println(" --local: only collect details locally, don't call process."); 13958 pw.println(" --package: interpret process arg as package, dumping all"); 13959 pw.println(" processes that have loaded that package."); 13960 pw.println("If [process] is specified it can be the name or "); 13961 pw.println("pid of a specific process to dump."); 13962 return; 13963 } else { 13964 pw.println("Unknown argument: " + opt + "; use -h for help"); 13965 } 13966 } 13967 13968 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13969 long uptime = SystemClock.uptimeMillis(); 13970 long realtime = SystemClock.elapsedRealtime(); 13971 final long[] tmpLong = new long[1]; 13972 13973 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13974 if (procs == null) { 13975 // No Java processes. Maybe they want to print a native process. 13976 if (args != null && args.length > opti 13977 && args[opti].charAt(0) != '-') { 13978 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13979 = new ArrayList<ProcessCpuTracker.Stats>(); 13980 updateCpuStatsNow(); 13981 int findPid = -1; 13982 try { 13983 findPid = Integer.parseInt(args[opti]); 13984 } catch (NumberFormatException e) { 13985 } 13986 synchronized (mProcessCpuTracker) { 13987 final int N = mProcessCpuTracker.countStats(); 13988 for (int i=0; i<N; i++) { 13989 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13990 if (st.pid == findPid || (st.baseName != null 13991 && st.baseName.equals(args[opti]))) { 13992 nativeProcs.add(st); 13993 } 13994 } 13995 } 13996 if (nativeProcs.size() > 0) { 13997 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13998 isCompact); 13999 Debug.MemoryInfo mi = null; 14000 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14001 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14002 final int pid = r.pid; 14003 if (!isCheckinRequest && dumpDetails) { 14004 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14005 } 14006 if (mi == null) { 14007 mi = new Debug.MemoryInfo(); 14008 } 14009 if (dumpDetails || (!brief && !oomOnly)) { 14010 Debug.getMemoryInfo(pid, mi); 14011 } else { 14012 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14013 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14014 } 14015 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14016 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14017 if (isCheckinRequest) { 14018 pw.println(); 14019 } 14020 } 14021 return; 14022 } 14023 } 14024 pw.println("No process found for: " + args[opti]); 14025 return; 14026 } 14027 14028 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14029 dumpDetails = true; 14030 } 14031 14032 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14033 14034 String[] innerArgs = new String[args.length-opti]; 14035 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14036 14037 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14038 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14039 long nativePss=0, dalvikPss=0, otherPss=0; 14040 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14041 14042 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14043 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14044 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14045 14046 long totalPss = 0; 14047 long cachedPss = 0; 14048 14049 Debug.MemoryInfo mi = null; 14050 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14051 final ProcessRecord r = procs.get(i); 14052 final IApplicationThread thread; 14053 final int pid; 14054 final int oomAdj; 14055 final boolean hasActivities; 14056 synchronized (this) { 14057 thread = r.thread; 14058 pid = r.pid; 14059 oomAdj = r.getSetAdjWithServices(); 14060 hasActivities = r.activities.size() > 0; 14061 } 14062 if (thread != null) { 14063 if (!isCheckinRequest && dumpDetails) { 14064 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14065 } 14066 if (mi == null) { 14067 mi = new Debug.MemoryInfo(); 14068 } 14069 if (dumpDetails || (!brief && !oomOnly)) { 14070 Debug.getMemoryInfo(pid, mi); 14071 } else { 14072 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14073 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14074 } 14075 if (dumpDetails) { 14076 if (localOnly) { 14077 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14078 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14079 if (isCheckinRequest) { 14080 pw.println(); 14081 } 14082 } else { 14083 try { 14084 pw.flush(); 14085 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14086 dumpDalvik, innerArgs); 14087 } catch (RemoteException e) { 14088 if (!isCheckinRequest) { 14089 pw.println("Got RemoteException!"); 14090 pw.flush(); 14091 } 14092 } 14093 } 14094 } 14095 14096 final long myTotalPss = mi.getTotalPss(); 14097 final long myTotalUss = mi.getTotalUss(); 14098 14099 synchronized (this) { 14100 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14101 // Record this for posterity if the process has been stable. 14102 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14103 } 14104 } 14105 14106 if (!isCheckinRequest && mi != null) { 14107 totalPss += myTotalPss; 14108 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14109 (hasActivities ? " / activities)" : ")"), 14110 r.processName, myTotalPss, pid, hasActivities); 14111 procMems.add(pssItem); 14112 procMemsMap.put(pid, pssItem); 14113 14114 nativePss += mi.nativePss; 14115 dalvikPss += mi.dalvikPss; 14116 otherPss += mi.otherPss; 14117 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14118 long mem = mi.getOtherPss(j); 14119 miscPss[j] += mem; 14120 otherPss -= mem; 14121 } 14122 14123 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14124 cachedPss += myTotalPss; 14125 } 14126 14127 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14128 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14129 || oomIndex == (oomPss.length-1)) { 14130 oomPss[oomIndex] += myTotalPss; 14131 if (oomProcs[oomIndex] == null) { 14132 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14133 } 14134 oomProcs[oomIndex].add(pssItem); 14135 break; 14136 } 14137 } 14138 } 14139 } 14140 } 14141 14142 long nativeProcTotalPss = 0; 14143 14144 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14145 // If we are showing aggregations, also look for native processes to 14146 // include so that our aggregations are more accurate. 14147 updateCpuStatsNow(); 14148 synchronized (mProcessCpuTracker) { 14149 final int N = mProcessCpuTracker.countStats(); 14150 for (int i=0; i<N; i++) { 14151 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14152 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14153 if (mi == null) { 14154 mi = new Debug.MemoryInfo(); 14155 } 14156 if (!brief && !oomOnly) { 14157 Debug.getMemoryInfo(st.pid, mi); 14158 } else { 14159 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14160 mi.nativePrivateDirty = (int)tmpLong[0]; 14161 } 14162 14163 final long myTotalPss = mi.getTotalPss(); 14164 totalPss += myTotalPss; 14165 nativeProcTotalPss += myTotalPss; 14166 14167 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14168 st.name, myTotalPss, st.pid, false); 14169 procMems.add(pssItem); 14170 14171 nativePss += mi.nativePss; 14172 dalvikPss += mi.dalvikPss; 14173 otherPss += mi.otherPss; 14174 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14175 long mem = mi.getOtherPss(j); 14176 miscPss[j] += mem; 14177 otherPss -= mem; 14178 } 14179 oomPss[0] += myTotalPss; 14180 if (oomProcs[0] == null) { 14181 oomProcs[0] = new ArrayList<MemItem>(); 14182 } 14183 oomProcs[0].add(pssItem); 14184 } 14185 } 14186 } 14187 14188 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14189 14190 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14191 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14192 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14193 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14194 String label = Debug.MemoryInfo.getOtherLabel(j); 14195 catMems.add(new MemItem(label, label, miscPss[j], j)); 14196 } 14197 14198 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14199 for (int j=0; j<oomPss.length; j++) { 14200 if (oomPss[j] != 0) { 14201 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14202 : DUMP_MEM_OOM_LABEL[j]; 14203 MemItem item = new MemItem(label, label, oomPss[j], 14204 DUMP_MEM_OOM_ADJ[j]); 14205 item.subitems = oomProcs[j]; 14206 oomMems.add(item); 14207 } 14208 } 14209 14210 if (!brief && !oomOnly && !isCompact) { 14211 pw.println(); 14212 pw.println("Total PSS by process:"); 14213 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14214 pw.println(); 14215 } 14216 if (!isCompact) { 14217 pw.println("Total PSS by OOM adjustment:"); 14218 } 14219 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14220 if (!brief && !oomOnly) { 14221 PrintWriter out = categoryPw != null ? categoryPw : pw; 14222 if (!isCompact) { 14223 out.println(); 14224 out.println("Total PSS by category:"); 14225 } 14226 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14227 } 14228 if (!isCompact) { 14229 pw.println(); 14230 } 14231 MemInfoReader memInfo = new MemInfoReader(); 14232 memInfo.readMemInfo(); 14233 if (nativeProcTotalPss > 0) { 14234 synchronized (this) { 14235 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14236 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14237 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14238 nativeProcTotalPss); 14239 } 14240 } 14241 if (!brief) { 14242 if (!isCompact) { 14243 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14244 pw.print(" kB (status "); 14245 switch (mLastMemoryLevel) { 14246 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14247 pw.println("normal)"); 14248 break; 14249 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14250 pw.println("moderate)"); 14251 break; 14252 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14253 pw.println("low)"); 14254 break; 14255 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14256 pw.println("critical)"); 14257 break; 14258 default: 14259 pw.print(mLastMemoryLevel); 14260 pw.println(")"); 14261 break; 14262 } 14263 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14264 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14265 pw.print(cachedPss); pw.print(" cached pss + "); 14266 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14267 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14268 } else { 14269 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14270 pw.print(cachedPss + memInfo.getCachedSizeKb() 14271 + memInfo.getFreeSizeKb()); pw.print(","); 14272 pw.println(totalPss - cachedPss); 14273 } 14274 } 14275 if (!isCompact) { 14276 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14277 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14278 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14279 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14280 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14281 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14282 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14283 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14284 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14285 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14286 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14287 } 14288 if (!brief) { 14289 if (memInfo.getZramTotalSizeKb() != 0) { 14290 if (!isCompact) { 14291 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14292 pw.print(" kB physical used for "); 14293 pw.print(memInfo.getSwapTotalSizeKb() 14294 - memInfo.getSwapFreeSizeKb()); 14295 pw.print(" kB in swap ("); 14296 pw.print(memInfo.getSwapTotalSizeKb()); 14297 pw.println(" kB total swap)"); 14298 } else { 14299 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14300 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14301 pw.println(memInfo.getSwapFreeSizeKb()); 14302 } 14303 } 14304 final int[] SINGLE_LONG_FORMAT = new int[] { 14305 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14306 }; 14307 long[] longOut = new long[1]; 14308 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14309 SINGLE_LONG_FORMAT, null, longOut, null); 14310 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14311 longOut[0] = 0; 14312 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14313 SINGLE_LONG_FORMAT, null, longOut, null); 14314 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14315 longOut[0] = 0; 14316 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14317 SINGLE_LONG_FORMAT, null, longOut, null); 14318 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14319 longOut[0] = 0; 14320 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14321 SINGLE_LONG_FORMAT, null, longOut, null); 14322 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14323 if (!isCompact) { 14324 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14325 pw.print(" KSM: "); pw.print(sharing); 14326 pw.print(" kB saved from shared "); 14327 pw.print(shared); pw.println(" kB"); 14328 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14329 pw.print(voltile); pw.println(" kB volatile"); 14330 } 14331 pw.print(" Tuning: "); 14332 pw.print(ActivityManager.staticGetMemoryClass()); 14333 pw.print(" (large "); 14334 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14335 pw.print("), oom "); 14336 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14337 pw.print(" kB"); 14338 pw.print(", restore limit "); 14339 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14340 pw.print(" kB"); 14341 if (ActivityManager.isLowRamDeviceStatic()) { 14342 pw.print(" (low-ram)"); 14343 } 14344 if (ActivityManager.isHighEndGfx()) { 14345 pw.print(" (high-end-gfx)"); 14346 } 14347 pw.println(); 14348 } else { 14349 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14350 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14351 pw.println(voltile); 14352 pw.print("tuning,"); 14353 pw.print(ActivityManager.staticGetMemoryClass()); 14354 pw.print(','); 14355 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14356 pw.print(','); 14357 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14358 if (ActivityManager.isLowRamDeviceStatic()) { 14359 pw.print(",low-ram"); 14360 } 14361 if (ActivityManager.isHighEndGfx()) { 14362 pw.print(",high-end-gfx"); 14363 } 14364 pw.println(); 14365 } 14366 } 14367 } 14368 } 14369 14370 /** 14371 * Searches array of arguments for the specified string 14372 * @param args array of argument strings 14373 * @param value value to search for 14374 * @return true if the value is contained in the array 14375 */ 14376 private static boolean scanArgs(String[] args, String value) { 14377 if (args != null) { 14378 for (String arg : args) { 14379 if (value.equals(arg)) { 14380 return true; 14381 } 14382 } 14383 } 14384 return false; 14385 } 14386 14387 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14388 ContentProviderRecord cpr, boolean always) { 14389 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14390 14391 if (!inLaunching || always) { 14392 synchronized (cpr) { 14393 cpr.launchingApp = null; 14394 cpr.notifyAll(); 14395 } 14396 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14397 String names[] = cpr.info.authority.split(";"); 14398 for (int j = 0; j < names.length; j++) { 14399 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14400 } 14401 } 14402 14403 for (int i=0; i<cpr.connections.size(); i++) { 14404 ContentProviderConnection conn = cpr.connections.get(i); 14405 if (conn.waiting) { 14406 // If this connection is waiting for the provider, then we don't 14407 // need to mess with its process unless we are always removing 14408 // or for some reason the provider is not currently launching. 14409 if (inLaunching && !always) { 14410 continue; 14411 } 14412 } 14413 ProcessRecord capp = conn.client; 14414 conn.dead = true; 14415 if (conn.stableCount > 0) { 14416 if (!capp.persistent && capp.thread != null 14417 && capp.pid != 0 14418 && capp.pid != MY_PID) { 14419 capp.kill("depends on provider " 14420 + cpr.name.flattenToShortString() 14421 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14422 } 14423 } else if (capp.thread != null && conn.provider.provider != null) { 14424 try { 14425 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14426 } catch (RemoteException e) { 14427 } 14428 // In the protocol here, we don't expect the client to correctly 14429 // clean up this connection, we'll just remove it. 14430 cpr.connections.remove(i); 14431 conn.client.conProviders.remove(conn); 14432 } 14433 } 14434 14435 if (inLaunching && always) { 14436 mLaunchingProviders.remove(cpr); 14437 } 14438 return inLaunching; 14439 } 14440 14441 /** 14442 * Main code for cleaning up a process when it has gone away. This is 14443 * called both as a result of the process dying, or directly when stopping 14444 * a process when running in single process mode. 14445 * 14446 * @return Returns true if the given process has been restarted, so the 14447 * app that was passed in must remain on the process lists. 14448 */ 14449 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14450 boolean restarting, boolean allowRestart, int index) { 14451 if (index >= 0) { 14452 removeLruProcessLocked(app); 14453 ProcessList.remove(app.pid); 14454 } 14455 14456 mProcessesToGc.remove(app); 14457 mPendingPssProcesses.remove(app); 14458 14459 // Dismiss any open dialogs. 14460 if (app.crashDialog != null && !app.forceCrashReport) { 14461 app.crashDialog.dismiss(); 14462 app.crashDialog = null; 14463 } 14464 if (app.anrDialog != null) { 14465 app.anrDialog.dismiss(); 14466 app.anrDialog = null; 14467 } 14468 if (app.waitDialog != null) { 14469 app.waitDialog.dismiss(); 14470 app.waitDialog = null; 14471 } 14472 14473 app.crashing = false; 14474 app.notResponding = false; 14475 14476 app.resetPackageList(mProcessStats); 14477 app.unlinkDeathRecipient(); 14478 app.makeInactive(mProcessStats); 14479 app.waitingToKill = null; 14480 app.forcingToForeground = null; 14481 updateProcessForegroundLocked(app, false, false); 14482 app.foregroundActivities = false; 14483 app.hasShownUi = false; 14484 app.treatLikeActivity = false; 14485 app.hasAboveClient = false; 14486 app.hasClientActivities = false; 14487 14488 mServices.killServicesLocked(app, allowRestart); 14489 14490 boolean restart = false; 14491 14492 // Remove published content providers. 14493 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14494 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14495 final boolean always = app.bad || !allowRestart; 14496 if (removeDyingProviderLocked(app, cpr, always) || always) { 14497 // We left the provider in the launching list, need to 14498 // restart it. 14499 restart = true; 14500 } 14501 14502 cpr.provider = null; 14503 cpr.proc = null; 14504 } 14505 app.pubProviders.clear(); 14506 14507 // Take care of any launching providers waiting for this process. 14508 if (checkAppInLaunchingProvidersLocked(app, false)) { 14509 restart = true; 14510 } 14511 14512 // Unregister from connected content providers. 14513 if (!app.conProviders.isEmpty()) { 14514 for (int i=0; i<app.conProviders.size(); i++) { 14515 ContentProviderConnection conn = app.conProviders.get(i); 14516 conn.provider.connections.remove(conn); 14517 } 14518 app.conProviders.clear(); 14519 } 14520 14521 // At this point there may be remaining entries in mLaunchingProviders 14522 // where we were the only one waiting, so they are no longer of use. 14523 // Look for these and clean up if found. 14524 // XXX Commented out for now. Trying to figure out a way to reproduce 14525 // the actual situation to identify what is actually going on. 14526 if (false) { 14527 for (int i=0; i<mLaunchingProviders.size(); i++) { 14528 ContentProviderRecord cpr = (ContentProviderRecord) 14529 mLaunchingProviders.get(i); 14530 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14531 synchronized (cpr) { 14532 cpr.launchingApp = null; 14533 cpr.notifyAll(); 14534 } 14535 } 14536 } 14537 } 14538 14539 skipCurrentReceiverLocked(app); 14540 14541 // Unregister any receivers. 14542 for (int i=app.receivers.size()-1; i>=0; i--) { 14543 removeReceiverLocked(app.receivers.valueAt(i)); 14544 } 14545 app.receivers.clear(); 14546 14547 // If the app is undergoing backup, tell the backup manager about it 14548 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14549 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14550 + mBackupTarget.appInfo + " died during backup"); 14551 try { 14552 IBackupManager bm = IBackupManager.Stub.asInterface( 14553 ServiceManager.getService(Context.BACKUP_SERVICE)); 14554 bm.agentDisconnected(app.info.packageName); 14555 } catch (RemoteException e) { 14556 // can't happen; backup manager is local 14557 } 14558 } 14559 14560 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14561 ProcessChangeItem item = mPendingProcessChanges.get(i); 14562 if (item.pid == app.pid) { 14563 mPendingProcessChanges.remove(i); 14564 mAvailProcessChanges.add(item); 14565 } 14566 } 14567 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14568 14569 // If the caller is restarting this app, then leave it in its 14570 // current lists and let the caller take care of it. 14571 if (restarting) { 14572 return false; 14573 } 14574 14575 if (!app.persistent || app.isolated) { 14576 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14577 "Removing non-persistent process during cleanup: " + app); 14578 mProcessNames.remove(app.processName, app.uid); 14579 mIsolatedProcesses.remove(app.uid); 14580 if (mHeavyWeightProcess == app) { 14581 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14582 mHeavyWeightProcess.userId, 0)); 14583 mHeavyWeightProcess = null; 14584 } 14585 } else if (!app.removed) { 14586 // This app is persistent, so we need to keep its record around. 14587 // If it is not already on the pending app list, add it there 14588 // and start a new process for it. 14589 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14590 mPersistentStartingProcesses.add(app); 14591 restart = true; 14592 } 14593 } 14594 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14595 "Clean-up removing on hold: " + app); 14596 mProcessesOnHold.remove(app); 14597 14598 if (app == mHomeProcess) { 14599 mHomeProcess = null; 14600 } 14601 if (app == mPreviousProcess) { 14602 mPreviousProcess = null; 14603 } 14604 14605 if (restart && !app.isolated) { 14606 // We have components that still need to be running in the 14607 // process, so re-launch it. 14608 if (index < 0) { 14609 ProcessList.remove(app.pid); 14610 } 14611 mProcessNames.put(app.processName, app.uid, app); 14612 startProcessLocked(app, "restart", app.processName); 14613 return true; 14614 } else if (app.pid > 0 && app.pid != MY_PID) { 14615 // Goodbye! 14616 boolean removed; 14617 synchronized (mPidsSelfLocked) { 14618 mPidsSelfLocked.remove(app.pid); 14619 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14620 } 14621 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14622 if (app.isolated) { 14623 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14624 } 14625 app.setPid(0); 14626 } 14627 return false; 14628 } 14629 14630 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14631 // Look through the content providers we are waiting to have launched, 14632 // and if any run in this process then either schedule a restart of 14633 // the process or kill the client waiting for it if this process has 14634 // gone bad. 14635 int NL = mLaunchingProviders.size(); 14636 boolean restart = false; 14637 for (int i=0; i<NL; i++) { 14638 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14639 if (cpr.launchingApp == app) { 14640 if (!alwaysBad && !app.bad) { 14641 restart = true; 14642 } else { 14643 removeDyingProviderLocked(app, cpr, true); 14644 // cpr should have been removed from mLaunchingProviders 14645 NL = mLaunchingProviders.size(); 14646 i--; 14647 } 14648 } 14649 } 14650 return restart; 14651 } 14652 14653 // ========================================================= 14654 // SERVICES 14655 // ========================================================= 14656 14657 @Override 14658 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14659 int flags) { 14660 enforceNotIsolatedCaller("getServices"); 14661 synchronized (this) { 14662 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14663 } 14664 } 14665 14666 @Override 14667 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14668 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14669 synchronized (this) { 14670 return mServices.getRunningServiceControlPanelLocked(name); 14671 } 14672 } 14673 14674 @Override 14675 public ComponentName startService(IApplicationThread caller, Intent service, 14676 String resolvedType, int userId) { 14677 enforceNotIsolatedCaller("startService"); 14678 // Refuse possible leaked file descriptors 14679 if (service != null && service.hasFileDescriptors() == true) { 14680 throw new IllegalArgumentException("File descriptors passed in Intent"); 14681 } 14682 14683 if (DEBUG_SERVICE) 14684 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14685 synchronized(this) { 14686 final int callingPid = Binder.getCallingPid(); 14687 final int callingUid = Binder.getCallingUid(); 14688 final long origId = Binder.clearCallingIdentity(); 14689 ComponentName res = mServices.startServiceLocked(caller, service, 14690 resolvedType, callingPid, callingUid, userId); 14691 Binder.restoreCallingIdentity(origId); 14692 return res; 14693 } 14694 } 14695 14696 ComponentName startServiceInPackage(int uid, 14697 Intent service, String resolvedType, int userId) { 14698 synchronized(this) { 14699 if (DEBUG_SERVICE) 14700 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14701 final long origId = Binder.clearCallingIdentity(); 14702 ComponentName res = mServices.startServiceLocked(null, service, 14703 resolvedType, -1, uid, userId); 14704 Binder.restoreCallingIdentity(origId); 14705 return res; 14706 } 14707 } 14708 14709 @Override 14710 public int stopService(IApplicationThread caller, Intent service, 14711 String resolvedType, int userId) { 14712 enforceNotIsolatedCaller("stopService"); 14713 // Refuse possible leaked file descriptors 14714 if (service != null && service.hasFileDescriptors() == true) { 14715 throw new IllegalArgumentException("File descriptors passed in Intent"); 14716 } 14717 14718 synchronized(this) { 14719 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14720 } 14721 } 14722 14723 @Override 14724 public IBinder peekService(Intent service, String resolvedType) { 14725 enforceNotIsolatedCaller("peekService"); 14726 // Refuse possible leaked file descriptors 14727 if (service != null && service.hasFileDescriptors() == true) { 14728 throw new IllegalArgumentException("File descriptors passed in Intent"); 14729 } 14730 synchronized(this) { 14731 return mServices.peekServiceLocked(service, resolvedType); 14732 } 14733 } 14734 14735 @Override 14736 public boolean stopServiceToken(ComponentName className, IBinder token, 14737 int startId) { 14738 synchronized(this) { 14739 return mServices.stopServiceTokenLocked(className, token, startId); 14740 } 14741 } 14742 14743 @Override 14744 public void setServiceForeground(ComponentName className, IBinder token, 14745 int id, Notification notification, boolean removeNotification) { 14746 synchronized(this) { 14747 mServices.setServiceForegroundLocked(className, token, id, notification, 14748 removeNotification); 14749 } 14750 } 14751 14752 @Override 14753 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14754 boolean requireFull, String name, String callerPackage) { 14755 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14756 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14757 } 14758 14759 int unsafeConvertIncomingUser(int userId) { 14760 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14761 ? mCurrentUserId : userId; 14762 } 14763 14764 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14765 int allowMode, String name, String callerPackage) { 14766 final int callingUserId = UserHandle.getUserId(callingUid); 14767 if (callingUserId == userId) { 14768 return userId; 14769 } 14770 14771 // Note that we may be accessing mCurrentUserId outside of a lock... 14772 // shouldn't be a big deal, if this is being called outside 14773 // of a locked context there is intrinsically a race with 14774 // the value the caller will receive and someone else changing it. 14775 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14776 // we will switch to the calling user if access to the current user fails. 14777 int targetUserId = unsafeConvertIncomingUser(userId); 14778 14779 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14780 final boolean allow; 14781 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14782 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14783 // If the caller has this permission, they always pass go. And collect $200. 14784 allow = true; 14785 } else if (allowMode == ALLOW_FULL_ONLY) { 14786 // We require full access, sucks to be you. 14787 allow = false; 14788 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14789 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14790 // If the caller does not have either permission, they are always doomed. 14791 allow = false; 14792 } else if (allowMode == ALLOW_NON_FULL) { 14793 // We are blanket allowing non-full access, you lucky caller! 14794 allow = true; 14795 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14796 // We may or may not allow this depending on whether the two users are 14797 // in the same profile. 14798 synchronized (mUserProfileGroupIdsSelfLocked) { 14799 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14800 UserInfo.NO_PROFILE_GROUP_ID); 14801 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14802 UserInfo.NO_PROFILE_GROUP_ID); 14803 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14804 && callingProfile == targetProfile; 14805 } 14806 } else { 14807 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14808 } 14809 if (!allow) { 14810 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14811 // In this case, they would like to just execute as their 14812 // owner user instead of failing. 14813 targetUserId = callingUserId; 14814 } else { 14815 StringBuilder builder = new StringBuilder(128); 14816 builder.append("Permission Denial: "); 14817 builder.append(name); 14818 if (callerPackage != null) { 14819 builder.append(" from "); 14820 builder.append(callerPackage); 14821 } 14822 builder.append(" asks to run as user "); 14823 builder.append(userId); 14824 builder.append(" but is calling from user "); 14825 builder.append(UserHandle.getUserId(callingUid)); 14826 builder.append("; this requires "); 14827 builder.append(INTERACT_ACROSS_USERS_FULL); 14828 if (allowMode != ALLOW_FULL_ONLY) { 14829 builder.append(" or "); 14830 builder.append(INTERACT_ACROSS_USERS); 14831 } 14832 String msg = builder.toString(); 14833 Slog.w(TAG, msg); 14834 throw new SecurityException(msg); 14835 } 14836 } 14837 } 14838 if (!allowAll && targetUserId < 0) { 14839 throw new IllegalArgumentException( 14840 "Call does not support special user #" + targetUserId); 14841 } 14842 // Check shell permission 14843 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14844 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14845 targetUserId)) { 14846 throw new SecurityException("Shell does not have permission to access user " 14847 + targetUserId + "\n " + Debug.getCallers(3)); 14848 } 14849 } 14850 return targetUserId; 14851 } 14852 14853 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14854 String className, int flags) { 14855 boolean result = false; 14856 // For apps that don't have pre-defined UIDs, check for permission 14857 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14858 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14859 if (ActivityManager.checkUidPermission( 14860 INTERACT_ACROSS_USERS, 14861 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14862 ComponentName comp = new ComponentName(aInfo.packageName, className); 14863 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14864 + " requests FLAG_SINGLE_USER, but app does not hold " 14865 + INTERACT_ACROSS_USERS; 14866 Slog.w(TAG, msg); 14867 throw new SecurityException(msg); 14868 } 14869 // Permission passed 14870 result = true; 14871 } 14872 } else if ("system".equals(componentProcessName)) { 14873 result = true; 14874 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14875 // Phone app and persistent apps are allowed to export singleuser providers. 14876 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14877 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14878 } 14879 if (DEBUG_MU) { 14880 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14881 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14882 } 14883 return result; 14884 } 14885 14886 /** 14887 * Checks to see if the caller is in the same app as the singleton 14888 * component, or the component is in a special app. It allows special apps 14889 * to export singleton components but prevents exporting singleton 14890 * components for regular apps. 14891 */ 14892 boolean isValidSingletonCall(int callingUid, int componentUid) { 14893 int componentAppId = UserHandle.getAppId(componentUid); 14894 return UserHandle.isSameApp(callingUid, componentUid) 14895 || componentAppId == Process.SYSTEM_UID 14896 || componentAppId == Process.PHONE_UID 14897 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14898 == PackageManager.PERMISSION_GRANTED; 14899 } 14900 14901 public int bindService(IApplicationThread caller, IBinder token, 14902 Intent service, String resolvedType, 14903 IServiceConnection connection, int flags, int userId) { 14904 enforceNotIsolatedCaller("bindService"); 14905 14906 // Refuse possible leaked file descriptors 14907 if (service != null && service.hasFileDescriptors() == true) { 14908 throw new IllegalArgumentException("File descriptors passed in Intent"); 14909 } 14910 14911 synchronized(this) { 14912 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14913 connection, flags, userId); 14914 } 14915 } 14916 14917 public boolean unbindService(IServiceConnection connection) { 14918 synchronized (this) { 14919 return mServices.unbindServiceLocked(connection); 14920 } 14921 } 14922 14923 public void publishService(IBinder token, Intent intent, IBinder service) { 14924 // Refuse possible leaked file descriptors 14925 if (intent != null && intent.hasFileDescriptors() == true) { 14926 throw new IllegalArgumentException("File descriptors passed in Intent"); 14927 } 14928 14929 synchronized(this) { 14930 if (!(token instanceof ServiceRecord)) { 14931 throw new IllegalArgumentException("Invalid service token"); 14932 } 14933 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14934 } 14935 } 14936 14937 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14938 // Refuse possible leaked file descriptors 14939 if (intent != null && intent.hasFileDescriptors() == true) { 14940 throw new IllegalArgumentException("File descriptors passed in Intent"); 14941 } 14942 14943 synchronized(this) { 14944 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14945 } 14946 } 14947 14948 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14949 synchronized(this) { 14950 if (!(token instanceof ServiceRecord)) { 14951 throw new IllegalArgumentException("Invalid service token"); 14952 } 14953 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14954 } 14955 } 14956 14957 // ========================================================= 14958 // BACKUP AND RESTORE 14959 // ========================================================= 14960 14961 // Cause the target app to be launched if necessary and its backup agent 14962 // instantiated. The backup agent will invoke backupAgentCreated() on the 14963 // activity manager to announce its creation. 14964 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14965 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14966 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14967 14968 synchronized(this) { 14969 // !!! TODO: currently no check here that we're already bound 14970 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14971 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14972 synchronized (stats) { 14973 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14974 } 14975 14976 // Backup agent is now in use, its package can't be stopped. 14977 try { 14978 AppGlobals.getPackageManager().setPackageStoppedState( 14979 app.packageName, false, UserHandle.getUserId(app.uid)); 14980 } catch (RemoteException e) { 14981 } catch (IllegalArgumentException e) { 14982 Slog.w(TAG, "Failed trying to unstop package " 14983 + app.packageName + ": " + e); 14984 } 14985 14986 BackupRecord r = new BackupRecord(ss, app, backupMode); 14987 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14988 ? new ComponentName(app.packageName, app.backupAgentName) 14989 : new ComponentName("android", "FullBackupAgent"); 14990 // startProcessLocked() returns existing proc's record if it's already running 14991 ProcessRecord proc = startProcessLocked(app.processName, app, 14992 false, 0, "backup", hostingName, false, false, false); 14993 if (proc == null) { 14994 Slog.e(TAG, "Unable to start backup agent process " + r); 14995 return false; 14996 } 14997 14998 r.app = proc; 14999 mBackupTarget = r; 15000 mBackupAppName = app.packageName; 15001 15002 // Try not to kill the process during backup 15003 updateOomAdjLocked(proc); 15004 15005 // If the process is already attached, schedule the creation of the backup agent now. 15006 // If it is not yet live, this will be done when it attaches to the framework. 15007 if (proc.thread != null) { 15008 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15009 try { 15010 proc.thread.scheduleCreateBackupAgent(app, 15011 compatibilityInfoForPackageLocked(app), backupMode); 15012 } catch (RemoteException e) { 15013 // Will time out on the backup manager side 15014 } 15015 } else { 15016 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15017 } 15018 // Invariants: at this point, the target app process exists and the application 15019 // is either already running or in the process of coming up. mBackupTarget and 15020 // mBackupAppName describe the app, so that when it binds back to the AM we 15021 // know that it's scheduled for a backup-agent operation. 15022 } 15023 15024 return true; 15025 } 15026 15027 @Override 15028 public void clearPendingBackup() { 15029 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15030 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15031 15032 synchronized (this) { 15033 mBackupTarget = null; 15034 mBackupAppName = null; 15035 } 15036 } 15037 15038 // A backup agent has just come up 15039 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15040 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15041 + " = " + agent); 15042 15043 synchronized(this) { 15044 if (!agentPackageName.equals(mBackupAppName)) { 15045 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15046 return; 15047 } 15048 } 15049 15050 long oldIdent = Binder.clearCallingIdentity(); 15051 try { 15052 IBackupManager bm = IBackupManager.Stub.asInterface( 15053 ServiceManager.getService(Context.BACKUP_SERVICE)); 15054 bm.agentConnected(agentPackageName, agent); 15055 } catch (RemoteException e) { 15056 // can't happen; the backup manager service is local 15057 } catch (Exception e) { 15058 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15059 e.printStackTrace(); 15060 } finally { 15061 Binder.restoreCallingIdentity(oldIdent); 15062 } 15063 } 15064 15065 // done with this agent 15066 public void unbindBackupAgent(ApplicationInfo appInfo) { 15067 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15068 if (appInfo == null) { 15069 Slog.w(TAG, "unbind backup agent for null app"); 15070 return; 15071 } 15072 15073 synchronized(this) { 15074 try { 15075 if (mBackupAppName == null) { 15076 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15077 return; 15078 } 15079 15080 if (!mBackupAppName.equals(appInfo.packageName)) { 15081 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15082 return; 15083 } 15084 15085 // Not backing this app up any more; reset its OOM adjustment 15086 final ProcessRecord proc = mBackupTarget.app; 15087 updateOomAdjLocked(proc); 15088 15089 // If the app crashed during backup, 'thread' will be null here 15090 if (proc.thread != null) { 15091 try { 15092 proc.thread.scheduleDestroyBackupAgent(appInfo, 15093 compatibilityInfoForPackageLocked(appInfo)); 15094 } catch (Exception e) { 15095 Slog.e(TAG, "Exception when unbinding backup agent:"); 15096 e.printStackTrace(); 15097 } 15098 } 15099 } finally { 15100 mBackupTarget = null; 15101 mBackupAppName = null; 15102 } 15103 } 15104 } 15105 // ========================================================= 15106 // BROADCASTS 15107 // ========================================================= 15108 15109 private final List getStickiesLocked(String action, IntentFilter filter, 15110 List cur, int userId) { 15111 final ContentResolver resolver = mContext.getContentResolver(); 15112 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15113 if (stickies == null) { 15114 return cur; 15115 } 15116 final ArrayList<Intent> list = stickies.get(action); 15117 if (list == null) { 15118 return cur; 15119 } 15120 int N = list.size(); 15121 for (int i=0; i<N; i++) { 15122 Intent intent = list.get(i); 15123 if (filter.match(resolver, intent, true, TAG) >= 0) { 15124 if (cur == null) { 15125 cur = new ArrayList<Intent>(); 15126 } 15127 cur.add(intent); 15128 } 15129 } 15130 return cur; 15131 } 15132 15133 boolean isPendingBroadcastProcessLocked(int pid) { 15134 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15135 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15136 } 15137 15138 void skipPendingBroadcastLocked(int pid) { 15139 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15140 for (BroadcastQueue queue : mBroadcastQueues) { 15141 queue.skipPendingBroadcastLocked(pid); 15142 } 15143 } 15144 15145 // The app just attached; send any pending broadcasts that it should receive 15146 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15147 boolean didSomething = false; 15148 for (BroadcastQueue queue : mBroadcastQueues) { 15149 didSomething |= queue.sendPendingBroadcastsLocked(app); 15150 } 15151 return didSomething; 15152 } 15153 15154 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15155 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15156 enforceNotIsolatedCaller("registerReceiver"); 15157 int callingUid; 15158 int callingPid; 15159 synchronized(this) { 15160 ProcessRecord callerApp = null; 15161 if (caller != null) { 15162 callerApp = getRecordForAppLocked(caller); 15163 if (callerApp == null) { 15164 throw new SecurityException( 15165 "Unable to find app for caller " + caller 15166 + " (pid=" + Binder.getCallingPid() 15167 + ") when registering receiver " + receiver); 15168 } 15169 if (callerApp.info.uid != Process.SYSTEM_UID && 15170 !callerApp.pkgList.containsKey(callerPackage) && 15171 !"android".equals(callerPackage)) { 15172 throw new SecurityException("Given caller package " + callerPackage 15173 + " is not running in process " + callerApp); 15174 } 15175 callingUid = callerApp.info.uid; 15176 callingPid = callerApp.pid; 15177 } else { 15178 callerPackage = null; 15179 callingUid = Binder.getCallingUid(); 15180 callingPid = Binder.getCallingPid(); 15181 } 15182 15183 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15184 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15185 15186 List allSticky = null; 15187 15188 // Look for any matching sticky broadcasts... 15189 Iterator actions = filter.actionsIterator(); 15190 if (actions != null) { 15191 while (actions.hasNext()) { 15192 String action = (String)actions.next(); 15193 allSticky = getStickiesLocked(action, filter, allSticky, 15194 UserHandle.USER_ALL); 15195 allSticky = getStickiesLocked(action, filter, allSticky, 15196 UserHandle.getUserId(callingUid)); 15197 } 15198 } else { 15199 allSticky = getStickiesLocked(null, filter, allSticky, 15200 UserHandle.USER_ALL); 15201 allSticky = getStickiesLocked(null, filter, allSticky, 15202 UserHandle.getUserId(callingUid)); 15203 } 15204 15205 // The first sticky in the list is returned directly back to 15206 // the client. 15207 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15208 15209 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15210 + ": " + sticky); 15211 15212 if (receiver == null) { 15213 return sticky; 15214 } 15215 15216 ReceiverList rl 15217 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15218 if (rl == null) { 15219 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15220 userId, receiver); 15221 if (rl.app != null) { 15222 rl.app.receivers.add(rl); 15223 } else { 15224 try { 15225 receiver.asBinder().linkToDeath(rl, 0); 15226 } catch (RemoteException e) { 15227 return sticky; 15228 } 15229 rl.linkedToDeath = true; 15230 } 15231 mRegisteredReceivers.put(receiver.asBinder(), rl); 15232 } else if (rl.uid != callingUid) { 15233 throw new IllegalArgumentException( 15234 "Receiver requested to register for uid " + callingUid 15235 + " was previously registered for uid " + rl.uid); 15236 } else if (rl.pid != callingPid) { 15237 throw new IllegalArgumentException( 15238 "Receiver requested to register for pid " + callingPid 15239 + " was previously registered for pid " + rl.pid); 15240 } else if (rl.userId != userId) { 15241 throw new IllegalArgumentException( 15242 "Receiver requested to register for user " + userId 15243 + " was previously registered for user " + rl.userId); 15244 } 15245 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15246 permission, callingUid, userId); 15247 rl.add(bf); 15248 if (!bf.debugCheck()) { 15249 Slog.w(TAG, "==> For Dynamic broadast"); 15250 } 15251 mReceiverResolver.addFilter(bf); 15252 15253 // Enqueue broadcasts for all existing stickies that match 15254 // this filter. 15255 if (allSticky != null) { 15256 ArrayList receivers = new ArrayList(); 15257 receivers.add(bf); 15258 15259 int N = allSticky.size(); 15260 for (int i=0; i<N; i++) { 15261 Intent intent = (Intent)allSticky.get(i); 15262 BroadcastQueue queue = broadcastQueueForIntent(intent); 15263 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15264 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15265 null, null, false, true, true, -1); 15266 queue.enqueueParallelBroadcastLocked(r); 15267 queue.scheduleBroadcastsLocked(); 15268 } 15269 } 15270 15271 return sticky; 15272 } 15273 } 15274 15275 public void unregisterReceiver(IIntentReceiver receiver) { 15276 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15277 15278 final long origId = Binder.clearCallingIdentity(); 15279 try { 15280 boolean doTrim = false; 15281 15282 synchronized(this) { 15283 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15284 if (rl != null) { 15285 if (rl.curBroadcast != null) { 15286 BroadcastRecord r = rl.curBroadcast; 15287 final boolean doNext = finishReceiverLocked( 15288 receiver.asBinder(), r.resultCode, r.resultData, 15289 r.resultExtras, r.resultAbort); 15290 if (doNext) { 15291 doTrim = true; 15292 r.queue.processNextBroadcast(false); 15293 } 15294 } 15295 15296 if (rl.app != null) { 15297 rl.app.receivers.remove(rl); 15298 } 15299 removeReceiverLocked(rl); 15300 if (rl.linkedToDeath) { 15301 rl.linkedToDeath = false; 15302 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15303 } 15304 } 15305 } 15306 15307 // If we actually concluded any broadcasts, we might now be able 15308 // to trim the recipients' apps from our working set 15309 if (doTrim) { 15310 trimApplications(); 15311 return; 15312 } 15313 15314 } finally { 15315 Binder.restoreCallingIdentity(origId); 15316 } 15317 } 15318 15319 void removeReceiverLocked(ReceiverList rl) { 15320 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15321 int N = rl.size(); 15322 for (int i=0; i<N; i++) { 15323 mReceiverResolver.removeFilter(rl.get(i)); 15324 } 15325 } 15326 15327 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15328 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15329 ProcessRecord r = mLruProcesses.get(i); 15330 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15331 try { 15332 r.thread.dispatchPackageBroadcast(cmd, packages); 15333 } catch (RemoteException ex) { 15334 } 15335 } 15336 } 15337 } 15338 15339 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15340 int callingUid, int[] users) { 15341 List<ResolveInfo> receivers = null; 15342 try { 15343 HashSet<ComponentName> singleUserReceivers = null; 15344 boolean scannedFirstReceivers = false; 15345 for (int user : users) { 15346 // Skip users that have Shell restrictions 15347 if (callingUid == Process.SHELL_UID 15348 && getUserManagerLocked().hasUserRestriction( 15349 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15350 continue; 15351 } 15352 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15353 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15354 if (user != 0 && newReceivers != null) { 15355 // If this is not the primary user, we need to check for 15356 // any receivers that should be filtered out. 15357 for (int i=0; i<newReceivers.size(); i++) { 15358 ResolveInfo ri = newReceivers.get(i); 15359 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15360 newReceivers.remove(i); 15361 i--; 15362 } 15363 } 15364 } 15365 if (newReceivers != null && newReceivers.size() == 0) { 15366 newReceivers = null; 15367 } 15368 if (receivers == null) { 15369 receivers = newReceivers; 15370 } else if (newReceivers != null) { 15371 // We need to concatenate the additional receivers 15372 // found with what we have do far. This would be easy, 15373 // but we also need to de-dup any receivers that are 15374 // singleUser. 15375 if (!scannedFirstReceivers) { 15376 // Collect any single user receivers we had already retrieved. 15377 scannedFirstReceivers = true; 15378 for (int i=0; i<receivers.size(); i++) { 15379 ResolveInfo ri = receivers.get(i); 15380 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15381 ComponentName cn = new ComponentName( 15382 ri.activityInfo.packageName, ri.activityInfo.name); 15383 if (singleUserReceivers == null) { 15384 singleUserReceivers = new HashSet<ComponentName>(); 15385 } 15386 singleUserReceivers.add(cn); 15387 } 15388 } 15389 } 15390 // Add the new results to the existing results, tracking 15391 // and de-dupping single user receivers. 15392 for (int i=0; i<newReceivers.size(); i++) { 15393 ResolveInfo ri = newReceivers.get(i); 15394 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15395 ComponentName cn = new ComponentName( 15396 ri.activityInfo.packageName, ri.activityInfo.name); 15397 if (singleUserReceivers == null) { 15398 singleUserReceivers = new HashSet<ComponentName>(); 15399 } 15400 if (!singleUserReceivers.contains(cn)) { 15401 singleUserReceivers.add(cn); 15402 receivers.add(ri); 15403 } 15404 } else { 15405 receivers.add(ri); 15406 } 15407 } 15408 } 15409 } 15410 } catch (RemoteException ex) { 15411 // pm is in same process, this will never happen. 15412 } 15413 return receivers; 15414 } 15415 15416 private final int broadcastIntentLocked(ProcessRecord callerApp, 15417 String callerPackage, Intent intent, String resolvedType, 15418 IIntentReceiver resultTo, int resultCode, String resultData, 15419 Bundle map, String requiredPermission, int appOp, 15420 boolean ordered, boolean sticky, int callingPid, int callingUid, 15421 int userId) { 15422 intent = new Intent(intent); 15423 15424 // By default broadcasts do not go to stopped apps. 15425 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15426 15427 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15428 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15429 + " ordered=" + ordered + " userid=" + userId); 15430 if ((resultTo != null) && !ordered) { 15431 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15432 } 15433 15434 userId = handleIncomingUser(callingPid, callingUid, userId, 15435 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15436 15437 // Make sure that the user who is receiving this broadcast is started. 15438 // If not, we will just skip it. 15439 15440 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15441 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15442 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15443 Slog.w(TAG, "Skipping broadcast of " + intent 15444 + ": user " + userId + " is stopped"); 15445 return ActivityManager.BROADCAST_SUCCESS; 15446 } 15447 } 15448 15449 /* 15450 * Prevent non-system code (defined here to be non-persistent 15451 * processes) from sending protected broadcasts. 15452 */ 15453 int callingAppId = UserHandle.getAppId(callingUid); 15454 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15455 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15456 || callingAppId == Process.NFC_UID || callingUid == 0) { 15457 // Always okay. 15458 } else if (callerApp == null || !callerApp.persistent) { 15459 try { 15460 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15461 intent.getAction())) { 15462 String msg = "Permission Denial: not allowed to send broadcast " 15463 + intent.getAction() + " from pid=" 15464 + callingPid + ", uid=" + callingUid; 15465 Slog.w(TAG, msg); 15466 throw new SecurityException(msg); 15467 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15468 // Special case for compatibility: we don't want apps to send this, 15469 // but historically it has not been protected and apps may be using it 15470 // to poke their own app widget. So, instead of making it protected, 15471 // just limit it to the caller. 15472 if (callerApp == null) { 15473 String msg = "Permission Denial: not allowed to send broadcast " 15474 + intent.getAction() + " from unknown caller."; 15475 Slog.w(TAG, msg); 15476 throw new SecurityException(msg); 15477 } else if (intent.getComponent() != null) { 15478 // They are good enough to send to an explicit component... verify 15479 // it is being sent to the calling app. 15480 if (!intent.getComponent().getPackageName().equals( 15481 callerApp.info.packageName)) { 15482 String msg = "Permission Denial: not allowed to send broadcast " 15483 + intent.getAction() + " to " 15484 + intent.getComponent().getPackageName() + " from " 15485 + callerApp.info.packageName; 15486 Slog.w(TAG, msg); 15487 throw new SecurityException(msg); 15488 } 15489 } else { 15490 // Limit broadcast to their own package. 15491 intent.setPackage(callerApp.info.packageName); 15492 } 15493 } 15494 } catch (RemoteException e) { 15495 Slog.w(TAG, "Remote exception", e); 15496 return ActivityManager.BROADCAST_SUCCESS; 15497 } 15498 } 15499 15500 // Handle special intents: if this broadcast is from the package 15501 // manager about a package being removed, we need to remove all of 15502 // its activities from the history stack. 15503 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15504 intent.getAction()); 15505 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15506 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15507 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15508 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15509 || uidRemoved) { 15510 if (checkComponentPermission( 15511 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15512 callingPid, callingUid, -1, true) 15513 == PackageManager.PERMISSION_GRANTED) { 15514 if (uidRemoved) { 15515 final Bundle intentExtras = intent.getExtras(); 15516 final int uid = intentExtras != null 15517 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15518 if (uid >= 0) { 15519 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15520 synchronized (bs) { 15521 bs.removeUidStatsLocked(uid); 15522 } 15523 mAppOpsService.uidRemoved(uid); 15524 } 15525 } else { 15526 // If resources are unavailable just force stop all 15527 // those packages and flush the attribute cache as well. 15528 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15529 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15530 if (list != null && (list.length > 0)) { 15531 for (String pkg : list) { 15532 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15533 "storage unmount"); 15534 } 15535 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15536 sendPackageBroadcastLocked( 15537 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15538 } 15539 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15540 intent.getAction())) { 15541 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15542 } else { 15543 Uri data = intent.getData(); 15544 String ssp; 15545 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15546 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15547 intent.getAction()); 15548 boolean fullUninstall = removed && 15549 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15550 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15551 forceStopPackageLocked(ssp, UserHandle.getAppId( 15552 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15553 false, fullUninstall, userId, 15554 removed ? "pkg removed" : "pkg changed"); 15555 } 15556 if (removed) { 15557 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15558 new String[] {ssp}, userId); 15559 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15560 mAppOpsService.packageRemoved( 15561 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15562 15563 // Remove all permissions granted from/to this package 15564 removeUriPermissionsForPackageLocked(ssp, userId, true); 15565 } 15566 } 15567 } 15568 } 15569 } 15570 } else { 15571 String msg = "Permission Denial: " + intent.getAction() 15572 + " broadcast from " + callerPackage + " (pid=" + callingPid 15573 + ", uid=" + callingUid + ")" 15574 + " requires " 15575 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15576 Slog.w(TAG, msg); 15577 throw new SecurityException(msg); 15578 } 15579 15580 // Special case for adding a package: by default turn on compatibility 15581 // mode. 15582 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15583 Uri data = intent.getData(); 15584 String ssp; 15585 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15586 mCompatModePackages.handlePackageAddedLocked(ssp, 15587 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15588 } 15589 } 15590 15591 /* 15592 * If this is the time zone changed action, queue up a message that will reset the timezone 15593 * of all currently running processes. This message will get queued up before the broadcast 15594 * happens. 15595 */ 15596 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15597 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15598 } 15599 15600 /* 15601 * If the user set the time, let all running processes know. 15602 */ 15603 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15604 final int is24Hour = intent.getBooleanExtra( 15605 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15606 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15607 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15608 synchronized (stats) { 15609 stats.noteCurrentTimeChangedLocked(); 15610 } 15611 } 15612 15613 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15614 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15615 } 15616 15617 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15618 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15619 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15620 } 15621 15622 // Add to the sticky list if requested. 15623 if (sticky) { 15624 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15625 callingPid, callingUid) 15626 != PackageManager.PERMISSION_GRANTED) { 15627 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15628 + callingPid + ", uid=" + callingUid 15629 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15630 Slog.w(TAG, msg); 15631 throw new SecurityException(msg); 15632 } 15633 if (requiredPermission != null) { 15634 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15635 + " and enforce permission " + requiredPermission); 15636 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15637 } 15638 if (intent.getComponent() != null) { 15639 throw new SecurityException( 15640 "Sticky broadcasts can't target a specific component"); 15641 } 15642 // We use userId directly here, since the "all" target is maintained 15643 // as a separate set of sticky broadcasts. 15644 if (userId != UserHandle.USER_ALL) { 15645 // But first, if this is not a broadcast to all users, then 15646 // make sure it doesn't conflict with an existing broadcast to 15647 // all users. 15648 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15649 UserHandle.USER_ALL); 15650 if (stickies != null) { 15651 ArrayList<Intent> list = stickies.get(intent.getAction()); 15652 if (list != null) { 15653 int N = list.size(); 15654 int i; 15655 for (i=0; i<N; i++) { 15656 if (intent.filterEquals(list.get(i))) { 15657 throw new IllegalArgumentException( 15658 "Sticky broadcast " + intent + " for user " 15659 + userId + " conflicts with existing global broadcast"); 15660 } 15661 } 15662 } 15663 } 15664 } 15665 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15666 if (stickies == null) { 15667 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15668 mStickyBroadcasts.put(userId, stickies); 15669 } 15670 ArrayList<Intent> list = stickies.get(intent.getAction()); 15671 if (list == null) { 15672 list = new ArrayList<Intent>(); 15673 stickies.put(intent.getAction(), list); 15674 } 15675 int N = list.size(); 15676 int i; 15677 for (i=0; i<N; i++) { 15678 if (intent.filterEquals(list.get(i))) { 15679 // This sticky already exists, replace it. 15680 list.set(i, new Intent(intent)); 15681 break; 15682 } 15683 } 15684 if (i >= N) { 15685 list.add(new Intent(intent)); 15686 } 15687 } 15688 15689 int[] users; 15690 if (userId == UserHandle.USER_ALL) { 15691 // Caller wants broadcast to go to all started users. 15692 users = mStartedUserArray; 15693 } else { 15694 // Caller wants broadcast to go to one specific user. 15695 users = new int[] {userId}; 15696 } 15697 15698 // Figure out who all will receive this broadcast. 15699 List receivers = null; 15700 List<BroadcastFilter> registeredReceivers = null; 15701 // Need to resolve the intent to interested receivers... 15702 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15703 == 0) { 15704 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15705 } 15706 if (intent.getComponent() == null) { 15707 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15708 // Query one target user at a time, excluding shell-restricted users 15709 UserManagerService ums = getUserManagerLocked(); 15710 for (int i = 0; i < users.length; i++) { 15711 if (ums.hasUserRestriction( 15712 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15713 continue; 15714 } 15715 List<BroadcastFilter> registeredReceiversForUser = 15716 mReceiverResolver.queryIntent(intent, 15717 resolvedType, false, users[i]); 15718 if (registeredReceivers == null) { 15719 registeredReceivers = registeredReceiversForUser; 15720 } else if (registeredReceiversForUser != null) { 15721 registeredReceivers.addAll(registeredReceiversForUser); 15722 } 15723 } 15724 } else { 15725 registeredReceivers = mReceiverResolver.queryIntent(intent, 15726 resolvedType, false, userId); 15727 } 15728 } 15729 15730 final boolean replacePending = 15731 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15732 15733 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15734 + " replacePending=" + replacePending); 15735 15736 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15737 if (!ordered && NR > 0) { 15738 // If we are not serializing this broadcast, then send the 15739 // registered receivers separately so they don't wait for the 15740 // components to be launched. 15741 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15742 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15743 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15744 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15745 ordered, sticky, false, userId); 15746 if (DEBUG_BROADCAST) Slog.v( 15747 TAG, "Enqueueing parallel broadcast " + r); 15748 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15749 if (!replaced) { 15750 queue.enqueueParallelBroadcastLocked(r); 15751 queue.scheduleBroadcastsLocked(); 15752 } 15753 registeredReceivers = null; 15754 NR = 0; 15755 } 15756 15757 // Merge into one list. 15758 int ir = 0; 15759 if (receivers != null) { 15760 // A special case for PACKAGE_ADDED: do not allow the package 15761 // being added to see this broadcast. This prevents them from 15762 // using this as a back door to get run as soon as they are 15763 // installed. Maybe in the future we want to have a special install 15764 // broadcast or such for apps, but we'd like to deliberately make 15765 // this decision. 15766 String skipPackages[] = null; 15767 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15768 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15769 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15770 Uri data = intent.getData(); 15771 if (data != null) { 15772 String pkgName = data.getSchemeSpecificPart(); 15773 if (pkgName != null) { 15774 skipPackages = new String[] { pkgName }; 15775 } 15776 } 15777 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15778 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15779 } 15780 if (skipPackages != null && (skipPackages.length > 0)) { 15781 for (String skipPackage : skipPackages) { 15782 if (skipPackage != null) { 15783 int NT = receivers.size(); 15784 for (int it=0; it<NT; it++) { 15785 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15786 if (curt.activityInfo.packageName.equals(skipPackage)) { 15787 receivers.remove(it); 15788 it--; 15789 NT--; 15790 } 15791 } 15792 } 15793 } 15794 } 15795 15796 int NT = receivers != null ? receivers.size() : 0; 15797 int it = 0; 15798 ResolveInfo curt = null; 15799 BroadcastFilter curr = null; 15800 while (it < NT && ir < NR) { 15801 if (curt == null) { 15802 curt = (ResolveInfo)receivers.get(it); 15803 } 15804 if (curr == null) { 15805 curr = registeredReceivers.get(ir); 15806 } 15807 if (curr.getPriority() >= curt.priority) { 15808 // Insert this broadcast record into the final list. 15809 receivers.add(it, curr); 15810 ir++; 15811 curr = null; 15812 it++; 15813 NT++; 15814 } else { 15815 // Skip to the next ResolveInfo in the final list. 15816 it++; 15817 curt = null; 15818 } 15819 } 15820 } 15821 while (ir < NR) { 15822 if (receivers == null) { 15823 receivers = new ArrayList(); 15824 } 15825 receivers.add(registeredReceivers.get(ir)); 15826 ir++; 15827 } 15828 15829 if ((receivers != null && receivers.size() > 0) 15830 || resultTo != null) { 15831 BroadcastQueue queue = broadcastQueueForIntent(intent); 15832 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15833 callerPackage, callingPid, callingUid, resolvedType, 15834 requiredPermission, appOp, receivers, resultTo, resultCode, 15835 resultData, map, ordered, sticky, false, userId); 15836 if (DEBUG_BROADCAST) Slog.v( 15837 TAG, "Enqueueing ordered broadcast " + r 15838 + ": prev had " + queue.mOrderedBroadcasts.size()); 15839 if (DEBUG_BROADCAST) { 15840 int seq = r.intent.getIntExtra("seq", -1); 15841 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15842 } 15843 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15844 if (!replaced) { 15845 queue.enqueueOrderedBroadcastLocked(r); 15846 queue.scheduleBroadcastsLocked(); 15847 } 15848 } 15849 15850 return ActivityManager.BROADCAST_SUCCESS; 15851 } 15852 15853 final Intent verifyBroadcastLocked(Intent intent) { 15854 // Refuse possible leaked file descriptors 15855 if (intent != null && intent.hasFileDescriptors() == true) { 15856 throw new IllegalArgumentException("File descriptors passed in Intent"); 15857 } 15858 15859 int flags = intent.getFlags(); 15860 15861 if (!mProcessesReady) { 15862 // if the caller really truly claims to know what they're doing, go 15863 // ahead and allow the broadcast without launching any receivers 15864 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15865 intent = new Intent(intent); 15866 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15867 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15868 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15869 + " before boot completion"); 15870 throw new IllegalStateException("Cannot broadcast before boot completed"); 15871 } 15872 } 15873 15874 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15875 throw new IllegalArgumentException( 15876 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15877 } 15878 15879 return intent; 15880 } 15881 15882 public final int broadcastIntent(IApplicationThread caller, 15883 Intent intent, String resolvedType, IIntentReceiver resultTo, 15884 int resultCode, String resultData, Bundle map, 15885 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15886 enforceNotIsolatedCaller("broadcastIntent"); 15887 synchronized(this) { 15888 intent = verifyBroadcastLocked(intent); 15889 15890 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15891 final int callingPid = Binder.getCallingPid(); 15892 final int callingUid = Binder.getCallingUid(); 15893 final long origId = Binder.clearCallingIdentity(); 15894 int res = broadcastIntentLocked(callerApp, 15895 callerApp != null ? callerApp.info.packageName : null, 15896 intent, resolvedType, resultTo, 15897 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15898 callingPid, callingUid, userId); 15899 Binder.restoreCallingIdentity(origId); 15900 return res; 15901 } 15902 } 15903 15904 int broadcastIntentInPackage(String packageName, int uid, 15905 Intent intent, String resolvedType, IIntentReceiver resultTo, 15906 int resultCode, String resultData, Bundle map, 15907 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15908 synchronized(this) { 15909 intent = verifyBroadcastLocked(intent); 15910 15911 final long origId = Binder.clearCallingIdentity(); 15912 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15913 resultTo, resultCode, resultData, map, requiredPermission, 15914 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15915 Binder.restoreCallingIdentity(origId); 15916 return res; 15917 } 15918 } 15919 15920 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15921 // Refuse possible leaked file descriptors 15922 if (intent != null && intent.hasFileDescriptors() == true) { 15923 throw new IllegalArgumentException("File descriptors passed in Intent"); 15924 } 15925 15926 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15927 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15928 15929 synchronized(this) { 15930 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15931 != PackageManager.PERMISSION_GRANTED) { 15932 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15933 + Binder.getCallingPid() 15934 + ", uid=" + Binder.getCallingUid() 15935 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15936 Slog.w(TAG, msg); 15937 throw new SecurityException(msg); 15938 } 15939 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15940 if (stickies != null) { 15941 ArrayList<Intent> list = stickies.get(intent.getAction()); 15942 if (list != null) { 15943 int N = list.size(); 15944 int i; 15945 for (i=0; i<N; i++) { 15946 if (intent.filterEquals(list.get(i))) { 15947 list.remove(i); 15948 break; 15949 } 15950 } 15951 if (list.size() <= 0) { 15952 stickies.remove(intent.getAction()); 15953 } 15954 } 15955 if (stickies.size() <= 0) { 15956 mStickyBroadcasts.remove(userId); 15957 } 15958 } 15959 } 15960 } 15961 15962 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15963 String resultData, Bundle resultExtras, boolean resultAbort) { 15964 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15965 if (r == null) { 15966 Slog.w(TAG, "finishReceiver called but not found on queue"); 15967 return false; 15968 } 15969 15970 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15971 } 15972 15973 void backgroundServicesFinishedLocked(int userId) { 15974 for (BroadcastQueue queue : mBroadcastQueues) { 15975 queue.backgroundServicesFinishedLocked(userId); 15976 } 15977 } 15978 15979 public void finishReceiver(IBinder who, int resultCode, String resultData, 15980 Bundle resultExtras, boolean resultAbort) { 15981 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15982 15983 // Refuse possible leaked file descriptors 15984 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15985 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15986 } 15987 15988 final long origId = Binder.clearCallingIdentity(); 15989 try { 15990 boolean doNext = false; 15991 BroadcastRecord r; 15992 15993 synchronized(this) { 15994 r = broadcastRecordForReceiverLocked(who); 15995 if (r != null) { 15996 doNext = r.queue.finishReceiverLocked(r, resultCode, 15997 resultData, resultExtras, resultAbort, true); 15998 } 15999 } 16000 16001 if (doNext) { 16002 r.queue.processNextBroadcast(false); 16003 } 16004 trimApplications(); 16005 } finally { 16006 Binder.restoreCallingIdentity(origId); 16007 } 16008 } 16009 16010 // ========================================================= 16011 // INSTRUMENTATION 16012 // ========================================================= 16013 16014 public boolean startInstrumentation(ComponentName className, 16015 String profileFile, int flags, Bundle arguments, 16016 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16017 int userId, String abiOverride) { 16018 enforceNotIsolatedCaller("startInstrumentation"); 16019 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16020 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16021 // Refuse possible leaked file descriptors 16022 if (arguments != null && arguments.hasFileDescriptors()) { 16023 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16024 } 16025 16026 synchronized(this) { 16027 InstrumentationInfo ii = null; 16028 ApplicationInfo ai = null; 16029 try { 16030 ii = mContext.getPackageManager().getInstrumentationInfo( 16031 className, STOCK_PM_FLAGS); 16032 ai = AppGlobals.getPackageManager().getApplicationInfo( 16033 ii.targetPackage, STOCK_PM_FLAGS, userId); 16034 } catch (PackageManager.NameNotFoundException e) { 16035 } catch (RemoteException e) { 16036 } 16037 if (ii == null) { 16038 reportStartInstrumentationFailure(watcher, className, 16039 "Unable to find instrumentation info for: " + className); 16040 return false; 16041 } 16042 if (ai == null) { 16043 reportStartInstrumentationFailure(watcher, className, 16044 "Unable to find instrumentation target package: " + ii.targetPackage); 16045 return false; 16046 } 16047 16048 int match = mContext.getPackageManager().checkSignatures( 16049 ii.targetPackage, ii.packageName); 16050 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16051 String msg = "Permission Denial: starting instrumentation " 16052 + className + " from pid=" 16053 + Binder.getCallingPid() 16054 + ", uid=" + Binder.getCallingPid() 16055 + " not allowed because package " + ii.packageName 16056 + " does not have a signature matching the target " 16057 + ii.targetPackage; 16058 reportStartInstrumentationFailure(watcher, className, msg); 16059 throw new SecurityException(msg); 16060 } 16061 16062 final long origId = Binder.clearCallingIdentity(); 16063 // Instrumentation can kill and relaunch even persistent processes 16064 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16065 "start instr"); 16066 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16067 app.instrumentationClass = className; 16068 app.instrumentationInfo = ai; 16069 app.instrumentationProfileFile = profileFile; 16070 app.instrumentationArguments = arguments; 16071 app.instrumentationWatcher = watcher; 16072 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16073 app.instrumentationResultClass = className; 16074 Binder.restoreCallingIdentity(origId); 16075 } 16076 16077 return true; 16078 } 16079 16080 /** 16081 * Report errors that occur while attempting to start Instrumentation. Always writes the 16082 * error to the logs, but if somebody is watching, send the report there too. This enables 16083 * the "am" command to report errors with more information. 16084 * 16085 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16086 * @param cn The component name of the instrumentation. 16087 * @param report The error report. 16088 */ 16089 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16090 ComponentName cn, String report) { 16091 Slog.w(TAG, report); 16092 try { 16093 if (watcher != null) { 16094 Bundle results = new Bundle(); 16095 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16096 results.putString("Error", report); 16097 watcher.instrumentationStatus(cn, -1, results); 16098 } 16099 } catch (RemoteException e) { 16100 Slog.w(TAG, e); 16101 } 16102 } 16103 16104 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16105 if (app.instrumentationWatcher != null) { 16106 try { 16107 // NOTE: IInstrumentationWatcher *must* be oneway here 16108 app.instrumentationWatcher.instrumentationFinished( 16109 app.instrumentationClass, 16110 resultCode, 16111 results); 16112 } catch (RemoteException e) { 16113 } 16114 } 16115 if (app.instrumentationUiAutomationConnection != null) { 16116 try { 16117 app.instrumentationUiAutomationConnection.shutdown(); 16118 } catch (RemoteException re) { 16119 /* ignore */ 16120 } 16121 // Only a UiAutomation can set this flag and now that 16122 // it is finished we make sure it is reset to its default. 16123 mUserIsMonkey = false; 16124 } 16125 app.instrumentationWatcher = null; 16126 app.instrumentationUiAutomationConnection = null; 16127 app.instrumentationClass = null; 16128 app.instrumentationInfo = null; 16129 app.instrumentationProfileFile = null; 16130 app.instrumentationArguments = null; 16131 16132 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16133 "finished inst"); 16134 } 16135 16136 public void finishInstrumentation(IApplicationThread target, 16137 int resultCode, Bundle results) { 16138 int userId = UserHandle.getCallingUserId(); 16139 // Refuse possible leaked file descriptors 16140 if (results != null && results.hasFileDescriptors()) { 16141 throw new IllegalArgumentException("File descriptors passed in Intent"); 16142 } 16143 16144 synchronized(this) { 16145 ProcessRecord app = getRecordForAppLocked(target); 16146 if (app == null) { 16147 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16148 return; 16149 } 16150 final long origId = Binder.clearCallingIdentity(); 16151 finishInstrumentationLocked(app, resultCode, results); 16152 Binder.restoreCallingIdentity(origId); 16153 } 16154 } 16155 16156 // ========================================================= 16157 // CONFIGURATION 16158 // ========================================================= 16159 16160 public ConfigurationInfo getDeviceConfigurationInfo() { 16161 ConfigurationInfo config = new ConfigurationInfo(); 16162 synchronized (this) { 16163 config.reqTouchScreen = mConfiguration.touchscreen; 16164 config.reqKeyboardType = mConfiguration.keyboard; 16165 config.reqNavigation = mConfiguration.navigation; 16166 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16167 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16168 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16169 } 16170 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16171 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16172 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16173 } 16174 config.reqGlEsVersion = GL_ES_VERSION; 16175 } 16176 return config; 16177 } 16178 16179 ActivityStack getFocusedStack() { 16180 return mStackSupervisor.getFocusedStack(); 16181 } 16182 16183 public Configuration getConfiguration() { 16184 Configuration ci; 16185 synchronized(this) { 16186 ci = new Configuration(mConfiguration); 16187 } 16188 return ci; 16189 } 16190 16191 public void updatePersistentConfiguration(Configuration values) { 16192 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16193 "updateConfiguration()"); 16194 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16195 "updateConfiguration()"); 16196 if (values == null) { 16197 throw new NullPointerException("Configuration must not be null"); 16198 } 16199 16200 synchronized(this) { 16201 final long origId = Binder.clearCallingIdentity(); 16202 updateConfigurationLocked(values, null, true, false); 16203 Binder.restoreCallingIdentity(origId); 16204 } 16205 } 16206 16207 public void updateConfiguration(Configuration values) { 16208 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16209 "updateConfiguration()"); 16210 16211 synchronized(this) { 16212 if (values == null && mWindowManager != null) { 16213 // sentinel: fetch the current configuration from the window manager 16214 values = mWindowManager.computeNewConfiguration(); 16215 } 16216 16217 if (mWindowManager != null) { 16218 mProcessList.applyDisplaySize(mWindowManager); 16219 } 16220 16221 final long origId = Binder.clearCallingIdentity(); 16222 if (values != null) { 16223 Settings.System.clearConfiguration(values); 16224 } 16225 updateConfigurationLocked(values, null, false, false); 16226 Binder.restoreCallingIdentity(origId); 16227 } 16228 } 16229 16230 /** 16231 * Do either or both things: (1) change the current configuration, and (2) 16232 * make sure the given activity is running with the (now) current 16233 * configuration. Returns true if the activity has been left running, or 16234 * false if <var>starting</var> is being destroyed to match the new 16235 * configuration. 16236 * @param persistent TODO 16237 */ 16238 boolean updateConfigurationLocked(Configuration values, 16239 ActivityRecord starting, boolean persistent, boolean initLocale) { 16240 int changes = 0; 16241 16242 if (values != null) { 16243 Configuration newConfig = new Configuration(mConfiguration); 16244 changes = newConfig.updateFrom(values); 16245 if (changes != 0) { 16246 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16247 Slog.i(TAG, "Updating configuration to: " + values); 16248 } 16249 16250 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16251 16252 if (values.locale != null && !initLocale) { 16253 saveLocaleLocked(values.locale, 16254 !values.locale.equals(mConfiguration.locale), 16255 values.userSetLocale); 16256 } 16257 16258 mConfigurationSeq++; 16259 if (mConfigurationSeq <= 0) { 16260 mConfigurationSeq = 1; 16261 } 16262 newConfig.seq = mConfigurationSeq; 16263 mConfiguration = newConfig; 16264 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16265 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16266 //mUsageStatsService.noteStartConfig(newConfig); 16267 16268 final Configuration configCopy = new Configuration(mConfiguration); 16269 16270 // TODO: If our config changes, should we auto dismiss any currently 16271 // showing dialogs? 16272 mShowDialogs = shouldShowDialogs(newConfig); 16273 16274 AttributeCache ac = AttributeCache.instance(); 16275 if (ac != null) { 16276 ac.updateConfiguration(configCopy); 16277 } 16278 16279 // Make sure all resources in our process are updated 16280 // right now, so that anyone who is going to retrieve 16281 // resource values after we return will be sure to get 16282 // the new ones. This is especially important during 16283 // boot, where the first config change needs to guarantee 16284 // all resources have that config before following boot 16285 // code is executed. 16286 mSystemThread.applyConfigurationToResources(configCopy); 16287 16288 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16289 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16290 msg.obj = new Configuration(configCopy); 16291 mHandler.sendMessage(msg); 16292 } 16293 16294 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16295 ProcessRecord app = mLruProcesses.get(i); 16296 try { 16297 if (app.thread != null) { 16298 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16299 + app.processName + " new config " + mConfiguration); 16300 app.thread.scheduleConfigurationChanged(configCopy); 16301 } 16302 } catch (Exception e) { 16303 } 16304 } 16305 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16306 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16307 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16308 | Intent.FLAG_RECEIVER_FOREGROUND); 16309 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16310 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16311 Process.SYSTEM_UID, UserHandle.USER_ALL); 16312 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16313 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16314 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16315 broadcastIntentLocked(null, null, intent, 16316 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16317 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16318 } 16319 } 16320 } 16321 16322 boolean kept = true; 16323 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16324 // mainStack is null during startup. 16325 if (mainStack != null) { 16326 if (changes != 0 && starting == null) { 16327 // If the configuration changed, and the caller is not already 16328 // in the process of starting an activity, then find the top 16329 // activity to check if its configuration needs to change. 16330 starting = mainStack.topRunningActivityLocked(null); 16331 } 16332 16333 if (starting != null) { 16334 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16335 // And we need to make sure at this point that all other activities 16336 // are made visible with the correct configuration. 16337 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16338 } 16339 } 16340 16341 if (values != null && mWindowManager != null) { 16342 mWindowManager.setNewConfiguration(mConfiguration); 16343 } 16344 16345 return kept; 16346 } 16347 16348 /** 16349 * Decide based on the configuration whether we should shouw the ANR, 16350 * crash, etc dialogs. The idea is that if there is no affordnace to 16351 * press the on-screen buttons, we shouldn't show the dialog. 16352 * 16353 * A thought: SystemUI might also want to get told about this, the Power 16354 * dialog / global actions also might want different behaviors. 16355 */ 16356 private static final boolean shouldShowDialogs(Configuration config) { 16357 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16358 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16359 } 16360 16361 /** 16362 * Save the locale. You must be inside a synchronized (this) block. 16363 */ 16364 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16365 if(isDiff) { 16366 SystemProperties.set("user.language", l.getLanguage()); 16367 SystemProperties.set("user.region", l.getCountry()); 16368 } 16369 16370 if(isPersist) { 16371 SystemProperties.set("persist.sys.language", l.getLanguage()); 16372 SystemProperties.set("persist.sys.country", l.getCountry()); 16373 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16374 16375 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16376 } 16377 } 16378 16379 @Override 16380 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16381 synchronized (this) { 16382 ActivityRecord srec = ActivityRecord.forToken(token); 16383 if (srec.task != null && srec.task.stack != null) { 16384 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16385 } 16386 } 16387 return false; 16388 } 16389 16390 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16391 Intent resultData) { 16392 16393 synchronized (this) { 16394 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16395 if (stack != null) { 16396 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16397 } 16398 return false; 16399 } 16400 } 16401 16402 public int getLaunchedFromUid(IBinder activityToken) { 16403 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16404 if (srec == null) { 16405 return -1; 16406 } 16407 return srec.launchedFromUid; 16408 } 16409 16410 public String getLaunchedFromPackage(IBinder activityToken) { 16411 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16412 if (srec == null) { 16413 return null; 16414 } 16415 return srec.launchedFromPackage; 16416 } 16417 16418 // ========================================================= 16419 // LIFETIME MANAGEMENT 16420 // ========================================================= 16421 16422 // Returns which broadcast queue the app is the current [or imminent] receiver 16423 // on, or 'null' if the app is not an active broadcast recipient. 16424 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16425 BroadcastRecord r = app.curReceiver; 16426 if (r != null) { 16427 return r.queue; 16428 } 16429 16430 // It's not the current receiver, but it might be starting up to become one 16431 synchronized (this) { 16432 for (BroadcastQueue queue : mBroadcastQueues) { 16433 r = queue.mPendingBroadcast; 16434 if (r != null && r.curApp == app) { 16435 // found it; report which queue it's in 16436 return queue; 16437 } 16438 } 16439 } 16440 16441 return null; 16442 } 16443 16444 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16445 boolean doingAll, long now) { 16446 if (mAdjSeq == app.adjSeq) { 16447 // This adjustment has already been computed. 16448 return app.curRawAdj; 16449 } 16450 16451 if (app.thread == null) { 16452 app.adjSeq = mAdjSeq; 16453 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16454 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16455 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16456 } 16457 16458 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16459 app.adjSource = null; 16460 app.adjTarget = null; 16461 app.empty = false; 16462 app.cached = false; 16463 16464 final int activitiesSize = app.activities.size(); 16465 16466 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16467 // The max adjustment doesn't allow this app to be anything 16468 // below foreground, so it is not worth doing work for it. 16469 app.adjType = "fixed"; 16470 app.adjSeq = mAdjSeq; 16471 app.curRawAdj = app.maxAdj; 16472 app.foregroundActivities = false; 16473 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16474 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16475 // System processes can do UI, and when they do we want to have 16476 // them trim their memory after the user leaves the UI. To 16477 // facilitate this, here we need to determine whether or not it 16478 // is currently showing UI. 16479 app.systemNoUi = true; 16480 if (app == TOP_APP) { 16481 app.systemNoUi = false; 16482 } else if (activitiesSize > 0) { 16483 for (int j = 0; j < activitiesSize; j++) { 16484 final ActivityRecord r = app.activities.get(j); 16485 if (r.visible) { 16486 app.systemNoUi = false; 16487 } 16488 } 16489 } 16490 if (!app.systemNoUi) { 16491 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16492 } 16493 return (app.curAdj=app.maxAdj); 16494 } 16495 16496 app.systemNoUi = false; 16497 16498 // Determine the importance of the process, starting with most 16499 // important to least, and assign an appropriate OOM adjustment. 16500 int adj; 16501 int schedGroup; 16502 int procState; 16503 boolean foregroundActivities = false; 16504 BroadcastQueue queue; 16505 if (app == TOP_APP) { 16506 // The last app on the list is the foreground app. 16507 adj = ProcessList.FOREGROUND_APP_ADJ; 16508 schedGroup = Process.THREAD_GROUP_DEFAULT; 16509 app.adjType = "top-activity"; 16510 foregroundActivities = true; 16511 procState = ActivityManager.PROCESS_STATE_TOP; 16512 } else if (app.instrumentationClass != null) { 16513 // Don't want to kill running instrumentation. 16514 adj = ProcessList.FOREGROUND_APP_ADJ; 16515 schedGroup = Process.THREAD_GROUP_DEFAULT; 16516 app.adjType = "instrumentation"; 16517 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16518 } else if ((queue = isReceivingBroadcast(app)) != null) { 16519 // An app that is currently receiving a broadcast also 16520 // counts as being in the foreground for OOM killer purposes. 16521 // It's placed in a sched group based on the nature of the 16522 // broadcast as reflected by which queue it's active in. 16523 adj = ProcessList.FOREGROUND_APP_ADJ; 16524 schedGroup = (queue == mFgBroadcastQueue) 16525 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16526 app.adjType = "broadcast"; 16527 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16528 } else if (app.executingServices.size() > 0) { 16529 // An app that is currently executing a service callback also 16530 // counts as being in the foreground. 16531 adj = ProcessList.FOREGROUND_APP_ADJ; 16532 schedGroup = app.execServicesFg ? 16533 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16534 app.adjType = "exec-service"; 16535 procState = ActivityManager.PROCESS_STATE_SERVICE; 16536 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16537 } else { 16538 // As far as we know the process is empty. We may change our mind later. 16539 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16540 // At this point we don't actually know the adjustment. Use the cached adj 16541 // value that the caller wants us to. 16542 adj = cachedAdj; 16543 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16544 app.cached = true; 16545 app.empty = true; 16546 app.adjType = "cch-empty"; 16547 } 16548 16549 // Examine all activities if not already foreground. 16550 if (!foregroundActivities && activitiesSize > 0) { 16551 for (int j = 0; j < activitiesSize; j++) { 16552 final ActivityRecord r = app.activities.get(j); 16553 if (r.app != app) { 16554 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16555 + app + "?!?"); 16556 continue; 16557 } 16558 if (r.visible) { 16559 // App has a visible activity; only upgrade adjustment. 16560 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16561 adj = ProcessList.VISIBLE_APP_ADJ; 16562 app.adjType = "visible"; 16563 } 16564 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16565 procState = ActivityManager.PROCESS_STATE_TOP; 16566 } 16567 schedGroup = Process.THREAD_GROUP_DEFAULT; 16568 app.cached = false; 16569 app.empty = false; 16570 foregroundActivities = true; 16571 break; 16572 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16573 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16574 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16575 app.adjType = "pausing"; 16576 } 16577 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16578 procState = ActivityManager.PROCESS_STATE_TOP; 16579 } 16580 schedGroup = Process.THREAD_GROUP_DEFAULT; 16581 app.cached = false; 16582 app.empty = false; 16583 foregroundActivities = true; 16584 } else if (r.state == ActivityState.STOPPING) { 16585 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16586 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16587 app.adjType = "stopping"; 16588 } 16589 // For the process state, we will at this point consider the 16590 // process to be cached. It will be cached either as an activity 16591 // or empty depending on whether the activity is finishing. We do 16592 // this so that we can treat the process as cached for purposes of 16593 // memory trimming (determing current memory level, trim command to 16594 // send to process) since there can be an arbitrary number of stopping 16595 // processes and they should soon all go into the cached state. 16596 if (!r.finishing) { 16597 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16598 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16599 } 16600 } 16601 app.cached = false; 16602 app.empty = false; 16603 foregroundActivities = true; 16604 } else { 16605 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16606 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16607 app.adjType = "cch-act"; 16608 } 16609 } 16610 } 16611 } 16612 16613 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16614 if (app.foregroundServices) { 16615 // The user is aware of this app, so make it visible. 16616 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16617 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16618 app.cached = false; 16619 app.adjType = "fg-service"; 16620 schedGroup = Process.THREAD_GROUP_DEFAULT; 16621 } else if (app.forcingToForeground != null) { 16622 // The user is aware of this app, so make it visible. 16623 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16624 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16625 app.cached = false; 16626 app.adjType = "force-fg"; 16627 app.adjSource = app.forcingToForeground; 16628 schedGroup = Process.THREAD_GROUP_DEFAULT; 16629 } 16630 } 16631 16632 if (app == mHeavyWeightProcess) { 16633 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16634 // We don't want to kill the current heavy-weight process. 16635 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16636 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16637 app.cached = false; 16638 app.adjType = "heavy"; 16639 } 16640 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16641 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16642 } 16643 } 16644 16645 if (app == mHomeProcess) { 16646 if (adj > ProcessList.HOME_APP_ADJ) { 16647 // This process is hosting what we currently consider to be the 16648 // home app, so we don't want to let it go into the background. 16649 adj = ProcessList.HOME_APP_ADJ; 16650 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16651 app.cached = false; 16652 app.adjType = "home"; 16653 } 16654 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16655 procState = ActivityManager.PROCESS_STATE_HOME; 16656 } 16657 } 16658 16659 if (app == mPreviousProcess && app.activities.size() > 0) { 16660 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16661 // This was the previous process that showed UI to the user. 16662 // We want to try to keep it around more aggressively, to give 16663 // a good experience around switching between two apps. 16664 adj = ProcessList.PREVIOUS_APP_ADJ; 16665 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16666 app.cached = false; 16667 app.adjType = "previous"; 16668 } 16669 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16670 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16671 } 16672 } 16673 16674 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16675 + " reason=" + app.adjType); 16676 16677 // By default, we use the computed adjustment. It may be changed if 16678 // there are applications dependent on our services or providers, but 16679 // this gives us a baseline and makes sure we don't get into an 16680 // infinite recursion. 16681 app.adjSeq = mAdjSeq; 16682 app.curRawAdj = adj; 16683 app.hasStartedServices = false; 16684 16685 if (mBackupTarget != null && app == mBackupTarget.app) { 16686 // If possible we want to avoid killing apps while they're being backed up 16687 if (adj > ProcessList.BACKUP_APP_ADJ) { 16688 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16689 adj = ProcessList.BACKUP_APP_ADJ; 16690 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16691 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16692 } 16693 app.adjType = "backup"; 16694 app.cached = false; 16695 } 16696 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16697 procState = ActivityManager.PROCESS_STATE_BACKUP; 16698 } 16699 } 16700 16701 boolean mayBeTop = false; 16702 16703 for (int is = app.services.size()-1; 16704 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16705 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16706 || procState > ActivityManager.PROCESS_STATE_TOP); 16707 is--) { 16708 ServiceRecord s = app.services.valueAt(is); 16709 if (s.startRequested) { 16710 app.hasStartedServices = true; 16711 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16712 procState = ActivityManager.PROCESS_STATE_SERVICE; 16713 } 16714 if (app.hasShownUi && app != mHomeProcess) { 16715 // If this process has shown some UI, let it immediately 16716 // go to the LRU list because it may be pretty heavy with 16717 // UI stuff. We'll tag it with a label just to help 16718 // debug and understand what is going on. 16719 if (adj > ProcessList.SERVICE_ADJ) { 16720 app.adjType = "cch-started-ui-services"; 16721 } 16722 } else { 16723 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16724 // This service has seen some activity within 16725 // recent memory, so we will keep its process ahead 16726 // of the background processes. 16727 if (adj > ProcessList.SERVICE_ADJ) { 16728 adj = ProcessList.SERVICE_ADJ; 16729 app.adjType = "started-services"; 16730 app.cached = false; 16731 } 16732 } 16733 // If we have let the service slide into the background 16734 // state, still have some text describing what it is doing 16735 // even though the service no longer has an impact. 16736 if (adj > ProcessList.SERVICE_ADJ) { 16737 app.adjType = "cch-started-services"; 16738 } 16739 } 16740 } 16741 for (int conni = s.connections.size()-1; 16742 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16743 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16744 || procState > ActivityManager.PROCESS_STATE_TOP); 16745 conni--) { 16746 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16747 for (int i = 0; 16748 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16749 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16750 || procState > ActivityManager.PROCESS_STATE_TOP); 16751 i++) { 16752 // XXX should compute this based on the max of 16753 // all connected clients. 16754 ConnectionRecord cr = clist.get(i); 16755 if (cr.binding.client == app) { 16756 // Binding to ourself is not interesting. 16757 continue; 16758 } 16759 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16760 ProcessRecord client = cr.binding.client; 16761 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16762 TOP_APP, doingAll, now); 16763 int clientProcState = client.curProcState; 16764 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16765 // If the other app is cached for any reason, for purposes here 16766 // we are going to consider it empty. The specific cached state 16767 // doesn't propagate except under certain conditions. 16768 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16769 } 16770 String adjType = null; 16771 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16772 // Not doing bind OOM management, so treat 16773 // this guy more like a started service. 16774 if (app.hasShownUi && app != mHomeProcess) { 16775 // If this process has shown some UI, let it immediately 16776 // go to the LRU list because it may be pretty heavy with 16777 // UI stuff. We'll tag it with a label just to help 16778 // debug and understand what is going on. 16779 if (adj > clientAdj) { 16780 adjType = "cch-bound-ui-services"; 16781 } 16782 app.cached = false; 16783 clientAdj = adj; 16784 clientProcState = procState; 16785 } else { 16786 if (now >= (s.lastActivity 16787 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16788 // This service has not seen activity within 16789 // recent memory, so allow it to drop to the 16790 // LRU list if there is no other reason to keep 16791 // it around. We'll also tag it with a label just 16792 // to help debug and undertand what is going on. 16793 if (adj > clientAdj) { 16794 adjType = "cch-bound-services"; 16795 } 16796 clientAdj = adj; 16797 } 16798 } 16799 } 16800 if (adj > clientAdj) { 16801 // If this process has recently shown UI, and 16802 // the process that is binding to it is less 16803 // important than being visible, then we don't 16804 // care about the binding as much as we care 16805 // about letting this process get into the LRU 16806 // list to be killed and restarted if needed for 16807 // memory. 16808 if (app.hasShownUi && app != mHomeProcess 16809 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16810 adjType = "cch-bound-ui-services"; 16811 } else { 16812 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16813 |Context.BIND_IMPORTANT)) != 0) { 16814 adj = clientAdj; 16815 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16816 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16817 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16818 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16819 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16820 adj = clientAdj; 16821 } else { 16822 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16823 adj = ProcessList.VISIBLE_APP_ADJ; 16824 } 16825 } 16826 if (!client.cached) { 16827 app.cached = false; 16828 } 16829 adjType = "service"; 16830 } 16831 } 16832 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16833 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16834 schedGroup = Process.THREAD_GROUP_DEFAULT; 16835 } 16836 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16837 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16838 // Special handling of clients who are in the top state. 16839 // We *may* want to consider this process to be in the 16840 // top state as well, but only if there is not another 16841 // reason for it to be running. Being on the top is a 16842 // special state, meaning you are specifically running 16843 // for the current top app. If the process is already 16844 // running in the background for some other reason, it 16845 // is more important to continue considering it to be 16846 // in the background state. 16847 mayBeTop = true; 16848 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16849 } else { 16850 // Special handling for above-top states (persistent 16851 // processes). These should not bring the current process 16852 // into the top state, since they are not on top. Instead 16853 // give them the best state after that. 16854 clientProcState = 16855 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16856 } 16857 } 16858 } else { 16859 if (clientProcState < 16860 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16861 clientProcState = 16862 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16863 } 16864 } 16865 if (procState > clientProcState) { 16866 procState = clientProcState; 16867 } 16868 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16869 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16870 app.pendingUiClean = true; 16871 } 16872 if (adjType != null) { 16873 app.adjType = adjType; 16874 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16875 .REASON_SERVICE_IN_USE; 16876 app.adjSource = cr.binding.client; 16877 app.adjSourceProcState = clientProcState; 16878 app.adjTarget = s.name; 16879 } 16880 } 16881 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16882 app.treatLikeActivity = true; 16883 } 16884 final ActivityRecord a = cr.activity; 16885 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16886 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16887 (a.visible || a.state == ActivityState.RESUMED 16888 || a.state == ActivityState.PAUSING)) { 16889 adj = ProcessList.FOREGROUND_APP_ADJ; 16890 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16891 schedGroup = Process.THREAD_GROUP_DEFAULT; 16892 } 16893 app.cached = false; 16894 app.adjType = "service"; 16895 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16896 .REASON_SERVICE_IN_USE; 16897 app.adjSource = a; 16898 app.adjSourceProcState = procState; 16899 app.adjTarget = s.name; 16900 } 16901 } 16902 } 16903 } 16904 } 16905 16906 for (int provi = app.pubProviders.size()-1; 16907 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16908 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16909 || procState > ActivityManager.PROCESS_STATE_TOP); 16910 provi--) { 16911 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16912 for (int i = cpr.connections.size()-1; 16913 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16914 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16915 || procState > ActivityManager.PROCESS_STATE_TOP); 16916 i--) { 16917 ContentProviderConnection conn = cpr.connections.get(i); 16918 ProcessRecord client = conn.client; 16919 if (client == app) { 16920 // Being our own client is not interesting. 16921 continue; 16922 } 16923 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16924 int clientProcState = client.curProcState; 16925 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16926 // If the other app is cached for any reason, for purposes here 16927 // we are going to consider it empty. 16928 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16929 } 16930 if (adj > clientAdj) { 16931 if (app.hasShownUi && app != mHomeProcess 16932 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16933 app.adjType = "cch-ui-provider"; 16934 } else { 16935 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16936 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16937 app.adjType = "provider"; 16938 } 16939 app.cached &= client.cached; 16940 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16941 .REASON_PROVIDER_IN_USE; 16942 app.adjSource = client; 16943 app.adjSourceProcState = clientProcState; 16944 app.adjTarget = cpr.name; 16945 } 16946 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16947 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16948 // Special handling of clients who are in the top state. 16949 // We *may* want to consider this process to be in the 16950 // top state as well, but only if there is not another 16951 // reason for it to be running. Being on the top is a 16952 // special state, meaning you are specifically running 16953 // for the current top app. If the process is already 16954 // running in the background for some other reason, it 16955 // is more important to continue considering it to be 16956 // in the background state. 16957 mayBeTop = true; 16958 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16959 } else { 16960 // Special handling for above-top states (persistent 16961 // processes). These should not bring the current process 16962 // into the top state, since they are not on top. Instead 16963 // give them the best state after that. 16964 clientProcState = 16965 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16966 } 16967 } 16968 if (procState > clientProcState) { 16969 procState = clientProcState; 16970 } 16971 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16972 schedGroup = Process.THREAD_GROUP_DEFAULT; 16973 } 16974 } 16975 // If the provider has external (non-framework) process 16976 // dependencies, ensure that its adjustment is at least 16977 // FOREGROUND_APP_ADJ. 16978 if (cpr.hasExternalProcessHandles()) { 16979 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16980 adj = ProcessList.FOREGROUND_APP_ADJ; 16981 schedGroup = Process.THREAD_GROUP_DEFAULT; 16982 app.cached = false; 16983 app.adjType = "provider"; 16984 app.adjTarget = cpr.name; 16985 } 16986 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16987 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16988 } 16989 } 16990 } 16991 16992 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16993 // A client of one of our services or providers is in the top state. We 16994 // *may* want to be in the top state, but not if we are already running in 16995 // the background for some other reason. For the decision here, we are going 16996 // to pick out a few specific states that we want to remain in when a client 16997 // is top (states that tend to be longer-term) and otherwise allow it to go 16998 // to the top state. 16999 switch (procState) { 17000 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17001 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17002 case ActivityManager.PROCESS_STATE_SERVICE: 17003 // These all are longer-term states, so pull them up to the top 17004 // of the background states, but not all the way to the top state. 17005 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17006 break; 17007 default: 17008 // Otherwise, top is a better choice, so take it. 17009 procState = ActivityManager.PROCESS_STATE_TOP; 17010 break; 17011 } 17012 } 17013 17014 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17015 if (app.hasClientActivities) { 17016 // This is a cached process, but with client activities. Mark it so. 17017 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17018 app.adjType = "cch-client-act"; 17019 } else if (app.treatLikeActivity) { 17020 // This is a cached process, but somebody wants us to treat it like it has 17021 // an activity, okay! 17022 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17023 app.adjType = "cch-as-act"; 17024 } 17025 } 17026 17027 if (adj == ProcessList.SERVICE_ADJ) { 17028 if (doingAll) { 17029 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17030 mNewNumServiceProcs++; 17031 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17032 if (!app.serviceb) { 17033 // This service isn't far enough down on the LRU list to 17034 // normally be a B service, but if we are low on RAM and it 17035 // is large we want to force it down since we would prefer to 17036 // keep launcher over it. 17037 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17038 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17039 app.serviceHighRam = true; 17040 app.serviceb = true; 17041 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17042 } else { 17043 mNewNumAServiceProcs++; 17044 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17045 } 17046 } else { 17047 app.serviceHighRam = false; 17048 } 17049 } 17050 if (app.serviceb) { 17051 adj = ProcessList.SERVICE_B_ADJ; 17052 } 17053 } 17054 17055 app.curRawAdj = adj; 17056 17057 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17058 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17059 if (adj > app.maxAdj) { 17060 adj = app.maxAdj; 17061 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17062 schedGroup = Process.THREAD_GROUP_DEFAULT; 17063 } 17064 } 17065 17066 // Do final modification to adj. Everything we do between here and applying 17067 // the final setAdj must be done in this function, because we will also use 17068 // it when computing the final cached adj later. Note that we don't need to 17069 // worry about this for max adj above, since max adj will always be used to 17070 // keep it out of the cached vaues. 17071 app.curAdj = app.modifyRawOomAdj(adj); 17072 app.curSchedGroup = schedGroup; 17073 app.curProcState = procState; 17074 app.foregroundActivities = foregroundActivities; 17075 17076 return app.curRawAdj; 17077 } 17078 17079 /** 17080 * Schedule PSS collection of a process. 17081 */ 17082 void requestPssLocked(ProcessRecord proc, int procState) { 17083 if (mPendingPssProcesses.contains(proc)) { 17084 return; 17085 } 17086 if (mPendingPssProcesses.size() == 0) { 17087 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17088 } 17089 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17090 proc.pssProcState = procState; 17091 mPendingPssProcesses.add(proc); 17092 } 17093 17094 /** 17095 * Schedule PSS collection of all processes. 17096 */ 17097 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17098 if (!always) { 17099 if (now < (mLastFullPssTime + 17100 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17101 return; 17102 } 17103 } 17104 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17105 mLastFullPssTime = now; 17106 mFullPssPending = true; 17107 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17108 mPendingPssProcesses.clear(); 17109 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17110 ProcessRecord app = mLruProcesses.get(i); 17111 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17112 app.pssProcState = app.setProcState; 17113 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17114 isSleeping(), now); 17115 mPendingPssProcesses.add(app); 17116 } 17117 } 17118 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17119 } 17120 17121 /** 17122 * Ask a given process to GC right now. 17123 */ 17124 final void performAppGcLocked(ProcessRecord app) { 17125 try { 17126 app.lastRequestedGc = SystemClock.uptimeMillis(); 17127 if (app.thread != null) { 17128 if (app.reportLowMemory) { 17129 app.reportLowMemory = false; 17130 app.thread.scheduleLowMemory(); 17131 } else { 17132 app.thread.processInBackground(); 17133 } 17134 } 17135 } catch (Exception e) { 17136 // whatever. 17137 } 17138 } 17139 17140 /** 17141 * Returns true if things are idle enough to perform GCs. 17142 */ 17143 private final boolean canGcNowLocked() { 17144 boolean processingBroadcasts = false; 17145 for (BroadcastQueue q : mBroadcastQueues) { 17146 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17147 processingBroadcasts = true; 17148 } 17149 } 17150 return !processingBroadcasts 17151 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17152 } 17153 17154 /** 17155 * Perform GCs on all processes that are waiting for it, but only 17156 * if things are idle. 17157 */ 17158 final void performAppGcsLocked() { 17159 final int N = mProcessesToGc.size(); 17160 if (N <= 0) { 17161 return; 17162 } 17163 if (canGcNowLocked()) { 17164 while (mProcessesToGc.size() > 0) { 17165 ProcessRecord proc = mProcessesToGc.remove(0); 17166 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17167 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17168 <= SystemClock.uptimeMillis()) { 17169 // To avoid spamming the system, we will GC processes one 17170 // at a time, waiting a few seconds between each. 17171 performAppGcLocked(proc); 17172 scheduleAppGcsLocked(); 17173 return; 17174 } else { 17175 // It hasn't been long enough since we last GCed this 17176 // process... put it in the list to wait for its time. 17177 addProcessToGcListLocked(proc); 17178 break; 17179 } 17180 } 17181 } 17182 17183 scheduleAppGcsLocked(); 17184 } 17185 } 17186 17187 /** 17188 * If all looks good, perform GCs on all processes waiting for them. 17189 */ 17190 final void performAppGcsIfAppropriateLocked() { 17191 if (canGcNowLocked()) { 17192 performAppGcsLocked(); 17193 return; 17194 } 17195 // Still not idle, wait some more. 17196 scheduleAppGcsLocked(); 17197 } 17198 17199 /** 17200 * Schedule the execution of all pending app GCs. 17201 */ 17202 final void scheduleAppGcsLocked() { 17203 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17204 17205 if (mProcessesToGc.size() > 0) { 17206 // Schedule a GC for the time to the next process. 17207 ProcessRecord proc = mProcessesToGc.get(0); 17208 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17209 17210 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17211 long now = SystemClock.uptimeMillis(); 17212 if (when < (now+GC_TIMEOUT)) { 17213 when = now + GC_TIMEOUT; 17214 } 17215 mHandler.sendMessageAtTime(msg, when); 17216 } 17217 } 17218 17219 /** 17220 * Add a process to the array of processes waiting to be GCed. Keeps the 17221 * list in sorted order by the last GC time. The process can't already be 17222 * on the list. 17223 */ 17224 final void addProcessToGcListLocked(ProcessRecord proc) { 17225 boolean added = false; 17226 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17227 if (mProcessesToGc.get(i).lastRequestedGc < 17228 proc.lastRequestedGc) { 17229 added = true; 17230 mProcessesToGc.add(i+1, proc); 17231 break; 17232 } 17233 } 17234 if (!added) { 17235 mProcessesToGc.add(0, proc); 17236 } 17237 } 17238 17239 /** 17240 * Set up to ask a process to GC itself. This will either do it 17241 * immediately, or put it on the list of processes to gc the next 17242 * time things are idle. 17243 */ 17244 final void scheduleAppGcLocked(ProcessRecord app) { 17245 long now = SystemClock.uptimeMillis(); 17246 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17247 return; 17248 } 17249 if (!mProcessesToGc.contains(app)) { 17250 addProcessToGcListLocked(app); 17251 scheduleAppGcsLocked(); 17252 } 17253 } 17254 17255 final void checkExcessivePowerUsageLocked(boolean doKills) { 17256 updateCpuStatsNow(); 17257 17258 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17259 boolean doWakeKills = doKills; 17260 boolean doCpuKills = doKills; 17261 if (mLastPowerCheckRealtime == 0) { 17262 doWakeKills = false; 17263 } 17264 if (mLastPowerCheckUptime == 0) { 17265 doCpuKills = false; 17266 } 17267 if (stats.isScreenOn()) { 17268 doWakeKills = false; 17269 } 17270 final long curRealtime = SystemClock.elapsedRealtime(); 17271 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17272 final long curUptime = SystemClock.uptimeMillis(); 17273 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17274 mLastPowerCheckRealtime = curRealtime; 17275 mLastPowerCheckUptime = curUptime; 17276 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17277 doWakeKills = false; 17278 } 17279 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17280 doCpuKills = false; 17281 } 17282 int i = mLruProcesses.size(); 17283 while (i > 0) { 17284 i--; 17285 ProcessRecord app = mLruProcesses.get(i); 17286 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17287 long wtime; 17288 synchronized (stats) { 17289 wtime = stats.getProcessWakeTime(app.info.uid, 17290 app.pid, curRealtime); 17291 } 17292 long wtimeUsed = wtime - app.lastWakeTime; 17293 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17294 if (DEBUG_POWER) { 17295 StringBuilder sb = new StringBuilder(128); 17296 sb.append("Wake for "); 17297 app.toShortString(sb); 17298 sb.append(": over "); 17299 TimeUtils.formatDuration(realtimeSince, sb); 17300 sb.append(" used "); 17301 TimeUtils.formatDuration(wtimeUsed, sb); 17302 sb.append(" ("); 17303 sb.append((wtimeUsed*100)/realtimeSince); 17304 sb.append("%)"); 17305 Slog.i(TAG, sb.toString()); 17306 sb.setLength(0); 17307 sb.append("CPU for "); 17308 app.toShortString(sb); 17309 sb.append(": over "); 17310 TimeUtils.formatDuration(uptimeSince, sb); 17311 sb.append(" used "); 17312 TimeUtils.formatDuration(cputimeUsed, sb); 17313 sb.append(" ("); 17314 sb.append((cputimeUsed*100)/uptimeSince); 17315 sb.append("%)"); 17316 Slog.i(TAG, sb.toString()); 17317 } 17318 // If a process has held a wake lock for more 17319 // than 50% of the time during this period, 17320 // that sounds bad. Kill! 17321 if (doWakeKills && realtimeSince > 0 17322 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17323 synchronized (stats) { 17324 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17325 realtimeSince, wtimeUsed); 17326 } 17327 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17328 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17329 } else if (doCpuKills && uptimeSince > 0 17330 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17331 synchronized (stats) { 17332 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17333 uptimeSince, cputimeUsed); 17334 } 17335 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17336 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17337 } else { 17338 app.lastWakeTime = wtime; 17339 app.lastCpuTime = app.curCpuTime; 17340 } 17341 } 17342 } 17343 } 17344 17345 private final boolean applyOomAdjLocked(ProcessRecord app, 17346 ProcessRecord TOP_APP, boolean doingAll, long now) { 17347 boolean success = true; 17348 17349 if (app.curRawAdj != app.setRawAdj) { 17350 app.setRawAdj = app.curRawAdj; 17351 } 17352 17353 int changes = 0; 17354 17355 if (app.curAdj != app.setAdj) { 17356 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17357 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17358 TAG, "Set " + app.pid + " " + app.processName + 17359 " adj " + app.curAdj + ": " + app.adjType); 17360 app.setAdj = app.curAdj; 17361 } 17362 17363 if (app.setSchedGroup != app.curSchedGroup) { 17364 app.setSchedGroup = app.curSchedGroup; 17365 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17366 "Setting process group of " + app.processName 17367 + " to " + app.curSchedGroup); 17368 if (app.waitingToKill != null && 17369 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17370 app.kill(app.waitingToKill, true); 17371 success = false; 17372 } else { 17373 if (true) { 17374 long oldId = Binder.clearCallingIdentity(); 17375 try { 17376 Process.setProcessGroup(app.pid, app.curSchedGroup); 17377 } catch (Exception e) { 17378 Slog.w(TAG, "Failed setting process group of " + app.pid 17379 + " to " + app.curSchedGroup); 17380 e.printStackTrace(); 17381 } finally { 17382 Binder.restoreCallingIdentity(oldId); 17383 } 17384 } else { 17385 if (app.thread != null) { 17386 try { 17387 app.thread.setSchedulingGroup(app.curSchedGroup); 17388 } catch (RemoteException e) { 17389 } 17390 } 17391 } 17392 Process.setSwappiness(app.pid, 17393 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17394 } 17395 } 17396 if (app.repForegroundActivities != app.foregroundActivities) { 17397 app.repForegroundActivities = app.foregroundActivities; 17398 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17399 } 17400 if (app.repProcState != app.curProcState) { 17401 app.repProcState = app.curProcState; 17402 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17403 if (app.thread != null) { 17404 try { 17405 if (false) { 17406 //RuntimeException h = new RuntimeException("here"); 17407 Slog.i(TAG, "Sending new process state " + app.repProcState 17408 + " to " + app /*, h*/); 17409 } 17410 app.thread.setProcessState(app.repProcState); 17411 } catch (RemoteException e) { 17412 } 17413 } 17414 } 17415 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17416 app.setProcState)) { 17417 app.lastStateTime = now; 17418 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17419 isSleeping(), now); 17420 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17421 + ProcessList.makeProcStateString(app.setProcState) + " to " 17422 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17423 + (app.nextPssTime-now) + ": " + app); 17424 } else { 17425 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17426 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17427 requestPssLocked(app, app.setProcState); 17428 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17429 isSleeping(), now); 17430 } else if (false && DEBUG_PSS) { 17431 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17432 } 17433 } 17434 if (app.setProcState != app.curProcState) { 17435 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17436 "Proc state change of " + app.processName 17437 + " to " + app.curProcState); 17438 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17439 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17440 if (setImportant && !curImportant) { 17441 // This app is no longer something we consider important enough to allow to 17442 // use arbitrary amounts of battery power. Note 17443 // its current wake lock time to later know to kill it if 17444 // it is not behaving well. 17445 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17446 synchronized (stats) { 17447 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17448 app.pid, SystemClock.elapsedRealtime()); 17449 } 17450 app.lastCpuTime = app.curCpuTime; 17451 17452 } 17453 app.setProcState = app.curProcState; 17454 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17455 app.notCachedSinceIdle = false; 17456 } 17457 if (!doingAll) { 17458 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17459 } else { 17460 app.procStateChanged = true; 17461 } 17462 } 17463 17464 if (changes != 0) { 17465 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17466 int i = mPendingProcessChanges.size()-1; 17467 ProcessChangeItem item = null; 17468 while (i >= 0) { 17469 item = mPendingProcessChanges.get(i); 17470 if (item.pid == app.pid) { 17471 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17472 break; 17473 } 17474 i--; 17475 } 17476 if (i < 0) { 17477 // No existing item in pending changes; need a new one. 17478 final int NA = mAvailProcessChanges.size(); 17479 if (NA > 0) { 17480 item = mAvailProcessChanges.remove(NA-1); 17481 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17482 } else { 17483 item = new ProcessChangeItem(); 17484 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17485 } 17486 item.changes = 0; 17487 item.pid = app.pid; 17488 item.uid = app.info.uid; 17489 if (mPendingProcessChanges.size() == 0) { 17490 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17491 "*** Enqueueing dispatch processes changed!"); 17492 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17493 } 17494 mPendingProcessChanges.add(item); 17495 } 17496 item.changes |= changes; 17497 item.processState = app.repProcState; 17498 item.foregroundActivities = app.repForegroundActivities; 17499 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17500 + Integer.toHexString(System.identityHashCode(item)) 17501 + " " + app.toShortString() + ": changes=" + item.changes 17502 + " procState=" + item.processState 17503 + " foreground=" + item.foregroundActivities 17504 + " type=" + app.adjType + " source=" + app.adjSource 17505 + " target=" + app.adjTarget); 17506 } 17507 17508 return success; 17509 } 17510 17511 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17512 if (proc.thread != null) { 17513 if (proc.baseProcessTracker != null) { 17514 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17515 } 17516 if (proc.repProcState >= 0) { 17517 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17518 proc.repProcState); 17519 } 17520 } 17521 } 17522 17523 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17524 ProcessRecord TOP_APP, boolean doingAll, long now) { 17525 if (app.thread == null) { 17526 return false; 17527 } 17528 17529 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17530 17531 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17532 } 17533 17534 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17535 boolean oomAdj) { 17536 if (isForeground != proc.foregroundServices) { 17537 proc.foregroundServices = isForeground; 17538 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17539 proc.info.uid); 17540 if (isForeground) { 17541 if (curProcs == null) { 17542 curProcs = new ArrayList<ProcessRecord>(); 17543 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17544 } 17545 if (!curProcs.contains(proc)) { 17546 curProcs.add(proc); 17547 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17548 proc.info.packageName, proc.info.uid); 17549 } 17550 } else { 17551 if (curProcs != null) { 17552 if (curProcs.remove(proc)) { 17553 mBatteryStatsService.noteEvent( 17554 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17555 proc.info.packageName, proc.info.uid); 17556 if (curProcs.size() <= 0) { 17557 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17558 } 17559 } 17560 } 17561 } 17562 if (oomAdj) { 17563 updateOomAdjLocked(); 17564 } 17565 } 17566 } 17567 17568 private final ActivityRecord resumedAppLocked() { 17569 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17570 String pkg; 17571 int uid; 17572 if (act != null) { 17573 pkg = act.packageName; 17574 uid = act.info.applicationInfo.uid; 17575 } else { 17576 pkg = null; 17577 uid = -1; 17578 } 17579 // Has the UID or resumed package name changed? 17580 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17581 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17582 if (mCurResumedPackage != null) { 17583 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17584 mCurResumedPackage, mCurResumedUid); 17585 } 17586 mCurResumedPackage = pkg; 17587 mCurResumedUid = uid; 17588 if (mCurResumedPackage != null) { 17589 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17590 mCurResumedPackage, mCurResumedUid); 17591 } 17592 } 17593 return act; 17594 } 17595 17596 final boolean updateOomAdjLocked(ProcessRecord app) { 17597 final ActivityRecord TOP_ACT = resumedAppLocked(); 17598 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17599 final boolean wasCached = app.cached; 17600 17601 mAdjSeq++; 17602 17603 // This is the desired cached adjusment we want to tell it to use. 17604 // If our app is currently cached, we know it, and that is it. Otherwise, 17605 // we don't know it yet, and it needs to now be cached we will then 17606 // need to do a complete oom adj. 17607 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17608 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17609 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17610 SystemClock.uptimeMillis()); 17611 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17612 // Changed to/from cached state, so apps after it in the LRU 17613 // list may also be changed. 17614 updateOomAdjLocked(); 17615 } 17616 return success; 17617 } 17618 17619 final void updateOomAdjLocked() { 17620 final ActivityRecord TOP_ACT = resumedAppLocked(); 17621 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17622 final long now = SystemClock.uptimeMillis(); 17623 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17624 final int N = mLruProcesses.size(); 17625 17626 if (false) { 17627 RuntimeException e = new RuntimeException(); 17628 e.fillInStackTrace(); 17629 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17630 } 17631 17632 mAdjSeq++; 17633 mNewNumServiceProcs = 0; 17634 mNewNumAServiceProcs = 0; 17635 17636 final int emptyProcessLimit; 17637 final int cachedProcessLimit; 17638 if (mProcessLimit <= 0) { 17639 emptyProcessLimit = cachedProcessLimit = 0; 17640 } else if (mProcessLimit == 1) { 17641 emptyProcessLimit = 1; 17642 cachedProcessLimit = 0; 17643 } else { 17644 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17645 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17646 } 17647 17648 // Let's determine how many processes we have running vs. 17649 // how many slots we have for background processes; we may want 17650 // to put multiple processes in a slot of there are enough of 17651 // them. 17652 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17653 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17654 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17655 if (numEmptyProcs > cachedProcessLimit) { 17656 // If there are more empty processes than our limit on cached 17657 // processes, then use the cached process limit for the factor. 17658 // This ensures that the really old empty processes get pushed 17659 // down to the bottom, so if we are running low on memory we will 17660 // have a better chance at keeping around more cached processes 17661 // instead of a gazillion empty processes. 17662 numEmptyProcs = cachedProcessLimit; 17663 } 17664 int emptyFactor = numEmptyProcs/numSlots; 17665 if (emptyFactor < 1) emptyFactor = 1; 17666 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17667 if (cachedFactor < 1) cachedFactor = 1; 17668 int stepCached = 0; 17669 int stepEmpty = 0; 17670 int numCached = 0; 17671 int numEmpty = 0; 17672 int numTrimming = 0; 17673 17674 mNumNonCachedProcs = 0; 17675 mNumCachedHiddenProcs = 0; 17676 17677 // First update the OOM adjustment for each of the 17678 // application processes based on their current state. 17679 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17680 int nextCachedAdj = curCachedAdj+1; 17681 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17682 int nextEmptyAdj = curEmptyAdj+2; 17683 for (int i=N-1; i>=0; i--) { 17684 ProcessRecord app = mLruProcesses.get(i); 17685 if (!app.killedByAm && app.thread != null) { 17686 app.procStateChanged = false; 17687 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17688 17689 // If we haven't yet assigned the final cached adj 17690 // to the process, do that now. 17691 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17692 switch (app.curProcState) { 17693 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17694 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17695 // This process is a cached process holding activities... 17696 // assign it the next cached value for that type, and then 17697 // step that cached level. 17698 app.curRawAdj = curCachedAdj; 17699 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17700 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17701 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17702 + ")"); 17703 if (curCachedAdj != nextCachedAdj) { 17704 stepCached++; 17705 if (stepCached >= cachedFactor) { 17706 stepCached = 0; 17707 curCachedAdj = nextCachedAdj; 17708 nextCachedAdj += 2; 17709 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17710 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17711 } 17712 } 17713 } 17714 break; 17715 default: 17716 // For everything else, assign next empty cached process 17717 // level and bump that up. Note that this means that 17718 // long-running services that have dropped down to the 17719 // cached level will be treated as empty (since their process 17720 // state is still as a service), which is what we want. 17721 app.curRawAdj = curEmptyAdj; 17722 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17723 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17724 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17725 + ")"); 17726 if (curEmptyAdj != nextEmptyAdj) { 17727 stepEmpty++; 17728 if (stepEmpty >= emptyFactor) { 17729 stepEmpty = 0; 17730 curEmptyAdj = nextEmptyAdj; 17731 nextEmptyAdj += 2; 17732 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17733 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17734 } 17735 } 17736 } 17737 break; 17738 } 17739 } 17740 17741 applyOomAdjLocked(app, TOP_APP, true, now); 17742 17743 // Count the number of process types. 17744 switch (app.curProcState) { 17745 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17746 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17747 mNumCachedHiddenProcs++; 17748 numCached++; 17749 if (numCached > cachedProcessLimit) { 17750 app.kill("cached #" + numCached, true); 17751 } 17752 break; 17753 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17754 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17755 && app.lastActivityTime < oldTime) { 17756 app.kill("empty for " 17757 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17758 / 1000) + "s", true); 17759 } else { 17760 numEmpty++; 17761 if (numEmpty > emptyProcessLimit) { 17762 app.kill("empty #" + numEmpty, true); 17763 } 17764 } 17765 break; 17766 default: 17767 mNumNonCachedProcs++; 17768 break; 17769 } 17770 17771 if (app.isolated && app.services.size() <= 0) { 17772 // If this is an isolated process, and there are no 17773 // services running in it, then the process is no longer 17774 // needed. We agressively kill these because we can by 17775 // definition not re-use the same process again, and it is 17776 // good to avoid having whatever code was running in them 17777 // left sitting around after no longer needed. 17778 app.kill("isolated not needed", true); 17779 } 17780 17781 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17782 && !app.killedByAm) { 17783 numTrimming++; 17784 } 17785 } 17786 } 17787 17788 mNumServiceProcs = mNewNumServiceProcs; 17789 17790 // Now determine the memory trimming level of background processes. 17791 // Unfortunately we need to start at the back of the list to do this 17792 // properly. We only do this if the number of background apps we 17793 // are managing to keep around is less than half the maximum we desire; 17794 // if we are keeping a good number around, we'll let them use whatever 17795 // memory they want. 17796 final int numCachedAndEmpty = numCached + numEmpty; 17797 int memFactor; 17798 if (numCached <= ProcessList.TRIM_CACHED_APPS 17799 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17800 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17801 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17802 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17803 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17804 } else { 17805 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17806 } 17807 } else { 17808 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17809 } 17810 // We always allow the memory level to go up (better). We only allow it to go 17811 // down if we are in a state where that is allowed, *and* the total number of processes 17812 // has gone down since last time. 17813 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17814 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17815 + " last=" + mLastNumProcesses); 17816 if (memFactor > mLastMemoryLevel) { 17817 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17818 memFactor = mLastMemoryLevel; 17819 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17820 } 17821 } 17822 mLastMemoryLevel = memFactor; 17823 mLastNumProcesses = mLruProcesses.size(); 17824 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17825 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17826 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17827 if (mLowRamStartTime == 0) { 17828 mLowRamStartTime = now; 17829 } 17830 int step = 0; 17831 int fgTrimLevel; 17832 switch (memFactor) { 17833 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17834 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17835 break; 17836 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17837 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17838 break; 17839 default: 17840 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17841 break; 17842 } 17843 int factor = numTrimming/3; 17844 int minFactor = 2; 17845 if (mHomeProcess != null) minFactor++; 17846 if (mPreviousProcess != null) minFactor++; 17847 if (factor < minFactor) factor = minFactor; 17848 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17849 for (int i=N-1; i>=0; i--) { 17850 ProcessRecord app = mLruProcesses.get(i); 17851 if (allChanged || app.procStateChanged) { 17852 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17853 app.procStateChanged = false; 17854 } 17855 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17856 && !app.killedByAm) { 17857 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17858 try { 17859 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17860 "Trimming memory of " + app.processName 17861 + " to " + curLevel); 17862 app.thread.scheduleTrimMemory(curLevel); 17863 } catch (RemoteException e) { 17864 } 17865 if (false) { 17866 // For now we won't do this; our memory trimming seems 17867 // to be good enough at this point that destroying 17868 // activities causes more harm than good. 17869 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17870 && app != mHomeProcess && app != mPreviousProcess) { 17871 // Need to do this on its own message because the stack may not 17872 // be in a consistent state at this point. 17873 // For these apps we will also finish their activities 17874 // to help them free memory. 17875 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17876 } 17877 } 17878 } 17879 app.trimMemoryLevel = curLevel; 17880 step++; 17881 if (step >= factor) { 17882 step = 0; 17883 switch (curLevel) { 17884 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17885 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17886 break; 17887 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17888 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17889 break; 17890 } 17891 } 17892 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17893 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17894 && app.thread != null) { 17895 try { 17896 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17897 "Trimming memory of heavy-weight " + app.processName 17898 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17899 app.thread.scheduleTrimMemory( 17900 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17901 } catch (RemoteException e) { 17902 } 17903 } 17904 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17905 } else { 17906 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17907 || app.systemNoUi) && app.pendingUiClean) { 17908 // If this application is now in the background and it 17909 // had done UI, then give it the special trim level to 17910 // have it free UI resources. 17911 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17912 if (app.trimMemoryLevel < level && app.thread != null) { 17913 try { 17914 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17915 "Trimming memory of bg-ui " + app.processName 17916 + " to " + level); 17917 app.thread.scheduleTrimMemory(level); 17918 } catch (RemoteException e) { 17919 } 17920 } 17921 app.pendingUiClean = false; 17922 } 17923 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17924 try { 17925 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17926 "Trimming memory of fg " + app.processName 17927 + " to " + fgTrimLevel); 17928 app.thread.scheduleTrimMemory(fgTrimLevel); 17929 } catch (RemoteException e) { 17930 } 17931 } 17932 app.trimMemoryLevel = fgTrimLevel; 17933 } 17934 } 17935 } else { 17936 if (mLowRamStartTime != 0) { 17937 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17938 mLowRamStartTime = 0; 17939 } 17940 for (int i=N-1; i>=0; i--) { 17941 ProcessRecord app = mLruProcesses.get(i); 17942 if (allChanged || app.procStateChanged) { 17943 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17944 app.procStateChanged = false; 17945 } 17946 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17947 || app.systemNoUi) && app.pendingUiClean) { 17948 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17949 && app.thread != null) { 17950 try { 17951 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17952 "Trimming memory of ui hidden " + app.processName 17953 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17954 app.thread.scheduleTrimMemory( 17955 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17956 } catch (RemoteException e) { 17957 } 17958 } 17959 app.pendingUiClean = false; 17960 } 17961 app.trimMemoryLevel = 0; 17962 } 17963 } 17964 17965 if (mAlwaysFinishActivities) { 17966 // Need to do this on its own message because the stack may not 17967 // be in a consistent state at this point. 17968 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17969 } 17970 17971 if (allChanged) { 17972 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17973 } 17974 17975 if (mProcessStats.shouldWriteNowLocked(now)) { 17976 mHandler.post(new Runnable() { 17977 @Override public void run() { 17978 synchronized (ActivityManagerService.this) { 17979 mProcessStats.writeStateAsyncLocked(); 17980 } 17981 } 17982 }); 17983 } 17984 17985 if (DEBUG_OOM_ADJ) { 17986 if (false) { 17987 RuntimeException here = new RuntimeException("here"); 17988 here.fillInStackTrace(); 17989 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17990 } else { 17991 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17992 } 17993 } 17994 } 17995 17996 final void trimApplications() { 17997 synchronized (this) { 17998 int i; 17999 18000 // First remove any unused application processes whose package 18001 // has been removed. 18002 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18003 final ProcessRecord app = mRemovedProcesses.get(i); 18004 if (app.activities.size() == 0 18005 && app.curReceiver == null && app.services.size() == 0) { 18006 Slog.i( 18007 TAG, "Exiting empty application process " 18008 + app.processName + " (" 18009 + (app.thread != null ? app.thread.asBinder() : null) 18010 + ")\n"); 18011 if (app.pid > 0 && app.pid != MY_PID) { 18012 app.kill("empty", false); 18013 } else { 18014 try { 18015 app.thread.scheduleExit(); 18016 } catch (Exception e) { 18017 // Ignore exceptions. 18018 } 18019 } 18020 cleanUpApplicationRecordLocked(app, false, true, -1); 18021 mRemovedProcesses.remove(i); 18022 18023 if (app.persistent) { 18024 addAppLocked(app.info, false, null /* ABI override */); 18025 } 18026 } 18027 } 18028 18029 // Now update the oom adj for all processes. 18030 updateOomAdjLocked(); 18031 } 18032 } 18033 18034 /** This method sends the specified signal to each of the persistent apps */ 18035 public void signalPersistentProcesses(int sig) throws RemoteException { 18036 if (sig != Process.SIGNAL_USR1) { 18037 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18038 } 18039 18040 synchronized (this) { 18041 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18042 != PackageManager.PERMISSION_GRANTED) { 18043 throw new SecurityException("Requires permission " 18044 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18045 } 18046 18047 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18048 ProcessRecord r = mLruProcesses.get(i); 18049 if (r.thread != null && r.persistent) { 18050 Process.sendSignal(r.pid, sig); 18051 } 18052 } 18053 } 18054 } 18055 18056 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18057 if (proc == null || proc == mProfileProc) { 18058 proc = mProfileProc; 18059 profileType = mProfileType; 18060 clearProfilerLocked(); 18061 } 18062 if (proc == null) { 18063 return; 18064 } 18065 try { 18066 proc.thread.profilerControl(false, null, profileType); 18067 } catch (RemoteException e) { 18068 throw new IllegalStateException("Process disappeared"); 18069 } 18070 } 18071 18072 private void clearProfilerLocked() { 18073 if (mProfileFd != null) { 18074 try { 18075 mProfileFd.close(); 18076 } catch (IOException e) { 18077 } 18078 } 18079 mProfileApp = null; 18080 mProfileProc = null; 18081 mProfileFile = null; 18082 mProfileType = 0; 18083 mAutoStopProfiler = false; 18084 mSamplingInterval = 0; 18085 } 18086 18087 public boolean profileControl(String process, int userId, boolean start, 18088 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18089 18090 try { 18091 synchronized (this) { 18092 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18093 // its own permission. 18094 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18095 != PackageManager.PERMISSION_GRANTED) { 18096 throw new SecurityException("Requires permission " 18097 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18098 } 18099 18100 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18101 throw new IllegalArgumentException("null profile info or fd"); 18102 } 18103 18104 ProcessRecord proc = null; 18105 if (process != null) { 18106 proc = findProcessLocked(process, userId, "profileControl"); 18107 } 18108 18109 if (start && (proc == null || proc.thread == null)) { 18110 throw new IllegalArgumentException("Unknown process: " + process); 18111 } 18112 18113 if (start) { 18114 stopProfilerLocked(null, 0); 18115 setProfileApp(proc.info, proc.processName, profilerInfo); 18116 mProfileProc = proc; 18117 mProfileType = profileType; 18118 ParcelFileDescriptor fd = profilerInfo.profileFd; 18119 try { 18120 fd = fd.dup(); 18121 } catch (IOException e) { 18122 fd = null; 18123 } 18124 profilerInfo.profileFd = fd; 18125 proc.thread.profilerControl(start, profilerInfo, profileType); 18126 fd = null; 18127 mProfileFd = null; 18128 } else { 18129 stopProfilerLocked(proc, profileType); 18130 if (profilerInfo != null && profilerInfo.profileFd != null) { 18131 try { 18132 profilerInfo.profileFd.close(); 18133 } catch (IOException e) { 18134 } 18135 } 18136 } 18137 18138 return true; 18139 } 18140 } catch (RemoteException e) { 18141 throw new IllegalStateException("Process disappeared"); 18142 } finally { 18143 if (profilerInfo != null && profilerInfo.profileFd != null) { 18144 try { 18145 profilerInfo.profileFd.close(); 18146 } catch (IOException e) { 18147 } 18148 } 18149 } 18150 } 18151 18152 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18153 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18154 userId, true, ALLOW_FULL_ONLY, callName, null); 18155 ProcessRecord proc = null; 18156 try { 18157 int pid = Integer.parseInt(process); 18158 synchronized (mPidsSelfLocked) { 18159 proc = mPidsSelfLocked.get(pid); 18160 } 18161 } catch (NumberFormatException e) { 18162 } 18163 18164 if (proc == null) { 18165 ArrayMap<String, SparseArray<ProcessRecord>> all 18166 = mProcessNames.getMap(); 18167 SparseArray<ProcessRecord> procs = all.get(process); 18168 if (procs != null && procs.size() > 0) { 18169 proc = procs.valueAt(0); 18170 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18171 for (int i=1; i<procs.size(); i++) { 18172 ProcessRecord thisProc = procs.valueAt(i); 18173 if (thisProc.userId == userId) { 18174 proc = thisProc; 18175 break; 18176 } 18177 } 18178 } 18179 } 18180 } 18181 18182 return proc; 18183 } 18184 18185 public boolean dumpHeap(String process, int userId, boolean managed, 18186 String path, ParcelFileDescriptor fd) throws RemoteException { 18187 18188 try { 18189 synchronized (this) { 18190 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18191 // its own permission (same as profileControl). 18192 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18193 != PackageManager.PERMISSION_GRANTED) { 18194 throw new SecurityException("Requires permission " 18195 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18196 } 18197 18198 if (fd == null) { 18199 throw new IllegalArgumentException("null fd"); 18200 } 18201 18202 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18203 if (proc == null || proc.thread == null) { 18204 throw new IllegalArgumentException("Unknown process: " + process); 18205 } 18206 18207 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18208 if (!isDebuggable) { 18209 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18210 throw new SecurityException("Process not debuggable: " + proc); 18211 } 18212 } 18213 18214 proc.thread.dumpHeap(managed, path, fd); 18215 fd = null; 18216 return true; 18217 } 18218 } catch (RemoteException e) { 18219 throw new IllegalStateException("Process disappeared"); 18220 } finally { 18221 if (fd != null) { 18222 try { 18223 fd.close(); 18224 } catch (IOException e) { 18225 } 18226 } 18227 } 18228 } 18229 18230 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18231 public void monitor() { 18232 synchronized (this) { } 18233 } 18234 18235 void onCoreSettingsChange(Bundle settings) { 18236 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18237 ProcessRecord processRecord = mLruProcesses.get(i); 18238 try { 18239 if (processRecord.thread != null) { 18240 processRecord.thread.setCoreSettings(settings); 18241 } 18242 } catch (RemoteException re) { 18243 /* ignore */ 18244 } 18245 } 18246 } 18247 18248 // Multi-user methods 18249 18250 /** 18251 * Start user, if its not already running, but don't bring it to foreground. 18252 */ 18253 @Override 18254 public boolean startUserInBackground(final int userId) { 18255 return startUser(userId, /* foreground */ false); 18256 } 18257 18258 /** 18259 * Start user, if its not already running, and bring it to foreground. 18260 */ 18261 boolean startUserInForeground(final int userId, Dialog dlg) { 18262 boolean result = startUser(userId, /* foreground */ true); 18263 dlg.dismiss(); 18264 return result; 18265 } 18266 18267 /** 18268 * Refreshes the list of users related to the current user when either a 18269 * user switch happens or when a new related user is started in the 18270 * background. 18271 */ 18272 private void updateCurrentProfileIdsLocked() { 18273 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18274 mCurrentUserId, false /* enabledOnly */); 18275 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18276 for (int i = 0; i < currentProfileIds.length; i++) { 18277 currentProfileIds[i] = profiles.get(i).id; 18278 } 18279 mCurrentProfileIds = currentProfileIds; 18280 18281 synchronized (mUserProfileGroupIdsSelfLocked) { 18282 mUserProfileGroupIdsSelfLocked.clear(); 18283 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18284 for (int i = 0; i < users.size(); i++) { 18285 UserInfo user = users.get(i); 18286 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18287 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18288 } 18289 } 18290 } 18291 } 18292 18293 private Set getProfileIdsLocked(int userId) { 18294 Set userIds = new HashSet<Integer>(); 18295 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18296 userId, false /* enabledOnly */); 18297 for (UserInfo user : profiles) { 18298 userIds.add(Integer.valueOf(user.id)); 18299 } 18300 return userIds; 18301 } 18302 18303 @Override 18304 public boolean switchUser(final int userId) { 18305 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18306 String userName; 18307 synchronized (this) { 18308 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18309 if (userInfo == null) { 18310 Slog.w(TAG, "No user info for user #" + userId); 18311 return false; 18312 } 18313 if (userInfo.isManagedProfile()) { 18314 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18315 return false; 18316 } 18317 userName = userInfo.name; 18318 mTargetUserId = userId; 18319 } 18320 mHandler.removeMessages(START_USER_SWITCH_MSG); 18321 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18322 return true; 18323 } 18324 18325 private void showUserSwitchDialog(int userId, String userName) { 18326 // The dialog will show and then initiate the user switch by calling startUserInForeground 18327 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18328 true /* above system */); 18329 d.show(); 18330 } 18331 18332 private boolean startUser(final int userId, final boolean foreground) { 18333 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18334 != PackageManager.PERMISSION_GRANTED) { 18335 String msg = "Permission Denial: switchUser() from pid=" 18336 + Binder.getCallingPid() 18337 + ", uid=" + Binder.getCallingUid() 18338 + " requires " + INTERACT_ACROSS_USERS_FULL; 18339 Slog.w(TAG, msg); 18340 throw new SecurityException(msg); 18341 } 18342 18343 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18344 18345 final long ident = Binder.clearCallingIdentity(); 18346 try { 18347 synchronized (this) { 18348 final int oldUserId = mCurrentUserId; 18349 if (oldUserId == userId) { 18350 return true; 18351 } 18352 18353 mStackSupervisor.setLockTaskModeLocked(null, false); 18354 18355 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18356 if (userInfo == null) { 18357 Slog.w(TAG, "No user info for user #" + userId); 18358 return false; 18359 } 18360 if (foreground && userInfo.isManagedProfile()) { 18361 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18362 return false; 18363 } 18364 18365 if (foreground) { 18366 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18367 R.anim.screen_user_enter); 18368 } 18369 18370 boolean needStart = false; 18371 18372 // If the user we are switching to is not currently started, then 18373 // we need to start it now. 18374 if (mStartedUsers.get(userId) == null) { 18375 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18376 updateStartedUserArrayLocked(); 18377 needStart = true; 18378 } 18379 18380 final Integer userIdInt = Integer.valueOf(userId); 18381 mUserLru.remove(userIdInt); 18382 mUserLru.add(userIdInt); 18383 18384 if (foreground) { 18385 mCurrentUserId = userId; 18386 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18387 updateCurrentProfileIdsLocked(); 18388 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18389 // Once the internal notion of the active user has switched, we lock the device 18390 // with the option to show the user switcher on the keyguard. 18391 mWindowManager.lockNow(null); 18392 } else { 18393 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18394 updateCurrentProfileIdsLocked(); 18395 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18396 mUserLru.remove(currentUserIdInt); 18397 mUserLru.add(currentUserIdInt); 18398 } 18399 18400 final UserStartedState uss = mStartedUsers.get(userId); 18401 18402 // Make sure user is in the started state. If it is currently 18403 // stopping, we need to knock that off. 18404 if (uss.mState == UserStartedState.STATE_STOPPING) { 18405 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18406 // so we can just fairly silently bring the user back from 18407 // the almost-dead. 18408 uss.mState = UserStartedState.STATE_RUNNING; 18409 updateStartedUserArrayLocked(); 18410 needStart = true; 18411 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18412 // This means ACTION_SHUTDOWN has been sent, so we will 18413 // need to treat this as a new boot of the user. 18414 uss.mState = UserStartedState.STATE_BOOTING; 18415 updateStartedUserArrayLocked(); 18416 needStart = true; 18417 } 18418 18419 if (uss.mState == UserStartedState.STATE_BOOTING) { 18420 // Booting up a new user, need to tell system services about it. 18421 // Note that this is on the same handler as scheduling of broadcasts, 18422 // which is important because it needs to go first. 18423 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18424 } 18425 18426 if (foreground) { 18427 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18428 oldUserId)); 18429 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18430 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18431 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18432 oldUserId, userId, uss)); 18433 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18434 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18435 } 18436 18437 if (needStart) { 18438 // Send USER_STARTED broadcast 18439 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18440 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18441 | Intent.FLAG_RECEIVER_FOREGROUND); 18442 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18443 broadcastIntentLocked(null, null, intent, 18444 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18445 false, false, MY_PID, Process.SYSTEM_UID, userId); 18446 } 18447 18448 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18449 if (userId != UserHandle.USER_OWNER) { 18450 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18451 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18452 broadcastIntentLocked(null, null, intent, null, 18453 new IIntentReceiver.Stub() { 18454 public void performReceive(Intent intent, int resultCode, 18455 String data, Bundle extras, boolean ordered, 18456 boolean sticky, int sendingUser) { 18457 onUserInitialized(uss, foreground, oldUserId, userId); 18458 } 18459 }, 0, null, null, null, AppOpsManager.OP_NONE, 18460 true, false, MY_PID, Process.SYSTEM_UID, 18461 userId); 18462 uss.initializing = true; 18463 } else { 18464 getUserManagerLocked().makeInitialized(userInfo.id); 18465 } 18466 } 18467 18468 if (foreground) { 18469 if (!uss.initializing) { 18470 moveUserToForeground(uss, oldUserId, userId); 18471 } 18472 } else { 18473 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18474 } 18475 18476 if (needStart) { 18477 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18479 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18480 broadcastIntentLocked(null, null, intent, 18481 null, new IIntentReceiver.Stub() { 18482 @Override 18483 public void performReceive(Intent intent, int resultCode, String data, 18484 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18485 throws RemoteException { 18486 } 18487 }, 0, null, null, 18488 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18489 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18490 } 18491 } 18492 } finally { 18493 Binder.restoreCallingIdentity(ident); 18494 } 18495 18496 return true; 18497 } 18498 18499 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18500 long ident = Binder.clearCallingIdentity(); 18501 try { 18502 Intent intent; 18503 if (oldUserId >= 0) { 18504 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18505 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18506 int count = profiles.size(); 18507 for (int i = 0; i < count; i++) { 18508 int profileUserId = profiles.get(i).id; 18509 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18510 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18511 | Intent.FLAG_RECEIVER_FOREGROUND); 18512 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18513 broadcastIntentLocked(null, null, intent, 18514 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18515 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18516 } 18517 } 18518 if (newUserId >= 0) { 18519 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18520 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18521 int count = profiles.size(); 18522 for (int i = 0; i < count; i++) { 18523 int profileUserId = profiles.get(i).id; 18524 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18525 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18526 | Intent.FLAG_RECEIVER_FOREGROUND); 18527 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18528 broadcastIntentLocked(null, null, intent, 18529 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18530 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18531 } 18532 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18533 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18534 | Intent.FLAG_RECEIVER_FOREGROUND); 18535 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18536 broadcastIntentLocked(null, null, intent, 18537 null, null, 0, null, null, 18538 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18539 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18540 } 18541 } finally { 18542 Binder.restoreCallingIdentity(ident); 18543 } 18544 } 18545 18546 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18547 final int newUserId) { 18548 final int N = mUserSwitchObservers.beginBroadcast(); 18549 if (N > 0) { 18550 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18551 int mCount = 0; 18552 @Override 18553 public void sendResult(Bundle data) throws RemoteException { 18554 synchronized (ActivityManagerService.this) { 18555 if (mCurUserSwitchCallback == this) { 18556 mCount++; 18557 if (mCount == N) { 18558 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18559 } 18560 } 18561 } 18562 } 18563 }; 18564 synchronized (this) { 18565 uss.switching = true; 18566 mCurUserSwitchCallback = callback; 18567 } 18568 for (int i=0; i<N; i++) { 18569 try { 18570 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18571 newUserId, callback); 18572 } catch (RemoteException e) { 18573 } 18574 } 18575 } else { 18576 synchronized (this) { 18577 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18578 } 18579 } 18580 mUserSwitchObservers.finishBroadcast(); 18581 } 18582 18583 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18584 synchronized (this) { 18585 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18586 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18587 } 18588 } 18589 18590 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18591 mCurUserSwitchCallback = null; 18592 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18593 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18594 oldUserId, newUserId, uss)); 18595 } 18596 18597 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18598 synchronized (this) { 18599 if (foreground) { 18600 moveUserToForeground(uss, oldUserId, newUserId); 18601 } 18602 } 18603 18604 completeSwitchAndInitalize(uss, newUserId, true, false); 18605 } 18606 18607 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18608 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18609 if (homeInFront) { 18610 startHomeActivityLocked(newUserId); 18611 } else { 18612 mStackSupervisor.resumeTopActivitiesLocked(); 18613 } 18614 EventLogTags.writeAmSwitchUser(newUserId); 18615 getUserManagerLocked().userForeground(newUserId); 18616 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18617 } 18618 18619 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18620 completeSwitchAndInitalize(uss, newUserId, false, true); 18621 } 18622 18623 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18624 boolean clearInitializing, boolean clearSwitching) { 18625 boolean unfrozen = false; 18626 synchronized (this) { 18627 if (clearInitializing) { 18628 uss.initializing = false; 18629 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18630 } 18631 if (clearSwitching) { 18632 uss.switching = false; 18633 } 18634 if (!uss.switching && !uss.initializing) { 18635 mWindowManager.stopFreezingScreen(); 18636 unfrozen = true; 18637 } 18638 } 18639 if (unfrozen) { 18640 final int N = mUserSwitchObservers.beginBroadcast(); 18641 for (int i=0; i<N; i++) { 18642 try { 18643 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18644 } catch (RemoteException e) { 18645 } 18646 } 18647 mUserSwitchObservers.finishBroadcast(); 18648 } 18649 } 18650 18651 void scheduleStartProfilesLocked() { 18652 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18653 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18654 DateUtils.SECOND_IN_MILLIS); 18655 } 18656 } 18657 18658 void startProfilesLocked() { 18659 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18660 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18661 mCurrentUserId, false /* enabledOnly */); 18662 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18663 for (UserInfo user : profiles) { 18664 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18665 && user.id != mCurrentUserId) { 18666 toStart.add(user); 18667 } 18668 } 18669 final int n = toStart.size(); 18670 int i = 0; 18671 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18672 startUserInBackground(toStart.get(i).id); 18673 } 18674 if (i < n) { 18675 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18676 } 18677 } 18678 18679 void finishUserBoot(UserStartedState uss) { 18680 synchronized (this) { 18681 if (uss.mState == UserStartedState.STATE_BOOTING 18682 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18683 uss.mState = UserStartedState.STATE_RUNNING; 18684 final int userId = uss.mHandle.getIdentifier(); 18685 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18686 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18687 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18688 broadcastIntentLocked(null, null, intent, 18689 null, null, 0, null, null, 18690 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18691 true, false, MY_PID, Process.SYSTEM_UID, userId); 18692 } 18693 } 18694 } 18695 18696 void finishUserSwitch(UserStartedState uss) { 18697 synchronized (this) { 18698 finishUserBoot(uss); 18699 18700 startProfilesLocked(); 18701 18702 int num = mUserLru.size(); 18703 int i = 0; 18704 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18705 Integer oldUserId = mUserLru.get(i); 18706 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18707 if (oldUss == null) { 18708 // Shouldn't happen, but be sane if it does. 18709 mUserLru.remove(i); 18710 num--; 18711 continue; 18712 } 18713 if (oldUss.mState == UserStartedState.STATE_STOPPING 18714 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18715 // This user is already stopping, doesn't count. 18716 num--; 18717 i++; 18718 continue; 18719 } 18720 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18721 // Owner and current can't be stopped, but count as running. 18722 i++; 18723 continue; 18724 } 18725 // This is a user to be stopped. 18726 stopUserLocked(oldUserId, null); 18727 num--; 18728 i++; 18729 } 18730 } 18731 } 18732 18733 @Override 18734 public int stopUser(final int userId, final IStopUserCallback callback) { 18735 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18736 != PackageManager.PERMISSION_GRANTED) { 18737 String msg = "Permission Denial: switchUser() from pid=" 18738 + Binder.getCallingPid() 18739 + ", uid=" + Binder.getCallingUid() 18740 + " requires " + INTERACT_ACROSS_USERS_FULL; 18741 Slog.w(TAG, msg); 18742 throw new SecurityException(msg); 18743 } 18744 if (userId <= 0) { 18745 throw new IllegalArgumentException("Can't stop primary user " + userId); 18746 } 18747 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18748 synchronized (this) { 18749 return stopUserLocked(userId, callback); 18750 } 18751 } 18752 18753 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18754 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18755 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18756 return ActivityManager.USER_OP_IS_CURRENT; 18757 } 18758 18759 final UserStartedState uss = mStartedUsers.get(userId); 18760 if (uss == null) { 18761 // User is not started, nothing to do... but we do need to 18762 // callback if requested. 18763 if (callback != null) { 18764 mHandler.post(new Runnable() { 18765 @Override 18766 public void run() { 18767 try { 18768 callback.userStopped(userId); 18769 } catch (RemoteException e) { 18770 } 18771 } 18772 }); 18773 } 18774 return ActivityManager.USER_OP_SUCCESS; 18775 } 18776 18777 if (callback != null) { 18778 uss.mStopCallbacks.add(callback); 18779 } 18780 18781 if (uss.mState != UserStartedState.STATE_STOPPING 18782 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18783 uss.mState = UserStartedState.STATE_STOPPING; 18784 updateStartedUserArrayLocked(); 18785 18786 long ident = Binder.clearCallingIdentity(); 18787 try { 18788 // We are going to broadcast ACTION_USER_STOPPING and then 18789 // once that is done send a final ACTION_SHUTDOWN and then 18790 // stop the user. 18791 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18792 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18793 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18794 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18795 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18796 // This is the result receiver for the final shutdown broadcast. 18797 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18798 @Override 18799 public void performReceive(Intent intent, int resultCode, String data, 18800 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18801 finishUserStop(uss); 18802 } 18803 }; 18804 // This is the result receiver for the initial stopping broadcast. 18805 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18806 @Override 18807 public void performReceive(Intent intent, int resultCode, String data, 18808 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18809 // On to the next. 18810 synchronized (ActivityManagerService.this) { 18811 if (uss.mState != UserStartedState.STATE_STOPPING) { 18812 // Whoops, we are being started back up. Abort, abort! 18813 return; 18814 } 18815 uss.mState = UserStartedState.STATE_SHUTDOWN; 18816 } 18817 mBatteryStatsService.noteEvent( 18818 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18819 Integer.toString(userId), userId); 18820 mSystemServiceManager.stopUser(userId); 18821 broadcastIntentLocked(null, null, shutdownIntent, 18822 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18823 true, false, MY_PID, Process.SYSTEM_UID, userId); 18824 } 18825 }; 18826 // Kick things off. 18827 broadcastIntentLocked(null, null, stoppingIntent, 18828 null, stoppingReceiver, 0, null, null, 18829 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18830 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18831 } finally { 18832 Binder.restoreCallingIdentity(ident); 18833 } 18834 } 18835 18836 return ActivityManager.USER_OP_SUCCESS; 18837 } 18838 18839 void finishUserStop(UserStartedState uss) { 18840 final int userId = uss.mHandle.getIdentifier(); 18841 boolean stopped; 18842 ArrayList<IStopUserCallback> callbacks; 18843 synchronized (this) { 18844 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18845 if (mStartedUsers.get(userId) != uss) { 18846 stopped = false; 18847 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18848 stopped = false; 18849 } else { 18850 stopped = true; 18851 // User can no longer run. 18852 mStartedUsers.remove(userId); 18853 mUserLru.remove(Integer.valueOf(userId)); 18854 updateStartedUserArrayLocked(); 18855 18856 // Clean up all state and processes associated with the user. 18857 // Kill all the processes for the user. 18858 forceStopUserLocked(userId, "finish user"); 18859 } 18860 18861 // Explicitly remove the old information in mRecentTasks. 18862 removeRecentTasksForUserLocked(userId); 18863 } 18864 18865 for (int i=0; i<callbacks.size(); i++) { 18866 try { 18867 if (stopped) callbacks.get(i).userStopped(userId); 18868 else callbacks.get(i).userStopAborted(userId); 18869 } catch (RemoteException e) { 18870 } 18871 } 18872 18873 if (stopped) { 18874 mSystemServiceManager.cleanupUser(userId); 18875 synchronized (this) { 18876 mStackSupervisor.removeUserLocked(userId); 18877 } 18878 } 18879 } 18880 18881 @Override 18882 public UserInfo getCurrentUser() { 18883 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18884 != PackageManager.PERMISSION_GRANTED) && ( 18885 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18886 != PackageManager.PERMISSION_GRANTED)) { 18887 String msg = "Permission Denial: getCurrentUser() from pid=" 18888 + Binder.getCallingPid() 18889 + ", uid=" + Binder.getCallingUid() 18890 + " requires " + INTERACT_ACROSS_USERS; 18891 Slog.w(TAG, msg); 18892 throw new SecurityException(msg); 18893 } 18894 synchronized (this) { 18895 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18896 return getUserManagerLocked().getUserInfo(userId); 18897 } 18898 } 18899 18900 int getCurrentUserIdLocked() { 18901 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18902 } 18903 18904 @Override 18905 public boolean isUserRunning(int userId, boolean orStopped) { 18906 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18907 != PackageManager.PERMISSION_GRANTED) { 18908 String msg = "Permission Denial: isUserRunning() from pid=" 18909 + Binder.getCallingPid() 18910 + ", uid=" + Binder.getCallingUid() 18911 + " requires " + INTERACT_ACROSS_USERS; 18912 Slog.w(TAG, msg); 18913 throw new SecurityException(msg); 18914 } 18915 synchronized (this) { 18916 return isUserRunningLocked(userId, orStopped); 18917 } 18918 } 18919 18920 boolean isUserRunningLocked(int userId, boolean orStopped) { 18921 UserStartedState state = mStartedUsers.get(userId); 18922 if (state == null) { 18923 return false; 18924 } 18925 if (orStopped) { 18926 return true; 18927 } 18928 return state.mState != UserStartedState.STATE_STOPPING 18929 && state.mState != UserStartedState.STATE_SHUTDOWN; 18930 } 18931 18932 @Override 18933 public int[] getRunningUserIds() { 18934 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18935 != PackageManager.PERMISSION_GRANTED) { 18936 String msg = "Permission Denial: isUserRunning() from pid=" 18937 + Binder.getCallingPid() 18938 + ", uid=" + Binder.getCallingUid() 18939 + " requires " + INTERACT_ACROSS_USERS; 18940 Slog.w(TAG, msg); 18941 throw new SecurityException(msg); 18942 } 18943 synchronized (this) { 18944 return mStartedUserArray; 18945 } 18946 } 18947 18948 private void updateStartedUserArrayLocked() { 18949 int num = 0; 18950 for (int i=0; i<mStartedUsers.size(); i++) { 18951 UserStartedState uss = mStartedUsers.valueAt(i); 18952 // This list does not include stopping users. 18953 if (uss.mState != UserStartedState.STATE_STOPPING 18954 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18955 num++; 18956 } 18957 } 18958 mStartedUserArray = new int[num]; 18959 num = 0; 18960 for (int i=0; i<mStartedUsers.size(); i++) { 18961 UserStartedState uss = mStartedUsers.valueAt(i); 18962 if (uss.mState != UserStartedState.STATE_STOPPING 18963 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18964 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18965 num++; 18966 } 18967 } 18968 } 18969 18970 @Override 18971 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18972 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18973 != PackageManager.PERMISSION_GRANTED) { 18974 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18975 + Binder.getCallingPid() 18976 + ", uid=" + Binder.getCallingUid() 18977 + " requires " + INTERACT_ACROSS_USERS_FULL; 18978 Slog.w(TAG, msg); 18979 throw new SecurityException(msg); 18980 } 18981 18982 mUserSwitchObservers.register(observer); 18983 } 18984 18985 @Override 18986 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18987 mUserSwitchObservers.unregister(observer); 18988 } 18989 18990 private boolean userExists(int userId) { 18991 if (userId == 0) { 18992 return true; 18993 } 18994 UserManagerService ums = getUserManagerLocked(); 18995 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18996 } 18997 18998 int[] getUsersLocked() { 18999 UserManagerService ums = getUserManagerLocked(); 19000 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19001 } 19002 19003 UserManagerService getUserManagerLocked() { 19004 if (mUserManager == null) { 19005 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19006 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19007 } 19008 return mUserManager; 19009 } 19010 19011 private int applyUserId(int uid, int userId) { 19012 return UserHandle.getUid(userId, uid); 19013 } 19014 19015 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19016 if (info == null) return null; 19017 ApplicationInfo newInfo = new ApplicationInfo(info); 19018 newInfo.uid = applyUserId(info.uid, userId); 19019 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19020 + info.packageName; 19021 return newInfo; 19022 } 19023 19024 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19025 if (aInfo == null 19026 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19027 return aInfo; 19028 } 19029 19030 ActivityInfo info = new ActivityInfo(aInfo); 19031 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19032 return info; 19033 } 19034 19035 private final class LocalService extends ActivityManagerInternal { 19036 @Override 19037 public void goingToSleep() { 19038 ActivityManagerService.this.goingToSleep(); 19039 } 19040 19041 @Override 19042 public void wakingUp() { 19043 ActivityManagerService.this.wakingUp(); 19044 } 19045 19046 @Override 19047 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19048 String processName, String abiOverride, int uid, Runnable crashHandler) { 19049 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19050 processName, abiOverride, uid, crashHandler); 19051 } 19052 } 19053 19054 /** 19055 * An implementation of IAppTask, that allows an app to manage its own tasks via 19056 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19057 * only the process that calls getAppTasks() can call the AppTask methods. 19058 */ 19059 class AppTaskImpl extends IAppTask.Stub { 19060 private int mTaskId; 19061 private int mCallingUid; 19062 19063 public AppTaskImpl(int taskId, int callingUid) { 19064 mTaskId = taskId; 19065 mCallingUid = callingUid; 19066 } 19067 19068 private void checkCaller() { 19069 if (mCallingUid != Binder.getCallingUid()) { 19070 throw new SecurityException("Caller " + mCallingUid 19071 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19072 } 19073 } 19074 19075 @Override 19076 public void finishAndRemoveTask() { 19077 checkCaller(); 19078 19079 synchronized (ActivityManagerService.this) { 19080 long origId = Binder.clearCallingIdentity(); 19081 try { 19082 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19083 if (tr == null) { 19084 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19085 } 19086 // Only kill the process if we are not a new document 19087 int flags = tr.getBaseIntent().getFlags(); 19088 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19089 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19090 removeTaskByIdLocked(mTaskId, 19091 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19092 } finally { 19093 Binder.restoreCallingIdentity(origId); 19094 } 19095 } 19096 } 19097 19098 @Override 19099 public ActivityManager.RecentTaskInfo getTaskInfo() { 19100 checkCaller(); 19101 19102 synchronized (ActivityManagerService.this) { 19103 long origId = Binder.clearCallingIdentity(); 19104 try { 19105 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19106 if (tr == null) { 19107 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19108 } 19109 return createRecentTaskInfoFromTaskRecord(tr); 19110 } finally { 19111 Binder.restoreCallingIdentity(origId); 19112 } 19113 } 19114 } 19115 19116 @Override 19117 public void moveToFront() { 19118 checkCaller(); 19119 19120 final TaskRecord tr; 19121 synchronized (ActivityManagerService.this) { 19122 tr = recentTaskForIdLocked(mTaskId); 19123 if (tr == null) { 19124 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19125 } 19126 if (tr.getRootActivity() != null) { 19127 moveTaskToFrontLocked(tr.taskId, 0, null); 19128 return; 19129 } 19130 } 19131 19132 startActivityFromRecentsInner(tr.taskId, null); 19133 } 19134 19135 @Override 19136 public int startActivity(IBinder whoThread, String callingPackage, 19137 Intent intent, String resolvedType, Bundle options) { 19138 checkCaller(); 19139 19140 int callingUser = UserHandle.getCallingUserId(); 19141 TaskRecord tr; 19142 IApplicationThread appThread; 19143 synchronized (ActivityManagerService.this) { 19144 tr = recentTaskForIdLocked(mTaskId); 19145 if (tr == null) { 19146 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19147 } 19148 appThread = ApplicationThreadNative.asInterface(whoThread); 19149 if (appThread == null) { 19150 throw new IllegalArgumentException("Bad app thread " + appThread); 19151 } 19152 } 19153 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19154 resolvedType, null, null, null, null, 0, 0, null, null, 19155 null, options, callingUser, null, tr); 19156 } 19157 19158 @Override 19159 public void setExcludeFromRecents(boolean exclude) { 19160 checkCaller(); 19161 19162 synchronized (ActivityManagerService.this) { 19163 long origId = Binder.clearCallingIdentity(); 19164 try { 19165 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19166 if (tr == null) { 19167 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19168 } 19169 Intent intent = tr.getBaseIntent(); 19170 if (exclude) { 19171 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19172 } else { 19173 intent.setFlags(intent.getFlags() 19174 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19175 } 19176 } finally { 19177 Binder.restoreCallingIdentity(origId); 19178 } 19179 } 19180 } 19181 } 19182} 19183