ActivityManagerService.java revision 0ec9c29fb724eef676d2472f2e15904ff8f52cc0
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; 33import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35import android.Manifest; 36import android.app.AppOpsManager; 37import android.app.ApplicationThreadNative; 38import android.app.IActivityContainer; 39import android.app.IActivityContainerCallback; 40import android.app.IAppTask; 41import android.app.ITaskStackListener; 42import android.app.ProfilerInfo; 43import android.app.admin.DevicePolicyManager; 44import android.app.usage.UsageEvents; 45import android.app.usage.UsageStatsManagerInternal; 46import android.appwidget.AppWidgetManager; 47import android.content.res.Resources; 48import android.graphics.Bitmap; 49import android.graphics.Point; 50import android.graphics.Rect; 51import android.os.BatteryStats; 52import android.os.PersistableBundle; 53import android.os.storage.IMountService; 54import android.os.storage.StorageManager; 55import android.service.voice.IVoiceInteractionSession; 56import android.util.ArrayMap; 57import android.util.ArraySet; 58import android.util.SparseIntArray; 59 60import com.android.internal.R; 61import com.android.internal.annotations.GuardedBy; 62import com.android.internal.app.IAppOpsService; 63import com.android.internal.app.IVoiceInteractor; 64import com.android.internal.app.ProcessMap; 65import com.android.internal.app.ProcessStats; 66import com.android.internal.os.BackgroundThread; 67import com.android.internal.os.BatteryStatsImpl; 68import com.android.internal.os.ProcessCpuTracker; 69import com.android.internal.os.TransferPipe; 70import com.android.internal.os.Zygote; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.MemInfoReader; 74import com.android.internal.util.Preconditions; 75import com.android.server.AppOpsService; 76import com.android.server.AttributeCache; 77import com.android.server.IntentResolver; 78import com.android.server.LocalServices; 79import com.android.server.ServiceThread; 80import com.android.server.SystemService; 81import com.android.server.SystemServiceManager; 82import com.android.server.Watchdog; 83import com.android.server.am.ActivityStack.ActivityState; 84import com.android.server.firewall.IntentFirewall; 85import com.android.server.pm.Installer; 86import com.android.server.pm.UserManagerService; 87import com.android.server.statusbar.StatusBarManagerInternal; 88import com.android.server.wm.AppTransition; 89import com.android.server.wm.WindowManagerService; 90import com.google.android.collect.Lists; 91import com.google.android.collect.Maps; 92 93import libcore.io.IoUtils; 94 95import org.xmlpull.v1.XmlPullParser; 96import org.xmlpull.v1.XmlPullParserException; 97import org.xmlpull.v1.XmlSerializer; 98 99import android.app.Activity; 100import android.app.ActivityManager; 101import android.app.ActivityManager.RunningTaskInfo; 102import android.app.ActivityManager.StackInfo; 103import android.app.ActivityManagerInternal; 104import android.app.ActivityManagerNative; 105import android.app.ActivityOptions; 106import android.app.ActivityThread; 107import android.app.AlertDialog; 108import android.app.AppGlobals; 109import android.app.ApplicationErrorReport; 110import android.app.Dialog; 111import android.app.IActivityController; 112import android.app.IApplicationThread; 113import android.app.IInstrumentationWatcher; 114import android.app.INotificationManager; 115import android.app.IProcessObserver; 116import android.app.IServiceConnection; 117import android.app.IStopUserCallback; 118import android.app.IUiAutomationConnection; 119import android.app.IUserSwitchObserver; 120import android.app.Instrumentation; 121import android.app.Notification; 122import android.app.NotificationManager; 123import android.app.PendingIntent; 124import android.app.backup.IBackupManager; 125import android.content.ActivityNotFoundException; 126import android.content.BroadcastReceiver; 127import android.content.ClipData; 128import android.content.ComponentCallbacks2; 129import android.content.ComponentName; 130import android.content.ContentProvider; 131import android.content.ContentResolver; 132import android.content.Context; 133import android.content.DialogInterface; 134import android.content.IContentProvider; 135import android.content.IIntentReceiver; 136import android.content.IIntentSender; 137import android.content.Intent; 138import android.content.IntentFilter; 139import android.content.IntentSender; 140import android.content.pm.ActivityInfo; 141import android.content.pm.ApplicationInfo; 142import android.content.pm.ConfigurationInfo; 143import android.content.pm.IPackageDataObserver; 144import android.content.pm.IPackageManager; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.PackageInfo; 147import android.content.pm.PackageManager; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.UserInfo; 150import android.content.pm.PackageManager.NameNotFoundException; 151import android.content.pm.PathPermission; 152import android.content.pm.ProviderInfo; 153import android.content.pm.ResolveInfo; 154import android.content.pm.ServiceInfo; 155import android.content.res.CompatibilityInfo; 156import android.content.res.Configuration; 157import android.net.Proxy; 158import android.net.ProxyInfo; 159import android.net.Uri; 160import android.os.Binder; 161import android.os.Build; 162import android.os.Bundle; 163import android.os.Debug; 164import android.os.DropBoxManager; 165import android.os.Environment; 166import android.os.FactoryTest; 167import android.os.FileObserver; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.IPermissionController; 172import android.os.IRemoteCallback; 173import android.os.IUserManager; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.PowerManagerInternal; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.SELinux; 183import android.os.ServiceManager; 184import android.os.StrictMode; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.UpdateLock; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.provider.Settings; 191import android.text.format.DateUtils; 192import android.text.format.Time; 193import android.util.AtomicFile; 194import android.util.EventLog; 195import android.util.Log; 196import android.util.Pair; 197import android.util.PrintWriterPrinter; 198import android.util.Slog; 199import android.util.SparseArray; 200import android.util.TimeUtils; 201import android.util.Xml; 202import android.view.Gravity; 203import android.view.LayoutInflater; 204import android.view.View; 205import android.view.WindowManager; 206 207import dalvik.system.VMRuntime; 208 209import java.io.BufferedInputStream; 210import java.io.BufferedOutputStream; 211import java.io.DataInputStream; 212import java.io.DataOutputStream; 213import java.io.File; 214import java.io.FileDescriptor; 215import java.io.FileInputStream; 216import java.io.FileNotFoundException; 217import java.io.FileOutputStream; 218import java.io.IOException; 219import java.io.InputStreamReader; 220import java.io.PrintWriter; 221import java.io.StringWriter; 222import java.lang.ref.WeakReference; 223import java.util.ArrayList; 224import java.util.Arrays; 225import java.util.Collections; 226import java.util.Comparator; 227import java.util.HashMap; 228import java.util.HashSet; 229import java.util.Iterator; 230import java.util.List; 231import java.util.Locale; 232import java.util.Map; 233import java.util.Set; 234import java.util.concurrent.atomic.AtomicBoolean; 235import java.util.concurrent.atomic.AtomicLong; 236 237public final class ActivityManagerService extends ActivityManagerNative 238 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 239 240 private static final String USER_DATA_DIR = "/data/user/"; 241 // File that stores last updated system version and called preboot receivers 242 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 243 244 static final String TAG = "ActivityManager"; 245 static final String TAG_MU = "ActivityManagerServiceMU"; 246 static final boolean DEBUG = false; 247 static final boolean localLOGV = DEBUG; 248 static final boolean DEBUG_BACKUP = localLOGV || false; 249 static final boolean DEBUG_BROADCAST = localLOGV || false; 250 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_CLEANUP = localLOGV || false; 253 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 254 static final boolean DEBUG_FOCUS = false; 255 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 256 static final boolean DEBUG_MU = localLOGV || false; 257 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 258 static final boolean DEBUG_LRU = localLOGV || false; 259 static final boolean DEBUG_PAUSE = localLOGV || false; 260 static final boolean DEBUG_POWER = localLOGV || false; 261 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 262 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 263 static final boolean DEBUG_PROCESSES = localLOGV || false; 264 static final boolean DEBUG_PROVIDER = localLOGV || false; 265 static final boolean DEBUG_RESULTS = localLOGV || false; 266 static final boolean DEBUG_SERVICE = localLOGV || false; 267 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 268 static final boolean DEBUG_STACK = localLOGV || false; 269 static final boolean DEBUG_SWITCH = localLOGV || false; 270 static final boolean DEBUG_TASKS = localLOGV || false; 271 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 272 static final boolean DEBUG_TRANSITION = localLOGV || false; 273 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 274 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 275 static final boolean DEBUG_VISBILITY = localLOGV || false; 276 static final boolean DEBUG_PSS = localLOGV || false; 277 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 278 static final boolean DEBUG_RECENTS = localLOGV || false; 279 static final boolean VALIDATE_TOKENS = false; 280 static final boolean SHOW_ACTIVITY_START_TIME = true; 281 282 // Control over CPU and battery monitoring. 283 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 284 static final boolean MONITOR_CPU_USAGE = true; 285 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 286 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 287 static final boolean MONITOR_THREAD_CPU_USAGE = false; 288 289 // The flags that are set for all calls we make to the package manager. 290 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 291 292 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 293 294 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 295 296 // Amount of time after a call to stopAppSwitches() during which we will 297 // prevent further untrusted switches from happening. 298 static final long APP_SWITCH_DELAY_TIME = 5*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real. 302 static final int PROC_START_TIMEOUT = 10*1000; 303 304 // How long we wait for a launched process to attach to the activity manager 305 // before we decide it's never going to come up for real, when the process was 306 // started with a wrapper for instrumentation (such as Valgrind) because it 307 // could take much longer than usual. 308 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 309 310 // How long to wait after going idle before forcing apps to GC. 311 static final int GC_TIMEOUT = 5*1000; 312 313 // The minimum amount of time between successive GC requests for a process. 314 static final int GC_MIN_INTERVAL = 60*1000; 315 316 // The minimum amount of time between successive PSS requests for a process. 317 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process 320 // when the request is due to the memory state being lowered. 321 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 322 323 // The rate at which we check for apps using excessive power -- 15 mins. 324 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on wake locks to start killing things. 328 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // The minimum sample duration we will allow before deciding we have 331 // enough data on CPU usage to start killing things. 332 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 333 334 // How long we allow a receiver to run before giving up on it. 335 static final int BROADCAST_FG_TIMEOUT = 10*1000; 336 static final int BROADCAST_BG_TIMEOUT = 60*1000; 337 338 // How long we wait until we timeout on key dispatching. 339 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 340 341 // How long we wait until we timeout on key dispatching during instrumentation. 342 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 343 344 // Amount of time we wait for observers to handle a user switch before 345 // giving up on them and unfreezing the screen. 346 static final int USER_SWITCH_TIMEOUT = 2*1000; 347 348 // Maximum number of users we allow to be running at a time. 349 static final int MAX_RUNNING_USERS = 3; 350 351 // How long to wait in getAssistContextExtras for the activity and foreground services 352 // to respond with the result. 353 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 354 355 // Maximum number of persisted Uri grants a package is allowed 356 static final int MAX_PERSISTED_URI_GRANTS = 128; 357 358 static final int MY_PID = Process.myPid(); 359 360 static final String[] EMPTY_STRING_ARRAY = new String[0]; 361 362 // How many bytes to write into the dropbox log before truncating 363 static final int DROPBOX_MAX_SIZE = 256 * 1024; 364 365 // Access modes for handleIncomingUser. 366 static final int ALLOW_NON_FULL = 0; 367 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 368 static final int ALLOW_FULL_ONLY = 2; 369 370 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 371 372 // Delay in notifying task stack change listeners (in millis) 373 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 374 375 /** All system services */ 376 SystemServiceManager mSystemServiceManager; 377 378 private Installer mInstaller; 379 380 /** Run all ActivityStacks through this */ 381 ActivityStackSupervisor mStackSupervisor; 382 383 /** Task stack change listeners. */ 384 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 385 new RemoteCallbackList<ITaskStackListener>(); 386 387 public IntentFirewall mIntentFirewall; 388 389 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 390 // default actuion automatically. Important for devices without direct input 391 // devices. 392 private boolean mShowDialogs = true; 393 394 BroadcastQueue mFgBroadcastQueue; 395 BroadcastQueue mBgBroadcastQueue; 396 // Convenient for easy iteration over the queues. Foreground is first 397 // so that dispatch of foreground broadcasts gets precedence. 398 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 399 400 BroadcastQueue broadcastQueueForIntent(Intent intent) { 401 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 402 if (DEBUG_BACKGROUND_BROADCAST) { 403 Slog.i(TAG, "Broadcast intent " + intent + " on " 404 + (isFg ? "foreground" : "background") 405 + " queue"); 406 } 407 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 408 } 409 410 /** 411 * Activity we have told the window manager to have key focus. 412 */ 413 ActivityRecord mFocusedActivity = null; 414 415 /** 416 * List of intents that were used to start the most recent tasks. 417 */ 418 private final RecentTasks mRecentTasks; 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 final static class Association { 739 final int mSourceUid; 740 final String mSourceProcess; 741 final int mTargetUid; 742 final ComponentName mTargetComponent; 743 final String mTargetProcess; 744 745 int mCount; 746 long mTime; 747 748 int mNesting; 749 long mStartTime; 750 751 Association(int sourceUid, String sourceProcess, int targetUid, 752 ComponentName targetComponent, String targetProcess) { 753 mSourceUid = sourceUid; 754 mSourceProcess = sourceProcess; 755 mTargetUid = targetUid; 756 mTargetComponent = targetComponent; 757 mTargetProcess = targetProcess; 758 } 759 } 760 761 /** 762 * When service association tracking is enabled, this is all of the associations we 763 * have seen. Mapping is target uid -> target component -> source uid -> source process name 764 * -> association data. 765 */ 766 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 767 mAssociations = new SparseArray<>(); 768 boolean mTrackingAssociations; 769 770 /** 771 * Backup/restore process management 772 */ 773 String mBackupAppName = null; 774 BackupRecord mBackupTarget = null; 775 776 final ProviderMap mProviderMap; 777 778 /** 779 * List of content providers who have clients waiting for them. The 780 * application is currently being launched and the provider will be 781 * removed from this list once it is published. 782 */ 783 final ArrayList<ContentProviderRecord> mLaunchingProviders 784 = new ArrayList<ContentProviderRecord>(); 785 786 /** 787 * File storing persisted {@link #mGrantedUriPermissions}. 788 */ 789 private final AtomicFile mGrantFile; 790 791 /** XML constants used in {@link #mGrantFile} */ 792 private static final String TAG_URI_GRANTS = "uri-grants"; 793 private static final String TAG_URI_GRANT = "uri-grant"; 794 private static final String ATTR_USER_HANDLE = "userHandle"; 795 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 796 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 797 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 798 private static final String ATTR_TARGET_PKG = "targetPkg"; 799 private static final String ATTR_URI = "uri"; 800 private static final String ATTR_MODE_FLAGS = "modeFlags"; 801 private static final String ATTR_CREATED_TIME = "createdTime"; 802 private static final String ATTR_PREFIX = "prefix"; 803 804 /** 805 * Global set of specific {@link Uri} permissions that have been granted. 806 * This optimized lookup structure maps from {@link UriPermission#targetUid} 807 * to {@link UriPermission#uri} to {@link UriPermission}. 808 */ 809 @GuardedBy("this") 810 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 811 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 812 813 public static class GrantUri { 814 public final int sourceUserId; 815 public final Uri uri; 816 public boolean prefix; 817 818 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 819 this.sourceUserId = sourceUserId; 820 this.uri = uri; 821 this.prefix = prefix; 822 } 823 824 @Override 825 public int hashCode() { 826 int hashCode = 1; 827 hashCode = 31 * hashCode + sourceUserId; 828 hashCode = 31 * hashCode + uri.hashCode(); 829 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 830 return hashCode; 831 } 832 833 @Override 834 public boolean equals(Object o) { 835 if (o instanceof GrantUri) { 836 GrantUri other = (GrantUri) o; 837 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 838 && prefix == other.prefix; 839 } 840 return false; 841 } 842 843 @Override 844 public String toString() { 845 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 846 if (prefix) result += " [prefix]"; 847 return result; 848 } 849 850 public String toSafeString() { 851 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 852 if (prefix) result += " [prefix]"; 853 return result; 854 } 855 856 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 857 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 858 ContentProvider.getUriWithoutUserId(uri), false); 859 } 860 } 861 862 CoreSettingsObserver mCoreSettingsObserver; 863 864 /** 865 * Thread-local storage used to carry caller permissions over through 866 * indirect content-provider access. 867 */ 868 private class Identity { 869 public final IBinder token; 870 public final int pid; 871 public final int uid; 872 873 Identity(IBinder _token, int _pid, int _uid) { 874 token = _token; 875 pid = _pid; 876 uid = _uid; 877 } 878 } 879 880 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 881 882 /** 883 * All information we have collected about the runtime performance of 884 * any user id that can impact battery performance. 885 */ 886 final BatteryStatsService mBatteryStatsService; 887 888 /** 889 * Information about component usage 890 */ 891 UsageStatsManagerInternal mUsageStatsService; 892 893 /** 894 * Information about and control over application operations 895 */ 896 final AppOpsService mAppOpsService; 897 898 /** 899 * Save recent tasks information across reboots. 900 */ 901 final TaskPersister mTaskPersister; 902 903 /** 904 * Current configuration information. HistoryRecord objects are given 905 * a reference to this object to indicate which configuration they are 906 * currently running in, so this object must be kept immutable. 907 */ 908 Configuration mConfiguration = new Configuration(); 909 910 /** 911 * Current sequencing integer of the configuration, for skipping old 912 * configurations. 913 */ 914 int mConfigurationSeq = 0; 915 916 /** 917 * Hardware-reported OpenGLES version. 918 */ 919 final int GL_ES_VERSION; 920 921 /** 922 * List of initialization arguments to pass to all processes when binding applications to them. 923 * For example, references to the commonly used services. 924 */ 925 HashMap<String, IBinder> mAppBindArgs; 926 927 /** 928 * Temporary to avoid allocations. Protected by main lock. 929 */ 930 final StringBuilder mStringBuilder = new StringBuilder(256); 931 932 /** 933 * Used to control how we initialize the service. 934 */ 935 ComponentName mTopComponent; 936 String mTopAction = Intent.ACTION_MAIN; 937 String mTopData; 938 boolean mProcessesReady = false; 939 boolean mSystemReady = false; 940 boolean mBooting = false; 941 boolean mCallFinishBooting = false; 942 boolean mBootAnimationComplete = false; 943 boolean mWaitingUpdate = false; 944 boolean mDidUpdate = false; 945 boolean mOnBattery = false; 946 boolean mLaunchWarningShown = false; 947 948 Context mContext; 949 950 int mFactoryTest; 951 952 boolean mCheckedForSetup; 953 954 /** 955 * The time at which we will allow normal application switches again, 956 * after a call to {@link #stopAppSwitches()}. 957 */ 958 long mAppSwitchesAllowedTime; 959 960 /** 961 * This is set to true after the first switch after mAppSwitchesAllowedTime 962 * is set; any switches after that will clear the time. 963 */ 964 boolean mDidAppSwitch; 965 966 /** 967 * Last time (in realtime) at which we checked for power usage. 968 */ 969 long mLastPowerCheckRealtime; 970 971 /** 972 * Last time (in uptime) at which we checked for power usage. 973 */ 974 long mLastPowerCheckUptime; 975 976 /** 977 * Set while we are wanting to sleep, to prevent any 978 * activities from being started/resumed. 979 */ 980 private boolean mSleeping = false; 981 982 /** 983 * Set while we are running a voice interaction. This overrides 984 * sleeping while it is active. 985 */ 986 private boolean mRunningVoice = false; 987 988 /** 989 * State of external calls telling us if the device is awake or asleep. 990 */ 991 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 992 993 static final int LOCK_SCREEN_HIDDEN = 0; 994 static final int LOCK_SCREEN_LEAVING = 1; 995 static final int LOCK_SCREEN_SHOWN = 2; 996 /** 997 * State of external call telling us if the lock screen is shown. 998 */ 999 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1000 1001 /** 1002 * Set if we are shutting down the system, similar to sleeping. 1003 */ 1004 boolean mShuttingDown = false; 1005 1006 /** 1007 * Current sequence id for oom_adj computation traversal. 1008 */ 1009 int mAdjSeq = 0; 1010 1011 /** 1012 * Current sequence id for process LRU updating. 1013 */ 1014 int mLruSeq = 0; 1015 1016 /** 1017 * Keep track of the non-cached/empty process we last found, to help 1018 * determine how to distribute cached/empty processes next time. 1019 */ 1020 int mNumNonCachedProcs = 0; 1021 1022 /** 1023 * Keep track of the number of cached hidden procs, to balance oom adj 1024 * distribution between those and empty procs. 1025 */ 1026 int mNumCachedHiddenProcs = 0; 1027 1028 /** 1029 * Keep track of the number of service processes we last found, to 1030 * determine on the next iteration which should be B services. 1031 */ 1032 int mNumServiceProcs = 0; 1033 int mNewNumAServiceProcs = 0; 1034 int mNewNumServiceProcs = 0; 1035 1036 /** 1037 * Allow the current computed overall memory level of the system to go down? 1038 * This is set to false when we are killing processes for reasons other than 1039 * memory management, so that the now smaller process list will not be taken as 1040 * an indication that memory is tighter. 1041 */ 1042 boolean mAllowLowerMemLevel = false; 1043 1044 /** 1045 * The last computed memory level, for holding when we are in a state that 1046 * processes are going away for other reasons. 1047 */ 1048 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1049 1050 /** 1051 * The last total number of process we have, to determine if changes actually look 1052 * like a shrinking number of process due to lower RAM. 1053 */ 1054 int mLastNumProcesses; 1055 1056 /** 1057 * The uptime of the last time we performed idle maintenance. 1058 */ 1059 long mLastIdleTime = SystemClock.uptimeMillis(); 1060 1061 /** 1062 * Total time spent with RAM that has been added in the past since the last idle time. 1063 */ 1064 long mLowRamTimeSinceLastIdle = 0; 1065 1066 /** 1067 * If RAM is currently low, when that horrible situation started. 1068 */ 1069 long mLowRamStartTime = 0; 1070 1071 /** 1072 * For reporting to battery stats the current top application. 1073 */ 1074 private String mCurResumedPackage = null; 1075 private int mCurResumedUid = -1; 1076 1077 /** 1078 * For reporting to battery stats the apps currently running foreground 1079 * service. The ProcessMap is package/uid tuples; each of these contain 1080 * an array of the currently foreground processes. 1081 */ 1082 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1083 = new ProcessMap<ArrayList<ProcessRecord>>(); 1084 1085 /** 1086 * This is set if we had to do a delayed dexopt of an app before launching 1087 * it, to increase the ANR timeouts in that case. 1088 */ 1089 boolean mDidDexOpt; 1090 1091 /** 1092 * Set if the systemServer made a call to enterSafeMode. 1093 */ 1094 boolean mSafeMode; 1095 1096 /** 1097 * If true, we are running under a test environment so will sample PSS from processes 1098 * much more rapidly to try to collect better data when the tests are rapidly 1099 * running through apps. 1100 */ 1101 boolean mTestPssMode = false; 1102 1103 String mDebugApp = null; 1104 boolean mWaitForDebugger = false; 1105 boolean mDebugTransient = false; 1106 String mOrigDebugApp = null; 1107 boolean mOrigWaitForDebugger = false; 1108 boolean mAlwaysFinishActivities = false; 1109 IActivityController mController = null; 1110 String mProfileApp = null; 1111 ProcessRecord mProfileProc = null; 1112 String mProfileFile; 1113 ParcelFileDescriptor mProfileFd; 1114 int mSamplingInterval = 0; 1115 boolean mAutoStopProfiler = false; 1116 int mProfileType = 0; 1117 String mOpenGlTraceApp = null; 1118 1119 final long[] mTmpLong = new long[1]; 1120 1121 static class ProcessChangeItem { 1122 static final int CHANGE_ACTIVITIES = 1<<0; 1123 static final int CHANGE_PROCESS_STATE = 1<<1; 1124 int changes; 1125 int uid; 1126 int pid; 1127 int processState; 1128 boolean foregroundActivities; 1129 } 1130 1131 final RemoteCallbackList<IProcessObserver> mProcessObservers 1132 = new RemoteCallbackList<IProcessObserver>(); 1133 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1134 1135 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1136 = new ArrayList<ProcessChangeItem>(); 1137 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1138 = new ArrayList<ProcessChangeItem>(); 1139 1140 /** 1141 * Runtime CPU use collection thread. This object's lock is used to 1142 * perform synchronization with the thread (notifying it to run). 1143 */ 1144 final Thread mProcessCpuThread; 1145 1146 /** 1147 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1148 * Must acquire this object's lock when accessing it. 1149 * NOTE: this lock will be held while doing long operations (trawling 1150 * through all processes in /proc), so it should never be acquired by 1151 * any critical paths such as when holding the main activity manager lock. 1152 */ 1153 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1154 MONITOR_THREAD_CPU_USAGE); 1155 final AtomicLong mLastCpuTime = new AtomicLong(0); 1156 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1157 1158 long mLastWriteTime = 0; 1159 1160 /** 1161 * Used to retain an update lock when the foreground activity is in 1162 * immersive mode. 1163 */ 1164 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1165 1166 /** 1167 * Set to true after the system has finished booting. 1168 */ 1169 boolean mBooted = false; 1170 1171 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1172 int mProcessLimitOverride = -1; 1173 1174 WindowManagerService mWindowManager; 1175 1176 final ActivityThread mSystemThread; 1177 1178 // Holds the current foreground user's id 1179 int mCurrentUserId = 0; 1180 // Holds the target user's id during a user switch 1181 int mTargetUserId = UserHandle.USER_NULL; 1182 // If there are multiple profiles for the current user, their ids are here 1183 // Currently only the primary user can have managed profiles 1184 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1185 1186 /** 1187 * Mapping from each known user ID to the profile group ID it is associated with. 1188 */ 1189 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1190 1191 private UserManagerService mUserManager; 1192 1193 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1194 final ProcessRecord mApp; 1195 final int mPid; 1196 final IApplicationThread mAppThread; 1197 1198 AppDeathRecipient(ProcessRecord app, int pid, 1199 IApplicationThread thread) { 1200 if (localLOGV) Slog.v( 1201 TAG, "New death recipient " + this 1202 + " for thread " + thread.asBinder()); 1203 mApp = app; 1204 mPid = pid; 1205 mAppThread = thread; 1206 } 1207 1208 @Override 1209 public void binderDied() { 1210 if (localLOGV) Slog.v( 1211 TAG, "Death received in " + this 1212 + " for thread " + mAppThread.asBinder()); 1213 synchronized(ActivityManagerService.this) { 1214 appDiedLocked(mApp, mPid, mAppThread); 1215 } 1216 } 1217 } 1218 1219 static final int SHOW_ERROR_MSG = 1; 1220 static final int SHOW_NOT_RESPONDING_MSG = 2; 1221 static final int SHOW_FACTORY_ERROR_MSG = 3; 1222 static final int UPDATE_CONFIGURATION_MSG = 4; 1223 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1224 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1225 static final int SERVICE_TIMEOUT_MSG = 12; 1226 static final int UPDATE_TIME_ZONE = 13; 1227 static final int SHOW_UID_ERROR_MSG = 14; 1228 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1229 static final int PROC_START_TIMEOUT_MSG = 20; 1230 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1231 static final int KILL_APPLICATION_MSG = 22; 1232 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1233 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1234 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1235 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1236 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1237 static final int CLEAR_DNS_CACHE_MSG = 28; 1238 static final int UPDATE_HTTP_PROXY_MSG = 29; 1239 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1240 static final int DISPATCH_PROCESSES_CHANGED = 31; 1241 static final int DISPATCH_PROCESS_DIED = 32; 1242 static final int REPORT_MEM_USAGE_MSG = 33; 1243 static final int REPORT_USER_SWITCH_MSG = 34; 1244 static final int CONTINUE_USER_SWITCH_MSG = 35; 1245 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1246 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1247 static final int PERSIST_URI_GRANTS_MSG = 38; 1248 static final int REQUEST_ALL_PSS_MSG = 39; 1249 static final int START_PROFILES_MSG = 40; 1250 static final int UPDATE_TIME = 41; 1251 static final int SYSTEM_USER_START_MSG = 42; 1252 static final int SYSTEM_USER_CURRENT_MSG = 43; 1253 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1254 static final int FINISH_BOOTING_MSG = 45; 1255 static final int START_USER_SWITCH_MSG = 46; 1256 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1257 static final int DISMISS_DIALOG_MSG = 48; 1258 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1259 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50; 1260 1261 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1262 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1263 static final int FIRST_COMPAT_MODE_MSG = 300; 1264 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1265 1266 CompatModeDialog mCompatModeDialog; 1267 long mLastMemUsageReportTime = 0; 1268 1269 /** 1270 * Flag whether the current user is a "monkey", i.e. whether 1271 * the UI is driven by a UI automation tool. 1272 */ 1273 private boolean mUserIsMonkey; 1274 1275 /** Flag whether the device has a Recents UI */ 1276 boolean mHasRecents; 1277 1278 /** The dimensions of the thumbnails in the Recents UI. */ 1279 int mThumbnailWidth; 1280 int mThumbnailHeight; 1281 1282 final ServiceThread mHandlerThread; 1283 final MainHandler mHandler; 1284 1285 final class MainHandler extends Handler { 1286 public MainHandler(Looper looper) { 1287 super(looper, null, true); 1288 } 1289 1290 @Override 1291 public void handleMessage(Message msg) { 1292 switch (msg.what) { 1293 case SHOW_ERROR_MSG: { 1294 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1295 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1296 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1297 synchronized (ActivityManagerService.this) { 1298 ProcessRecord proc = (ProcessRecord)data.get("app"); 1299 AppErrorResult res = (AppErrorResult) data.get("result"); 1300 if (proc != null && proc.crashDialog != null) { 1301 Slog.e(TAG, "App already has crash dialog: " + proc); 1302 if (res != null) { 1303 res.set(0); 1304 } 1305 return; 1306 } 1307 boolean isBackground = (UserHandle.getAppId(proc.uid) 1308 >= Process.FIRST_APPLICATION_UID 1309 && proc.pid != MY_PID); 1310 for (int userId : mCurrentProfileIds) { 1311 isBackground &= (proc.userId != userId); 1312 } 1313 if (isBackground && !showBackground) { 1314 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1315 if (res != null) { 1316 res.set(0); 1317 } 1318 return; 1319 } 1320 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1321 Dialog d = new AppErrorDialog(mContext, 1322 ActivityManagerService.this, res, proc); 1323 d.show(); 1324 proc.crashDialog = d; 1325 } else { 1326 // The device is asleep, so just pretend that the user 1327 // saw a crash dialog and hit "force quit". 1328 if (res != null) { 1329 res.set(0); 1330 } 1331 } 1332 } 1333 1334 ensureBootCompleted(); 1335 } break; 1336 case SHOW_NOT_RESPONDING_MSG: { 1337 synchronized (ActivityManagerService.this) { 1338 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1339 ProcessRecord proc = (ProcessRecord)data.get("app"); 1340 if (proc != null && proc.anrDialog != null) { 1341 Slog.e(TAG, "App already has anr dialog: " + proc); 1342 return; 1343 } 1344 1345 Intent intent = new Intent("android.intent.action.ANR"); 1346 if (!mProcessesReady) { 1347 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1348 | Intent.FLAG_RECEIVER_FOREGROUND); 1349 } 1350 broadcastIntentLocked(null, null, intent, 1351 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1352 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1353 1354 if (mShowDialogs) { 1355 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1356 mContext, proc, (ActivityRecord)data.get("activity"), 1357 msg.arg1 != 0); 1358 d.show(); 1359 proc.anrDialog = d; 1360 } else { 1361 // Just kill the app if there is no dialog to be shown. 1362 killAppAtUsersRequest(proc, null); 1363 } 1364 } 1365 1366 ensureBootCompleted(); 1367 } break; 1368 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1369 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1370 synchronized (ActivityManagerService.this) { 1371 ProcessRecord proc = (ProcessRecord) data.get("app"); 1372 if (proc == null) { 1373 Slog.e(TAG, "App not found when showing strict mode dialog."); 1374 break; 1375 } 1376 if (proc.crashDialog != null) { 1377 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1378 return; 1379 } 1380 AppErrorResult res = (AppErrorResult) data.get("result"); 1381 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1382 Dialog d = new StrictModeViolationDialog(mContext, 1383 ActivityManagerService.this, res, proc); 1384 d.show(); 1385 proc.crashDialog = d; 1386 } else { 1387 // The device is asleep, so just pretend that the user 1388 // saw a crash dialog and hit "force quit". 1389 res.set(0); 1390 } 1391 } 1392 ensureBootCompleted(); 1393 } break; 1394 case SHOW_FACTORY_ERROR_MSG: { 1395 Dialog d = new FactoryErrorDialog( 1396 mContext, msg.getData().getCharSequence("msg")); 1397 d.show(); 1398 ensureBootCompleted(); 1399 } break; 1400 case UPDATE_CONFIGURATION_MSG: { 1401 final ContentResolver resolver = mContext.getContentResolver(); 1402 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1403 } break; 1404 case GC_BACKGROUND_PROCESSES_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 performAppGcsIfAppropriateLocked(); 1407 } 1408 } break; 1409 case WAIT_FOR_DEBUGGER_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 ProcessRecord app = (ProcessRecord)msg.obj; 1412 if (msg.arg1 != 0) { 1413 if (!app.waitedForDebugger) { 1414 Dialog d = new AppWaitingForDebuggerDialog( 1415 ActivityManagerService.this, 1416 mContext, app); 1417 app.waitDialog = d; 1418 app.waitedForDebugger = true; 1419 d.show(); 1420 } 1421 } else { 1422 if (app.waitDialog != null) { 1423 app.waitDialog.dismiss(); 1424 app.waitDialog = null; 1425 } 1426 } 1427 } 1428 } break; 1429 case SERVICE_TIMEOUT_MSG: { 1430 if (mDidDexOpt) { 1431 mDidDexOpt = false; 1432 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1433 nmsg.obj = msg.obj; 1434 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1435 return; 1436 } 1437 mServices.serviceTimeout((ProcessRecord)msg.obj); 1438 } break; 1439 case UPDATE_TIME_ZONE: { 1440 synchronized (ActivityManagerService.this) { 1441 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1442 ProcessRecord r = mLruProcesses.get(i); 1443 if (r.thread != null) { 1444 try { 1445 r.thread.updateTimeZone(); 1446 } catch (RemoteException ex) { 1447 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1448 } 1449 } 1450 } 1451 } 1452 } break; 1453 case CLEAR_DNS_CACHE_MSG: { 1454 synchronized (ActivityManagerService.this) { 1455 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1456 ProcessRecord r = mLruProcesses.get(i); 1457 if (r.thread != null) { 1458 try { 1459 r.thread.clearDnsCache(); 1460 } catch (RemoteException ex) { 1461 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1462 } 1463 } 1464 } 1465 } 1466 } break; 1467 case UPDATE_HTTP_PROXY_MSG: { 1468 ProxyInfo proxy = (ProxyInfo)msg.obj; 1469 String host = ""; 1470 String port = ""; 1471 String exclList = ""; 1472 Uri pacFileUrl = Uri.EMPTY; 1473 if (proxy != null) { 1474 host = proxy.getHost(); 1475 port = Integer.toString(proxy.getPort()); 1476 exclList = proxy.getExclusionListAsString(); 1477 pacFileUrl = proxy.getPacFileUrl(); 1478 } 1479 synchronized (ActivityManagerService.this) { 1480 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1481 ProcessRecord r = mLruProcesses.get(i); 1482 if (r.thread != null) { 1483 try { 1484 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1485 } catch (RemoteException ex) { 1486 Slog.w(TAG, "Failed to update http proxy for: " + 1487 r.info.processName); 1488 } 1489 } 1490 } 1491 } 1492 } break; 1493 case SHOW_UID_ERROR_MSG: { 1494 if (mShowDialogs) { 1495 AlertDialog d = new BaseErrorDialog(mContext); 1496 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1497 d.setCancelable(false); 1498 d.setTitle(mContext.getText(R.string.android_system_label)); 1499 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1500 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1501 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1502 d.show(); 1503 } 1504 } break; 1505 case SHOW_FINGERPRINT_ERROR_MSG: { 1506 if (mShowDialogs) { 1507 AlertDialog d = new BaseErrorDialog(mContext); 1508 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1509 d.setCancelable(false); 1510 d.setTitle(mContext.getText(R.string.android_system_label)); 1511 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1512 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1513 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1514 d.show(); 1515 } 1516 } break; 1517 case PROC_START_TIMEOUT_MSG: { 1518 if (mDidDexOpt) { 1519 mDidDexOpt = false; 1520 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1521 nmsg.obj = msg.obj; 1522 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1523 return; 1524 } 1525 ProcessRecord app = (ProcessRecord)msg.obj; 1526 synchronized (ActivityManagerService.this) { 1527 processStartTimedOutLocked(app); 1528 } 1529 } break; 1530 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1531 synchronized (ActivityManagerService.this) { 1532 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1533 } 1534 } break; 1535 case KILL_APPLICATION_MSG: { 1536 synchronized (ActivityManagerService.this) { 1537 int appid = msg.arg1; 1538 boolean restart = (msg.arg2 == 1); 1539 Bundle bundle = (Bundle)msg.obj; 1540 String pkg = bundle.getString("pkg"); 1541 String reason = bundle.getString("reason"); 1542 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1543 false, UserHandle.USER_ALL, reason); 1544 } 1545 } break; 1546 case FINALIZE_PENDING_INTENT_MSG: { 1547 ((PendingIntentRecord)msg.obj).completeFinalize(); 1548 } break; 1549 case POST_HEAVY_NOTIFICATION_MSG: { 1550 INotificationManager inm = NotificationManager.getService(); 1551 if (inm == null) { 1552 return; 1553 } 1554 1555 ActivityRecord root = (ActivityRecord)msg.obj; 1556 ProcessRecord process = root.app; 1557 if (process == null) { 1558 return; 1559 } 1560 1561 try { 1562 Context context = mContext.createPackageContext(process.info.packageName, 0); 1563 String text = mContext.getString(R.string.heavy_weight_notification, 1564 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1565 Notification notification = new Notification(); 1566 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1567 notification.when = 0; 1568 notification.flags = Notification.FLAG_ONGOING_EVENT; 1569 notification.tickerText = text; 1570 notification.defaults = 0; // please be quiet 1571 notification.sound = null; 1572 notification.vibrate = null; 1573 notification.color = mContext.getResources().getColor( 1574 com.android.internal.R.color.system_notification_accent_color); 1575 notification.setLatestEventInfo(context, text, 1576 mContext.getText(R.string.heavy_weight_notification_detail), 1577 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1578 PendingIntent.FLAG_CANCEL_CURRENT, null, 1579 new UserHandle(root.userId))); 1580 1581 try { 1582 int[] outId = new int[1]; 1583 inm.enqueueNotificationWithTag("android", "android", null, 1584 R.string.heavy_weight_notification, 1585 notification, outId, root.userId); 1586 } catch (RuntimeException e) { 1587 Slog.w(ActivityManagerService.TAG, 1588 "Error showing notification for heavy-weight app", e); 1589 } catch (RemoteException e) { 1590 } 1591 } catch (NameNotFoundException e) { 1592 Slog.w(TAG, "Unable to create context for heavy notification", e); 1593 } 1594 } break; 1595 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1596 INotificationManager inm = NotificationManager.getService(); 1597 if (inm == null) { 1598 return; 1599 } 1600 try { 1601 inm.cancelNotificationWithTag("android", null, 1602 R.string.heavy_weight_notification, msg.arg1); 1603 } catch (RuntimeException e) { 1604 Slog.w(ActivityManagerService.TAG, 1605 "Error canceling notification for service", e); 1606 } catch (RemoteException e) { 1607 } 1608 } break; 1609 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1610 synchronized (ActivityManagerService.this) { 1611 checkExcessivePowerUsageLocked(true); 1612 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1613 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1614 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1615 } 1616 } break; 1617 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1618 synchronized (ActivityManagerService.this) { 1619 ActivityRecord ar = (ActivityRecord)msg.obj; 1620 if (mCompatModeDialog != null) { 1621 if (mCompatModeDialog.mAppInfo.packageName.equals( 1622 ar.info.applicationInfo.packageName)) { 1623 return; 1624 } 1625 mCompatModeDialog.dismiss(); 1626 mCompatModeDialog = null; 1627 } 1628 if (ar != null && false) { 1629 if (mCompatModePackages.getPackageAskCompatModeLocked( 1630 ar.packageName)) { 1631 int mode = mCompatModePackages.computeCompatModeLocked( 1632 ar.info.applicationInfo); 1633 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1634 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1635 mCompatModeDialog = new CompatModeDialog( 1636 ActivityManagerService.this, mContext, 1637 ar.info.applicationInfo); 1638 mCompatModeDialog.show(); 1639 } 1640 } 1641 } 1642 } 1643 break; 1644 } 1645 case DISPATCH_PROCESSES_CHANGED: { 1646 dispatchProcessesChanged(); 1647 break; 1648 } 1649 case DISPATCH_PROCESS_DIED: { 1650 final int pid = msg.arg1; 1651 final int uid = msg.arg2; 1652 dispatchProcessDied(pid, uid); 1653 break; 1654 } 1655 case REPORT_MEM_USAGE_MSG: { 1656 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1657 Thread thread = new Thread() { 1658 @Override public void run() { 1659 reportMemUsage(memInfos); 1660 } 1661 }; 1662 thread.start(); 1663 break; 1664 } 1665 case START_USER_SWITCH_MSG: { 1666 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1667 break; 1668 } 1669 case REPORT_USER_SWITCH_MSG: { 1670 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1671 break; 1672 } 1673 case CONTINUE_USER_SWITCH_MSG: { 1674 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1675 break; 1676 } 1677 case USER_SWITCH_TIMEOUT_MSG: { 1678 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1679 break; 1680 } 1681 case IMMERSIVE_MODE_LOCK_MSG: { 1682 final boolean nextState = (msg.arg1 != 0); 1683 if (mUpdateLock.isHeld() != nextState) { 1684 if (DEBUG_IMMERSIVE) { 1685 final ActivityRecord r = (ActivityRecord) msg.obj; 1686 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1687 } 1688 if (nextState) { 1689 mUpdateLock.acquire(); 1690 } else { 1691 mUpdateLock.release(); 1692 } 1693 } 1694 break; 1695 } 1696 case PERSIST_URI_GRANTS_MSG: { 1697 writeGrantedUriPermissions(); 1698 break; 1699 } 1700 case REQUEST_ALL_PSS_MSG: { 1701 synchronized (ActivityManagerService.this) { 1702 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1703 } 1704 break; 1705 } 1706 case START_PROFILES_MSG: { 1707 synchronized (ActivityManagerService.this) { 1708 startProfilesLocked(); 1709 } 1710 break; 1711 } 1712 case UPDATE_TIME: { 1713 synchronized (ActivityManagerService.this) { 1714 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1715 ProcessRecord r = mLruProcesses.get(i); 1716 if (r.thread != null) { 1717 try { 1718 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1719 } catch (RemoteException ex) { 1720 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1721 } 1722 } 1723 } 1724 } 1725 break; 1726 } 1727 case SYSTEM_USER_START_MSG: { 1728 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1729 Integer.toString(msg.arg1), msg.arg1); 1730 mSystemServiceManager.startUser(msg.arg1); 1731 break; 1732 } 1733 case SYSTEM_USER_CURRENT_MSG: { 1734 mBatteryStatsService.noteEvent( 1735 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1736 Integer.toString(msg.arg2), msg.arg2); 1737 mBatteryStatsService.noteEvent( 1738 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1739 Integer.toString(msg.arg1), msg.arg1); 1740 mSystemServiceManager.switchUser(msg.arg1); 1741 break; 1742 } 1743 case ENTER_ANIMATION_COMPLETE_MSG: { 1744 synchronized (ActivityManagerService.this) { 1745 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1746 if (r != null && r.app != null && r.app.thread != null) { 1747 try { 1748 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1749 } catch (RemoteException e) { 1750 } 1751 } 1752 } 1753 break; 1754 } 1755 case FINISH_BOOTING_MSG: { 1756 if (msg.arg1 != 0) { 1757 finishBooting(); 1758 } 1759 if (msg.arg2 != 0) { 1760 enableScreenAfterBoot(); 1761 } 1762 break; 1763 } 1764 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1765 try { 1766 Locale l = (Locale) msg.obj; 1767 IBinder service = ServiceManager.getService("mount"); 1768 IMountService mountService = IMountService.Stub.asInterface(service); 1769 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1770 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1771 } catch (RemoteException e) { 1772 Log.e(TAG, "Error storing locale for decryption UI", e); 1773 } 1774 break; 1775 } 1776 case DISMISS_DIALOG_MSG: { 1777 final Dialog d = (Dialog) msg.obj; 1778 d.dismiss(); 1779 break; 1780 } 1781 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1782 synchronized (ActivityManagerService.this) { 1783 int i = mTaskStackListeners.beginBroadcast(); 1784 while (i > 0) { 1785 i--; 1786 try { 1787 // Make a one-way callback to the listener 1788 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1789 } catch (RemoteException e){ 1790 // Handled by the RemoteCallbackList 1791 } 1792 } 1793 mTaskStackListeners.finishBroadcast(); 1794 } 1795 break; 1796 } 1797 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 1798 final int uid = msg.arg1; 1799 final byte[] firstPacket = (byte[]) msg.obj; 1800 1801 synchronized (mPidsSelfLocked) { 1802 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 1803 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 1804 if (p.uid == uid) { 1805 try { 1806 p.thread.notifyCleartextNetwork(firstPacket); 1807 } catch (RemoteException ignored) { 1808 } 1809 } 1810 } 1811 } 1812 break; 1813 } 1814 } 1815 } 1816 }; 1817 1818 static final int COLLECT_PSS_BG_MSG = 1; 1819 1820 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1821 @Override 1822 public void handleMessage(Message msg) { 1823 switch (msg.what) { 1824 case COLLECT_PSS_BG_MSG: { 1825 long start = SystemClock.uptimeMillis(); 1826 MemInfoReader memInfo = null; 1827 synchronized (ActivityManagerService.this) { 1828 if (mFullPssPending) { 1829 mFullPssPending = false; 1830 memInfo = new MemInfoReader(); 1831 } 1832 } 1833 if (memInfo != null) { 1834 updateCpuStatsNow(); 1835 long nativeTotalPss = 0; 1836 synchronized (mProcessCpuTracker) { 1837 final int N = mProcessCpuTracker.countStats(); 1838 for (int j=0; j<N; j++) { 1839 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1840 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1841 // This is definitely an application process; skip it. 1842 continue; 1843 } 1844 synchronized (mPidsSelfLocked) { 1845 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1846 // This is one of our own processes; skip it. 1847 continue; 1848 } 1849 } 1850 nativeTotalPss += Debug.getPss(st.pid, null, null); 1851 } 1852 } 1853 memInfo.readMemInfo(); 1854 synchronized (ActivityManagerService.this) { 1855 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1856 + (SystemClock.uptimeMillis()-start) + "ms"); 1857 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1858 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1859 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1860 } 1861 } 1862 1863 int num = 0; 1864 long[] tmp = new long[1]; 1865 do { 1866 ProcessRecord proc; 1867 int procState; 1868 int pid; 1869 long lastPssTime; 1870 synchronized (ActivityManagerService.this) { 1871 if (mPendingPssProcesses.size() <= 0) { 1872 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1873 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1874 mPendingPssProcesses.clear(); 1875 return; 1876 } 1877 proc = mPendingPssProcesses.remove(0); 1878 procState = proc.pssProcState; 1879 lastPssTime = proc.lastPssTime; 1880 if (proc.thread != null && procState == proc.setProcState 1881 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1882 < SystemClock.uptimeMillis()) { 1883 pid = proc.pid; 1884 } else { 1885 proc = null; 1886 pid = 0; 1887 } 1888 } 1889 if (proc != null) { 1890 long pss = Debug.getPss(pid, tmp, null); 1891 synchronized (ActivityManagerService.this) { 1892 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1893 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1894 num++; 1895 recordPssSample(proc, procState, pss, tmp[0], 1896 SystemClock.uptimeMillis()); 1897 } 1898 } 1899 } 1900 } while (true); 1901 } 1902 } 1903 } 1904 }; 1905 1906 public void setSystemProcess() { 1907 try { 1908 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1909 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1910 ServiceManager.addService("meminfo", new MemBinder(this)); 1911 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1912 ServiceManager.addService("dbinfo", new DbBinder(this)); 1913 if (MONITOR_CPU_USAGE) { 1914 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1915 } 1916 ServiceManager.addService("permission", new PermissionController(this)); 1917 1918 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1919 "android", STOCK_PM_FLAGS); 1920 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1921 1922 synchronized (this) { 1923 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1924 app.persistent = true; 1925 app.pid = MY_PID; 1926 app.maxAdj = ProcessList.SYSTEM_ADJ; 1927 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1928 mProcessNames.put(app.processName, app.uid, app); 1929 synchronized (mPidsSelfLocked) { 1930 mPidsSelfLocked.put(app.pid, app); 1931 } 1932 updateLruProcessLocked(app, false, null); 1933 updateOomAdjLocked(); 1934 } 1935 } catch (PackageManager.NameNotFoundException e) { 1936 throw new RuntimeException( 1937 "Unable to find android system package", e); 1938 } 1939 } 1940 1941 public void setWindowManager(WindowManagerService wm) { 1942 mWindowManager = wm; 1943 mStackSupervisor.setWindowManager(wm); 1944 } 1945 1946 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1947 mUsageStatsService = usageStatsManager; 1948 } 1949 1950 public void startObservingNativeCrashes() { 1951 final NativeCrashListener ncl = new NativeCrashListener(this); 1952 ncl.start(); 1953 } 1954 1955 public IAppOpsService getAppOpsService() { 1956 return mAppOpsService; 1957 } 1958 1959 static class MemBinder extends Binder { 1960 ActivityManagerService mActivityManagerService; 1961 MemBinder(ActivityManagerService activityManagerService) { 1962 mActivityManagerService = activityManagerService; 1963 } 1964 1965 @Override 1966 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1967 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1968 != PackageManager.PERMISSION_GRANTED) { 1969 pw.println("Permission Denial: can't dump meminfo from from pid=" 1970 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1971 + " without permission " + android.Manifest.permission.DUMP); 1972 return; 1973 } 1974 1975 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1976 } 1977 } 1978 1979 static class GraphicsBinder extends Binder { 1980 ActivityManagerService mActivityManagerService; 1981 GraphicsBinder(ActivityManagerService activityManagerService) { 1982 mActivityManagerService = activityManagerService; 1983 } 1984 1985 @Override 1986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1987 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1988 != PackageManager.PERMISSION_GRANTED) { 1989 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1990 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1991 + " without permission " + android.Manifest.permission.DUMP); 1992 return; 1993 } 1994 1995 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1996 } 1997 } 1998 1999 static class DbBinder extends Binder { 2000 ActivityManagerService mActivityManagerService; 2001 DbBinder(ActivityManagerService activityManagerService) { 2002 mActivityManagerService = activityManagerService; 2003 } 2004 2005 @Override 2006 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2007 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2008 != PackageManager.PERMISSION_GRANTED) { 2009 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2010 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2011 + " without permission " + android.Manifest.permission.DUMP); 2012 return; 2013 } 2014 2015 mActivityManagerService.dumpDbInfo(fd, pw, args); 2016 } 2017 } 2018 2019 static class CpuBinder extends Binder { 2020 ActivityManagerService mActivityManagerService; 2021 CpuBinder(ActivityManagerService activityManagerService) { 2022 mActivityManagerService = activityManagerService; 2023 } 2024 2025 @Override 2026 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2027 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2028 != PackageManager.PERMISSION_GRANTED) { 2029 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2030 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2031 + " without permission " + android.Manifest.permission.DUMP); 2032 return; 2033 } 2034 2035 synchronized (mActivityManagerService.mProcessCpuTracker) { 2036 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2037 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2038 SystemClock.uptimeMillis())); 2039 } 2040 } 2041 } 2042 2043 public static final class Lifecycle extends SystemService { 2044 private final ActivityManagerService mService; 2045 2046 public Lifecycle(Context context) { 2047 super(context); 2048 mService = new ActivityManagerService(context); 2049 } 2050 2051 @Override 2052 public void onStart() { 2053 mService.start(); 2054 } 2055 2056 public ActivityManagerService getService() { 2057 return mService; 2058 } 2059 } 2060 2061 // Note: This method is invoked on the main thread but may need to attach various 2062 // handlers to other threads. So take care to be explicit about the looper. 2063 public ActivityManagerService(Context systemContext) { 2064 mContext = systemContext; 2065 mFactoryTest = FactoryTest.getMode(); 2066 mSystemThread = ActivityThread.currentActivityThread(); 2067 2068 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2069 2070 mHandlerThread = new ServiceThread(TAG, 2071 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2072 mHandlerThread.start(); 2073 mHandler = new MainHandler(mHandlerThread.getLooper()); 2074 2075 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2076 "foreground", BROADCAST_FG_TIMEOUT, false); 2077 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2078 "background", BROADCAST_BG_TIMEOUT, true); 2079 mBroadcastQueues[0] = mFgBroadcastQueue; 2080 mBroadcastQueues[1] = mBgBroadcastQueue; 2081 2082 mServices = new ActiveServices(this); 2083 mProviderMap = new ProviderMap(this); 2084 2085 // TODO: Move creation of battery stats service outside of activity manager service. 2086 File dataDir = Environment.getDataDirectory(); 2087 File systemDir = new File(dataDir, "system"); 2088 systemDir.mkdirs(); 2089 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2090 mBatteryStatsService.getActiveStatistics().readLocked(); 2091 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2092 mOnBattery = DEBUG_POWER ? true 2093 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2094 mBatteryStatsService.getActiveStatistics().setCallback(this); 2095 2096 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2097 2098 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2099 2100 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2101 2102 // User 0 is the first and only user that runs at boot. 2103 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2104 mUserLru.add(Integer.valueOf(0)); 2105 updateStartedUserArrayLocked(); 2106 2107 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2108 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2109 2110 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2111 2112 mConfiguration.setToDefaults(); 2113 mConfiguration.locale = Locale.getDefault(); 2114 2115 mConfigurationSeq = mConfiguration.seq = 1; 2116 mProcessCpuTracker.init(); 2117 2118 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2119 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2120 mRecentTasks = new RecentTasks(this); 2121 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks); 2122 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks); 2123 2124 mProcessCpuThread = new Thread("CpuTracker") { 2125 @Override 2126 public void run() { 2127 while (true) { 2128 try { 2129 try { 2130 synchronized(this) { 2131 final long now = SystemClock.uptimeMillis(); 2132 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2133 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2134 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2135 // + ", write delay=" + nextWriteDelay); 2136 if (nextWriteDelay < nextCpuDelay) { 2137 nextCpuDelay = nextWriteDelay; 2138 } 2139 if (nextCpuDelay > 0) { 2140 mProcessCpuMutexFree.set(true); 2141 this.wait(nextCpuDelay); 2142 } 2143 } 2144 } catch (InterruptedException e) { 2145 } 2146 updateCpuStatsNow(); 2147 } catch (Exception e) { 2148 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2149 } 2150 } 2151 } 2152 }; 2153 2154 Watchdog.getInstance().addMonitor(this); 2155 Watchdog.getInstance().addThread(mHandler); 2156 } 2157 2158 public void setSystemServiceManager(SystemServiceManager mgr) { 2159 mSystemServiceManager = mgr; 2160 } 2161 2162 public void setInstaller(Installer installer) { 2163 mInstaller = installer; 2164 } 2165 2166 private void start() { 2167 Process.removeAllProcessGroups(); 2168 mProcessCpuThread.start(); 2169 2170 mBatteryStatsService.publish(mContext); 2171 mAppOpsService.publish(mContext); 2172 Slog.d("AppOps", "AppOpsService published"); 2173 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2174 } 2175 2176 public void initPowerManagement() { 2177 mStackSupervisor.initPowerManagement(); 2178 mBatteryStatsService.initPowerManagement(); 2179 } 2180 2181 @Override 2182 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2183 throws RemoteException { 2184 if (code == SYSPROPS_TRANSACTION) { 2185 // We need to tell all apps about the system property change. 2186 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2187 synchronized(this) { 2188 final int NP = mProcessNames.getMap().size(); 2189 for (int ip=0; ip<NP; ip++) { 2190 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2191 final int NA = apps.size(); 2192 for (int ia=0; ia<NA; ia++) { 2193 ProcessRecord app = apps.valueAt(ia); 2194 if (app.thread != null) { 2195 procs.add(app.thread.asBinder()); 2196 } 2197 } 2198 } 2199 } 2200 2201 int N = procs.size(); 2202 for (int i=0; i<N; i++) { 2203 Parcel data2 = Parcel.obtain(); 2204 try { 2205 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2206 } catch (RemoteException e) { 2207 } 2208 data2.recycle(); 2209 } 2210 } 2211 try { 2212 return super.onTransact(code, data, reply, flags); 2213 } catch (RuntimeException e) { 2214 // The activity manager only throws security exceptions, so let's 2215 // log all others. 2216 if (!(e instanceof SecurityException)) { 2217 Slog.wtf(TAG, "Activity Manager Crash", e); 2218 } 2219 throw e; 2220 } 2221 } 2222 2223 void updateCpuStats() { 2224 final long now = SystemClock.uptimeMillis(); 2225 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2226 return; 2227 } 2228 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2229 synchronized (mProcessCpuThread) { 2230 mProcessCpuThread.notify(); 2231 } 2232 } 2233 } 2234 2235 void updateCpuStatsNow() { 2236 synchronized (mProcessCpuTracker) { 2237 mProcessCpuMutexFree.set(false); 2238 final long now = SystemClock.uptimeMillis(); 2239 boolean haveNewCpuStats = false; 2240 2241 if (MONITOR_CPU_USAGE && 2242 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2243 mLastCpuTime.set(now); 2244 haveNewCpuStats = true; 2245 mProcessCpuTracker.update(); 2246 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2247 //Slog.i(TAG, "Total CPU usage: " 2248 // + mProcessCpu.getTotalCpuPercent() + "%"); 2249 2250 // Slog the cpu usage if the property is set. 2251 if ("true".equals(SystemProperties.get("events.cpu"))) { 2252 int user = mProcessCpuTracker.getLastUserTime(); 2253 int system = mProcessCpuTracker.getLastSystemTime(); 2254 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2255 int irq = mProcessCpuTracker.getLastIrqTime(); 2256 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2257 int idle = mProcessCpuTracker.getLastIdleTime(); 2258 2259 int total = user + system + iowait + irq + softIrq + idle; 2260 if (total == 0) total = 1; 2261 2262 EventLog.writeEvent(EventLogTags.CPU, 2263 ((user+system+iowait+irq+softIrq) * 100) / total, 2264 (user * 100) / total, 2265 (system * 100) / total, 2266 (iowait * 100) / total, 2267 (irq * 100) / total, 2268 (softIrq * 100) / total); 2269 } 2270 } 2271 2272 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2273 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2274 synchronized(bstats) { 2275 synchronized(mPidsSelfLocked) { 2276 if (haveNewCpuStats) { 2277 if (mOnBattery) { 2278 int perc = bstats.startAddingCpuLocked(); 2279 int totalUTime = 0; 2280 int totalSTime = 0; 2281 final int N = mProcessCpuTracker.countStats(); 2282 for (int i=0; i<N; i++) { 2283 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2284 if (!st.working) { 2285 continue; 2286 } 2287 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2288 int otherUTime = (st.rel_utime*perc)/100; 2289 int otherSTime = (st.rel_stime*perc)/100; 2290 totalUTime += otherUTime; 2291 totalSTime += otherSTime; 2292 if (pr != null) { 2293 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2294 if (ps == null || !ps.isActive()) { 2295 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2296 pr.info.uid, pr.processName); 2297 } 2298 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2299 st.rel_stime-otherSTime); 2300 ps.addSpeedStepTimes(cpuSpeedTimes); 2301 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2302 } else { 2303 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2304 if (ps == null || !ps.isActive()) { 2305 st.batteryStats = ps = bstats.getProcessStatsLocked( 2306 bstats.mapUid(st.uid), st.name); 2307 } 2308 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2309 st.rel_stime-otherSTime); 2310 ps.addSpeedStepTimes(cpuSpeedTimes); 2311 } 2312 } 2313 bstats.finishAddingCpuLocked(perc, totalUTime, 2314 totalSTime, cpuSpeedTimes); 2315 } 2316 } 2317 } 2318 2319 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2320 mLastWriteTime = now; 2321 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2322 } 2323 } 2324 } 2325 } 2326 2327 @Override 2328 public void batteryNeedsCpuUpdate() { 2329 updateCpuStatsNow(); 2330 } 2331 2332 @Override 2333 public void batteryPowerChanged(boolean onBattery) { 2334 // When plugging in, update the CPU stats first before changing 2335 // the plug state. 2336 updateCpuStatsNow(); 2337 synchronized (this) { 2338 synchronized(mPidsSelfLocked) { 2339 mOnBattery = DEBUG_POWER ? true : onBattery; 2340 } 2341 } 2342 } 2343 2344 /** 2345 * Initialize the application bind args. These are passed to each 2346 * process when the bindApplication() IPC is sent to the process. They're 2347 * lazily setup to make sure the services are running when they're asked for. 2348 */ 2349 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2350 if (mAppBindArgs == null) { 2351 mAppBindArgs = new HashMap<>(); 2352 2353 // Isolated processes won't get this optimization, so that we don't 2354 // violate the rules about which services they have access to. 2355 if (!isolated) { 2356 // Setup the application init args 2357 mAppBindArgs.put("package", ServiceManager.getService("package")); 2358 mAppBindArgs.put("window", ServiceManager.getService("window")); 2359 mAppBindArgs.put(Context.ALARM_SERVICE, 2360 ServiceManager.getService(Context.ALARM_SERVICE)); 2361 } 2362 } 2363 return mAppBindArgs; 2364 } 2365 2366 final void setFocusedActivityLocked(ActivityRecord r) { 2367 if (mFocusedActivity != r) { 2368 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2369 mFocusedActivity = r; 2370 if (r.task != null && r.task.voiceInteractor != null) { 2371 startRunningVoiceLocked(); 2372 } else { 2373 finishRunningVoiceLocked(); 2374 } 2375 mStackSupervisor.setFocusedStack(r); 2376 if (r != null) { 2377 mWindowManager.setFocusedApp(r.appToken, true); 2378 } 2379 applyUpdateLockStateLocked(r); 2380 } 2381 } 2382 2383 final void clearFocusedActivity(ActivityRecord r) { 2384 if (mFocusedActivity == r) { 2385 mFocusedActivity = null; 2386 } 2387 } 2388 2389 @Override 2390 public void setFocusedStack(int stackId) { 2391 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2392 synchronized (ActivityManagerService.this) { 2393 ActivityStack stack = mStackSupervisor.getStack(stackId); 2394 if (stack != null) { 2395 ActivityRecord r = stack.topRunningActivityLocked(null); 2396 if (r != null) { 2397 setFocusedActivityLocked(r); 2398 } 2399 } 2400 } 2401 } 2402 2403 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2404 @Override 2405 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2406 synchronized (ActivityManagerService.this) { 2407 if (listener != null) { 2408 mTaskStackListeners.register(listener); 2409 } 2410 } 2411 } 2412 2413 @Override 2414 public void notifyActivityDrawn(IBinder token) { 2415 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2416 synchronized (this) { 2417 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2418 if (r != null) { 2419 r.task.stack.notifyActivityDrawnLocked(r); 2420 } 2421 } 2422 } 2423 2424 final void applyUpdateLockStateLocked(ActivityRecord r) { 2425 // Modifications to the UpdateLock state are done on our handler, outside 2426 // the activity manager's locks. The new state is determined based on the 2427 // state *now* of the relevant activity record. The object is passed to 2428 // the handler solely for logging detail, not to be consulted/modified. 2429 final boolean nextState = r != null && r.immersive; 2430 mHandler.sendMessage( 2431 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2432 } 2433 2434 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2435 Message msg = Message.obtain(); 2436 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2437 msg.obj = r.task.askedCompatMode ? null : r; 2438 mHandler.sendMessage(msg); 2439 } 2440 2441 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2442 String what, Object obj, ProcessRecord srcApp) { 2443 app.lastActivityTime = now; 2444 2445 if (app.activities.size() > 0) { 2446 // Don't want to touch dependent processes that are hosting activities. 2447 return index; 2448 } 2449 2450 int lrui = mLruProcesses.lastIndexOf(app); 2451 if (lrui < 0) { 2452 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2453 + what + " " + obj + " from " + srcApp); 2454 return index; 2455 } 2456 2457 if (lrui >= index) { 2458 // Don't want to cause this to move dependent processes *back* in the 2459 // list as if they were less frequently used. 2460 return index; 2461 } 2462 2463 if (lrui >= mLruProcessActivityStart) { 2464 // Don't want to touch dependent processes that are hosting activities. 2465 return index; 2466 } 2467 2468 mLruProcesses.remove(lrui); 2469 if (index > 0) { 2470 index--; 2471 } 2472 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2473 + " in LRU list: " + app); 2474 mLruProcesses.add(index, app); 2475 return index; 2476 } 2477 2478 final void removeLruProcessLocked(ProcessRecord app) { 2479 int lrui = mLruProcesses.lastIndexOf(app); 2480 if (lrui >= 0) { 2481 if (!app.killed) { 2482 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2483 Process.killProcessQuiet(app.pid); 2484 Process.killProcessGroup(app.info.uid, app.pid); 2485 } 2486 if (lrui <= mLruProcessActivityStart) { 2487 mLruProcessActivityStart--; 2488 } 2489 if (lrui <= mLruProcessServiceStart) { 2490 mLruProcessServiceStart--; 2491 } 2492 mLruProcesses.remove(lrui); 2493 } 2494 } 2495 2496 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2497 ProcessRecord client) { 2498 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2499 || app.treatLikeActivity; 2500 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2501 if (!activityChange && hasActivity) { 2502 // The process has activities, so we are only allowing activity-based adjustments 2503 // to move it. It should be kept in the front of the list with other 2504 // processes that have activities, and we don't want those to change their 2505 // order except due to activity operations. 2506 return; 2507 } 2508 2509 mLruSeq++; 2510 final long now = SystemClock.uptimeMillis(); 2511 app.lastActivityTime = now; 2512 2513 // First a quick reject: if the app is already at the position we will 2514 // put it, then there is nothing to do. 2515 if (hasActivity) { 2516 final int N = mLruProcesses.size(); 2517 if (N > 0 && mLruProcesses.get(N-1) == app) { 2518 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2519 return; 2520 } 2521 } else { 2522 if (mLruProcessServiceStart > 0 2523 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2524 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2525 return; 2526 } 2527 } 2528 2529 int lrui = mLruProcesses.lastIndexOf(app); 2530 2531 if (app.persistent && lrui >= 0) { 2532 // We don't care about the position of persistent processes, as long as 2533 // they are in the list. 2534 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2535 return; 2536 } 2537 2538 /* In progress: compute new position first, so we can avoid doing work 2539 if the process is not actually going to move. Not yet working. 2540 int addIndex; 2541 int nextIndex; 2542 boolean inActivity = false, inService = false; 2543 if (hasActivity) { 2544 // Process has activities, put it at the very tipsy-top. 2545 addIndex = mLruProcesses.size(); 2546 nextIndex = mLruProcessServiceStart; 2547 inActivity = true; 2548 } else if (hasService) { 2549 // Process has services, put it at the top of the service list. 2550 addIndex = mLruProcessActivityStart; 2551 nextIndex = mLruProcessServiceStart; 2552 inActivity = true; 2553 inService = true; 2554 } else { 2555 // Process not otherwise of interest, it goes to the top of the non-service area. 2556 addIndex = mLruProcessServiceStart; 2557 if (client != null) { 2558 int clientIndex = mLruProcesses.lastIndexOf(client); 2559 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2560 + app); 2561 if (clientIndex >= 0 && addIndex > clientIndex) { 2562 addIndex = clientIndex; 2563 } 2564 } 2565 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2566 } 2567 2568 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2569 + mLruProcessActivityStart + "): " + app); 2570 */ 2571 2572 if (lrui >= 0) { 2573 if (lrui < mLruProcessActivityStart) { 2574 mLruProcessActivityStart--; 2575 } 2576 if (lrui < mLruProcessServiceStart) { 2577 mLruProcessServiceStart--; 2578 } 2579 /* 2580 if (addIndex > lrui) { 2581 addIndex--; 2582 } 2583 if (nextIndex > lrui) { 2584 nextIndex--; 2585 } 2586 */ 2587 mLruProcesses.remove(lrui); 2588 } 2589 2590 /* 2591 mLruProcesses.add(addIndex, app); 2592 if (inActivity) { 2593 mLruProcessActivityStart++; 2594 } 2595 if (inService) { 2596 mLruProcessActivityStart++; 2597 } 2598 */ 2599 2600 int nextIndex; 2601 if (hasActivity) { 2602 final int N = mLruProcesses.size(); 2603 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2604 // Process doesn't have activities, but has clients with 2605 // activities... move it up, but one below the top (the top 2606 // should always have a real activity). 2607 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2608 mLruProcesses.add(N-1, app); 2609 // To keep it from spamming the LRU list (by making a bunch of clients), 2610 // we will push down any other entries owned by the app. 2611 final int uid = app.info.uid; 2612 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2613 ProcessRecord subProc = mLruProcesses.get(i); 2614 if (subProc.info.uid == uid) { 2615 // We want to push this one down the list. If the process after 2616 // it is for the same uid, however, don't do so, because we don't 2617 // want them internally to be re-ordered. 2618 if (mLruProcesses.get(i-1).info.uid != uid) { 2619 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2620 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2621 ProcessRecord tmp = mLruProcesses.get(i); 2622 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2623 mLruProcesses.set(i-1, tmp); 2624 i--; 2625 } 2626 } else { 2627 // A gap, we can stop here. 2628 break; 2629 } 2630 } 2631 } else { 2632 // Process has activities, put it at the very tipsy-top. 2633 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2634 mLruProcesses.add(app); 2635 } 2636 nextIndex = mLruProcessServiceStart; 2637 } else if (hasService) { 2638 // Process has services, put it at the top of the service list. 2639 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2640 mLruProcesses.add(mLruProcessActivityStart, app); 2641 nextIndex = mLruProcessServiceStart; 2642 mLruProcessActivityStart++; 2643 } else { 2644 // Process not otherwise of interest, it goes to the top of the non-service area. 2645 int index = mLruProcessServiceStart; 2646 if (client != null) { 2647 // If there is a client, don't allow the process to be moved up higher 2648 // in the list than that client. 2649 int clientIndex = mLruProcesses.lastIndexOf(client); 2650 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2651 + " when updating " + app); 2652 if (clientIndex <= lrui) { 2653 // Don't allow the client index restriction to push it down farther in the 2654 // list than it already is. 2655 clientIndex = lrui; 2656 } 2657 if (clientIndex >= 0 && index > clientIndex) { 2658 index = clientIndex; 2659 } 2660 } 2661 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2662 mLruProcesses.add(index, app); 2663 nextIndex = index-1; 2664 mLruProcessActivityStart++; 2665 mLruProcessServiceStart++; 2666 } 2667 2668 // If the app is currently using a content provider or service, 2669 // bump those processes as well. 2670 for (int j=app.connections.size()-1; j>=0; j--) { 2671 ConnectionRecord cr = app.connections.valueAt(j); 2672 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2673 && cr.binding.service.app != null 2674 && cr.binding.service.app.lruSeq != mLruSeq 2675 && !cr.binding.service.app.persistent) { 2676 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2677 "service connection", cr, app); 2678 } 2679 } 2680 for (int j=app.conProviders.size()-1; j>=0; j--) { 2681 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2682 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2683 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2684 "provider reference", cpr, app); 2685 } 2686 } 2687 } 2688 2689 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2690 if (uid == Process.SYSTEM_UID) { 2691 // The system gets to run in any process. If there are multiple 2692 // processes with the same uid, just pick the first (this 2693 // should never happen). 2694 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2695 if (procs == null) return null; 2696 final int N = procs.size(); 2697 for (int i = 0; i < N; i++) { 2698 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2699 } 2700 } 2701 ProcessRecord proc = mProcessNames.get(processName, uid); 2702 if (false && proc != null && !keepIfLarge 2703 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2704 && proc.lastCachedPss >= 4000) { 2705 // Turn this condition on to cause killing to happen regularly, for testing. 2706 if (proc.baseProcessTracker != null) { 2707 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2708 } 2709 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2710 } else if (proc != null && !keepIfLarge 2711 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2712 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2713 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2714 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2715 if (proc.baseProcessTracker != null) { 2716 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2717 } 2718 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2719 } 2720 } 2721 return proc; 2722 } 2723 2724 void ensurePackageDexOpt(String packageName) { 2725 IPackageManager pm = AppGlobals.getPackageManager(); 2726 try { 2727 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2728 mDidDexOpt = true; 2729 } 2730 } catch (RemoteException e) { 2731 } 2732 } 2733 2734 boolean isNextTransitionForward() { 2735 int transit = mWindowManager.getPendingAppTransition(); 2736 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2737 || transit == AppTransition.TRANSIT_TASK_OPEN 2738 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2739 } 2740 2741 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2742 String processName, String abiOverride, int uid, Runnable crashHandler) { 2743 synchronized(this) { 2744 ApplicationInfo info = new ApplicationInfo(); 2745 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2746 // For isolated processes, the former contains the parent's uid and the latter the 2747 // actual uid of the isolated process. 2748 // In the special case introduced by this method (which is, starting an isolated 2749 // process directly from the SystemServer without an actual parent app process) the 2750 // closest thing to a parent's uid is SYSTEM_UID. 2751 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2752 // the |isolated| logic in the ProcessRecord constructor. 2753 info.uid = Process.SYSTEM_UID; 2754 info.processName = processName; 2755 info.className = entryPoint; 2756 info.packageName = "android"; 2757 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2758 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2759 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2760 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2761 crashHandler); 2762 return proc != null ? proc.pid : 0; 2763 } 2764 } 2765 2766 final ProcessRecord startProcessLocked(String processName, 2767 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2768 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2769 boolean isolated, boolean keepIfLarge) { 2770 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2771 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2772 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2773 null /* crashHandler */); 2774 } 2775 2776 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2777 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2778 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2779 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2780 long startTime = SystemClock.elapsedRealtime(); 2781 ProcessRecord app; 2782 if (!isolated) { 2783 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2784 checkTime(startTime, "startProcess: after getProcessRecord"); 2785 } else { 2786 // If this is an isolated process, it can't re-use an existing process. 2787 app = null; 2788 } 2789 // We don't have to do anything more if: 2790 // (1) There is an existing application record; and 2791 // (2) The caller doesn't think it is dead, OR there is no thread 2792 // object attached to it so we know it couldn't have crashed; and 2793 // (3) There is a pid assigned to it, so it is either starting or 2794 // already running. 2795 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2796 + " app=" + app + " knownToBeDead=" + knownToBeDead 2797 + " thread=" + (app != null ? app.thread : null) 2798 + " pid=" + (app != null ? app.pid : -1)); 2799 if (app != null && app.pid > 0) { 2800 if (!knownToBeDead || app.thread == null) { 2801 // We already have the app running, or are waiting for it to 2802 // come up (we have a pid but not yet its thread), so keep it. 2803 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2804 // If this is a new package in the process, add the package to the list 2805 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2806 checkTime(startTime, "startProcess: done, added package to proc"); 2807 return app; 2808 } 2809 2810 // An application record is attached to a previous process, 2811 // clean it up now. 2812 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2813 checkTime(startTime, "startProcess: bad proc running, killing"); 2814 Process.killProcessGroup(app.info.uid, app.pid); 2815 handleAppDiedLocked(app, true, true); 2816 checkTime(startTime, "startProcess: done killing old proc"); 2817 } 2818 2819 String hostingNameStr = hostingName != null 2820 ? hostingName.flattenToShortString() : null; 2821 2822 if (!isolated) { 2823 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2824 // If we are in the background, then check to see if this process 2825 // is bad. If so, we will just silently fail. 2826 if (mBadProcesses.get(info.processName, info.uid) != null) { 2827 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2828 + "/" + info.processName); 2829 return null; 2830 } 2831 } else { 2832 // When the user is explicitly starting a process, then clear its 2833 // crash count so that we won't make it bad until they see at 2834 // least one crash dialog again, and make the process good again 2835 // if it had been bad. 2836 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2837 + "/" + info.processName); 2838 mProcessCrashTimes.remove(info.processName, info.uid); 2839 if (mBadProcesses.get(info.processName, info.uid) != null) { 2840 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2841 UserHandle.getUserId(info.uid), info.uid, 2842 info.processName); 2843 mBadProcesses.remove(info.processName, info.uid); 2844 if (app != null) { 2845 app.bad = false; 2846 } 2847 } 2848 } 2849 } 2850 2851 if (app == null) { 2852 checkTime(startTime, "startProcess: creating new process record"); 2853 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2854 if (app == null) { 2855 Slog.w(TAG, "Failed making new process record for " 2856 + processName + "/" + info.uid + " isolated=" + isolated); 2857 return null; 2858 } 2859 app.crashHandler = crashHandler; 2860 mProcessNames.put(processName, app.uid, app); 2861 if (isolated) { 2862 mIsolatedProcesses.put(app.uid, app); 2863 } 2864 checkTime(startTime, "startProcess: done creating new process record"); 2865 } else { 2866 // If this is a new package in the process, add the package to the list 2867 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2868 checkTime(startTime, "startProcess: added package to existing proc"); 2869 } 2870 2871 // If the system is not ready yet, then hold off on starting this 2872 // process until it is. 2873 if (!mProcessesReady 2874 && !isAllowedWhileBooting(info) 2875 && !allowWhileBooting) { 2876 if (!mProcessesOnHold.contains(app)) { 2877 mProcessesOnHold.add(app); 2878 } 2879 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2880 checkTime(startTime, "startProcess: returning with proc on hold"); 2881 return app; 2882 } 2883 2884 checkTime(startTime, "startProcess: stepping in to startProcess"); 2885 startProcessLocked( 2886 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2887 checkTime(startTime, "startProcess: done starting proc!"); 2888 return (app.pid != 0) ? app : null; 2889 } 2890 2891 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2892 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2893 } 2894 2895 private final void startProcessLocked(ProcessRecord app, 2896 String hostingType, String hostingNameStr) { 2897 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2898 null /* entryPoint */, null /* entryPointArgs */); 2899 } 2900 2901 private final void startProcessLocked(ProcessRecord app, String hostingType, 2902 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2903 long startTime = SystemClock.elapsedRealtime(); 2904 if (app.pid > 0 && app.pid != MY_PID) { 2905 checkTime(startTime, "startProcess: removing from pids map"); 2906 synchronized (mPidsSelfLocked) { 2907 mPidsSelfLocked.remove(app.pid); 2908 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2909 } 2910 checkTime(startTime, "startProcess: done removing from pids map"); 2911 app.setPid(0); 2912 } 2913 2914 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2915 "startProcessLocked removing on hold: " + app); 2916 mProcessesOnHold.remove(app); 2917 2918 checkTime(startTime, "startProcess: starting to update cpu stats"); 2919 updateCpuStats(); 2920 checkTime(startTime, "startProcess: done updating cpu stats"); 2921 2922 try { 2923 int uid = app.uid; 2924 2925 int[] gids = null; 2926 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2927 if (!app.isolated) { 2928 int[] permGids = null; 2929 try { 2930 checkTime(startTime, "startProcess: getting gids from package manager"); 2931 final PackageManager pm = mContext.getPackageManager(); 2932 permGids = pm.getPackageGids(app.info.packageName); 2933 2934 if (Environment.isExternalStorageEmulated()) { 2935 checkTime(startTime, "startProcess: checking external storage perm"); 2936 if (pm.checkPermission( 2937 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2938 app.info.packageName) == PERMISSION_GRANTED) { 2939 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2940 } else { 2941 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2942 } 2943 } 2944 } catch (PackageManager.NameNotFoundException e) { 2945 Slog.w(TAG, "Unable to retrieve gids", e); 2946 } 2947 2948 /* 2949 * Add shared application and profile GIDs so applications can share some 2950 * resources like shared libraries and access user-wide resources 2951 */ 2952 if (permGids == null) { 2953 gids = new int[2]; 2954 } else { 2955 gids = new int[permGids.length + 2]; 2956 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2957 } 2958 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2959 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2960 } 2961 checkTime(startTime, "startProcess: building args"); 2962 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2963 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2964 && mTopComponent != null 2965 && app.processName.equals(mTopComponent.getPackageName())) { 2966 uid = 0; 2967 } 2968 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2969 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2970 uid = 0; 2971 } 2972 } 2973 int debugFlags = 0; 2974 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2975 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2976 // Also turn on CheckJNI for debuggable apps. It's quite 2977 // awkward to turn on otherwise. 2978 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2979 } 2980 // Run the app in safe mode if its manifest requests so or the 2981 // system is booted in safe mode. 2982 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2983 mSafeMode == true) { 2984 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2985 } 2986 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2988 } 2989 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2991 } 2992 if ("1".equals(SystemProperties.get("debug.assert"))) { 2993 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2994 } 2995 2996 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2997 if (requiredAbi == null) { 2998 requiredAbi = Build.SUPPORTED_ABIS[0]; 2999 } 3000 3001 String instructionSet = null; 3002 if (app.info.primaryCpuAbi != null) { 3003 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3004 } 3005 3006 app.gids = gids; 3007 app.requiredAbi = requiredAbi; 3008 app.instructionSet = instructionSet; 3009 3010 // Start the process. It will either succeed and return a result containing 3011 // the PID of the new process, or else throw a RuntimeException. 3012 boolean isActivityProcess = (entryPoint == null); 3013 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3014 checkTime(startTime, "startProcess: asking zygote to start proc"); 3015 Process.ProcessStartResult startResult = Process.start(entryPoint, 3016 app.processName, uid, uid, gids, debugFlags, mountExternal, 3017 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3018 app.info.dataDir, entryPointArgs); 3019 checkTime(startTime, "startProcess: returned from zygote!"); 3020 3021 if (app.isolated) { 3022 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3023 } 3024 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3025 checkTime(startTime, "startProcess: done updating battery stats"); 3026 3027 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3028 UserHandle.getUserId(uid), startResult.pid, uid, 3029 app.processName, hostingType, 3030 hostingNameStr != null ? hostingNameStr : ""); 3031 3032 if (app.persistent) { 3033 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3034 } 3035 3036 checkTime(startTime, "startProcess: building log message"); 3037 StringBuilder buf = mStringBuilder; 3038 buf.setLength(0); 3039 buf.append("Start proc "); 3040 buf.append(startResult.pid); 3041 buf.append(':'); 3042 buf.append(app.processName); 3043 buf.append('/'); 3044 UserHandle.formatUid(buf, uid); 3045 if (!isActivityProcess) { 3046 buf.append(" ["); 3047 buf.append(entryPoint); 3048 buf.append("]"); 3049 } 3050 buf.append(" for "); 3051 buf.append(hostingType); 3052 if (hostingNameStr != null) { 3053 buf.append(" "); 3054 buf.append(hostingNameStr); 3055 } 3056 Slog.i(TAG, buf.toString()); 3057 app.setPid(startResult.pid); 3058 app.usingWrapper = startResult.usingWrapper; 3059 app.removed = false; 3060 app.killed = false; 3061 app.killedByAm = false; 3062 checkTime(startTime, "startProcess: starting to update pids map"); 3063 synchronized (mPidsSelfLocked) { 3064 this.mPidsSelfLocked.put(startResult.pid, app); 3065 if (isActivityProcess) { 3066 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3067 msg.obj = app; 3068 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3069 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3070 } 3071 } 3072 checkTime(startTime, "startProcess: done updating pids map"); 3073 } catch (RuntimeException e) { 3074 // XXX do better error recovery. 3075 app.setPid(0); 3076 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3077 if (app.isolated) { 3078 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3079 } 3080 Slog.e(TAG, "Failure starting process " + app.processName, e); 3081 } 3082 } 3083 3084 void updateUsageStats(ActivityRecord component, boolean resumed) { 3085 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3086 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3087 if (resumed) { 3088 if (mUsageStatsService != null) { 3089 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3090 UsageEvents.Event.MOVE_TO_FOREGROUND); 3091 } 3092 synchronized (stats) { 3093 stats.noteActivityResumedLocked(component.app.uid); 3094 } 3095 } else { 3096 if (mUsageStatsService != null) { 3097 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3098 UsageEvents.Event.MOVE_TO_BACKGROUND); 3099 } 3100 synchronized (stats) { 3101 stats.noteActivityPausedLocked(component.app.uid); 3102 } 3103 } 3104 } 3105 3106 Intent getHomeIntent() { 3107 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3108 intent.setComponent(mTopComponent); 3109 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3110 intent.addCategory(Intent.CATEGORY_HOME); 3111 } 3112 return intent; 3113 } 3114 3115 boolean startHomeActivityLocked(int userId) { 3116 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3117 && mTopAction == null) { 3118 // We are running in factory test mode, but unable to find 3119 // the factory test app, so just sit around displaying the 3120 // error message and don't try to start anything. 3121 return false; 3122 } 3123 Intent intent = getHomeIntent(); 3124 ActivityInfo aInfo = 3125 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3126 if (aInfo != null) { 3127 intent.setComponent(new ComponentName( 3128 aInfo.applicationInfo.packageName, aInfo.name)); 3129 // Don't do this if the home app is currently being 3130 // instrumented. 3131 aInfo = new ActivityInfo(aInfo); 3132 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3133 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3134 aInfo.applicationInfo.uid, true); 3135 if (app == null || app.instrumentationClass == null) { 3136 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3137 mStackSupervisor.startHomeActivity(intent, aInfo); 3138 } 3139 } 3140 3141 return true; 3142 } 3143 3144 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3145 ActivityInfo ai = null; 3146 ComponentName comp = intent.getComponent(); 3147 try { 3148 if (comp != null) { 3149 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3150 } else { 3151 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3152 intent, 3153 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3154 flags, userId); 3155 3156 if (info != null) { 3157 ai = info.activityInfo; 3158 } 3159 } 3160 } catch (RemoteException e) { 3161 // ignore 3162 } 3163 3164 return ai; 3165 } 3166 3167 /** 3168 * Starts the "new version setup screen" if appropriate. 3169 */ 3170 void startSetupActivityLocked() { 3171 // Only do this once per boot. 3172 if (mCheckedForSetup) { 3173 return; 3174 } 3175 3176 // We will show this screen if the current one is a different 3177 // version than the last one shown, and we are not running in 3178 // low-level factory test mode. 3179 final ContentResolver resolver = mContext.getContentResolver(); 3180 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3181 Settings.Global.getInt(resolver, 3182 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3183 mCheckedForSetup = true; 3184 3185 // See if we should be showing the platform update setup UI. 3186 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3187 List<ResolveInfo> ris = mContext.getPackageManager() 3188 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3189 3190 // We don't allow third party apps to replace this. 3191 ResolveInfo ri = null; 3192 for (int i=0; ris != null && i<ris.size(); i++) { 3193 if ((ris.get(i).activityInfo.applicationInfo.flags 3194 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3195 ri = ris.get(i); 3196 break; 3197 } 3198 } 3199 3200 if (ri != null) { 3201 String vers = ri.activityInfo.metaData != null 3202 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3203 : null; 3204 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3205 vers = ri.activityInfo.applicationInfo.metaData.getString( 3206 Intent.METADATA_SETUP_VERSION); 3207 } 3208 String lastVers = Settings.Secure.getString( 3209 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3210 if (vers != null && !vers.equals(lastVers)) { 3211 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3212 intent.setComponent(new ComponentName( 3213 ri.activityInfo.packageName, ri.activityInfo.name)); 3214 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3215 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3216 null); 3217 } 3218 } 3219 } 3220 } 3221 3222 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3223 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3224 } 3225 3226 void enforceNotIsolatedCaller(String caller) { 3227 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3228 throw new SecurityException("Isolated process not allowed to call " + caller); 3229 } 3230 } 3231 3232 void enforceShellRestriction(String restriction, int userHandle) { 3233 if (Binder.getCallingUid() == Process.SHELL_UID) { 3234 if (userHandle < 0 3235 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3236 throw new SecurityException("Shell does not have permission to access user " 3237 + userHandle); 3238 } 3239 } 3240 } 3241 3242 @Override 3243 public int getFrontActivityScreenCompatMode() { 3244 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3245 synchronized (this) { 3246 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3247 } 3248 } 3249 3250 @Override 3251 public void setFrontActivityScreenCompatMode(int mode) { 3252 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3253 "setFrontActivityScreenCompatMode"); 3254 synchronized (this) { 3255 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3256 } 3257 } 3258 3259 @Override 3260 public int getPackageScreenCompatMode(String packageName) { 3261 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3262 synchronized (this) { 3263 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3264 } 3265 } 3266 3267 @Override 3268 public void setPackageScreenCompatMode(String packageName, int mode) { 3269 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3270 "setPackageScreenCompatMode"); 3271 synchronized (this) { 3272 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3273 } 3274 } 3275 3276 @Override 3277 public boolean getPackageAskScreenCompat(String packageName) { 3278 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3279 synchronized (this) { 3280 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3281 } 3282 } 3283 3284 @Override 3285 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3286 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3287 "setPackageAskScreenCompat"); 3288 synchronized (this) { 3289 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3290 } 3291 } 3292 3293 private void dispatchProcessesChanged() { 3294 int N; 3295 synchronized (this) { 3296 N = mPendingProcessChanges.size(); 3297 if (mActiveProcessChanges.length < N) { 3298 mActiveProcessChanges = new ProcessChangeItem[N]; 3299 } 3300 mPendingProcessChanges.toArray(mActiveProcessChanges); 3301 mAvailProcessChanges.addAll(mPendingProcessChanges); 3302 mPendingProcessChanges.clear(); 3303 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3304 } 3305 3306 int i = mProcessObservers.beginBroadcast(); 3307 while (i > 0) { 3308 i--; 3309 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3310 if (observer != null) { 3311 try { 3312 for (int j=0; j<N; j++) { 3313 ProcessChangeItem item = mActiveProcessChanges[j]; 3314 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3315 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3316 + item.pid + " uid=" + item.uid + ": " 3317 + item.foregroundActivities); 3318 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3319 item.foregroundActivities); 3320 } 3321 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3322 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3323 + item.pid + " uid=" + item.uid + ": " + item.processState); 3324 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3325 } 3326 } 3327 } catch (RemoteException e) { 3328 } 3329 } 3330 } 3331 mProcessObservers.finishBroadcast(); 3332 } 3333 3334 private void dispatchProcessDied(int pid, int uid) { 3335 int i = mProcessObservers.beginBroadcast(); 3336 while (i > 0) { 3337 i--; 3338 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3339 if (observer != null) { 3340 try { 3341 observer.onProcessDied(pid, uid); 3342 } catch (RemoteException e) { 3343 } 3344 } 3345 } 3346 mProcessObservers.finishBroadcast(); 3347 } 3348 3349 @Override 3350 public final int startActivity(IApplicationThread caller, String callingPackage, 3351 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3352 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3353 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3354 resultWho, requestCode, startFlags, profilerInfo, options, 3355 UserHandle.getCallingUserId()); 3356 } 3357 3358 @Override 3359 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3360 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3361 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3362 enforceNotIsolatedCaller("startActivity"); 3363 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3364 false, ALLOW_FULL_ONLY, "startActivity", null); 3365 // TODO: Switch to user app stacks here. 3366 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3367 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3368 profilerInfo, null, null, options, userId, null, null); 3369 } 3370 3371 @Override 3372 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3373 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3374 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3375 3376 // This is very dangerous -- it allows you to perform a start activity (including 3377 // permission grants) as any app that may launch one of your own activities. So 3378 // we will only allow this to be done from activities that are part of the core framework, 3379 // and then only when they are running as the system. 3380 final ActivityRecord sourceRecord; 3381 final int targetUid; 3382 final String targetPackage; 3383 synchronized (this) { 3384 if (resultTo == null) { 3385 throw new SecurityException("Must be called from an activity"); 3386 } 3387 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3388 if (sourceRecord == null) { 3389 throw new SecurityException("Called with bad activity token: " + resultTo); 3390 } 3391 if (!sourceRecord.info.packageName.equals("android")) { 3392 throw new SecurityException( 3393 "Must be called from an activity that is declared in the android package"); 3394 } 3395 if (sourceRecord.app == null) { 3396 throw new SecurityException("Called without a process attached to activity"); 3397 } 3398 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3399 // This is still okay, as long as this activity is running under the 3400 // uid of the original calling activity. 3401 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3402 throw new SecurityException( 3403 "Calling activity in uid " + sourceRecord.app.uid 3404 + " must be system uid or original calling uid " 3405 + sourceRecord.launchedFromUid); 3406 } 3407 } 3408 targetUid = sourceRecord.launchedFromUid; 3409 targetPackage = sourceRecord.launchedFromPackage; 3410 } 3411 3412 if (userId == UserHandle.USER_NULL) { 3413 userId = UserHandle.getUserId(sourceRecord.app.uid); 3414 } 3415 3416 // TODO: Switch to user app stacks here. 3417 try { 3418 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3419 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3420 null, null, options, userId, null, null); 3421 return ret; 3422 } catch (SecurityException e) { 3423 // XXX need to figure out how to propagate to original app. 3424 // A SecurityException here is generally actually a fault of the original 3425 // calling activity (such as a fairly granting permissions), so propagate it 3426 // back to them. 3427 /* 3428 StringBuilder msg = new StringBuilder(); 3429 msg.append("While launching"); 3430 msg.append(intent.toString()); 3431 msg.append(": "); 3432 msg.append(e.getMessage()); 3433 */ 3434 throw e; 3435 } 3436 } 3437 3438 @Override 3439 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3440 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3441 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3442 enforceNotIsolatedCaller("startActivityAndWait"); 3443 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3444 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3445 WaitResult res = new WaitResult(); 3446 // TODO: Switch to user app stacks here. 3447 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3448 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3449 options, userId, null, null); 3450 return res; 3451 } 3452 3453 @Override 3454 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3455 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3456 int startFlags, Configuration config, Bundle options, int userId) { 3457 enforceNotIsolatedCaller("startActivityWithConfig"); 3458 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3459 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3460 // TODO: Switch to user app stacks here. 3461 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3462 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3463 null, null, config, options, userId, null, null); 3464 return ret; 3465 } 3466 3467 @Override 3468 public int startActivityIntentSender(IApplicationThread caller, 3469 IntentSender intent, Intent fillInIntent, String resolvedType, 3470 IBinder resultTo, String resultWho, int requestCode, 3471 int flagsMask, int flagsValues, Bundle options) { 3472 enforceNotIsolatedCaller("startActivityIntentSender"); 3473 // Refuse possible leaked file descriptors 3474 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3475 throw new IllegalArgumentException("File descriptors passed in Intent"); 3476 } 3477 3478 IIntentSender sender = intent.getTarget(); 3479 if (!(sender instanceof PendingIntentRecord)) { 3480 throw new IllegalArgumentException("Bad PendingIntent object"); 3481 } 3482 3483 PendingIntentRecord pir = (PendingIntentRecord)sender; 3484 3485 synchronized (this) { 3486 // If this is coming from the currently resumed activity, it is 3487 // effectively saying that app switches are allowed at this point. 3488 final ActivityStack stack = getFocusedStack(); 3489 if (stack.mResumedActivity != null && 3490 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3491 mAppSwitchesAllowedTime = 0; 3492 } 3493 } 3494 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3495 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3496 return ret; 3497 } 3498 3499 @Override 3500 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3501 Intent intent, String resolvedType, IVoiceInteractionSession session, 3502 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3503 Bundle options, int userId) { 3504 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3505 != PackageManager.PERMISSION_GRANTED) { 3506 String msg = "Permission Denial: startVoiceActivity() from pid=" 3507 + Binder.getCallingPid() 3508 + ", uid=" + Binder.getCallingUid() 3509 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3510 Slog.w(TAG, msg); 3511 throw new SecurityException(msg); 3512 } 3513 if (session == null || interactor == null) { 3514 throw new NullPointerException("null session or interactor"); 3515 } 3516 userId = handleIncomingUser(callingPid, callingUid, userId, 3517 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3518 // TODO: Switch to user app stacks here. 3519 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3520 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3521 null, options, userId, null, null); 3522 } 3523 3524 @Override 3525 public boolean startNextMatchingActivity(IBinder callingActivity, 3526 Intent intent, Bundle options) { 3527 // Refuse possible leaked file descriptors 3528 if (intent != null && intent.hasFileDescriptors() == true) { 3529 throw new IllegalArgumentException("File descriptors passed in Intent"); 3530 } 3531 3532 synchronized (this) { 3533 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3534 if (r == null) { 3535 ActivityOptions.abort(options); 3536 return false; 3537 } 3538 if (r.app == null || r.app.thread == null) { 3539 // The caller is not running... d'oh! 3540 ActivityOptions.abort(options); 3541 return false; 3542 } 3543 intent = new Intent(intent); 3544 // The caller is not allowed to change the data. 3545 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3546 // And we are resetting to find the next component... 3547 intent.setComponent(null); 3548 3549 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3550 3551 ActivityInfo aInfo = null; 3552 try { 3553 List<ResolveInfo> resolves = 3554 AppGlobals.getPackageManager().queryIntentActivities( 3555 intent, r.resolvedType, 3556 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3557 UserHandle.getCallingUserId()); 3558 3559 // Look for the original activity in the list... 3560 final int N = resolves != null ? resolves.size() : 0; 3561 for (int i=0; i<N; i++) { 3562 ResolveInfo rInfo = resolves.get(i); 3563 if (rInfo.activityInfo.packageName.equals(r.packageName) 3564 && rInfo.activityInfo.name.equals(r.info.name)) { 3565 // We found the current one... the next matching is 3566 // after it. 3567 i++; 3568 if (i<N) { 3569 aInfo = resolves.get(i).activityInfo; 3570 } 3571 if (debug) { 3572 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3573 + "/" + r.info.name); 3574 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3575 + "/" + aInfo.name); 3576 } 3577 break; 3578 } 3579 } 3580 } catch (RemoteException e) { 3581 } 3582 3583 if (aInfo == null) { 3584 // Nobody who is next! 3585 ActivityOptions.abort(options); 3586 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3587 return false; 3588 } 3589 3590 intent.setComponent(new ComponentName( 3591 aInfo.applicationInfo.packageName, aInfo.name)); 3592 intent.setFlags(intent.getFlags()&~( 3593 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3594 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3595 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3596 Intent.FLAG_ACTIVITY_NEW_TASK)); 3597 3598 // Okay now we need to start the new activity, replacing the 3599 // currently running activity. This is a little tricky because 3600 // we want to start the new one as if the current one is finished, 3601 // but not finish the current one first so that there is no flicker. 3602 // And thus... 3603 final boolean wasFinishing = r.finishing; 3604 r.finishing = true; 3605 3606 // Propagate reply information over to the new activity. 3607 final ActivityRecord resultTo = r.resultTo; 3608 final String resultWho = r.resultWho; 3609 final int requestCode = r.requestCode; 3610 r.resultTo = null; 3611 if (resultTo != null) { 3612 resultTo.removeResultsLocked(r, resultWho, requestCode); 3613 } 3614 3615 final long origId = Binder.clearCallingIdentity(); 3616 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3617 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3618 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3619 -1, r.launchedFromUid, 0, options, false, null, null, null); 3620 Binder.restoreCallingIdentity(origId); 3621 3622 r.finishing = wasFinishing; 3623 if (res != ActivityManager.START_SUCCESS) { 3624 return false; 3625 } 3626 return true; 3627 } 3628 } 3629 3630 @Override 3631 public final int startActivityFromRecents(int taskId, Bundle options) { 3632 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3633 String msg = "Permission Denial: startActivityFromRecents called without " + 3634 START_TASKS_FROM_RECENTS; 3635 Slog.w(TAG, msg); 3636 throw new SecurityException(msg); 3637 } 3638 return startActivityFromRecentsInner(taskId, options); 3639 } 3640 3641 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3642 final TaskRecord task; 3643 final int callingUid; 3644 final String callingPackage; 3645 final Intent intent; 3646 final int userId; 3647 synchronized (this) { 3648 task = mRecentTasks.taskForIdLocked(taskId); 3649 if (task == null) { 3650 throw new IllegalArgumentException("Task " + taskId + " not found."); 3651 } 3652 if (task.getRootActivity() != null) { 3653 moveTaskToFrontLocked(task.taskId, 0, null); 3654 return ActivityManager.START_TASK_TO_FRONT; 3655 } 3656 callingUid = task.mCallingUid; 3657 callingPackage = task.mCallingPackage; 3658 intent = task.intent; 3659 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3660 userId = task.userId; 3661 } 3662 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3663 options, userId, null, task); 3664 } 3665 3666 final int startActivityInPackage(int uid, String callingPackage, 3667 Intent intent, String resolvedType, IBinder resultTo, 3668 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3669 IActivityContainer container, TaskRecord inTask) { 3670 3671 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3672 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3673 3674 // TODO: Switch to user app stacks here. 3675 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3676 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3677 null, null, null, options, userId, container, inTask); 3678 return ret; 3679 } 3680 3681 @Override 3682 public final int startActivities(IApplicationThread caller, String callingPackage, 3683 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3684 int userId) { 3685 enforceNotIsolatedCaller("startActivities"); 3686 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3687 false, ALLOW_FULL_ONLY, "startActivity", null); 3688 // TODO: Switch to user app stacks here. 3689 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3690 resolvedTypes, resultTo, options, userId); 3691 return ret; 3692 } 3693 3694 final int startActivitiesInPackage(int uid, String callingPackage, 3695 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3696 Bundle options, int userId) { 3697 3698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3699 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3700 // TODO: Switch to user app stacks here. 3701 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3702 resultTo, options, userId); 3703 return ret; 3704 } 3705 3706 @Override 3707 public void reportActivityFullyDrawn(IBinder token) { 3708 synchronized (this) { 3709 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3710 if (r == null) { 3711 return; 3712 } 3713 r.reportFullyDrawnLocked(); 3714 } 3715 } 3716 3717 @Override 3718 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3719 synchronized (this) { 3720 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3721 if (r == null) { 3722 return; 3723 } 3724 final long origId = Binder.clearCallingIdentity(); 3725 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3726 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3727 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3728 if (config != null) { 3729 r.frozenBeforeDestroy = true; 3730 if (!updateConfigurationLocked(config, r, false, false)) { 3731 mStackSupervisor.resumeTopActivitiesLocked(); 3732 } 3733 } 3734 Binder.restoreCallingIdentity(origId); 3735 } 3736 } 3737 3738 @Override 3739 public int getRequestedOrientation(IBinder token) { 3740 synchronized (this) { 3741 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3742 if (r == null) { 3743 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3744 } 3745 return mWindowManager.getAppOrientation(r.appToken); 3746 } 3747 } 3748 3749 /** 3750 * This is the internal entry point for handling Activity.finish(). 3751 * 3752 * @param token The Binder token referencing the Activity we want to finish. 3753 * @param resultCode Result code, if any, from this Activity. 3754 * @param resultData Result data (Intent), if any, from this Activity. 3755 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3756 * the root Activity in the task. 3757 * 3758 * @return Returns true if the activity successfully finished, or false if it is still running. 3759 */ 3760 @Override 3761 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3762 boolean finishTask) { 3763 // Refuse possible leaked file descriptors 3764 if (resultData != null && resultData.hasFileDescriptors() == true) { 3765 throw new IllegalArgumentException("File descriptors passed in Intent"); 3766 } 3767 3768 synchronized(this) { 3769 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3770 if (r == null) { 3771 return true; 3772 } 3773 // Keep track of the root activity of the task before we finish it 3774 TaskRecord tr = r.task; 3775 ActivityRecord rootR = tr.getRootActivity(); 3776 if (rootR == null) { 3777 Slog.w(TAG, "Finishing task with all activities already finished"); 3778 } 3779 // Do not allow task to finish in Lock Task mode. 3780 if (tr == mStackSupervisor.mLockTaskModeTask) { 3781 if (rootR == r) { 3782 Slog.i(TAG, "Not finishing task in lock task mode"); 3783 mStackSupervisor.showLockTaskToast(); 3784 return false; 3785 } 3786 } 3787 if (mController != null) { 3788 // Find the first activity that is not finishing. 3789 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3790 if (next != null) { 3791 // ask watcher if this is allowed 3792 boolean resumeOK = true; 3793 try { 3794 resumeOK = mController.activityResuming(next.packageName); 3795 } catch (RemoteException e) { 3796 mController = null; 3797 Watchdog.getInstance().setActivityController(null); 3798 } 3799 3800 if (!resumeOK) { 3801 Slog.i(TAG, "Not finishing activity because controller resumed"); 3802 return false; 3803 } 3804 } 3805 } 3806 final long origId = Binder.clearCallingIdentity(); 3807 try { 3808 boolean res; 3809 if (finishTask && r == rootR) { 3810 // If requested, remove the task that is associated to this activity only if it 3811 // was the root activity in the task. The result code and data is ignored 3812 // because we don't support returning them across task boundaries. 3813 res = removeTaskByIdLocked(tr.taskId, false); 3814 if (!res) { 3815 Slog.i(TAG, "Removing task failed to finish activity"); 3816 } 3817 } else { 3818 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3819 resultData, "app-request", true); 3820 if (!res) { 3821 Slog.i(TAG, "Failed to finish by app-request"); 3822 } 3823 } 3824 return res; 3825 } finally { 3826 Binder.restoreCallingIdentity(origId); 3827 } 3828 } 3829 } 3830 3831 @Override 3832 public final void finishHeavyWeightApp() { 3833 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3834 != PackageManager.PERMISSION_GRANTED) { 3835 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3836 + Binder.getCallingPid() 3837 + ", uid=" + Binder.getCallingUid() 3838 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3839 Slog.w(TAG, msg); 3840 throw new SecurityException(msg); 3841 } 3842 3843 synchronized(this) { 3844 if (mHeavyWeightProcess == null) { 3845 return; 3846 } 3847 3848 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3849 mHeavyWeightProcess.activities); 3850 for (int i=0; i<activities.size(); i++) { 3851 ActivityRecord r = activities.get(i); 3852 if (!r.finishing) { 3853 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3854 null, "finish-heavy", true); 3855 } 3856 } 3857 3858 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3859 mHeavyWeightProcess.userId, 0)); 3860 mHeavyWeightProcess = null; 3861 } 3862 } 3863 3864 @Override 3865 public void crashApplication(int uid, int initialPid, String packageName, 3866 String message) { 3867 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3868 != PackageManager.PERMISSION_GRANTED) { 3869 String msg = "Permission Denial: crashApplication() from pid=" 3870 + Binder.getCallingPid() 3871 + ", uid=" + Binder.getCallingUid() 3872 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3873 Slog.w(TAG, msg); 3874 throw new SecurityException(msg); 3875 } 3876 3877 synchronized(this) { 3878 ProcessRecord proc = null; 3879 3880 // Figure out which process to kill. We don't trust that initialPid 3881 // still has any relation to current pids, so must scan through the 3882 // list. 3883 synchronized (mPidsSelfLocked) { 3884 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3885 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3886 if (p.uid != uid) { 3887 continue; 3888 } 3889 if (p.pid == initialPid) { 3890 proc = p; 3891 break; 3892 } 3893 if (p.pkgList.containsKey(packageName)) { 3894 proc = p; 3895 } 3896 } 3897 } 3898 3899 if (proc == null) { 3900 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3901 + " initialPid=" + initialPid 3902 + " packageName=" + packageName); 3903 return; 3904 } 3905 3906 if (proc.thread != null) { 3907 if (proc.pid == Process.myPid()) { 3908 Log.w(TAG, "crashApplication: trying to crash self!"); 3909 return; 3910 } 3911 long ident = Binder.clearCallingIdentity(); 3912 try { 3913 proc.thread.scheduleCrash(message); 3914 } catch (RemoteException e) { 3915 } 3916 Binder.restoreCallingIdentity(ident); 3917 } 3918 } 3919 } 3920 3921 @Override 3922 public final void finishSubActivity(IBinder token, String resultWho, 3923 int requestCode) { 3924 synchronized(this) { 3925 final long origId = Binder.clearCallingIdentity(); 3926 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3927 if (r != null) { 3928 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3929 } 3930 Binder.restoreCallingIdentity(origId); 3931 } 3932 } 3933 3934 @Override 3935 public boolean finishActivityAffinity(IBinder token) { 3936 synchronized(this) { 3937 final long origId = Binder.clearCallingIdentity(); 3938 try { 3939 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3940 3941 ActivityRecord rootR = r.task.getRootActivity(); 3942 // Do not allow task to finish in Lock Task mode. 3943 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3944 if (rootR == r) { 3945 mStackSupervisor.showLockTaskToast(); 3946 return false; 3947 } 3948 } 3949 boolean res = false; 3950 if (r != null) { 3951 res = r.task.stack.finishActivityAffinityLocked(r); 3952 } 3953 return res; 3954 } finally { 3955 Binder.restoreCallingIdentity(origId); 3956 } 3957 } 3958 } 3959 3960 @Override 3961 public void finishVoiceTask(IVoiceInteractionSession session) { 3962 synchronized(this) { 3963 final long origId = Binder.clearCallingIdentity(); 3964 try { 3965 mStackSupervisor.finishVoiceTask(session); 3966 } finally { 3967 Binder.restoreCallingIdentity(origId); 3968 } 3969 } 3970 3971 } 3972 3973 @Override 3974 public boolean releaseActivityInstance(IBinder token) { 3975 synchronized(this) { 3976 final long origId = Binder.clearCallingIdentity(); 3977 try { 3978 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3979 if (r.task == null || r.task.stack == null) { 3980 return false; 3981 } 3982 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 3983 } finally { 3984 Binder.restoreCallingIdentity(origId); 3985 } 3986 } 3987 } 3988 3989 @Override 3990 public void releaseSomeActivities(IApplicationThread appInt) { 3991 synchronized(this) { 3992 final long origId = Binder.clearCallingIdentity(); 3993 try { 3994 ProcessRecord app = getRecordForAppLocked(appInt); 3995 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 3996 } finally { 3997 Binder.restoreCallingIdentity(origId); 3998 } 3999 } 4000 } 4001 4002 @Override 4003 public boolean willActivityBeVisible(IBinder token) { 4004 synchronized(this) { 4005 ActivityStack stack = ActivityRecord.getStackLocked(token); 4006 if (stack != null) { 4007 return stack.willActivityBeVisibleLocked(token); 4008 } 4009 return false; 4010 } 4011 } 4012 4013 @Override 4014 public void overridePendingTransition(IBinder token, String packageName, 4015 int enterAnim, int exitAnim) { 4016 synchronized(this) { 4017 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4018 if (self == null) { 4019 return; 4020 } 4021 4022 final long origId = Binder.clearCallingIdentity(); 4023 4024 if (self.state == ActivityState.RESUMED 4025 || self.state == ActivityState.PAUSING) { 4026 mWindowManager.overridePendingAppTransition(packageName, 4027 enterAnim, exitAnim, null); 4028 } 4029 4030 Binder.restoreCallingIdentity(origId); 4031 } 4032 } 4033 4034 /** 4035 * Main function for removing an existing process from the activity manager 4036 * as a result of that process going away. Clears out all connections 4037 * to the process. 4038 */ 4039 private final void handleAppDiedLocked(ProcessRecord app, 4040 boolean restarting, boolean allowRestart) { 4041 int pid = app.pid; 4042 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4043 if (!kept && !restarting) { 4044 removeLruProcessLocked(app); 4045 if (pid > 0) { 4046 ProcessList.remove(pid); 4047 } 4048 } 4049 4050 if (mProfileProc == app) { 4051 clearProfilerLocked(); 4052 } 4053 4054 // Remove this application's activities from active lists. 4055 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4056 4057 app.activities.clear(); 4058 4059 if (app.instrumentationClass != null) { 4060 Slog.w(TAG, "Crash of app " + app.processName 4061 + " running instrumentation " + app.instrumentationClass); 4062 Bundle info = new Bundle(); 4063 info.putString("shortMsg", "Process crashed."); 4064 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4065 } 4066 4067 if (!restarting) { 4068 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4069 // If there was nothing to resume, and we are not already 4070 // restarting this process, but there is a visible activity that 4071 // is hosted by the process... then make sure all visible 4072 // activities are running, taking care of restarting this 4073 // process. 4074 if (hasVisibleActivities) { 4075 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4076 } 4077 } 4078 } 4079 } 4080 4081 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4082 IBinder threadBinder = thread.asBinder(); 4083 // Find the application record. 4084 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4085 ProcessRecord rec = mLruProcesses.get(i); 4086 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4087 return i; 4088 } 4089 } 4090 return -1; 4091 } 4092 4093 final ProcessRecord getRecordForAppLocked( 4094 IApplicationThread thread) { 4095 if (thread == null) { 4096 return null; 4097 } 4098 4099 int appIndex = getLRURecordIndexForAppLocked(thread); 4100 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4101 } 4102 4103 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4104 // If there are no longer any background processes running, 4105 // and the app that died was not running instrumentation, 4106 // then tell everyone we are now low on memory. 4107 boolean haveBg = false; 4108 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4109 ProcessRecord rec = mLruProcesses.get(i); 4110 if (rec.thread != null 4111 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4112 haveBg = true; 4113 break; 4114 } 4115 } 4116 4117 if (!haveBg) { 4118 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4119 if (doReport) { 4120 long now = SystemClock.uptimeMillis(); 4121 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4122 doReport = false; 4123 } else { 4124 mLastMemUsageReportTime = now; 4125 } 4126 } 4127 final ArrayList<ProcessMemInfo> memInfos 4128 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4129 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4130 long now = SystemClock.uptimeMillis(); 4131 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4132 ProcessRecord rec = mLruProcesses.get(i); 4133 if (rec == dyingProc || rec.thread == null) { 4134 continue; 4135 } 4136 if (doReport) { 4137 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4138 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4139 } 4140 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4141 // The low memory report is overriding any current 4142 // state for a GC request. Make sure to do 4143 // heavy/important/visible/foreground processes first. 4144 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4145 rec.lastRequestedGc = 0; 4146 } else { 4147 rec.lastRequestedGc = rec.lastLowMemory; 4148 } 4149 rec.reportLowMemory = true; 4150 rec.lastLowMemory = now; 4151 mProcessesToGc.remove(rec); 4152 addProcessToGcListLocked(rec); 4153 } 4154 } 4155 if (doReport) { 4156 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4157 mHandler.sendMessage(msg); 4158 } 4159 scheduleAppGcsLocked(); 4160 } 4161 } 4162 4163 final void appDiedLocked(ProcessRecord app) { 4164 appDiedLocked(app, app.pid, app.thread); 4165 } 4166 4167 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4168 // First check if this ProcessRecord is actually active for the pid. 4169 synchronized (mPidsSelfLocked) { 4170 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4171 if (curProc != app) { 4172 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4173 return; 4174 } 4175 } 4176 4177 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4178 synchronized (stats) { 4179 stats.noteProcessDiedLocked(app.info.uid, pid); 4180 } 4181 4182 if (!app.killed) { 4183 Process.killProcessQuiet(pid); 4184 Process.killProcessGroup(app.info.uid, pid); 4185 app.killed = true; 4186 } 4187 4188 // Clean up already done if the process has been re-started. 4189 if (app.pid == pid && app.thread != null && 4190 app.thread.asBinder() == thread.asBinder()) { 4191 boolean doLowMem = app.instrumentationClass == null; 4192 boolean doOomAdj = doLowMem; 4193 if (!app.killedByAm) { 4194 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4195 + ") has died"); 4196 mAllowLowerMemLevel = true; 4197 } else { 4198 // Note that we always want to do oom adj to update our state with the 4199 // new number of procs. 4200 mAllowLowerMemLevel = false; 4201 doLowMem = false; 4202 } 4203 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4204 if (DEBUG_CLEANUP) Slog.v( 4205 TAG, "Dying app: " + app + ", pid: " + pid 4206 + ", thread: " + thread.asBinder()); 4207 handleAppDiedLocked(app, false, true); 4208 4209 if (doOomAdj) { 4210 updateOomAdjLocked(); 4211 } 4212 if (doLowMem) { 4213 doLowMemReportIfNeededLocked(app); 4214 } 4215 } else if (app.pid != pid) { 4216 // A new process has already been started. 4217 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4218 + ") has died and restarted (pid " + app.pid + ")."); 4219 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4220 } else if (DEBUG_PROCESSES) { 4221 Slog.d(TAG, "Received spurious death notification for thread " 4222 + thread.asBinder()); 4223 } 4224 } 4225 4226 /** 4227 * If a stack trace dump file is configured, dump process stack traces. 4228 * @param clearTraces causes the dump file to be erased prior to the new 4229 * traces being written, if true; when false, the new traces will be 4230 * appended to any existing file content. 4231 * @param firstPids of dalvik VM processes to dump stack traces for first 4232 * @param lastPids of dalvik VM processes to dump stack traces for last 4233 * @param nativeProcs optional list of native process names to dump stack crawls 4234 * @return file containing stack traces, or null if no dump file is configured 4235 */ 4236 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4237 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4238 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4239 if (tracesPath == null || tracesPath.length() == 0) { 4240 return null; 4241 } 4242 4243 File tracesFile = new File(tracesPath); 4244 try { 4245 File tracesDir = tracesFile.getParentFile(); 4246 if (!tracesDir.exists()) { 4247 tracesDir.mkdirs(); 4248 if (!SELinux.restorecon(tracesDir)) { 4249 return null; 4250 } 4251 } 4252 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4253 4254 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4255 tracesFile.createNewFile(); 4256 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4257 } catch (IOException e) { 4258 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4259 return null; 4260 } 4261 4262 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4263 return tracesFile; 4264 } 4265 4266 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4267 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4268 // Use a FileObserver to detect when traces finish writing. 4269 // The order of traces is considered important to maintain for legibility. 4270 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4271 @Override 4272 public synchronized void onEvent(int event, String path) { notify(); } 4273 }; 4274 4275 try { 4276 observer.startWatching(); 4277 4278 // First collect all of the stacks of the most important pids. 4279 if (firstPids != null) { 4280 try { 4281 int num = firstPids.size(); 4282 for (int i = 0; i < num; i++) { 4283 synchronized (observer) { 4284 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4285 observer.wait(200); // Wait for write-close, give up after 200msec 4286 } 4287 } 4288 } catch (InterruptedException e) { 4289 Slog.wtf(TAG, e); 4290 } 4291 } 4292 4293 // Next collect the stacks of the native pids 4294 if (nativeProcs != null) { 4295 int[] pids = Process.getPidsForCommands(nativeProcs); 4296 if (pids != null) { 4297 for (int pid : pids) { 4298 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4299 } 4300 } 4301 } 4302 4303 // Lastly, measure CPU usage. 4304 if (processCpuTracker != null) { 4305 processCpuTracker.init(); 4306 System.gc(); 4307 processCpuTracker.update(); 4308 try { 4309 synchronized (processCpuTracker) { 4310 processCpuTracker.wait(500); // measure over 1/2 second. 4311 } 4312 } catch (InterruptedException e) { 4313 } 4314 processCpuTracker.update(); 4315 4316 // We'll take the stack crawls of just the top apps using CPU. 4317 final int N = processCpuTracker.countWorkingStats(); 4318 int numProcs = 0; 4319 for (int i=0; i<N && numProcs<5; i++) { 4320 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4321 if (lastPids.indexOfKey(stats.pid) >= 0) { 4322 numProcs++; 4323 try { 4324 synchronized (observer) { 4325 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4326 observer.wait(200); // Wait for write-close, give up after 200msec 4327 } 4328 } catch (InterruptedException e) { 4329 Slog.wtf(TAG, e); 4330 } 4331 4332 } 4333 } 4334 } 4335 } finally { 4336 observer.stopWatching(); 4337 } 4338 } 4339 4340 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4341 if (true || IS_USER_BUILD) { 4342 return; 4343 } 4344 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4345 if (tracesPath == null || tracesPath.length() == 0) { 4346 return; 4347 } 4348 4349 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4350 StrictMode.allowThreadDiskWrites(); 4351 try { 4352 final File tracesFile = new File(tracesPath); 4353 final File tracesDir = tracesFile.getParentFile(); 4354 final File tracesTmp = new File(tracesDir, "__tmp__"); 4355 try { 4356 if (!tracesDir.exists()) { 4357 tracesDir.mkdirs(); 4358 if (!SELinux.restorecon(tracesDir.getPath())) { 4359 return; 4360 } 4361 } 4362 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4363 4364 if (tracesFile.exists()) { 4365 tracesTmp.delete(); 4366 tracesFile.renameTo(tracesTmp); 4367 } 4368 StringBuilder sb = new StringBuilder(); 4369 Time tobj = new Time(); 4370 tobj.set(System.currentTimeMillis()); 4371 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4372 sb.append(": "); 4373 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4374 sb.append(" since "); 4375 sb.append(msg); 4376 FileOutputStream fos = new FileOutputStream(tracesFile); 4377 fos.write(sb.toString().getBytes()); 4378 if (app == null) { 4379 fos.write("\n*** No application process!".getBytes()); 4380 } 4381 fos.close(); 4382 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4383 } catch (IOException e) { 4384 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4385 return; 4386 } 4387 4388 if (app != null) { 4389 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4390 firstPids.add(app.pid); 4391 dumpStackTraces(tracesPath, firstPids, null, null, null); 4392 } 4393 4394 File lastTracesFile = null; 4395 File curTracesFile = null; 4396 for (int i=9; i>=0; i--) { 4397 String name = String.format(Locale.US, "slow%02d.txt", i); 4398 curTracesFile = new File(tracesDir, name); 4399 if (curTracesFile.exists()) { 4400 if (lastTracesFile != null) { 4401 curTracesFile.renameTo(lastTracesFile); 4402 } else { 4403 curTracesFile.delete(); 4404 } 4405 } 4406 lastTracesFile = curTracesFile; 4407 } 4408 tracesFile.renameTo(curTracesFile); 4409 if (tracesTmp.exists()) { 4410 tracesTmp.renameTo(tracesFile); 4411 } 4412 } finally { 4413 StrictMode.setThreadPolicy(oldPolicy); 4414 } 4415 } 4416 4417 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4418 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4419 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4420 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4421 4422 if (mController != null) { 4423 try { 4424 // 0 == continue, -1 = kill process immediately 4425 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4426 if (res < 0 && app.pid != MY_PID) { 4427 app.kill("anr", true); 4428 } 4429 } catch (RemoteException e) { 4430 mController = null; 4431 Watchdog.getInstance().setActivityController(null); 4432 } 4433 } 4434 4435 long anrTime = SystemClock.uptimeMillis(); 4436 if (MONITOR_CPU_USAGE) { 4437 updateCpuStatsNow(); 4438 } 4439 4440 synchronized (this) { 4441 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4442 if (mShuttingDown) { 4443 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4444 return; 4445 } else if (app.notResponding) { 4446 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4447 return; 4448 } else if (app.crashing) { 4449 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4450 return; 4451 } 4452 4453 // In case we come through here for the same app before completing 4454 // this one, mark as anring now so we will bail out. 4455 app.notResponding = true; 4456 4457 // Log the ANR to the event log. 4458 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4459 app.processName, app.info.flags, annotation); 4460 4461 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4462 firstPids.add(app.pid); 4463 4464 int parentPid = app.pid; 4465 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4466 if (parentPid != app.pid) firstPids.add(parentPid); 4467 4468 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4469 4470 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4471 ProcessRecord r = mLruProcesses.get(i); 4472 if (r != null && r.thread != null) { 4473 int pid = r.pid; 4474 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4475 if (r.persistent) { 4476 firstPids.add(pid); 4477 } else { 4478 lastPids.put(pid, Boolean.TRUE); 4479 } 4480 } 4481 } 4482 } 4483 } 4484 4485 // Log the ANR to the main log. 4486 StringBuilder info = new StringBuilder(); 4487 info.setLength(0); 4488 info.append("ANR in ").append(app.processName); 4489 if (activity != null && activity.shortComponentName != null) { 4490 info.append(" (").append(activity.shortComponentName).append(")"); 4491 } 4492 info.append("\n"); 4493 info.append("PID: ").append(app.pid).append("\n"); 4494 if (annotation != null) { 4495 info.append("Reason: ").append(annotation).append("\n"); 4496 } 4497 if (parent != null && parent != activity) { 4498 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4499 } 4500 4501 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4502 4503 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4504 NATIVE_STACKS_OF_INTEREST); 4505 4506 String cpuInfo = null; 4507 if (MONITOR_CPU_USAGE) { 4508 updateCpuStatsNow(); 4509 synchronized (mProcessCpuTracker) { 4510 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4511 } 4512 info.append(processCpuTracker.printCurrentLoad()); 4513 info.append(cpuInfo); 4514 } 4515 4516 info.append(processCpuTracker.printCurrentState(anrTime)); 4517 4518 Slog.e(TAG, info.toString()); 4519 if (tracesFile == null) { 4520 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4521 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4522 } 4523 4524 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4525 cpuInfo, tracesFile, null); 4526 4527 if (mController != null) { 4528 try { 4529 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4530 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4531 if (res != 0) { 4532 if (res < 0 && app.pid != MY_PID) { 4533 app.kill("anr", true); 4534 } else { 4535 synchronized (this) { 4536 mServices.scheduleServiceTimeoutLocked(app); 4537 } 4538 } 4539 return; 4540 } 4541 } catch (RemoteException e) { 4542 mController = null; 4543 Watchdog.getInstance().setActivityController(null); 4544 } 4545 } 4546 4547 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4548 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4549 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4550 4551 synchronized (this) { 4552 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 4553 4554 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4555 app.kill("bg anr", true); 4556 return; 4557 } 4558 4559 // Set the app's notResponding state, and look up the errorReportReceiver 4560 makeAppNotRespondingLocked(app, 4561 activity != null ? activity.shortComponentName : null, 4562 annotation != null ? "ANR " + annotation : "ANR", 4563 info.toString()); 4564 4565 // Bring up the infamous App Not Responding dialog 4566 Message msg = Message.obtain(); 4567 HashMap<String, Object> map = new HashMap<String, Object>(); 4568 msg.what = SHOW_NOT_RESPONDING_MSG; 4569 msg.obj = map; 4570 msg.arg1 = aboveSystem ? 1 : 0; 4571 map.put("app", app); 4572 if (activity != null) { 4573 map.put("activity", activity); 4574 } 4575 4576 mHandler.sendMessage(msg); 4577 } 4578 } 4579 4580 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4581 if (!mLaunchWarningShown) { 4582 mLaunchWarningShown = true; 4583 mHandler.post(new Runnable() { 4584 @Override 4585 public void run() { 4586 synchronized (ActivityManagerService.this) { 4587 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4588 d.show(); 4589 mHandler.postDelayed(new Runnable() { 4590 @Override 4591 public void run() { 4592 synchronized (ActivityManagerService.this) { 4593 d.dismiss(); 4594 mLaunchWarningShown = false; 4595 } 4596 } 4597 }, 4000); 4598 } 4599 } 4600 }); 4601 } 4602 } 4603 4604 @Override 4605 public boolean clearApplicationUserData(final String packageName, 4606 final IPackageDataObserver observer, int userId) { 4607 enforceNotIsolatedCaller("clearApplicationUserData"); 4608 int uid = Binder.getCallingUid(); 4609 int pid = Binder.getCallingPid(); 4610 userId = handleIncomingUser(pid, uid, 4611 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4612 long callingId = Binder.clearCallingIdentity(); 4613 try { 4614 IPackageManager pm = AppGlobals.getPackageManager(); 4615 int pkgUid = -1; 4616 synchronized(this) { 4617 try { 4618 pkgUid = pm.getPackageUid(packageName, userId); 4619 } catch (RemoteException e) { 4620 } 4621 if (pkgUid == -1) { 4622 Slog.w(TAG, "Invalid packageName: " + packageName); 4623 if (observer != null) { 4624 try { 4625 observer.onRemoveCompleted(packageName, false); 4626 } catch (RemoteException e) { 4627 Slog.i(TAG, "Observer no longer exists."); 4628 } 4629 } 4630 return false; 4631 } 4632 if (uid == pkgUid || checkComponentPermission( 4633 android.Manifest.permission.CLEAR_APP_USER_DATA, 4634 pid, uid, -1, true) 4635 == PackageManager.PERMISSION_GRANTED) { 4636 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4637 } else { 4638 throw new SecurityException("PID " + pid + " does not have permission " 4639 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4640 + " of package " + packageName); 4641 } 4642 4643 // Remove all tasks match the cleared application package and user 4644 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 4645 final TaskRecord tr = mRecentTasks.get(i); 4646 final String taskPackageName = 4647 tr.getBaseIntent().getComponent().getPackageName(); 4648 if (tr.userId != userId) continue; 4649 if (!taskPackageName.equals(packageName)) continue; 4650 removeTaskByIdLocked(tr.taskId, false); 4651 } 4652 } 4653 4654 try { 4655 // Clear application user data 4656 pm.clearApplicationUserData(packageName, observer, userId); 4657 4658 synchronized(this) { 4659 // Remove all permissions granted from/to this package 4660 removeUriPermissionsForPackageLocked(packageName, userId, true); 4661 } 4662 4663 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4664 Uri.fromParts("package", packageName, null)); 4665 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4666 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4667 null, null, 0, null, null, null, false, false, userId); 4668 } catch (RemoteException e) { 4669 } 4670 } finally { 4671 Binder.restoreCallingIdentity(callingId); 4672 } 4673 return true; 4674 } 4675 4676 @Override 4677 public void killBackgroundProcesses(final String packageName, int userId) { 4678 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4679 != PackageManager.PERMISSION_GRANTED && 4680 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4681 != PackageManager.PERMISSION_GRANTED) { 4682 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4683 + Binder.getCallingPid() 4684 + ", uid=" + Binder.getCallingUid() 4685 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4686 Slog.w(TAG, msg); 4687 throw new SecurityException(msg); 4688 } 4689 4690 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4691 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4692 long callingId = Binder.clearCallingIdentity(); 4693 try { 4694 IPackageManager pm = AppGlobals.getPackageManager(); 4695 synchronized(this) { 4696 int appId = -1; 4697 try { 4698 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4699 } catch (RemoteException e) { 4700 } 4701 if (appId == -1) { 4702 Slog.w(TAG, "Invalid packageName: " + packageName); 4703 return; 4704 } 4705 killPackageProcessesLocked(packageName, appId, userId, 4706 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4707 } 4708 } finally { 4709 Binder.restoreCallingIdentity(callingId); 4710 } 4711 } 4712 4713 @Override 4714 public void killAllBackgroundProcesses() { 4715 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4716 != PackageManager.PERMISSION_GRANTED) { 4717 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4718 + Binder.getCallingPid() 4719 + ", uid=" + Binder.getCallingUid() 4720 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4721 Slog.w(TAG, msg); 4722 throw new SecurityException(msg); 4723 } 4724 4725 long callingId = Binder.clearCallingIdentity(); 4726 try { 4727 synchronized(this) { 4728 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4729 final int NP = mProcessNames.getMap().size(); 4730 for (int ip=0; ip<NP; ip++) { 4731 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4732 final int NA = apps.size(); 4733 for (int ia=0; ia<NA; ia++) { 4734 ProcessRecord app = apps.valueAt(ia); 4735 if (app.persistent) { 4736 // we don't kill persistent processes 4737 continue; 4738 } 4739 if (app.removed) { 4740 procs.add(app); 4741 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4742 app.removed = true; 4743 procs.add(app); 4744 } 4745 } 4746 } 4747 4748 int N = procs.size(); 4749 for (int i=0; i<N; i++) { 4750 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4751 } 4752 mAllowLowerMemLevel = true; 4753 updateOomAdjLocked(); 4754 doLowMemReportIfNeededLocked(null); 4755 } 4756 } finally { 4757 Binder.restoreCallingIdentity(callingId); 4758 } 4759 } 4760 4761 @Override 4762 public void forceStopPackage(final String packageName, int userId) { 4763 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4764 != PackageManager.PERMISSION_GRANTED) { 4765 String msg = "Permission Denial: forceStopPackage() from pid=" 4766 + Binder.getCallingPid() 4767 + ", uid=" + Binder.getCallingUid() 4768 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4769 Slog.w(TAG, msg); 4770 throw new SecurityException(msg); 4771 } 4772 final int callingPid = Binder.getCallingPid(); 4773 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4774 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4775 long callingId = Binder.clearCallingIdentity(); 4776 try { 4777 IPackageManager pm = AppGlobals.getPackageManager(); 4778 synchronized(this) { 4779 int[] users = userId == UserHandle.USER_ALL 4780 ? getUsersLocked() : new int[] { userId }; 4781 for (int user : users) { 4782 int pkgUid = -1; 4783 try { 4784 pkgUid = pm.getPackageUid(packageName, user); 4785 } catch (RemoteException e) { 4786 } 4787 if (pkgUid == -1) { 4788 Slog.w(TAG, "Invalid packageName: " + packageName); 4789 continue; 4790 } 4791 try { 4792 pm.setPackageStoppedState(packageName, true, user); 4793 } catch (RemoteException e) { 4794 } catch (IllegalArgumentException e) { 4795 Slog.w(TAG, "Failed trying to unstop package " 4796 + packageName + ": " + e); 4797 } 4798 if (isUserRunningLocked(user, false)) { 4799 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4800 } 4801 } 4802 } 4803 } finally { 4804 Binder.restoreCallingIdentity(callingId); 4805 } 4806 } 4807 4808 @Override 4809 public void addPackageDependency(String packageName) { 4810 synchronized (this) { 4811 int callingPid = Binder.getCallingPid(); 4812 if (callingPid == Process.myPid()) { 4813 // Yeah, um, no. 4814 return; 4815 } 4816 ProcessRecord proc; 4817 synchronized (mPidsSelfLocked) { 4818 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 4819 } 4820 if (proc != null) { 4821 if (proc.pkgDeps == null) { 4822 proc.pkgDeps = new ArraySet<String>(1); 4823 } 4824 proc.pkgDeps.add(packageName); 4825 } 4826 } 4827 } 4828 4829 /* 4830 * The pkg name and app id have to be specified. 4831 */ 4832 @Override 4833 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4834 if (pkg == null) { 4835 return; 4836 } 4837 // Make sure the uid is valid. 4838 if (appid < 0) { 4839 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4840 return; 4841 } 4842 int callerUid = Binder.getCallingUid(); 4843 // Only the system server can kill an application 4844 if (callerUid == Process.SYSTEM_UID) { 4845 // Post an aysnc message to kill the application 4846 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4847 msg.arg1 = appid; 4848 msg.arg2 = 0; 4849 Bundle bundle = new Bundle(); 4850 bundle.putString("pkg", pkg); 4851 bundle.putString("reason", reason); 4852 msg.obj = bundle; 4853 mHandler.sendMessage(msg); 4854 } else { 4855 throw new SecurityException(callerUid + " cannot kill pkg: " + 4856 pkg); 4857 } 4858 } 4859 4860 @Override 4861 public void closeSystemDialogs(String reason) { 4862 enforceNotIsolatedCaller("closeSystemDialogs"); 4863 4864 final int pid = Binder.getCallingPid(); 4865 final int uid = Binder.getCallingUid(); 4866 final long origId = Binder.clearCallingIdentity(); 4867 try { 4868 synchronized (this) { 4869 // Only allow this from foreground processes, so that background 4870 // applications can't abuse it to prevent system UI from being shown. 4871 if (uid >= Process.FIRST_APPLICATION_UID) { 4872 ProcessRecord proc; 4873 synchronized (mPidsSelfLocked) { 4874 proc = mPidsSelfLocked.get(pid); 4875 } 4876 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4877 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4878 + " from background process " + proc); 4879 return; 4880 } 4881 } 4882 closeSystemDialogsLocked(reason); 4883 } 4884 } finally { 4885 Binder.restoreCallingIdentity(origId); 4886 } 4887 } 4888 4889 void closeSystemDialogsLocked(String reason) { 4890 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4892 | Intent.FLAG_RECEIVER_FOREGROUND); 4893 if (reason != null) { 4894 intent.putExtra("reason", reason); 4895 } 4896 mWindowManager.closeSystemDialogs(reason); 4897 4898 mStackSupervisor.closeSystemDialogsLocked(); 4899 4900 broadcastIntentLocked(null, null, intent, null, 4901 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4902 Process.SYSTEM_UID, UserHandle.USER_ALL); 4903 } 4904 4905 @Override 4906 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4907 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4908 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4909 for (int i=pids.length-1; i>=0; i--) { 4910 ProcessRecord proc; 4911 int oomAdj; 4912 synchronized (this) { 4913 synchronized (mPidsSelfLocked) { 4914 proc = mPidsSelfLocked.get(pids[i]); 4915 oomAdj = proc != null ? proc.setAdj : 0; 4916 } 4917 } 4918 infos[i] = new Debug.MemoryInfo(); 4919 Debug.getMemoryInfo(pids[i], infos[i]); 4920 if (proc != null) { 4921 synchronized (this) { 4922 if (proc.thread != null && proc.setAdj == oomAdj) { 4923 // Record this for posterity if the process has been stable. 4924 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4925 infos[i].getTotalUss(), false, proc.pkgList); 4926 } 4927 } 4928 } 4929 } 4930 return infos; 4931 } 4932 4933 @Override 4934 public long[] getProcessPss(int[] pids) { 4935 enforceNotIsolatedCaller("getProcessPss"); 4936 long[] pss = new long[pids.length]; 4937 for (int i=pids.length-1; i>=0; i--) { 4938 ProcessRecord proc; 4939 int oomAdj; 4940 synchronized (this) { 4941 synchronized (mPidsSelfLocked) { 4942 proc = mPidsSelfLocked.get(pids[i]); 4943 oomAdj = proc != null ? proc.setAdj : 0; 4944 } 4945 } 4946 long[] tmpUss = new long[1]; 4947 pss[i] = Debug.getPss(pids[i], tmpUss, null); 4948 if (proc != null) { 4949 synchronized (this) { 4950 if (proc.thread != null && proc.setAdj == oomAdj) { 4951 // Record this for posterity if the process has been stable. 4952 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4953 } 4954 } 4955 } 4956 } 4957 return pss; 4958 } 4959 4960 @Override 4961 public void killApplicationProcess(String processName, int uid) { 4962 if (processName == null) { 4963 return; 4964 } 4965 4966 int callerUid = Binder.getCallingUid(); 4967 // Only the system server can kill an application 4968 if (callerUid == Process.SYSTEM_UID) { 4969 synchronized (this) { 4970 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4971 if (app != null && app.thread != null) { 4972 try { 4973 app.thread.scheduleSuicide(); 4974 } catch (RemoteException e) { 4975 // If the other end already died, then our work here is done. 4976 } 4977 } else { 4978 Slog.w(TAG, "Process/uid not found attempting kill of " 4979 + processName + " / " + uid); 4980 } 4981 } 4982 } else { 4983 throw new SecurityException(callerUid + " cannot kill app process: " + 4984 processName); 4985 } 4986 } 4987 4988 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4989 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4990 false, true, false, false, UserHandle.getUserId(uid), reason); 4991 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4992 Uri.fromParts("package", packageName, null)); 4993 if (!mProcessesReady) { 4994 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4995 | Intent.FLAG_RECEIVER_FOREGROUND); 4996 } 4997 intent.putExtra(Intent.EXTRA_UID, uid); 4998 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4999 broadcastIntentLocked(null, null, intent, 5000 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5001 false, false, 5002 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5003 } 5004 5005 private void forceStopUserLocked(int userId, String reason) { 5006 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5007 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5008 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5009 | Intent.FLAG_RECEIVER_FOREGROUND); 5010 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5011 broadcastIntentLocked(null, null, intent, 5012 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5013 false, false, 5014 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5015 } 5016 5017 private final boolean killPackageProcessesLocked(String packageName, int appId, 5018 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5019 boolean doit, boolean evenPersistent, String reason) { 5020 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5021 5022 // Remove all processes this package may have touched: all with the 5023 // same UID (except for the system or root user), and all whose name 5024 // matches the package name. 5025 final int NP = mProcessNames.getMap().size(); 5026 for (int ip=0; ip<NP; ip++) { 5027 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5028 final int NA = apps.size(); 5029 for (int ia=0; ia<NA; ia++) { 5030 ProcessRecord app = apps.valueAt(ia); 5031 if (app.persistent && !evenPersistent) { 5032 // we don't kill persistent processes 5033 continue; 5034 } 5035 if (app.removed) { 5036 if (doit) { 5037 procs.add(app); 5038 } 5039 continue; 5040 } 5041 5042 // Skip process if it doesn't meet our oom adj requirement. 5043 if (app.setAdj < minOomAdj) { 5044 continue; 5045 } 5046 5047 // If no package is specified, we call all processes under the 5048 // give user id. 5049 if (packageName == null) { 5050 if (app.userId != userId) { 5051 continue; 5052 } 5053 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5054 continue; 5055 } 5056 // Package has been specified, we want to hit all processes 5057 // that match it. We need to qualify this by the processes 5058 // that are running under the specified app and user ID. 5059 } else { 5060 final boolean isDep = app.pkgDeps != null 5061 && app.pkgDeps.contains(packageName); 5062 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5063 continue; 5064 } 5065 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5066 continue; 5067 } 5068 if (!app.pkgList.containsKey(packageName) && !isDep) { 5069 continue; 5070 } 5071 } 5072 5073 // Process has passed all conditions, kill it! 5074 if (!doit) { 5075 return true; 5076 } 5077 app.removed = true; 5078 procs.add(app); 5079 } 5080 } 5081 5082 int N = procs.size(); 5083 for (int i=0; i<N; i++) { 5084 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5085 } 5086 updateOomAdjLocked(); 5087 return N > 0; 5088 } 5089 5090 private final boolean forceStopPackageLocked(String name, int appId, 5091 boolean callerWillRestart, boolean purgeCache, boolean doit, 5092 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5093 int i; 5094 int N; 5095 5096 if (userId == UserHandle.USER_ALL && name == null) { 5097 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5098 } 5099 5100 if (appId < 0 && name != null) { 5101 try { 5102 appId = UserHandle.getAppId( 5103 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5104 } catch (RemoteException e) { 5105 } 5106 } 5107 5108 if (doit) { 5109 if (name != null) { 5110 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5111 + " user=" + userId + ": " + reason); 5112 } else { 5113 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5114 } 5115 5116 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5117 for (int ip=pmap.size()-1; ip>=0; ip--) { 5118 SparseArray<Long> ba = pmap.valueAt(ip); 5119 for (i=ba.size()-1; i>=0; i--) { 5120 boolean remove = false; 5121 final int entUid = ba.keyAt(i); 5122 if (name != null) { 5123 if (userId == UserHandle.USER_ALL) { 5124 if (UserHandle.getAppId(entUid) == appId) { 5125 remove = true; 5126 } 5127 } else { 5128 if (entUid == UserHandle.getUid(userId, appId)) { 5129 remove = true; 5130 } 5131 } 5132 } else if (UserHandle.getUserId(entUid) == userId) { 5133 remove = true; 5134 } 5135 if (remove) { 5136 ba.removeAt(i); 5137 } 5138 } 5139 if (ba.size() == 0) { 5140 pmap.removeAt(ip); 5141 } 5142 } 5143 } 5144 5145 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5146 -100, callerWillRestart, true, doit, evenPersistent, 5147 name == null ? ("stop user " + userId) : ("stop " + name)); 5148 5149 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5150 if (!doit) { 5151 return true; 5152 } 5153 didSomething = true; 5154 } 5155 5156 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5157 if (!doit) { 5158 return true; 5159 } 5160 didSomething = true; 5161 } 5162 5163 if (name == null) { 5164 // Remove all sticky broadcasts from this user. 5165 mStickyBroadcasts.remove(userId); 5166 } 5167 5168 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5169 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5170 userId, providers)) { 5171 if (!doit) { 5172 return true; 5173 } 5174 didSomething = true; 5175 } 5176 N = providers.size(); 5177 for (i=0; i<N; i++) { 5178 removeDyingProviderLocked(null, providers.get(i), true); 5179 } 5180 5181 // Remove transient permissions granted from/to this package/user 5182 removeUriPermissionsForPackageLocked(name, userId, false); 5183 5184 if (name == null || uninstalling) { 5185 // Remove pending intents. For now we only do this when force 5186 // stopping users, because we have some problems when doing this 5187 // for packages -- app widgets are not currently cleaned up for 5188 // such packages, so they can be left with bad pending intents. 5189 if (mIntentSenderRecords.size() > 0) { 5190 Iterator<WeakReference<PendingIntentRecord>> it 5191 = mIntentSenderRecords.values().iterator(); 5192 while (it.hasNext()) { 5193 WeakReference<PendingIntentRecord> wpir = it.next(); 5194 if (wpir == null) { 5195 it.remove(); 5196 continue; 5197 } 5198 PendingIntentRecord pir = wpir.get(); 5199 if (pir == null) { 5200 it.remove(); 5201 continue; 5202 } 5203 if (name == null) { 5204 // Stopping user, remove all objects for the user. 5205 if (pir.key.userId != userId) { 5206 // Not the same user, skip it. 5207 continue; 5208 } 5209 } else { 5210 if (UserHandle.getAppId(pir.uid) != appId) { 5211 // Different app id, skip it. 5212 continue; 5213 } 5214 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5215 // Different user, skip it. 5216 continue; 5217 } 5218 if (!pir.key.packageName.equals(name)) { 5219 // Different package, skip it. 5220 continue; 5221 } 5222 } 5223 if (!doit) { 5224 return true; 5225 } 5226 didSomething = true; 5227 it.remove(); 5228 pir.canceled = true; 5229 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5230 pir.key.activity.pendingResults.remove(pir.ref); 5231 } 5232 } 5233 } 5234 } 5235 5236 if (doit) { 5237 if (purgeCache && name != null) { 5238 AttributeCache ac = AttributeCache.instance(); 5239 if (ac != null) { 5240 ac.removePackage(name); 5241 } 5242 } 5243 if (mBooted) { 5244 mStackSupervisor.resumeTopActivitiesLocked(); 5245 mStackSupervisor.scheduleIdleLocked(); 5246 } 5247 } 5248 5249 return didSomething; 5250 } 5251 5252 private final boolean removeProcessLocked(ProcessRecord app, 5253 boolean callerWillRestart, boolean allowRestart, String reason) { 5254 final String name = app.processName; 5255 final int uid = app.uid; 5256 if (DEBUG_PROCESSES) Slog.d( 5257 TAG, "Force removing proc " + app.toShortString() + " (" + name 5258 + "/" + uid + ")"); 5259 5260 mProcessNames.remove(name, uid); 5261 mIsolatedProcesses.remove(app.uid); 5262 if (mHeavyWeightProcess == app) { 5263 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5264 mHeavyWeightProcess.userId, 0)); 5265 mHeavyWeightProcess = null; 5266 } 5267 boolean needRestart = false; 5268 if (app.pid > 0 && app.pid != MY_PID) { 5269 int pid = app.pid; 5270 synchronized (mPidsSelfLocked) { 5271 mPidsSelfLocked.remove(pid); 5272 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5273 } 5274 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5275 if (app.isolated) { 5276 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5277 } 5278 app.kill(reason, true); 5279 handleAppDiedLocked(app, true, allowRestart); 5280 removeLruProcessLocked(app); 5281 5282 if (app.persistent && !app.isolated) { 5283 if (!callerWillRestart) { 5284 addAppLocked(app.info, false, null /* ABI override */); 5285 } else { 5286 needRestart = true; 5287 } 5288 } 5289 } else { 5290 mRemovedProcesses.add(app); 5291 } 5292 5293 return needRestart; 5294 } 5295 5296 private final void processStartTimedOutLocked(ProcessRecord app) { 5297 final int pid = app.pid; 5298 boolean gone = false; 5299 synchronized (mPidsSelfLocked) { 5300 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5301 if (knownApp != null && knownApp.thread == null) { 5302 mPidsSelfLocked.remove(pid); 5303 gone = true; 5304 } 5305 } 5306 5307 if (gone) { 5308 Slog.w(TAG, "Process " + app + " failed to attach"); 5309 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5310 pid, app.uid, app.processName); 5311 mProcessNames.remove(app.processName, app.uid); 5312 mIsolatedProcesses.remove(app.uid); 5313 if (mHeavyWeightProcess == app) { 5314 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5315 mHeavyWeightProcess.userId, 0)); 5316 mHeavyWeightProcess = null; 5317 } 5318 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5319 if (app.isolated) { 5320 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5321 } 5322 // Take care of any launching providers waiting for this process. 5323 checkAppInLaunchingProvidersLocked(app, true); 5324 // Take care of any services that are waiting for the process. 5325 mServices.processStartTimedOutLocked(app); 5326 app.kill("start timeout", true); 5327 removeLruProcessLocked(app); 5328 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5329 Slog.w(TAG, "Unattached app died before backup, skipping"); 5330 try { 5331 IBackupManager bm = IBackupManager.Stub.asInterface( 5332 ServiceManager.getService(Context.BACKUP_SERVICE)); 5333 bm.agentDisconnected(app.info.packageName); 5334 } catch (RemoteException e) { 5335 // Can't happen; the backup manager is local 5336 } 5337 } 5338 if (isPendingBroadcastProcessLocked(pid)) { 5339 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5340 skipPendingBroadcastLocked(pid); 5341 } 5342 } else { 5343 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5344 } 5345 } 5346 5347 private final boolean attachApplicationLocked(IApplicationThread thread, 5348 int pid) { 5349 5350 // Find the application record that is being attached... either via 5351 // the pid if we are running in multiple processes, or just pull the 5352 // next app record if we are emulating process with anonymous threads. 5353 ProcessRecord app; 5354 if (pid != MY_PID && pid >= 0) { 5355 synchronized (mPidsSelfLocked) { 5356 app = mPidsSelfLocked.get(pid); 5357 } 5358 } else { 5359 app = null; 5360 } 5361 5362 if (app == null) { 5363 Slog.w(TAG, "No pending application record for pid " + pid 5364 + " (IApplicationThread " + thread + "); dropping process"); 5365 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5366 if (pid > 0 && pid != MY_PID) { 5367 Process.killProcessQuiet(pid); 5368 //TODO: Process.killProcessGroup(app.info.uid, pid); 5369 } else { 5370 try { 5371 thread.scheduleExit(); 5372 } catch (Exception e) { 5373 // Ignore exceptions. 5374 } 5375 } 5376 return false; 5377 } 5378 5379 // If this application record is still attached to a previous 5380 // process, clean it up now. 5381 if (app.thread != null) { 5382 handleAppDiedLocked(app, true, true); 5383 } 5384 5385 // Tell the process all about itself. 5386 5387 if (localLOGV) Slog.v( 5388 TAG, "Binding process pid " + pid + " to record " + app); 5389 5390 final String processName = app.processName; 5391 try { 5392 AppDeathRecipient adr = new AppDeathRecipient( 5393 app, pid, thread); 5394 thread.asBinder().linkToDeath(adr, 0); 5395 app.deathRecipient = adr; 5396 } catch (RemoteException e) { 5397 app.resetPackageList(mProcessStats); 5398 startProcessLocked(app, "link fail", processName); 5399 return false; 5400 } 5401 5402 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5403 5404 app.makeActive(thread, mProcessStats); 5405 app.curAdj = app.setAdj = -100; 5406 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5407 app.forcingToForeground = null; 5408 updateProcessForegroundLocked(app, false, false); 5409 app.hasShownUi = false; 5410 app.debugging = false; 5411 app.cached = false; 5412 app.killedByAm = false; 5413 5414 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5415 5416 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5417 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5418 5419 if (!normalMode) { 5420 Slog.i(TAG, "Launching preboot mode app: " + app); 5421 } 5422 5423 if (localLOGV) Slog.v( 5424 TAG, "New app record " + app 5425 + " thread=" + thread.asBinder() + " pid=" + pid); 5426 try { 5427 int testMode = IApplicationThread.DEBUG_OFF; 5428 if (mDebugApp != null && mDebugApp.equals(processName)) { 5429 testMode = mWaitForDebugger 5430 ? IApplicationThread.DEBUG_WAIT 5431 : IApplicationThread.DEBUG_ON; 5432 app.debugging = true; 5433 if (mDebugTransient) { 5434 mDebugApp = mOrigDebugApp; 5435 mWaitForDebugger = mOrigWaitForDebugger; 5436 } 5437 } 5438 String profileFile = app.instrumentationProfileFile; 5439 ParcelFileDescriptor profileFd = null; 5440 int samplingInterval = 0; 5441 boolean profileAutoStop = false; 5442 if (mProfileApp != null && mProfileApp.equals(processName)) { 5443 mProfileProc = app; 5444 profileFile = mProfileFile; 5445 profileFd = mProfileFd; 5446 samplingInterval = mSamplingInterval; 5447 profileAutoStop = mAutoStopProfiler; 5448 } 5449 boolean enableOpenGlTrace = false; 5450 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5451 enableOpenGlTrace = true; 5452 mOpenGlTraceApp = null; 5453 } 5454 5455 // If the app is being launched for restore or full backup, set it up specially 5456 boolean isRestrictedBackupMode = false; 5457 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5458 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5459 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5460 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5461 } 5462 5463 ensurePackageDexOpt(app.instrumentationInfo != null 5464 ? app.instrumentationInfo.packageName 5465 : app.info.packageName); 5466 if (app.instrumentationClass != null) { 5467 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5468 } 5469 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5470 + processName + " with config " + mConfiguration); 5471 ApplicationInfo appInfo = app.instrumentationInfo != null 5472 ? app.instrumentationInfo : app.info; 5473 app.compat = compatibilityInfoForPackageLocked(appInfo); 5474 if (profileFd != null) { 5475 profileFd = profileFd.dup(); 5476 } 5477 ProfilerInfo profilerInfo = profileFile == null ? null 5478 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5479 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5480 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5481 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5482 isRestrictedBackupMode || !normalMode, app.persistent, 5483 new Configuration(mConfiguration), app.compat, 5484 getCommonServicesLocked(app.isolated), 5485 mCoreSettingsObserver.getCoreSettingsLocked()); 5486 updateLruProcessLocked(app, false, null); 5487 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5488 } catch (Exception e) { 5489 // todo: Yikes! What should we do? For now we will try to 5490 // start another process, but that could easily get us in 5491 // an infinite loop of restarting processes... 5492 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5493 5494 app.resetPackageList(mProcessStats); 5495 app.unlinkDeathRecipient(); 5496 startProcessLocked(app, "bind fail", processName); 5497 return false; 5498 } 5499 5500 // Remove this record from the list of starting applications. 5501 mPersistentStartingProcesses.remove(app); 5502 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5503 "Attach application locked removing on hold: " + app); 5504 mProcessesOnHold.remove(app); 5505 5506 boolean badApp = false; 5507 boolean didSomething = false; 5508 5509 // See if the top visible activity is waiting to run in this process... 5510 if (normalMode) { 5511 try { 5512 if (mStackSupervisor.attachApplicationLocked(app)) { 5513 didSomething = true; 5514 } 5515 } catch (Exception e) { 5516 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5517 badApp = true; 5518 } 5519 } 5520 5521 // Find any services that should be running in this process... 5522 if (!badApp) { 5523 try { 5524 didSomething |= mServices.attachApplicationLocked(app, processName); 5525 } catch (Exception e) { 5526 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5527 badApp = true; 5528 } 5529 } 5530 5531 // Check if a next-broadcast receiver is in this process... 5532 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5533 try { 5534 didSomething |= sendPendingBroadcastsLocked(app); 5535 } catch (Exception e) { 5536 // If the app died trying to launch the receiver we declare it 'bad' 5537 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5538 badApp = true; 5539 } 5540 } 5541 5542 // Check whether the next backup agent is in this process... 5543 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5544 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5545 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5546 try { 5547 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5548 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5549 mBackupTarget.backupMode); 5550 } catch (Exception e) { 5551 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5552 badApp = true; 5553 } 5554 } 5555 5556 if (badApp) { 5557 app.kill("error during init", true); 5558 handleAppDiedLocked(app, false, true); 5559 return false; 5560 } 5561 5562 if (!didSomething) { 5563 updateOomAdjLocked(); 5564 } 5565 5566 return true; 5567 } 5568 5569 @Override 5570 public final void attachApplication(IApplicationThread thread) { 5571 synchronized (this) { 5572 int callingPid = Binder.getCallingPid(); 5573 final long origId = Binder.clearCallingIdentity(); 5574 attachApplicationLocked(thread, callingPid); 5575 Binder.restoreCallingIdentity(origId); 5576 } 5577 } 5578 5579 @Override 5580 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5581 final long origId = Binder.clearCallingIdentity(); 5582 synchronized (this) { 5583 ActivityStack stack = ActivityRecord.getStackLocked(token); 5584 if (stack != null) { 5585 ActivityRecord r = 5586 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5587 if (stopProfiling) { 5588 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5589 try { 5590 mProfileFd.close(); 5591 } catch (IOException e) { 5592 } 5593 clearProfilerLocked(); 5594 } 5595 } 5596 } 5597 } 5598 Binder.restoreCallingIdentity(origId); 5599 } 5600 5601 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 5602 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 5603 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 5604 } 5605 5606 void enableScreenAfterBoot() { 5607 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5608 SystemClock.uptimeMillis()); 5609 mWindowManager.enableScreenAfterBoot(); 5610 5611 synchronized (this) { 5612 updateEventDispatchingLocked(); 5613 } 5614 } 5615 5616 @Override 5617 public void showBootMessage(final CharSequence msg, final boolean always) { 5618 enforceNotIsolatedCaller("showBootMessage"); 5619 mWindowManager.showBootMessage(msg, always); 5620 } 5621 5622 @Override 5623 public void keyguardWaitingForActivityDrawn() { 5624 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 5625 final long token = Binder.clearCallingIdentity(); 5626 try { 5627 synchronized (this) { 5628 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5629 mWindowManager.keyguardWaitingForActivityDrawn(); 5630 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 5631 mLockScreenShown = LOCK_SCREEN_LEAVING; 5632 updateSleepIfNeededLocked(); 5633 } 5634 } 5635 } finally { 5636 Binder.restoreCallingIdentity(token); 5637 } 5638 } 5639 5640 final void finishBooting() { 5641 synchronized (this) { 5642 if (!mBootAnimationComplete) { 5643 mCallFinishBooting = true; 5644 return; 5645 } 5646 mCallFinishBooting = false; 5647 } 5648 5649 ArraySet<String> completedIsas = new ArraySet<String>(); 5650 for (String abi : Build.SUPPORTED_ABIS) { 5651 Process.establishZygoteConnectionForAbi(abi); 5652 final String instructionSet = VMRuntime.getInstructionSet(abi); 5653 if (!completedIsas.contains(instructionSet)) { 5654 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 5655 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 5656 } 5657 completedIsas.add(instructionSet); 5658 } 5659 } 5660 5661 IntentFilter pkgFilter = new IntentFilter(); 5662 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5663 pkgFilter.addDataScheme("package"); 5664 mContext.registerReceiver(new BroadcastReceiver() { 5665 @Override 5666 public void onReceive(Context context, Intent intent) { 5667 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5668 if (pkgs != null) { 5669 for (String pkg : pkgs) { 5670 synchronized (ActivityManagerService.this) { 5671 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 5672 0, "finished booting")) { 5673 setResultCode(Activity.RESULT_OK); 5674 return; 5675 } 5676 } 5677 } 5678 } 5679 } 5680 }, pkgFilter); 5681 5682 // Let system services know. 5683 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 5684 5685 synchronized (this) { 5686 // Ensure that any processes we had put on hold are now started 5687 // up. 5688 final int NP = mProcessesOnHold.size(); 5689 if (NP > 0) { 5690 ArrayList<ProcessRecord> procs = 5691 new ArrayList<ProcessRecord>(mProcessesOnHold); 5692 for (int ip=0; ip<NP; ip++) { 5693 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5694 + procs.get(ip)); 5695 startProcessLocked(procs.get(ip), "on-hold", null); 5696 } 5697 } 5698 5699 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5700 // Start looking for apps that are abusing wake locks. 5701 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5702 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5703 // Tell anyone interested that we are done booting! 5704 SystemProperties.set("sys.boot_completed", "1"); 5705 5706 // And trigger dev.bootcomplete if we are not showing encryption progress 5707 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 5708 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 5709 SystemProperties.set("dev.bootcomplete", "1"); 5710 } 5711 for (int i=0; i<mStartedUsers.size(); i++) { 5712 UserStartedState uss = mStartedUsers.valueAt(i); 5713 if (uss.mState == UserStartedState.STATE_BOOTING) { 5714 uss.mState = UserStartedState.STATE_RUNNING; 5715 final int userId = mStartedUsers.keyAt(i); 5716 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5717 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5718 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5719 broadcastIntentLocked(null, null, intent, null, 5720 new IIntentReceiver.Stub() { 5721 @Override 5722 public void performReceive(Intent intent, int resultCode, 5723 String data, Bundle extras, boolean ordered, 5724 boolean sticky, int sendingUser) { 5725 synchronized (ActivityManagerService.this) { 5726 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5727 true, false); 5728 } 5729 } 5730 }, 5731 0, null, null, 5732 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5733 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5734 userId); 5735 } 5736 } 5737 scheduleStartProfilesLocked(); 5738 } 5739 } 5740 } 5741 5742 @Override 5743 public void bootAnimationComplete() { 5744 final boolean callFinishBooting; 5745 synchronized (this) { 5746 callFinishBooting = mCallFinishBooting; 5747 mBootAnimationComplete = true; 5748 } 5749 if (callFinishBooting) { 5750 finishBooting(); 5751 } 5752 } 5753 5754 @Override 5755 public void systemBackupRestored() { 5756 synchronized (this) { 5757 if (mSystemReady) { 5758 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 5759 } else { 5760 Slog.w(TAG, "System backup restored before system is ready"); 5761 } 5762 } 5763 } 5764 5765 final void ensureBootCompleted() { 5766 boolean booting; 5767 boolean enableScreen; 5768 synchronized (this) { 5769 booting = mBooting; 5770 mBooting = false; 5771 enableScreen = !mBooted; 5772 mBooted = true; 5773 } 5774 5775 if (booting) { 5776 finishBooting(); 5777 } 5778 5779 if (enableScreen) { 5780 enableScreenAfterBoot(); 5781 } 5782 } 5783 5784 @Override 5785 public final void activityResumed(IBinder token) { 5786 final long origId = Binder.clearCallingIdentity(); 5787 synchronized(this) { 5788 ActivityStack stack = ActivityRecord.getStackLocked(token); 5789 if (stack != null) { 5790 ActivityRecord.activityResumedLocked(token); 5791 } 5792 } 5793 Binder.restoreCallingIdentity(origId); 5794 } 5795 5796 @Override 5797 public final void activityPaused(IBinder token) { 5798 final long origId = Binder.clearCallingIdentity(); 5799 synchronized(this) { 5800 ActivityStack stack = ActivityRecord.getStackLocked(token); 5801 if (stack != null) { 5802 stack.activityPausedLocked(token, false); 5803 } 5804 } 5805 Binder.restoreCallingIdentity(origId); 5806 } 5807 5808 @Override 5809 public final void activityStopped(IBinder token, Bundle icicle, 5810 PersistableBundle persistentState, CharSequence description) { 5811 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5812 5813 // Refuse possible leaked file descriptors 5814 if (icicle != null && icicle.hasFileDescriptors()) { 5815 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5816 } 5817 5818 final long origId = Binder.clearCallingIdentity(); 5819 5820 synchronized (this) { 5821 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5822 if (r != null) { 5823 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5824 } 5825 } 5826 5827 trimApplications(); 5828 5829 Binder.restoreCallingIdentity(origId); 5830 } 5831 5832 @Override 5833 public final void activityDestroyed(IBinder token) { 5834 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5835 synchronized (this) { 5836 ActivityStack stack = ActivityRecord.getStackLocked(token); 5837 if (stack != null) { 5838 stack.activityDestroyedLocked(token); 5839 } 5840 } 5841 } 5842 5843 @Override 5844 public final void backgroundResourcesReleased(IBinder token) { 5845 final long origId = Binder.clearCallingIdentity(); 5846 try { 5847 synchronized (this) { 5848 ActivityStack stack = ActivityRecord.getStackLocked(token); 5849 if (stack != null) { 5850 stack.backgroundResourcesReleased(); 5851 } 5852 } 5853 } finally { 5854 Binder.restoreCallingIdentity(origId); 5855 } 5856 } 5857 5858 @Override 5859 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5860 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5861 } 5862 5863 @Override 5864 public final void notifyEnterAnimationComplete(IBinder token) { 5865 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 5866 } 5867 5868 @Override 5869 public String getCallingPackage(IBinder token) { 5870 synchronized (this) { 5871 ActivityRecord r = getCallingRecordLocked(token); 5872 return r != null ? r.info.packageName : null; 5873 } 5874 } 5875 5876 @Override 5877 public ComponentName getCallingActivity(IBinder token) { 5878 synchronized (this) { 5879 ActivityRecord r = getCallingRecordLocked(token); 5880 return r != null ? r.intent.getComponent() : null; 5881 } 5882 } 5883 5884 private ActivityRecord getCallingRecordLocked(IBinder token) { 5885 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5886 if (r == null) { 5887 return null; 5888 } 5889 return r.resultTo; 5890 } 5891 5892 @Override 5893 public ComponentName getActivityClassForToken(IBinder token) { 5894 synchronized(this) { 5895 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5896 if (r == null) { 5897 return null; 5898 } 5899 return r.intent.getComponent(); 5900 } 5901 } 5902 5903 @Override 5904 public String getPackageForToken(IBinder token) { 5905 synchronized(this) { 5906 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5907 if (r == null) { 5908 return null; 5909 } 5910 return r.packageName; 5911 } 5912 } 5913 5914 @Override 5915 public IIntentSender getIntentSender(int type, 5916 String packageName, IBinder token, String resultWho, 5917 int requestCode, Intent[] intents, String[] resolvedTypes, 5918 int flags, Bundle options, int userId) { 5919 enforceNotIsolatedCaller("getIntentSender"); 5920 // Refuse possible leaked file descriptors 5921 if (intents != null) { 5922 if (intents.length < 1) { 5923 throw new IllegalArgumentException("Intents array length must be >= 1"); 5924 } 5925 for (int i=0; i<intents.length; i++) { 5926 Intent intent = intents[i]; 5927 if (intent != null) { 5928 if (intent.hasFileDescriptors()) { 5929 throw new IllegalArgumentException("File descriptors passed in Intent"); 5930 } 5931 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5932 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5933 throw new IllegalArgumentException( 5934 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5935 } 5936 intents[i] = new Intent(intent); 5937 } 5938 } 5939 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5940 throw new IllegalArgumentException( 5941 "Intent array length does not match resolvedTypes length"); 5942 } 5943 } 5944 if (options != null) { 5945 if (options.hasFileDescriptors()) { 5946 throw new IllegalArgumentException("File descriptors passed in options"); 5947 } 5948 } 5949 5950 synchronized(this) { 5951 int callingUid = Binder.getCallingUid(); 5952 int origUserId = userId; 5953 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5954 type == ActivityManager.INTENT_SENDER_BROADCAST, 5955 ALLOW_NON_FULL, "getIntentSender", null); 5956 if (origUserId == UserHandle.USER_CURRENT) { 5957 // We don't want to evaluate this until the pending intent is 5958 // actually executed. However, we do want to always do the 5959 // security checking for it above. 5960 userId = UserHandle.USER_CURRENT; 5961 } 5962 try { 5963 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5964 int uid = AppGlobals.getPackageManager() 5965 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5966 if (!UserHandle.isSameApp(callingUid, uid)) { 5967 String msg = "Permission Denial: getIntentSender() from pid=" 5968 + Binder.getCallingPid() 5969 + ", uid=" + Binder.getCallingUid() 5970 + ", (need uid=" + uid + ")" 5971 + " is not allowed to send as package " + packageName; 5972 Slog.w(TAG, msg); 5973 throw new SecurityException(msg); 5974 } 5975 } 5976 5977 return getIntentSenderLocked(type, packageName, callingUid, userId, 5978 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5979 5980 } catch (RemoteException e) { 5981 throw new SecurityException(e); 5982 } 5983 } 5984 } 5985 5986 IIntentSender getIntentSenderLocked(int type, String packageName, 5987 int callingUid, int userId, IBinder token, String resultWho, 5988 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5989 Bundle options) { 5990 if (DEBUG_MU) 5991 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5992 ActivityRecord activity = null; 5993 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5994 activity = ActivityRecord.isInStackLocked(token); 5995 if (activity == null) { 5996 return null; 5997 } 5998 if (activity.finishing) { 5999 return null; 6000 } 6001 } 6002 6003 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6004 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6005 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6006 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6007 |PendingIntent.FLAG_UPDATE_CURRENT); 6008 6009 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6010 type, packageName, activity, resultWho, 6011 requestCode, intents, resolvedTypes, flags, options, userId); 6012 WeakReference<PendingIntentRecord> ref; 6013 ref = mIntentSenderRecords.get(key); 6014 PendingIntentRecord rec = ref != null ? ref.get() : null; 6015 if (rec != null) { 6016 if (!cancelCurrent) { 6017 if (updateCurrent) { 6018 if (rec.key.requestIntent != null) { 6019 rec.key.requestIntent.replaceExtras(intents != null ? 6020 intents[intents.length - 1] : null); 6021 } 6022 if (intents != null) { 6023 intents[intents.length-1] = rec.key.requestIntent; 6024 rec.key.allIntents = intents; 6025 rec.key.allResolvedTypes = resolvedTypes; 6026 } else { 6027 rec.key.allIntents = null; 6028 rec.key.allResolvedTypes = null; 6029 } 6030 } 6031 return rec; 6032 } 6033 rec.canceled = true; 6034 mIntentSenderRecords.remove(key); 6035 } 6036 if (noCreate) { 6037 return rec; 6038 } 6039 rec = new PendingIntentRecord(this, key, callingUid); 6040 mIntentSenderRecords.put(key, rec.ref); 6041 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6042 if (activity.pendingResults == null) { 6043 activity.pendingResults 6044 = new HashSet<WeakReference<PendingIntentRecord>>(); 6045 } 6046 activity.pendingResults.add(rec.ref); 6047 } 6048 return rec; 6049 } 6050 6051 @Override 6052 public void cancelIntentSender(IIntentSender sender) { 6053 if (!(sender instanceof PendingIntentRecord)) { 6054 return; 6055 } 6056 synchronized(this) { 6057 PendingIntentRecord rec = (PendingIntentRecord)sender; 6058 try { 6059 int uid = AppGlobals.getPackageManager() 6060 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6061 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6062 String msg = "Permission Denial: cancelIntentSender() from pid=" 6063 + Binder.getCallingPid() 6064 + ", uid=" + Binder.getCallingUid() 6065 + " is not allowed to cancel packges " 6066 + rec.key.packageName; 6067 Slog.w(TAG, msg); 6068 throw new SecurityException(msg); 6069 } 6070 } catch (RemoteException e) { 6071 throw new SecurityException(e); 6072 } 6073 cancelIntentSenderLocked(rec, true); 6074 } 6075 } 6076 6077 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6078 rec.canceled = true; 6079 mIntentSenderRecords.remove(rec.key); 6080 if (cleanActivity && rec.key.activity != null) { 6081 rec.key.activity.pendingResults.remove(rec.ref); 6082 } 6083 } 6084 6085 @Override 6086 public String getPackageForIntentSender(IIntentSender pendingResult) { 6087 if (!(pendingResult instanceof PendingIntentRecord)) { 6088 return null; 6089 } 6090 try { 6091 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6092 return res.key.packageName; 6093 } catch (ClassCastException e) { 6094 } 6095 return null; 6096 } 6097 6098 @Override 6099 public int getUidForIntentSender(IIntentSender sender) { 6100 if (sender instanceof PendingIntentRecord) { 6101 try { 6102 PendingIntentRecord res = (PendingIntentRecord)sender; 6103 return res.uid; 6104 } catch (ClassCastException e) { 6105 } 6106 } 6107 return -1; 6108 } 6109 6110 @Override 6111 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6112 if (!(pendingResult instanceof PendingIntentRecord)) { 6113 return false; 6114 } 6115 try { 6116 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6117 if (res.key.allIntents == null) { 6118 return false; 6119 } 6120 for (int i=0; i<res.key.allIntents.length; i++) { 6121 Intent intent = res.key.allIntents[i]; 6122 if (intent.getPackage() != null && intent.getComponent() != null) { 6123 return false; 6124 } 6125 } 6126 return true; 6127 } catch (ClassCastException e) { 6128 } 6129 return false; 6130 } 6131 6132 @Override 6133 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6134 if (!(pendingResult instanceof PendingIntentRecord)) { 6135 return false; 6136 } 6137 try { 6138 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6139 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6140 return true; 6141 } 6142 return false; 6143 } catch (ClassCastException e) { 6144 } 6145 return false; 6146 } 6147 6148 @Override 6149 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6150 if (!(pendingResult instanceof PendingIntentRecord)) { 6151 return null; 6152 } 6153 try { 6154 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6155 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6156 } catch (ClassCastException e) { 6157 } 6158 return null; 6159 } 6160 6161 @Override 6162 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6163 if (!(pendingResult instanceof PendingIntentRecord)) { 6164 return null; 6165 } 6166 try { 6167 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6168 Intent intent = res.key.requestIntent; 6169 if (intent != null) { 6170 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6171 || res.lastTagPrefix.equals(prefix))) { 6172 return res.lastTag; 6173 } 6174 res.lastTagPrefix = prefix; 6175 StringBuilder sb = new StringBuilder(128); 6176 if (prefix != null) { 6177 sb.append(prefix); 6178 } 6179 if (intent.getAction() != null) { 6180 sb.append(intent.getAction()); 6181 } else if (intent.getComponent() != null) { 6182 intent.getComponent().appendShortString(sb); 6183 } else { 6184 sb.append("?"); 6185 } 6186 return res.lastTag = sb.toString(); 6187 } 6188 } catch (ClassCastException e) { 6189 } 6190 return null; 6191 } 6192 6193 @Override 6194 public void setProcessLimit(int max) { 6195 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6196 "setProcessLimit()"); 6197 synchronized (this) { 6198 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6199 mProcessLimitOverride = max; 6200 } 6201 trimApplications(); 6202 } 6203 6204 @Override 6205 public int getProcessLimit() { 6206 synchronized (this) { 6207 return mProcessLimitOverride; 6208 } 6209 } 6210 6211 void foregroundTokenDied(ForegroundToken token) { 6212 synchronized (ActivityManagerService.this) { 6213 synchronized (mPidsSelfLocked) { 6214 ForegroundToken cur 6215 = mForegroundProcesses.get(token.pid); 6216 if (cur != token) { 6217 return; 6218 } 6219 mForegroundProcesses.remove(token.pid); 6220 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6221 if (pr == null) { 6222 return; 6223 } 6224 pr.forcingToForeground = null; 6225 updateProcessForegroundLocked(pr, false, false); 6226 } 6227 updateOomAdjLocked(); 6228 } 6229 } 6230 6231 @Override 6232 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6233 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6234 "setProcessForeground()"); 6235 synchronized(this) { 6236 boolean changed = false; 6237 6238 synchronized (mPidsSelfLocked) { 6239 ProcessRecord pr = mPidsSelfLocked.get(pid); 6240 if (pr == null && isForeground) { 6241 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6242 return; 6243 } 6244 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6245 if (oldToken != null) { 6246 oldToken.token.unlinkToDeath(oldToken, 0); 6247 mForegroundProcesses.remove(pid); 6248 if (pr != null) { 6249 pr.forcingToForeground = null; 6250 } 6251 changed = true; 6252 } 6253 if (isForeground && token != null) { 6254 ForegroundToken newToken = new ForegroundToken() { 6255 @Override 6256 public void binderDied() { 6257 foregroundTokenDied(this); 6258 } 6259 }; 6260 newToken.pid = pid; 6261 newToken.token = token; 6262 try { 6263 token.linkToDeath(newToken, 0); 6264 mForegroundProcesses.put(pid, newToken); 6265 pr.forcingToForeground = token; 6266 changed = true; 6267 } catch (RemoteException e) { 6268 // If the process died while doing this, we will later 6269 // do the cleanup with the process death link. 6270 } 6271 } 6272 } 6273 6274 if (changed) { 6275 updateOomAdjLocked(); 6276 } 6277 } 6278 } 6279 6280 // ========================================================= 6281 // PERMISSIONS 6282 // ========================================================= 6283 6284 static class PermissionController extends IPermissionController.Stub { 6285 ActivityManagerService mActivityManagerService; 6286 PermissionController(ActivityManagerService activityManagerService) { 6287 mActivityManagerService = activityManagerService; 6288 } 6289 6290 @Override 6291 public boolean checkPermission(String permission, int pid, int uid) { 6292 return mActivityManagerService.checkPermission(permission, pid, 6293 uid) == PackageManager.PERMISSION_GRANTED; 6294 } 6295 } 6296 6297 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6298 @Override 6299 public int checkComponentPermission(String permission, int pid, int uid, 6300 int owningUid, boolean exported) { 6301 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6302 owningUid, exported); 6303 } 6304 6305 @Override 6306 public Object getAMSLock() { 6307 return ActivityManagerService.this; 6308 } 6309 } 6310 6311 /** 6312 * This can be called with or without the global lock held. 6313 */ 6314 int checkComponentPermission(String permission, int pid, int uid, 6315 int owningUid, boolean exported) { 6316 if (pid == MY_PID) { 6317 return PackageManager.PERMISSION_GRANTED; 6318 } 6319 return ActivityManager.checkComponentPermission(permission, uid, 6320 owningUid, exported); 6321 } 6322 6323 /** 6324 * As the only public entry point for permissions checking, this method 6325 * can enforce the semantic that requesting a check on a null global 6326 * permission is automatically denied. (Internally a null permission 6327 * string is used when calling {@link #checkComponentPermission} in cases 6328 * when only uid-based security is needed.) 6329 * 6330 * This can be called with or without the global lock held. 6331 */ 6332 @Override 6333 public int checkPermission(String permission, int pid, int uid) { 6334 if (permission == null) { 6335 return PackageManager.PERMISSION_DENIED; 6336 } 6337 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6338 } 6339 6340 @Override 6341 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6342 if (permission == null) { 6343 return PackageManager.PERMISSION_DENIED; 6344 } 6345 6346 // We might be performing an operation on behalf of an indirect binder 6347 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6348 // client identity accordingly before proceeding. 6349 Identity tlsIdentity = sCallerIdentity.get(); 6350 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6351 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6352 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6353 uid = tlsIdentity.uid; 6354 pid = tlsIdentity.pid; 6355 } 6356 6357 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6358 } 6359 6360 /** 6361 * Binder IPC calls go through the public entry point. 6362 * This can be called with or without the global lock held. 6363 */ 6364 int checkCallingPermission(String permission) { 6365 return checkPermission(permission, 6366 Binder.getCallingPid(), 6367 UserHandle.getAppId(Binder.getCallingUid())); 6368 } 6369 6370 /** 6371 * This can be called with or without the global lock held. 6372 */ 6373 void enforceCallingPermission(String permission, String func) { 6374 if (checkCallingPermission(permission) 6375 == PackageManager.PERMISSION_GRANTED) { 6376 return; 6377 } 6378 6379 String msg = "Permission Denial: " + func + " from pid=" 6380 + Binder.getCallingPid() 6381 + ", uid=" + Binder.getCallingUid() 6382 + " requires " + permission; 6383 Slog.w(TAG, msg); 6384 throw new SecurityException(msg); 6385 } 6386 6387 /** 6388 * Determine if UID is holding permissions required to access {@link Uri} in 6389 * the given {@link ProviderInfo}. Final permission checking is always done 6390 * in {@link ContentProvider}. 6391 */ 6392 private final boolean checkHoldingPermissionsLocked( 6393 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6394 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6395 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6396 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6397 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6398 != PERMISSION_GRANTED) { 6399 return false; 6400 } 6401 } 6402 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6403 } 6404 6405 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6406 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6407 if (pi.applicationInfo.uid == uid) { 6408 return true; 6409 } else if (!pi.exported) { 6410 return false; 6411 } 6412 6413 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6414 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6415 try { 6416 // check if target holds top-level <provider> permissions 6417 if (!readMet && pi.readPermission != null && considerUidPermissions 6418 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6419 readMet = true; 6420 } 6421 if (!writeMet && pi.writePermission != null && considerUidPermissions 6422 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6423 writeMet = true; 6424 } 6425 6426 // track if unprotected read/write is allowed; any denied 6427 // <path-permission> below removes this ability 6428 boolean allowDefaultRead = pi.readPermission == null; 6429 boolean allowDefaultWrite = pi.writePermission == null; 6430 6431 // check if target holds any <path-permission> that match uri 6432 final PathPermission[] pps = pi.pathPermissions; 6433 if (pps != null) { 6434 final String path = grantUri.uri.getPath(); 6435 int i = pps.length; 6436 while (i > 0 && (!readMet || !writeMet)) { 6437 i--; 6438 PathPermission pp = pps[i]; 6439 if (pp.match(path)) { 6440 if (!readMet) { 6441 final String pprperm = pp.getReadPermission(); 6442 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6443 + pprperm + " for " + pp.getPath() 6444 + ": match=" + pp.match(path) 6445 + " check=" + pm.checkUidPermission(pprperm, uid)); 6446 if (pprperm != null) { 6447 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6448 == PERMISSION_GRANTED) { 6449 readMet = true; 6450 } else { 6451 allowDefaultRead = false; 6452 } 6453 } 6454 } 6455 if (!writeMet) { 6456 final String ppwperm = pp.getWritePermission(); 6457 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6458 + ppwperm + " for " + pp.getPath() 6459 + ": match=" + pp.match(path) 6460 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6461 if (ppwperm != null) { 6462 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6463 == PERMISSION_GRANTED) { 6464 writeMet = true; 6465 } else { 6466 allowDefaultWrite = false; 6467 } 6468 } 6469 } 6470 } 6471 } 6472 } 6473 6474 // grant unprotected <provider> read/write, if not blocked by 6475 // <path-permission> above 6476 if (allowDefaultRead) readMet = true; 6477 if (allowDefaultWrite) writeMet = true; 6478 6479 } catch (RemoteException e) { 6480 return false; 6481 } 6482 6483 return readMet && writeMet; 6484 } 6485 6486 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6487 ProviderInfo pi = null; 6488 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6489 if (cpr != null) { 6490 pi = cpr.info; 6491 } else { 6492 try { 6493 pi = AppGlobals.getPackageManager().resolveContentProvider( 6494 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6495 } catch (RemoteException ex) { 6496 } 6497 } 6498 return pi; 6499 } 6500 6501 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6502 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6503 if (targetUris != null) { 6504 return targetUris.get(grantUri); 6505 } 6506 return null; 6507 } 6508 6509 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6510 String targetPkg, int targetUid, GrantUri grantUri) { 6511 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6512 if (targetUris == null) { 6513 targetUris = Maps.newArrayMap(); 6514 mGrantedUriPermissions.put(targetUid, targetUris); 6515 } 6516 6517 UriPermission perm = targetUris.get(grantUri); 6518 if (perm == null) { 6519 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6520 targetUris.put(grantUri, perm); 6521 } 6522 6523 return perm; 6524 } 6525 6526 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6527 final int modeFlags) { 6528 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6529 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6530 : UriPermission.STRENGTH_OWNED; 6531 6532 // Root gets to do everything. 6533 if (uid == 0) { 6534 return true; 6535 } 6536 6537 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6538 if (perms == null) return false; 6539 6540 // First look for exact match 6541 final UriPermission exactPerm = perms.get(grantUri); 6542 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6543 return true; 6544 } 6545 6546 // No exact match, look for prefixes 6547 final int N = perms.size(); 6548 for (int i = 0; i < N; i++) { 6549 final UriPermission perm = perms.valueAt(i); 6550 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6551 && perm.getStrength(modeFlags) >= minStrength) { 6552 return true; 6553 } 6554 } 6555 6556 return false; 6557 } 6558 6559 /** 6560 * @param uri This uri must NOT contain an embedded userId. 6561 * @param userId The userId in which the uri is to be resolved. 6562 */ 6563 @Override 6564 public int checkUriPermission(Uri uri, int pid, int uid, 6565 final int modeFlags, int userId, IBinder callerToken) { 6566 enforceNotIsolatedCaller("checkUriPermission"); 6567 6568 // Another redirected-binder-call permissions check as in 6569 // {@link checkPermissionWithToken}. 6570 Identity tlsIdentity = sCallerIdentity.get(); 6571 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6572 uid = tlsIdentity.uid; 6573 pid = tlsIdentity.pid; 6574 } 6575 6576 // Our own process gets to do everything. 6577 if (pid == MY_PID) { 6578 return PackageManager.PERMISSION_GRANTED; 6579 } 6580 synchronized (this) { 6581 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6582 ? PackageManager.PERMISSION_GRANTED 6583 : PackageManager.PERMISSION_DENIED; 6584 } 6585 } 6586 6587 /** 6588 * Check if the targetPkg can be granted permission to access uri by 6589 * the callingUid using the given modeFlags. Throws a security exception 6590 * if callingUid is not allowed to do this. Returns the uid of the target 6591 * if the URI permission grant should be performed; returns -1 if it is not 6592 * needed (for example targetPkg already has permission to access the URI). 6593 * If you already know the uid of the target, you can supply it in 6594 * lastTargetUid else set that to -1. 6595 */ 6596 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6597 final int modeFlags, int lastTargetUid) { 6598 if (!Intent.isAccessUriMode(modeFlags)) { 6599 return -1; 6600 } 6601 6602 if (targetPkg != null) { 6603 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6604 "Checking grant " + targetPkg + " permission to " + grantUri); 6605 } 6606 6607 final IPackageManager pm = AppGlobals.getPackageManager(); 6608 6609 // If this is not a content: uri, we can't do anything with it. 6610 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6611 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6612 "Can't grant URI permission for non-content URI: " + grantUri); 6613 return -1; 6614 } 6615 6616 final String authority = grantUri.uri.getAuthority(); 6617 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6618 if (pi == null) { 6619 Slog.w(TAG, "No content provider found for permission check: " + 6620 grantUri.uri.toSafeString()); 6621 return -1; 6622 } 6623 6624 int targetUid = lastTargetUid; 6625 if (targetUid < 0 && targetPkg != null) { 6626 try { 6627 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6628 if (targetUid < 0) { 6629 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6630 "Can't grant URI permission no uid for: " + targetPkg); 6631 return -1; 6632 } 6633 } catch (RemoteException ex) { 6634 return -1; 6635 } 6636 } 6637 6638 if (targetUid >= 0) { 6639 // First... does the target actually need this permission? 6640 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6641 // No need to grant the target this permission. 6642 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6643 "Target " + targetPkg + " already has full permission to " + grantUri); 6644 return -1; 6645 } 6646 } else { 6647 // First... there is no target package, so can anyone access it? 6648 boolean allowed = pi.exported; 6649 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6650 if (pi.readPermission != null) { 6651 allowed = false; 6652 } 6653 } 6654 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6655 if (pi.writePermission != null) { 6656 allowed = false; 6657 } 6658 } 6659 if (allowed) { 6660 return -1; 6661 } 6662 } 6663 6664 /* There is a special cross user grant if: 6665 * - The target is on another user. 6666 * - Apps on the current user can access the uri without any uid permissions. 6667 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6668 * grant uri permissions. 6669 */ 6670 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6671 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6672 modeFlags, false /*without considering the uid permissions*/); 6673 6674 // Second... is the provider allowing granting of URI permissions? 6675 if (!specialCrossUserGrant) { 6676 if (!pi.grantUriPermissions) { 6677 throw new SecurityException("Provider " + pi.packageName 6678 + "/" + pi.name 6679 + " does not allow granting of Uri permissions (uri " 6680 + grantUri + ")"); 6681 } 6682 if (pi.uriPermissionPatterns != null) { 6683 final int N = pi.uriPermissionPatterns.length; 6684 boolean allowed = false; 6685 for (int i=0; i<N; i++) { 6686 if (pi.uriPermissionPatterns[i] != null 6687 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6688 allowed = true; 6689 break; 6690 } 6691 } 6692 if (!allowed) { 6693 throw new SecurityException("Provider " + pi.packageName 6694 + "/" + pi.name 6695 + " does not allow granting of permission to path of Uri " 6696 + grantUri); 6697 } 6698 } 6699 } 6700 6701 // Third... does the caller itself have permission to access 6702 // this uri? 6703 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6704 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6705 // Require they hold a strong enough Uri permission 6706 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6707 throw new SecurityException("Uid " + callingUid 6708 + " does not have permission to uri " + grantUri); 6709 } 6710 } 6711 } 6712 return targetUid; 6713 } 6714 6715 /** 6716 * @param uri This uri must NOT contain an embedded userId. 6717 * @param userId The userId in which the uri is to be resolved. 6718 */ 6719 @Override 6720 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6721 final int modeFlags, int userId) { 6722 enforceNotIsolatedCaller("checkGrantUriPermission"); 6723 synchronized(this) { 6724 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6725 new GrantUri(userId, uri, false), modeFlags, -1); 6726 } 6727 } 6728 6729 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6730 final int modeFlags, UriPermissionOwner owner) { 6731 if (!Intent.isAccessUriMode(modeFlags)) { 6732 return; 6733 } 6734 6735 // So here we are: the caller has the assumed permission 6736 // to the uri, and the target doesn't. Let's now give this to 6737 // the target. 6738 6739 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6740 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6741 6742 final String authority = grantUri.uri.getAuthority(); 6743 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6744 if (pi == null) { 6745 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6746 return; 6747 } 6748 6749 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6750 grantUri.prefix = true; 6751 } 6752 final UriPermission perm = findOrCreateUriPermissionLocked( 6753 pi.packageName, targetPkg, targetUid, grantUri); 6754 perm.grantModes(modeFlags, owner); 6755 } 6756 6757 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6758 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 6759 if (targetPkg == null) { 6760 throw new NullPointerException("targetPkg"); 6761 } 6762 int targetUid; 6763 final IPackageManager pm = AppGlobals.getPackageManager(); 6764 try { 6765 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6766 } catch (RemoteException ex) { 6767 return; 6768 } 6769 6770 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6771 targetUid); 6772 if (targetUid < 0) { 6773 return; 6774 } 6775 6776 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6777 owner); 6778 } 6779 6780 static class NeededUriGrants extends ArrayList<GrantUri> { 6781 final String targetPkg; 6782 final int targetUid; 6783 final int flags; 6784 6785 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6786 this.targetPkg = targetPkg; 6787 this.targetUid = targetUid; 6788 this.flags = flags; 6789 } 6790 } 6791 6792 /** 6793 * Like checkGrantUriPermissionLocked, but takes an Intent. 6794 */ 6795 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6796 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6797 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6798 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6799 + " clip=" + (intent != null ? intent.getClipData() : null) 6800 + " from " + intent + "; flags=0x" 6801 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6802 6803 if (targetPkg == null) { 6804 throw new NullPointerException("targetPkg"); 6805 } 6806 6807 if (intent == null) { 6808 return null; 6809 } 6810 Uri data = intent.getData(); 6811 ClipData clip = intent.getClipData(); 6812 if (data == null && clip == null) { 6813 return null; 6814 } 6815 // Default userId for uris in the intent (if they don't specify it themselves) 6816 int contentUserHint = intent.getContentUserHint(); 6817 if (contentUserHint == UserHandle.USER_CURRENT) { 6818 contentUserHint = UserHandle.getUserId(callingUid); 6819 } 6820 final IPackageManager pm = AppGlobals.getPackageManager(); 6821 int targetUid; 6822 if (needed != null) { 6823 targetUid = needed.targetUid; 6824 } else { 6825 try { 6826 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6827 } catch (RemoteException ex) { 6828 return null; 6829 } 6830 if (targetUid < 0) { 6831 if (DEBUG_URI_PERMISSION) { 6832 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6833 + " on user " + targetUserId); 6834 } 6835 return null; 6836 } 6837 } 6838 if (data != null) { 6839 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 6840 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6841 targetUid); 6842 if (targetUid > 0) { 6843 if (needed == null) { 6844 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6845 } 6846 needed.add(grantUri); 6847 } 6848 } 6849 if (clip != null) { 6850 for (int i=0; i<clip.getItemCount(); i++) { 6851 Uri uri = clip.getItemAt(i).getUri(); 6852 if (uri != null) { 6853 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 6854 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6855 targetUid); 6856 if (targetUid > 0) { 6857 if (needed == null) { 6858 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6859 } 6860 needed.add(grantUri); 6861 } 6862 } else { 6863 Intent clipIntent = clip.getItemAt(i).getIntent(); 6864 if (clipIntent != null) { 6865 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6866 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6867 if (newNeeded != null) { 6868 needed = newNeeded; 6869 } 6870 } 6871 } 6872 } 6873 } 6874 6875 return needed; 6876 } 6877 6878 /** 6879 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6880 */ 6881 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6882 UriPermissionOwner owner) { 6883 if (needed != null) { 6884 for (int i=0; i<needed.size(); i++) { 6885 GrantUri grantUri = needed.get(i); 6886 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6887 grantUri, needed.flags, owner); 6888 } 6889 } 6890 } 6891 6892 void grantUriPermissionFromIntentLocked(int callingUid, 6893 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6894 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6895 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6896 if (needed == null) { 6897 return; 6898 } 6899 6900 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6901 } 6902 6903 /** 6904 * @param uri This uri must NOT contain an embedded userId. 6905 * @param userId The userId in which the uri is to be resolved. 6906 */ 6907 @Override 6908 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6909 final int modeFlags, int userId) { 6910 enforceNotIsolatedCaller("grantUriPermission"); 6911 GrantUri grantUri = new GrantUri(userId, uri, false); 6912 synchronized(this) { 6913 final ProcessRecord r = getRecordForAppLocked(caller); 6914 if (r == null) { 6915 throw new SecurityException("Unable to find app for caller " 6916 + caller 6917 + " when granting permission to uri " + grantUri); 6918 } 6919 if (targetPkg == null) { 6920 throw new IllegalArgumentException("null target"); 6921 } 6922 if (grantUri == null) { 6923 throw new IllegalArgumentException("null uri"); 6924 } 6925 6926 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6927 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6928 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6929 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6930 6931 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 6932 UserHandle.getUserId(r.uid)); 6933 } 6934 } 6935 6936 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6937 if (perm.modeFlags == 0) { 6938 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6939 perm.targetUid); 6940 if (perms != null) { 6941 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6942 "Removing " + perm.targetUid + " permission to " + perm.uri); 6943 6944 perms.remove(perm.uri); 6945 if (perms.isEmpty()) { 6946 mGrantedUriPermissions.remove(perm.targetUid); 6947 } 6948 } 6949 } 6950 } 6951 6952 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6953 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6954 6955 final IPackageManager pm = AppGlobals.getPackageManager(); 6956 final String authority = grantUri.uri.getAuthority(); 6957 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6958 if (pi == null) { 6959 Slog.w(TAG, "No content provider found for permission revoke: " 6960 + grantUri.toSafeString()); 6961 return; 6962 } 6963 6964 // Does the caller have this permission on the URI? 6965 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6966 // If they don't have direct access to the URI, then revoke any 6967 // ownerless URI permissions that have been granted to them. 6968 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6969 if (perms != null) { 6970 boolean persistChanged = false; 6971 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6972 final UriPermission perm = it.next(); 6973 if (perm.uri.sourceUserId == grantUri.sourceUserId 6974 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6975 if (DEBUG_URI_PERMISSION) 6976 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 6977 " permission to " + perm.uri); 6978 persistChanged |= perm.revokeModes( 6979 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 6980 if (perm.modeFlags == 0) { 6981 it.remove(); 6982 } 6983 } 6984 } 6985 if (perms.isEmpty()) { 6986 mGrantedUriPermissions.remove(callingUid); 6987 } 6988 if (persistChanged) { 6989 schedulePersistUriGrants(); 6990 } 6991 } 6992 return; 6993 } 6994 6995 boolean persistChanged = false; 6996 6997 // Go through all of the permissions and remove any that match. 6998 int N = mGrantedUriPermissions.size(); 6999 for (int i = 0; i < N; i++) { 7000 final int targetUid = mGrantedUriPermissions.keyAt(i); 7001 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7002 7003 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7004 final UriPermission perm = it.next(); 7005 if (perm.uri.sourceUserId == grantUri.sourceUserId 7006 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7007 if (DEBUG_URI_PERMISSION) 7008 Slog.v(TAG, 7009 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7010 persistChanged |= perm.revokeModes( 7011 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7012 if (perm.modeFlags == 0) { 7013 it.remove(); 7014 } 7015 } 7016 } 7017 7018 if (perms.isEmpty()) { 7019 mGrantedUriPermissions.remove(targetUid); 7020 N--; 7021 i--; 7022 } 7023 } 7024 7025 if (persistChanged) { 7026 schedulePersistUriGrants(); 7027 } 7028 } 7029 7030 /** 7031 * @param uri This uri must NOT contain an embedded userId. 7032 * @param userId The userId in which the uri is to be resolved. 7033 */ 7034 @Override 7035 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7036 int userId) { 7037 enforceNotIsolatedCaller("revokeUriPermission"); 7038 synchronized(this) { 7039 final ProcessRecord r = getRecordForAppLocked(caller); 7040 if (r == null) { 7041 throw new SecurityException("Unable to find app for caller " 7042 + caller 7043 + " when revoking permission to uri " + uri); 7044 } 7045 if (uri == null) { 7046 Slog.w(TAG, "revokeUriPermission: null uri"); 7047 return; 7048 } 7049 7050 if (!Intent.isAccessUriMode(modeFlags)) { 7051 return; 7052 } 7053 7054 final IPackageManager pm = AppGlobals.getPackageManager(); 7055 final String authority = uri.getAuthority(); 7056 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7057 if (pi == null) { 7058 Slog.w(TAG, "No content provider found for permission revoke: " 7059 + uri.toSafeString()); 7060 return; 7061 } 7062 7063 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7064 } 7065 } 7066 7067 /** 7068 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7069 * given package. 7070 * 7071 * @param packageName Package name to match, or {@code null} to apply to all 7072 * packages. 7073 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7074 * to all users. 7075 * @param persistable If persistable grants should be removed. 7076 */ 7077 private void removeUriPermissionsForPackageLocked( 7078 String packageName, int userHandle, boolean persistable) { 7079 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7080 throw new IllegalArgumentException("Must narrow by either package or user"); 7081 } 7082 7083 boolean persistChanged = false; 7084 7085 int N = mGrantedUriPermissions.size(); 7086 for (int i = 0; i < N; i++) { 7087 final int targetUid = mGrantedUriPermissions.keyAt(i); 7088 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7089 7090 // Only inspect grants matching user 7091 if (userHandle == UserHandle.USER_ALL 7092 || userHandle == UserHandle.getUserId(targetUid)) { 7093 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7094 final UriPermission perm = it.next(); 7095 7096 // Only inspect grants matching package 7097 if (packageName == null || perm.sourcePkg.equals(packageName) 7098 || perm.targetPkg.equals(packageName)) { 7099 persistChanged |= perm.revokeModes(persistable 7100 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7101 7102 // Only remove when no modes remain; any persisted grants 7103 // will keep this alive. 7104 if (perm.modeFlags == 0) { 7105 it.remove(); 7106 } 7107 } 7108 } 7109 7110 if (perms.isEmpty()) { 7111 mGrantedUriPermissions.remove(targetUid); 7112 N--; 7113 i--; 7114 } 7115 } 7116 } 7117 7118 if (persistChanged) { 7119 schedulePersistUriGrants(); 7120 } 7121 } 7122 7123 @Override 7124 public IBinder newUriPermissionOwner(String name) { 7125 enforceNotIsolatedCaller("newUriPermissionOwner"); 7126 synchronized(this) { 7127 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7128 return owner.getExternalTokenLocked(); 7129 } 7130 } 7131 7132 /** 7133 * @param uri This uri must NOT contain an embedded userId. 7134 * @param sourceUserId The userId in which the uri is to be resolved. 7135 * @param targetUserId The userId of the app that receives the grant. 7136 */ 7137 @Override 7138 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7139 final int modeFlags, int sourceUserId, int targetUserId) { 7140 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7141 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7142 synchronized(this) { 7143 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7144 if (owner == null) { 7145 throw new IllegalArgumentException("Unknown owner: " + token); 7146 } 7147 if (fromUid != Binder.getCallingUid()) { 7148 if (Binder.getCallingUid() != Process.myUid()) { 7149 // Only system code can grant URI permissions on behalf 7150 // of other users. 7151 throw new SecurityException("nice try"); 7152 } 7153 } 7154 if (targetPkg == null) { 7155 throw new IllegalArgumentException("null target"); 7156 } 7157 if (uri == null) { 7158 throw new IllegalArgumentException("null uri"); 7159 } 7160 7161 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7162 modeFlags, owner, targetUserId); 7163 } 7164 } 7165 7166 /** 7167 * @param uri This uri must NOT contain an embedded userId. 7168 * @param userId The userId in which the uri is to be resolved. 7169 */ 7170 @Override 7171 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7172 synchronized(this) { 7173 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7174 if (owner == null) { 7175 throw new IllegalArgumentException("Unknown owner: " + token); 7176 } 7177 7178 if (uri == null) { 7179 owner.removeUriPermissionsLocked(mode); 7180 } else { 7181 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7182 } 7183 } 7184 } 7185 7186 private void schedulePersistUriGrants() { 7187 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7188 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7189 10 * DateUtils.SECOND_IN_MILLIS); 7190 } 7191 } 7192 7193 private void writeGrantedUriPermissions() { 7194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7195 7196 // Snapshot permissions so we can persist without lock 7197 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7198 synchronized (this) { 7199 final int size = mGrantedUriPermissions.size(); 7200 for (int i = 0; i < size; i++) { 7201 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7202 for (UriPermission perm : perms.values()) { 7203 if (perm.persistedModeFlags != 0) { 7204 persist.add(perm.snapshot()); 7205 } 7206 } 7207 } 7208 } 7209 7210 FileOutputStream fos = null; 7211 try { 7212 fos = mGrantFile.startWrite(); 7213 7214 XmlSerializer out = new FastXmlSerializer(); 7215 out.setOutput(fos, "utf-8"); 7216 out.startDocument(null, true); 7217 out.startTag(null, TAG_URI_GRANTS); 7218 for (UriPermission.Snapshot perm : persist) { 7219 out.startTag(null, TAG_URI_GRANT); 7220 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7221 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7222 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7223 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7224 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7225 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7226 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7227 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7228 out.endTag(null, TAG_URI_GRANT); 7229 } 7230 out.endTag(null, TAG_URI_GRANTS); 7231 out.endDocument(); 7232 7233 mGrantFile.finishWrite(fos); 7234 } catch (IOException e) { 7235 if (fos != null) { 7236 mGrantFile.failWrite(fos); 7237 } 7238 } 7239 } 7240 7241 private void readGrantedUriPermissionsLocked() { 7242 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7243 7244 final long now = System.currentTimeMillis(); 7245 7246 FileInputStream fis = null; 7247 try { 7248 fis = mGrantFile.openRead(); 7249 final XmlPullParser in = Xml.newPullParser(); 7250 in.setInput(fis, null); 7251 7252 int type; 7253 while ((type = in.next()) != END_DOCUMENT) { 7254 final String tag = in.getName(); 7255 if (type == START_TAG) { 7256 if (TAG_URI_GRANT.equals(tag)) { 7257 final int sourceUserId; 7258 final int targetUserId; 7259 final int userHandle = readIntAttribute(in, 7260 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7261 if (userHandle != UserHandle.USER_NULL) { 7262 // For backwards compatibility. 7263 sourceUserId = userHandle; 7264 targetUserId = userHandle; 7265 } else { 7266 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7267 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7268 } 7269 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7270 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7271 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7272 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7273 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7274 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7275 7276 // Sanity check that provider still belongs to source package 7277 final ProviderInfo pi = getProviderInfoLocked( 7278 uri.getAuthority(), sourceUserId); 7279 if (pi != null && sourcePkg.equals(pi.packageName)) { 7280 int targetUid = -1; 7281 try { 7282 targetUid = AppGlobals.getPackageManager() 7283 .getPackageUid(targetPkg, targetUserId); 7284 } catch (RemoteException e) { 7285 } 7286 if (targetUid != -1) { 7287 final UriPermission perm = findOrCreateUriPermissionLocked( 7288 sourcePkg, targetPkg, targetUid, 7289 new GrantUri(sourceUserId, uri, prefix)); 7290 perm.initPersistedModes(modeFlags, createdTime); 7291 } 7292 } else { 7293 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7294 + " but instead found " + pi); 7295 } 7296 } 7297 } 7298 } 7299 } catch (FileNotFoundException e) { 7300 // Missing grants is okay 7301 } catch (IOException e) { 7302 Slog.wtf(TAG, "Failed reading Uri grants", e); 7303 } catch (XmlPullParserException e) { 7304 Slog.wtf(TAG, "Failed reading Uri grants", e); 7305 } finally { 7306 IoUtils.closeQuietly(fis); 7307 } 7308 } 7309 7310 /** 7311 * @param uri This uri must NOT contain an embedded userId. 7312 * @param userId The userId in which the uri is to be resolved. 7313 */ 7314 @Override 7315 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7316 enforceNotIsolatedCaller("takePersistableUriPermission"); 7317 7318 Preconditions.checkFlagsArgument(modeFlags, 7319 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7320 7321 synchronized (this) { 7322 final int callingUid = Binder.getCallingUid(); 7323 boolean persistChanged = false; 7324 GrantUri grantUri = new GrantUri(userId, uri, false); 7325 7326 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7327 new GrantUri(userId, uri, false)); 7328 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7329 new GrantUri(userId, uri, true)); 7330 7331 final boolean exactValid = (exactPerm != null) 7332 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7333 final boolean prefixValid = (prefixPerm != null) 7334 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7335 7336 if (!(exactValid || prefixValid)) { 7337 throw new SecurityException("No persistable permission grants found for UID " 7338 + callingUid + " and Uri " + grantUri.toSafeString()); 7339 } 7340 7341 if (exactValid) { 7342 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7343 } 7344 if (prefixValid) { 7345 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7346 } 7347 7348 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7349 7350 if (persistChanged) { 7351 schedulePersistUriGrants(); 7352 } 7353 } 7354 } 7355 7356 /** 7357 * @param uri This uri must NOT contain an embedded userId. 7358 * @param userId The userId in which the uri is to be resolved. 7359 */ 7360 @Override 7361 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7362 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7363 7364 Preconditions.checkFlagsArgument(modeFlags, 7365 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7366 7367 synchronized (this) { 7368 final int callingUid = Binder.getCallingUid(); 7369 boolean persistChanged = false; 7370 7371 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7372 new GrantUri(userId, uri, false)); 7373 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7374 new GrantUri(userId, uri, true)); 7375 if (exactPerm == null && prefixPerm == null) { 7376 throw new SecurityException("No permission grants found for UID " + callingUid 7377 + " and Uri " + uri.toSafeString()); 7378 } 7379 7380 if (exactPerm != null) { 7381 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7382 removeUriPermissionIfNeededLocked(exactPerm); 7383 } 7384 if (prefixPerm != null) { 7385 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7386 removeUriPermissionIfNeededLocked(prefixPerm); 7387 } 7388 7389 if (persistChanged) { 7390 schedulePersistUriGrants(); 7391 } 7392 } 7393 } 7394 7395 /** 7396 * Prune any older {@link UriPermission} for the given UID until outstanding 7397 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7398 * 7399 * @return if any mutations occured that require persisting. 7400 */ 7401 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7402 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7403 if (perms == null) return false; 7404 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7405 7406 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7407 for (UriPermission perm : perms.values()) { 7408 if (perm.persistedModeFlags != 0) { 7409 persisted.add(perm); 7410 } 7411 } 7412 7413 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7414 if (trimCount <= 0) return false; 7415 7416 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7417 for (int i = 0; i < trimCount; i++) { 7418 final UriPermission perm = persisted.get(i); 7419 7420 if (DEBUG_URI_PERMISSION) { 7421 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7422 } 7423 7424 perm.releasePersistableModes(~0); 7425 removeUriPermissionIfNeededLocked(perm); 7426 } 7427 7428 return true; 7429 } 7430 7431 @Override 7432 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7433 String packageName, boolean incoming) { 7434 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7435 Preconditions.checkNotNull(packageName, "packageName"); 7436 7437 final int callingUid = Binder.getCallingUid(); 7438 final IPackageManager pm = AppGlobals.getPackageManager(); 7439 try { 7440 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7441 if (packageUid != callingUid) { 7442 throw new SecurityException( 7443 "Package " + packageName + " does not belong to calling UID " + callingUid); 7444 } 7445 } catch (RemoteException e) { 7446 throw new SecurityException("Failed to verify package name ownership"); 7447 } 7448 7449 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7450 synchronized (this) { 7451 if (incoming) { 7452 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7453 callingUid); 7454 if (perms == null) { 7455 Slog.w(TAG, "No permission grants found for " + packageName); 7456 } else { 7457 for (UriPermission perm : perms.values()) { 7458 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7459 result.add(perm.buildPersistedPublicApiObject()); 7460 } 7461 } 7462 } 7463 } else { 7464 final int size = mGrantedUriPermissions.size(); 7465 for (int i = 0; i < size; i++) { 7466 final ArrayMap<GrantUri, UriPermission> perms = 7467 mGrantedUriPermissions.valueAt(i); 7468 for (UriPermission perm : perms.values()) { 7469 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7470 result.add(perm.buildPersistedPublicApiObject()); 7471 } 7472 } 7473 } 7474 } 7475 } 7476 return new ParceledListSlice<android.content.UriPermission>(result); 7477 } 7478 7479 @Override 7480 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7481 synchronized (this) { 7482 ProcessRecord app = 7483 who != null ? getRecordForAppLocked(who) : null; 7484 if (app == null) return; 7485 7486 Message msg = Message.obtain(); 7487 msg.what = WAIT_FOR_DEBUGGER_MSG; 7488 msg.obj = app; 7489 msg.arg1 = waiting ? 1 : 0; 7490 mHandler.sendMessage(msg); 7491 } 7492 } 7493 7494 @Override 7495 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7496 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7497 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7498 outInfo.availMem = Process.getFreeMemory(); 7499 outInfo.totalMem = Process.getTotalMemory(); 7500 outInfo.threshold = homeAppMem; 7501 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7502 outInfo.hiddenAppThreshold = cachedAppMem; 7503 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7504 ProcessList.SERVICE_ADJ); 7505 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7506 ProcessList.VISIBLE_APP_ADJ); 7507 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7508 ProcessList.FOREGROUND_APP_ADJ); 7509 } 7510 7511 // ========================================================= 7512 // TASK MANAGEMENT 7513 // ========================================================= 7514 7515 @Override 7516 public List<IAppTask> getAppTasks(String callingPackage) { 7517 int callingUid = Binder.getCallingUid(); 7518 long ident = Binder.clearCallingIdentity(); 7519 7520 synchronized(this) { 7521 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7522 try { 7523 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7524 7525 final int N = mRecentTasks.size(); 7526 for (int i = 0; i < N; i++) { 7527 TaskRecord tr = mRecentTasks.get(i); 7528 // Skip tasks that do not match the caller. We don't need to verify 7529 // callingPackage, because we are also limiting to callingUid and know 7530 // that will limit to the correct security sandbox. 7531 if (tr.effectiveUid != callingUid) { 7532 continue; 7533 } 7534 Intent intent = tr.getBaseIntent(); 7535 if (intent == null || 7536 !callingPackage.equals(intent.getComponent().getPackageName())) { 7537 continue; 7538 } 7539 ActivityManager.RecentTaskInfo taskInfo = 7540 createRecentTaskInfoFromTaskRecord(tr); 7541 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7542 list.add(taskImpl); 7543 } 7544 } finally { 7545 Binder.restoreCallingIdentity(ident); 7546 } 7547 return list; 7548 } 7549 } 7550 7551 @Override 7552 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7553 final int callingUid = Binder.getCallingUid(); 7554 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7555 7556 synchronized(this) { 7557 if (localLOGV) Slog.v( 7558 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7559 7560 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7561 callingUid); 7562 7563 // TODO: Improve with MRU list from all ActivityStacks. 7564 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7565 } 7566 7567 return list; 7568 } 7569 7570 /** 7571 * Creates a new RecentTaskInfo from a TaskRecord. 7572 */ 7573 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7574 // Update the task description to reflect any changes in the task stack 7575 tr.updateTaskDescription(); 7576 7577 // Compose the recent task info 7578 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7579 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 7580 rti.persistentId = tr.taskId; 7581 rti.baseIntent = new Intent(tr.getBaseIntent()); 7582 rti.origActivity = tr.origActivity; 7583 rti.description = tr.lastDescription; 7584 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7585 rti.userId = tr.userId; 7586 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7587 rti.firstActiveTime = tr.firstActiveTime; 7588 rti.lastActiveTime = tr.lastActiveTime; 7589 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7590 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 7591 return rti; 7592 } 7593 7594 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 7595 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 7596 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 7597 if (!allowed) { 7598 if (checkPermission(android.Manifest.permission.GET_TASKS, 7599 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 7600 // Temporary compatibility: some existing apps on the system image may 7601 // still be requesting the old permission and not switched to the new 7602 // one; if so, we'll still allow them full access. This means we need 7603 // to see if they are holding the old permission and are a system app. 7604 try { 7605 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 7606 allowed = true; 7607 Slog.w(TAG, caller + ": caller " + callingUid 7608 + " is using old GET_TASKS but privileged; allowing"); 7609 } 7610 } catch (RemoteException e) { 7611 } 7612 } 7613 } 7614 if (!allowed) { 7615 Slog.w(TAG, caller + ": caller " + callingUid 7616 + " does not hold GET_TASKS; limiting output"); 7617 } 7618 return allowed; 7619 } 7620 7621 @Override 7622 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7623 final int callingUid = Binder.getCallingUid(); 7624 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7625 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7626 7627 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7628 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7629 synchronized (this) { 7630 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 7631 callingUid); 7632 final boolean detailed = checkCallingPermission( 7633 android.Manifest.permission.GET_DETAILED_TASKS) 7634 == PackageManager.PERMISSION_GRANTED; 7635 7636 final int N = mRecentTasks.size(); 7637 ArrayList<ActivityManager.RecentTaskInfo> res 7638 = new ArrayList<ActivityManager.RecentTaskInfo>( 7639 maxNum < N ? maxNum : N); 7640 7641 final Set<Integer> includedUsers; 7642 if (includeProfiles) { 7643 includedUsers = getProfileIdsLocked(userId); 7644 } else { 7645 includedUsers = new HashSet<Integer>(); 7646 } 7647 includedUsers.add(Integer.valueOf(userId)); 7648 7649 for (int i=0; i<N && maxNum > 0; i++) { 7650 TaskRecord tr = mRecentTasks.get(i); 7651 // Only add calling user or related users recent tasks 7652 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 7653 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 7654 continue; 7655 } 7656 7657 // Return the entry if desired by the caller. We always return 7658 // the first entry, because callers always expect this to be the 7659 // foreground app. We may filter others if the caller has 7660 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7661 // we should exclude the entry. 7662 7663 if (i == 0 7664 || withExcluded 7665 || (tr.intent == null) 7666 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7667 == 0)) { 7668 if (!allowed) { 7669 // If the caller doesn't have the GET_TASKS permission, then only 7670 // allow them to see a small subset of tasks -- their own and home. 7671 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 7672 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 7673 continue; 7674 } 7675 } 7676 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 7677 if (tr.stack != null && tr.stack.isHomeStack()) { 7678 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 7679 continue; 7680 } 7681 } 7682 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 7683 // Don't include auto remove tasks that are finished or finishing. 7684 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 7685 + tr); 7686 continue; 7687 } 7688 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 7689 && !tr.isAvailable) { 7690 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 7691 continue; 7692 } 7693 7694 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7695 if (!detailed) { 7696 rti.baseIntent.replaceExtras((Bundle)null); 7697 } 7698 7699 res.add(rti); 7700 maxNum--; 7701 } 7702 } 7703 return res; 7704 } 7705 } 7706 7707 @Override 7708 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7709 synchronized (this) { 7710 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7711 "getTaskThumbnail()"); 7712 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 7713 if (tr != null) { 7714 return tr.getTaskThumbnailLocked(); 7715 } 7716 } 7717 return null; 7718 } 7719 7720 @Override 7721 public int addAppTask(IBinder activityToken, Intent intent, 7722 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 7723 final int callingUid = Binder.getCallingUid(); 7724 final long callingIdent = Binder.clearCallingIdentity(); 7725 7726 try { 7727 synchronized (this) { 7728 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 7729 if (r == null) { 7730 throw new IllegalArgumentException("Activity does not exist; token=" 7731 + activityToken); 7732 } 7733 ComponentName comp = intent.getComponent(); 7734 if (comp == null) { 7735 throw new IllegalArgumentException("Intent " + intent 7736 + " must specify explicit component"); 7737 } 7738 if (thumbnail.getWidth() != mThumbnailWidth 7739 || thumbnail.getHeight() != mThumbnailHeight) { 7740 throw new IllegalArgumentException("Bad thumbnail size: got " 7741 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 7742 + mThumbnailWidth + "x" + mThumbnailHeight); 7743 } 7744 if (intent.getSelector() != null) { 7745 intent.setSelector(null); 7746 } 7747 if (intent.getSourceBounds() != null) { 7748 intent.setSourceBounds(null); 7749 } 7750 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 7751 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 7752 // The caller has added this as an auto-remove task... that makes no 7753 // sense, so turn off auto-remove. 7754 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 7755 } 7756 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 7757 // Must be a new task. 7758 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7759 } 7760 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 7761 mLastAddedTaskActivity = null; 7762 } 7763 ActivityInfo ainfo = mLastAddedTaskActivity; 7764 if (ainfo == null) { 7765 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 7766 comp, 0, UserHandle.getUserId(callingUid)); 7767 if (ainfo.applicationInfo.uid != callingUid) { 7768 throw new SecurityException( 7769 "Can't add task for another application: target uid=" 7770 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 7771 } 7772 } 7773 7774 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 7775 intent, description); 7776 7777 int trimIdx = mRecentTasks.trimForTaskLocked(task, false); 7778 if (trimIdx >= 0) { 7779 // If this would have caused a trim, then we'll abort because that 7780 // means it would be added at the end of the list but then just removed. 7781 return INVALID_TASK_ID; 7782 } 7783 7784 final int N = mRecentTasks.size(); 7785 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 7786 final TaskRecord tr = mRecentTasks.remove(N - 1); 7787 tr.removedFromRecents(); 7788 } 7789 7790 task.inRecents = true; 7791 mRecentTasks.add(task); 7792 r.task.stack.addTask(task, false, false); 7793 7794 task.setLastThumbnail(thumbnail); 7795 task.freeLastThumbnail(); 7796 7797 return task.taskId; 7798 } 7799 } finally { 7800 Binder.restoreCallingIdentity(callingIdent); 7801 } 7802 } 7803 7804 @Override 7805 public Point getAppTaskThumbnailSize() { 7806 synchronized (this) { 7807 return new Point(mThumbnailWidth, mThumbnailHeight); 7808 } 7809 } 7810 7811 @Override 7812 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7813 synchronized (this) { 7814 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7815 if (r != null) { 7816 r.setTaskDescription(td); 7817 r.task.updateTaskDescription(); 7818 } 7819 } 7820 } 7821 7822 @Override 7823 public Bitmap getTaskDescriptionIcon(String filename) { 7824 if (!FileUtils.isValidExtFilename(filename) 7825 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 7826 throw new IllegalArgumentException("Bad filename: " + filename); 7827 } 7828 return mTaskPersister.getTaskDescriptionIcon(filename); 7829 } 7830 7831 @Override 7832 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 7833 throws RemoteException { 7834 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 7835 opts.getCustomInPlaceResId() == 0) { 7836 throw new IllegalArgumentException("Expected in-place ActivityOption " + 7837 "with valid animation"); 7838 } 7839 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 7840 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 7841 opts.getCustomInPlaceResId()); 7842 mWindowManager.executeAppTransition(); 7843 } 7844 7845 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 7846 mRecentTasks.remove(tr); 7847 tr.removedFromRecents(); 7848 ComponentName component = tr.getBaseIntent().getComponent(); 7849 if (component == null) { 7850 Slog.w(TAG, "No component for base intent of task: " + tr); 7851 return; 7852 } 7853 7854 if (!killProcess) { 7855 return; 7856 } 7857 7858 // Determine if the process(es) for this task should be killed. 7859 final String pkg = component.getPackageName(); 7860 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 7861 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7862 for (int i = 0; i < pmap.size(); i++) { 7863 7864 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7865 for (int j = 0; j < uids.size(); j++) { 7866 ProcessRecord proc = uids.valueAt(j); 7867 if (proc.userId != tr.userId) { 7868 // Don't kill process for a different user. 7869 continue; 7870 } 7871 if (proc == mHomeProcess) { 7872 // Don't kill the home process along with tasks from the same package. 7873 continue; 7874 } 7875 if (!proc.pkgList.containsKey(pkg)) { 7876 // Don't kill process that is not associated with this task. 7877 continue; 7878 } 7879 7880 for (int k = 0; k < proc.activities.size(); k++) { 7881 TaskRecord otherTask = proc.activities.get(k).task; 7882 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 7883 // Don't kill process(es) that has an activity in a different task that is 7884 // also in recents. 7885 return; 7886 } 7887 } 7888 7889 // Add process to kill list. 7890 procsToKill.add(proc); 7891 } 7892 } 7893 7894 // Find any running services associated with this app and stop if needed. 7895 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 7896 7897 // Kill the running processes. 7898 for (int i = 0; i < procsToKill.size(); i++) { 7899 ProcessRecord pr = procsToKill.get(i); 7900 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7901 pr.kill("remove task", true); 7902 } else { 7903 pr.waitingToKill = "remove task"; 7904 } 7905 } 7906 } 7907 7908 private void removeTasksByPackageNameLocked(String packageName, int userId) { 7909 // Remove all tasks with activities in the specified package from the list of recent tasks 7910 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 7911 TaskRecord tr = mRecentTasks.get(i); 7912 if (tr.userId != userId) continue; 7913 7914 ComponentName cn = tr.intent.getComponent(); 7915 if (cn != null && cn.getPackageName().equals(packageName)) { 7916 // If the package name matches, remove the task. 7917 removeTaskByIdLocked(tr.taskId, true); 7918 } 7919 } 7920 } 7921 7922 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 7923 final IPackageManager pm = AppGlobals.getPackageManager(); 7924 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 7925 7926 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 7927 TaskRecord tr = mRecentTasks.get(i); 7928 if (tr.userId != userId) continue; 7929 7930 ComponentName cn = tr.intent.getComponent(); 7931 if (cn != null && cn.getPackageName().equals(packageName)) { 7932 // Skip if component still exists in the package. 7933 if (componentsKnownToExist.contains(cn)) continue; 7934 7935 try { 7936 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 7937 if (info != null) { 7938 componentsKnownToExist.add(cn); 7939 } else { 7940 removeTaskByIdLocked(tr.taskId, false); 7941 } 7942 } catch (RemoteException e) { 7943 Log.e(TAG, "Activity info query failed. component=" + cn, e); 7944 } 7945 } 7946 } 7947 } 7948 7949 /** 7950 * Removes the task with the specified task id. 7951 * 7952 * @param taskId Identifier of the task to be removed. 7953 * @param killProcess Kill any process associated with the task if possible. 7954 * @return Returns true if the given task was found and removed. 7955 */ 7956 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 7957 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 7958 if (tr != null) { 7959 tr.removeTaskActivitiesLocked(); 7960 cleanUpRemovedTaskLocked(tr, killProcess); 7961 if (tr.isPersistable) { 7962 notifyTaskPersisterLocked(null, true); 7963 } 7964 return true; 7965 } 7966 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 7967 return false; 7968 } 7969 7970 @Override 7971 public boolean removeTask(int taskId) { 7972 synchronized (this) { 7973 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7974 "removeTask()"); 7975 long ident = Binder.clearCallingIdentity(); 7976 try { 7977 return removeTaskByIdLocked(taskId, true); 7978 } finally { 7979 Binder.restoreCallingIdentity(ident); 7980 } 7981 } 7982 } 7983 7984 /** 7985 * TODO: Add mController hook 7986 */ 7987 @Override 7988 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7989 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7990 "moveTaskToFront()"); 7991 7992 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7993 synchronized(this) { 7994 moveTaskToFrontLocked(taskId, flags, options); 7995 } 7996 } 7997 7998 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 7999 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8000 Binder.getCallingUid(), -1, -1, "Task to front")) { 8001 ActivityOptions.abort(options); 8002 return; 8003 } 8004 final long origId = Binder.clearCallingIdentity(); 8005 try { 8006 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8007 if (task == null) { 8008 Slog.d(TAG, "Could not find task for id: "+ taskId); 8009 return; 8010 } 8011 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8012 mStackSupervisor.showLockTaskToast(); 8013 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8014 return; 8015 } 8016 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8017 if (prev != null && prev.isRecentsActivity()) { 8018 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8019 } 8020 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8021 } finally { 8022 Binder.restoreCallingIdentity(origId); 8023 } 8024 ActivityOptions.abort(options); 8025 } 8026 8027 /** 8028 * Moves an activity, and all of the other activities within the same task, to the bottom 8029 * of the history stack. The activity's order within the task is unchanged. 8030 * 8031 * @param token A reference to the activity we wish to move 8032 * @param nonRoot If false then this only works if the activity is the root 8033 * of a task; if true it will work for any activity in a task. 8034 * @return Returns true if the move completed, false if not. 8035 */ 8036 @Override 8037 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8038 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8039 synchronized(this) { 8040 final long origId = Binder.clearCallingIdentity(); 8041 try { 8042 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8043 if (taskId >= 0) { 8044 if ((mStackSupervisor.mLockTaskModeTask != null) 8045 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8046 mStackSupervisor.showLockTaskToast(); 8047 return false; 8048 } 8049 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8050 } 8051 } finally { 8052 Binder.restoreCallingIdentity(origId); 8053 } 8054 } 8055 return false; 8056 } 8057 8058 @Override 8059 public void moveTaskBackwards(int task) { 8060 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8061 "moveTaskBackwards()"); 8062 8063 synchronized(this) { 8064 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8065 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8066 return; 8067 } 8068 final long origId = Binder.clearCallingIdentity(); 8069 moveTaskBackwardsLocked(task); 8070 Binder.restoreCallingIdentity(origId); 8071 } 8072 } 8073 8074 private final void moveTaskBackwardsLocked(int task) { 8075 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8076 } 8077 8078 @Override 8079 public IBinder getHomeActivityToken() throws RemoteException { 8080 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8081 "getHomeActivityToken()"); 8082 synchronized (this) { 8083 return mStackSupervisor.getHomeActivityToken(); 8084 } 8085 } 8086 8087 @Override 8088 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken, 8089 IActivityContainerCallback callback) throws RemoteException { 8090 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8091 "createActivityContainer()"); 8092 synchronized (this) { 8093 if (parentActivityToken == null) { 8094 throw new IllegalArgumentException("parent token must not be null"); 8095 } 8096 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8097 if (r == null) { 8098 return null; 8099 } 8100 if (callback == null) { 8101 throw new IllegalArgumentException("callback must not be null"); 8102 } 8103 return mStackSupervisor.createVirtualActivityContainer(r, callback); 8104 } 8105 } 8106 8107 @Override 8108 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8109 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8110 "deleteActivityContainer()"); 8111 synchronized (this) { 8112 mStackSupervisor.deleteActivityContainer(container); 8113 } 8114 } 8115 8116 @Override 8117 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8118 throws RemoteException { 8119 synchronized (this) { 8120 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8121 if (stack != null) { 8122 return stack.mActivityContainer; 8123 } 8124 return null; 8125 } 8126 } 8127 8128 @Override 8129 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8130 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8131 "moveTaskToStack()"); 8132 if (stackId == HOME_STACK_ID) { 8133 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8134 new RuntimeException("here").fillInStackTrace()); 8135 } 8136 synchronized (this) { 8137 long ident = Binder.clearCallingIdentity(); 8138 try { 8139 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8140 + stackId + " toTop=" + toTop); 8141 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8142 } finally { 8143 Binder.restoreCallingIdentity(ident); 8144 } 8145 } 8146 } 8147 8148 @Override 8149 public void resizeStack(int stackBoxId, Rect bounds) { 8150 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8151 "resizeStackBox()"); 8152 long ident = Binder.clearCallingIdentity(); 8153 try { 8154 mWindowManager.resizeStack(stackBoxId, bounds); 8155 } finally { 8156 Binder.restoreCallingIdentity(ident); 8157 } 8158 } 8159 8160 @Override 8161 public List<StackInfo> getAllStackInfos() { 8162 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8163 "getAllStackInfos()"); 8164 long ident = Binder.clearCallingIdentity(); 8165 try { 8166 synchronized (this) { 8167 return mStackSupervisor.getAllStackInfosLocked(); 8168 } 8169 } finally { 8170 Binder.restoreCallingIdentity(ident); 8171 } 8172 } 8173 8174 @Override 8175 public StackInfo getStackInfo(int stackId) { 8176 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8177 "getStackInfo()"); 8178 long ident = Binder.clearCallingIdentity(); 8179 try { 8180 synchronized (this) { 8181 return mStackSupervisor.getStackInfoLocked(stackId); 8182 } 8183 } finally { 8184 Binder.restoreCallingIdentity(ident); 8185 } 8186 } 8187 8188 @Override 8189 public boolean isInHomeStack(int taskId) { 8190 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8191 "getStackInfo()"); 8192 long ident = Binder.clearCallingIdentity(); 8193 try { 8194 synchronized (this) { 8195 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8196 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8197 } 8198 } finally { 8199 Binder.restoreCallingIdentity(ident); 8200 } 8201 } 8202 8203 @Override 8204 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8205 synchronized(this) { 8206 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8207 } 8208 } 8209 8210 private boolean isLockTaskAuthorized(String pkg) { 8211 final DevicePolicyManager dpm = (DevicePolicyManager) 8212 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8213 try { 8214 int uid = mContext.getPackageManager().getPackageUid(pkg, 8215 Binder.getCallingUserHandle().getIdentifier()); 8216 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8217 } catch (NameNotFoundException e) { 8218 return false; 8219 } 8220 } 8221 8222 void startLockTaskMode(TaskRecord task) { 8223 final String pkg; 8224 synchronized (this) { 8225 pkg = task.intent.getComponent().getPackageName(); 8226 } 8227 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8228 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8229 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8230 StatusBarManagerInternal.class); 8231 if (statusBarManager != null) { 8232 statusBarManager.showScreenPinningRequest(); 8233 } 8234 return; 8235 } 8236 long ident = Binder.clearCallingIdentity(); 8237 try { 8238 synchronized (this) { 8239 // Since we lost lock on task, make sure it is still there. 8240 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8241 if (task != null) { 8242 if (!isSystemInitiated 8243 && ((mStackSupervisor.getFocusedStack() == null) 8244 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8245 throw new IllegalArgumentException("Invalid task, not in foreground"); 8246 } 8247 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8248 } 8249 } 8250 } finally { 8251 Binder.restoreCallingIdentity(ident); 8252 } 8253 } 8254 8255 @Override 8256 public void startLockTaskMode(int taskId) { 8257 final TaskRecord task; 8258 long ident = Binder.clearCallingIdentity(); 8259 try { 8260 synchronized (this) { 8261 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8262 } 8263 } finally { 8264 Binder.restoreCallingIdentity(ident); 8265 } 8266 if (task != null) { 8267 startLockTaskMode(task); 8268 } 8269 } 8270 8271 @Override 8272 public void startLockTaskMode(IBinder token) { 8273 final TaskRecord task; 8274 long ident = Binder.clearCallingIdentity(); 8275 try { 8276 synchronized (this) { 8277 final ActivityRecord r = ActivityRecord.forToken(token); 8278 if (r == null) { 8279 return; 8280 } 8281 task = r.task; 8282 } 8283 } finally { 8284 Binder.restoreCallingIdentity(ident); 8285 } 8286 if (task != null) { 8287 startLockTaskMode(task); 8288 } 8289 } 8290 8291 @Override 8292 public void startLockTaskModeOnCurrent() throws RemoteException { 8293 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8294 "startLockTaskModeOnCurrent"); 8295 long ident = Binder.clearCallingIdentity(); 8296 try { 8297 ActivityRecord r = null; 8298 synchronized (this) { 8299 r = mStackSupervisor.topRunningActivityLocked(); 8300 } 8301 startLockTaskMode(r.task); 8302 } finally { 8303 Binder.restoreCallingIdentity(ident); 8304 } 8305 } 8306 8307 @Override 8308 public void stopLockTaskMode() { 8309 // Verify that the user matches the package of the intent for the TaskRecord 8310 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8311 // and stopLockTaskMode. 8312 final int callingUid = Binder.getCallingUid(); 8313 if (callingUid != Process.SYSTEM_UID) { 8314 try { 8315 String pkg = 8316 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8317 int uid = mContext.getPackageManager().getPackageUid(pkg, 8318 Binder.getCallingUserHandle().getIdentifier()); 8319 if (uid != callingUid) { 8320 throw new SecurityException("Invalid uid, expected " + uid); 8321 } 8322 } catch (NameNotFoundException e) { 8323 Log.d(TAG, "stopLockTaskMode " + e); 8324 return; 8325 } 8326 } 8327 long ident = Binder.clearCallingIdentity(); 8328 try { 8329 Log.d(TAG, "stopLockTaskMode"); 8330 // Stop lock task 8331 synchronized (this) { 8332 mStackSupervisor.setLockTaskModeLocked(null, false); 8333 } 8334 } finally { 8335 Binder.restoreCallingIdentity(ident); 8336 } 8337 } 8338 8339 @Override 8340 public void stopLockTaskModeOnCurrent() throws RemoteException { 8341 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8342 "stopLockTaskModeOnCurrent"); 8343 long ident = Binder.clearCallingIdentity(); 8344 try { 8345 stopLockTaskMode(); 8346 } finally { 8347 Binder.restoreCallingIdentity(ident); 8348 } 8349 } 8350 8351 @Override 8352 public boolean isInLockTaskMode() { 8353 synchronized (this) { 8354 return mStackSupervisor.isInLockTaskMode(); 8355 } 8356 } 8357 8358 // ========================================================= 8359 // CONTENT PROVIDERS 8360 // ========================================================= 8361 8362 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8363 List<ProviderInfo> providers = null; 8364 try { 8365 providers = AppGlobals.getPackageManager(). 8366 queryContentProviders(app.processName, app.uid, 8367 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8368 } catch (RemoteException ex) { 8369 } 8370 if (DEBUG_MU) 8371 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8372 int userId = app.userId; 8373 if (providers != null) { 8374 int N = providers.size(); 8375 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8376 for (int i=0; i<N; i++) { 8377 ProviderInfo cpi = 8378 (ProviderInfo)providers.get(i); 8379 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8380 cpi.name, cpi.flags); 8381 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8382 // This is a singleton provider, but a user besides the 8383 // default user is asking to initialize a process it runs 8384 // in... well, no, it doesn't actually run in this process, 8385 // it runs in the process of the default user. Get rid of it. 8386 providers.remove(i); 8387 N--; 8388 i--; 8389 continue; 8390 } 8391 8392 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8393 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8394 if (cpr == null) { 8395 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8396 mProviderMap.putProviderByClass(comp, cpr); 8397 } 8398 if (DEBUG_MU) 8399 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8400 app.pubProviders.put(cpi.name, cpr); 8401 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8402 // Don't add this if it is a platform component that is marked 8403 // to run in multiple processes, because this is actually 8404 // part of the framework so doesn't make sense to track as a 8405 // separate apk in the process. 8406 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8407 mProcessStats); 8408 } 8409 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8410 } 8411 } 8412 return providers; 8413 } 8414 8415 /** 8416 * Check if {@link ProcessRecord} has a possible chance at accessing the 8417 * given {@link ProviderInfo}. Final permission checking is always done 8418 * in {@link ContentProvider}. 8419 */ 8420 private final String checkContentProviderPermissionLocked( 8421 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8422 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8423 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8424 boolean checkedGrants = false; 8425 if (checkUser) { 8426 // Looking for cross-user grants before enforcing the typical cross-users permissions 8427 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8428 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8429 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8430 return null; 8431 } 8432 checkedGrants = true; 8433 } 8434 userId = handleIncomingUser(callingPid, callingUid, userId, 8435 false, ALLOW_NON_FULL, 8436 "checkContentProviderPermissionLocked " + cpi.authority, null); 8437 if (userId != tmpTargetUserId) { 8438 // When we actually went to determine the final targer user ID, this ended 8439 // up different than our initial check for the authority. This is because 8440 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8441 // SELF. So we need to re-check the grants again. 8442 checkedGrants = false; 8443 } 8444 } 8445 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8446 cpi.applicationInfo.uid, cpi.exported) 8447 == PackageManager.PERMISSION_GRANTED) { 8448 return null; 8449 } 8450 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8451 cpi.applicationInfo.uid, cpi.exported) 8452 == PackageManager.PERMISSION_GRANTED) { 8453 return null; 8454 } 8455 8456 PathPermission[] pps = cpi.pathPermissions; 8457 if (pps != null) { 8458 int i = pps.length; 8459 while (i > 0) { 8460 i--; 8461 PathPermission pp = pps[i]; 8462 String pprperm = pp.getReadPermission(); 8463 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8464 cpi.applicationInfo.uid, cpi.exported) 8465 == PackageManager.PERMISSION_GRANTED) { 8466 return null; 8467 } 8468 String ppwperm = pp.getWritePermission(); 8469 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8470 cpi.applicationInfo.uid, cpi.exported) 8471 == PackageManager.PERMISSION_GRANTED) { 8472 return null; 8473 } 8474 } 8475 } 8476 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8477 return null; 8478 } 8479 8480 String msg; 8481 if (!cpi.exported) { 8482 msg = "Permission Denial: opening provider " + cpi.name 8483 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8484 + ", uid=" + callingUid + ") that is not exported from uid " 8485 + cpi.applicationInfo.uid; 8486 } else { 8487 msg = "Permission Denial: opening provider " + cpi.name 8488 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8489 + ", uid=" + callingUid + ") requires " 8490 + cpi.readPermission + " or " + cpi.writePermission; 8491 } 8492 Slog.w(TAG, msg); 8493 return msg; 8494 } 8495 8496 /** 8497 * Returns if the ContentProvider has granted a uri to callingUid 8498 */ 8499 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8500 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8501 if (perms != null) { 8502 for (int i=perms.size()-1; i>=0; i--) { 8503 GrantUri grantUri = perms.keyAt(i); 8504 if (grantUri.sourceUserId == userId || !checkUser) { 8505 if (matchesProvider(grantUri.uri, cpi)) { 8506 return true; 8507 } 8508 } 8509 } 8510 } 8511 return false; 8512 } 8513 8514 /** 8515 * Returns true if the uri authority is one of the authorities specified in the provider. 8516 */ 8517 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8518 String uriAuth = uri.getAuthority(); 8519 String cpiAuth = cpi.authority; 8520 if (cpiAuth.indexOf(';') == -1) { 8521 return cpiAuth.equals(uriAuth); 8522 } 8523 String[] cpiAuths = cpiAuth.split(";"); 8524 int length = cpiAuths.length; 8525 for (int i = 0; i < length; i++) { 8526 if (cpiAuths[i].equals(uriAuth)) return true; 8527 } 8528 return false; 8529 } 8530 8531 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8532 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8533 if (r != null) { 8534 for (int i=0; i<r.conProviders.size(); i++) { 8535 ContentProviderConnection conn = r.conProviders.get(i); 8536 if (conn.provider == cpr) { 8537 if (DEBUG_PROVIDER) Slog.v(TAG, 8538 "Adding provider requested by " 8539 + r.processName + " from process " 8540 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8541 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8542 if (stable) { 8543 conn.stableCount++; 8544 conn.numStableIncs++; 8545 } else { 8546 conn.unstableCount++; 8547 conn.numUnstableIncs++; 8548 } 8549 return conn; 8550 } 8551 } 8552 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8553 if (stable) { 8554 conn.stableCount = 1; 8555 conn.numStableIncs = 1; 8556 } else { 8557 conn.unstableCount = 1; 8558 conn.numUnstableIncs = 1; 8559 } 8560 cpr.connections.add(conn); 8561 r.conProviders.add(conn); 8562 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 8563 return conn; 8564 } 8565 cpr.addExternalProcessHandleLocked(externalProcessToken); 8566 return null; 8567 } 8568 8569 boolean decProviderCountLocked(ContentProviderConnection conn, 8570 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8571 if (conn != null) { 8572 cpr = conn.provider; 8573 if (DEBUG_PROVIDER) Slog.v(TAG, 8574 "Removing provider requested by " 8575 + conn.client.processName + " from process " 8576 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8577 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8578 if (stable) { 8579 conn.stableCount--; 8580 } else { 8581 conn.unstableCount--; 8582 } 8583 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8584 cpr.connections.remove(conn); 8585 conn.client.conProviders.remove(conn); 8586 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 8587 return true; 8588 } 8589 return false; 8590 } 8591 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8592 return false; 8593 } 8594 8595 private void checkTime(long startTime, String where) { 8596 long now = SystemClock.elapsedRealtime(); 8597 if ((now-startTime) > 1000) { 8598 // If we are taking more than a second, log about it. 8599 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8600 } 8601 } 8602 8603 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8604 String name, IBinder token, boolean stable, int userId) { 8605 ContentProviderRecord cpr; 8606 ContentProviderConnection conn = null; 8607 ProviderInfo cpi = null; 8608 8609 synchronized(this) { 8610 long startTime = SystemClock.elapsedRealtime(); 8611 8612 ProcessRecord r = null; 8613 if (caller != null) { 8614 r = getRecordForAppLocked(caller); 8615 if (r == null) { 8616 throw new SecurityException( 8617 "Unable to find app for caller " + caller 8618 + " (pid=" + Binder.getCallingPid() 8619 + ") when getting content provider " + name); 8620 } 8621 } 8622 8623 boolean checkCrossUser = true; 8624 8625 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 8626 8627 // First check if this content provider has been published... 8628 cpr = mProviderMap.getProviderByName(name, userId); 8629 // If that didn't work, check if it exists for user 0 and then 8630 // verify that it's a singleton provider before using it. 8631 if (cpr == null && userId != UserHandle.USER_OWNER) { 8632 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8633 if (cpr != null) { 8634 cpi = cpr.info; 8635 if (isSingleton(cpi.processName, cpi.applicationInfo, 8636 cpi.name, cpi.flags) 8637 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8638 userId = UserHandle.USER_OWNER; 8639 checkCrossUser = false; 8640 } else { 8641 cpr = null; 8642 cpi = null; 8643 } 8644 } 8645 } 8646 8647 boolean providerRunning = cpr != null; 8648 if (providerRunning) { 8649 cpi = cpr.info; 8650 String msg; 8651 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 8652 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8653 != null) { 8654 throw new SecurityException(msg); 8655 } 8656 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 8657 8658 if (r != null && cpr.canRunHere(r)) { 8659 // This provider has been published or is in the process 8660 // of being published... but it is also allowed to run 8661 // in the caller's process, so don't make a connection 8662 // and just let the caller instantiate its own instance. 8663 ContentProviderHolder holder = cpr.newHolder(null); 8664 // don't give caller the provider object, it needs 8665 // to make its own. 8666 holder.provider = null; 8667 return holder; 8668 } 8669 8670 final long origId = Binder.clearCallingIdentity(); 8671 8672 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 8673 8674 // In this case the provider instance already exists, so we can 8675 // return it right away. 8676 conn = incProviderCountLocked(r, cpr, token, stable); 8677 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8678 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8679 // If this is a perceptible app accessing the provider, 8680 // make sure to count it as being accessed and thus 8681 // back up on the LRU list. This is good because 8682 // content providers are often expensive to start. 8683 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 8684 updateLruProcessLocked(cpr.proc, false, null); 8685 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 8686 } 8687 } 8688 8689 if (cpr.proc != null) { 8690 if (false) { 8691 if (cpr.name.flattenToShortString().equals( 8692 "com.android.providers.calendar/.CalendarProvider2")) { 8693 Slog.v(TAG, "****************** KILLING " 8694 + cpr.name.flattenToShortString()); 8695 Process.killProcess(cpr.proc.pid); 8696 } 8697 } 8698 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 8699 boolean success = updateOomAdjLocked(cpr.proc); 8700 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 8701 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8702 // NOTE: there is still a race here where a signal could be 8703 // pending on the process even though we managed to update its 8704 // adj level. Not sure what to do about this, but at least 8705 // the race is now smaller. 8706 if (!success) { 8707 // Uh oh... it looks like the provider's process 8708 // has been killed on us. We need to wait for a new 8709 // process to be started, and make sure its death 8710 // doesn't kill our process. 8711 Slog.i(TAG, 8712 "Existing provider " + cpr.name.flattenToShortString() 8713 + " is crashing; detaching " + r); 8714 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8715 checkTime(startTime, "getContentProviderImpl: before appDied"); 8716 appDiedLocked(cpr.proc); 8717 checkTime(startTime, "getContentProviderImpl: after appDied"); 8718 if (!lastRef) { 8719 // This wasn't the last ref our process had on 8720 // the provider... we have now been killed, bail. 8721 return null; 8722 } 8723 providerRunning = false; 8724 conn = null; 8725 } 8726 } 8727 8728 Binder.restoreCallingIdentity(origId); 8729 } 8730 8731 boolean singleton; 8732 if (!providerRunning) { 8733 try { 8734 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 8735 cpi = AppGlobals.getPackageManager(). 8736 resolveContentProvider(name, 8737 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8738 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 8739 } catch (RemoteException ex) { 8740 } 8741 if (cpi == null) { 8742 return null; 8743 } 8744 // If the provider is a singleton AND 8745 // (it's a call within the same user || the provider is a 8746 // privileged app) 8747 // Then allow connecting to the singleton provider 8748 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8749 cpi.name, cpi.flags) 8750 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8751 if (singleton) { 8752 userId = UserHandle.USER_OWNER; 8753 } 8754 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8755 checkTime(startTime, "getContentProviderImpl: got app info for user"); 8756 8757 String msg; 8758 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 8759 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8760 != null) { 8761 throw new SecurityException(msg); 8762 } 8763 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 8764 8765 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8766 && !cpi.processName.equals("system")) { 8767 // If this content provider does not run in the system 8768 // process, and the system is not yet ready to run other 8769 // processes, then fail fast instead of hanging. 8770 throw new IllegalArgumentException( 8771 "Attempt to launch content provider before system ready"); 8772 } 8773 8774 // Make sure that the user who owns this provider is running. If not, 8775 // we don't want to allow it to run. 8776 if (!isUserRunningLocked(userId, false)) { 8777 Slog.w(TAG, "Unable to launch app " 8778 + cpi.applicationInfo.packageName + "/" 8779 + cpi.applicationInfo.uid + " for provider " 8780 + name + ": user " + userId + " is stopped"); 8781 return null; 8782 } 8783 8784 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8785 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 8786 cpr = mProviderMap.getProviderByClass(comp, userId); 8787 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 8788 final boolean firstClass = cpr == null; 8789 if (firstClass) { 8790 final long ident = Binder.clearCallingIdentity(); 8791 try { 8792 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 8793 ApplicationInfo ai = 8794 AppGlobals.getPackageManager(). 8795 getApplicationInfo( 8796 cpi.applicationInfo.packageName, 8797 STOCK_PM_FLAGS, userId); 8798 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 8799 if (ai == null) { 8800 Slog.w(TAG, "No package info for content provider " 8801 + cpi.name); 8802 return null; 8803 } 8804 ai = getAppInfoForUser(ai, userId); 8805 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8806 } catch (RemoteException ex) { 8807 // pm is in same process, this will never happen. 8808 } finally { 8809 Binder.restoreCallingIdentity(ident); 8810 } 8811 } 8812 8813 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 8814 8815 if (r != null && cpr.canRunHere(r)) { 8816 // If this is a multiprocess provider, then just return its 8817 // info and allow the caller to instantiate it. Only do 8818 // this if the provider is the same user as the caller's 8819 // process, or can run as root (so can be in any process). 8820 return cpr.newHolder(null); 8821 } 8822 8823 if (DEBUG_PROVIDER) { 8824 RuntimeException e = new RuntimeException("here"); 8825 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8826 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8827 } 8828 8829 // This is single process, and our app is now connecting to it. 8830 // See if we are already in the process of launching this 8831 // provider. 8832 final int N = mLaunchingProviders.size(); 8833 int i; 8834 for (i=0; i<N; i++) { 8835 if (mLaunchingProviders.get(i) == cpr) { 8836 break; 8837 } 8838 } 8839 8840 // If the provider is not already being launched, then get it 8841 // started. 8842 if (i >= N) { 8843 final long origId = Binder.clearCallingIdentity(); 8844 8845 try { 8846 // Content provider is now in use, its package can't be stopped. 8847 try { 8848 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 8849 AppGlobals.getPackageManager().setPackageStoppedState( 8850 cpr.appInfo.packageName, false, userId); 8851 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 8852 } catch (RemoteException e) { 8853 } catch (IllegalArgumentException e) { 8854 Slog.w(TAG, "Failed trying to unstop package " 8855 + cpr.appInfo.packageName + ": " + e); 8856 } 8857 8858 // Use existing process if already started 8859 checkTime(startTime, "getContentProviderImpl: looking for process record"); 8860 ProcessRecord proc = getProcessRecordLocked( 8861 cpi.processName, cpr.appInfo.uid, false); 8862 if (proc != null && proc.thread != null) { 8863 if (DEBUG_PROVIDER) { 8864 Slog.d(TAG, "Installing in existing process " + proc); 8865 } 8866 if (!proc.pubProviders.containsKey(cpi.name)) { 8867 checkTime(startTime, "getContentProviderImpl: scheduling install"); 8868 proc.pubProviders.put(cpi.name, cpr); 8869 try { 8870 proc.thread.scheduleInstallProvider(cpi); 8871 } catch (RemoteException e) { 8872 } 8873 } 8874 } else { 8875 checkTime(startTime, "getContentProviderImpl: before start process"); 8876 proc = startProcessLocked(cpi.processName, 8877 cpr.appInfo, false, 0, "content provider", 8878 new ComponentName(cpi.applicationInfo.packageName, 8879 cpi.name), false, false, false); 8880 checkTime(startTime, "getContentProviderImpl: after start process"); 8881 if (proc == null) { 8882 Slog.w(TAG, "Unable to launch app " 8883 + cpi.applicationInfo.packageName + "/" 8884 + cpi.applicationInfo.uid + " for provider " 8885 + name + ": process is bad"); 8886 return null; 8887 } 8888 } 8889 cpr.launchingApp = proc; 8890 mLaunchingProviders.add(cpr); 8891 } finally { 8892 Binder.restoreCallingIdentity(origId); 8893 } 8894 } 8895 8896 checkTime(startTime, "getContentProviderImpl: updating data structures"); 8897 8898 // Make sure the provider is published (the same provider class 8899 // may be published under multiple names). 8900 if (firstClass) { 8901 mProviderMap.putProviderByClass(comp, cpr); 8902 } 8903 8904 mProviderMap.putProviderByName(name, cpr); 8905 conn = incProviderCountLocked(r, cpr, token, stable); 8906 if (conn != null) { 8907 conn.waiting = true; 8908 } 8909 } 8910 checkTime(startTime, "getContentProviderImpl: done!"); 8911 } 8912 8913 // Wait for the provider to be published... 8914 synchronized (cpr) { 8915 while (cpr.provider == null) { 8916 if (cpr.launchingApp == null) { 8917 Slog.w(TAG, "Unable to launch app " 8918 + cpi.applicationInfo.packageName + "/" 8919 + cpi.applicationInfo.uid + " for provider " 8920 + name + ": launching app became null"); 8921 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8922 UserHandle.getUserId(cpi.applicationInfo.uid), 8923 cpi.applicationInfo.packageName, 8924 cpi.applicationInfo.uid, name); 8925 return null; 8926 } 8927 try { 8928 if (DEBUG_MU) { 8929 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8930 + cpr.launchingApp); 8931 } 8932 if (conn != null) { 8933 conn.waiting = true; 8934 } 8935 cpr.wait(); 8936 } catch (InterruptedException ex) { 8937 } finally { 8938 if (conn != null) { 8939 conn.waiting = false; 8940 } 8941 } 8942 } 8943 } 8944 return cpr != null ? cpr.newHolder(conn) : null; 8945 } 8946 8947 @Override 8948 public final ContentProviderHolder getContentProvider( 8949 IApplicationThread caller, String name, int userId, boolean stable) { 8950 enforceNotIsolatedCaller("getContentProvider"); 8951 if (caller == null) { 8952 String msg = "null IApplicationThread when getting content provider " 8953 + name; 8954 Slog.w(TAG, msg); 8955 throw new SecurityException(msg); 8956 } 8957 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8958 // with cross-user grant. 8959 return getContentProviderImpl(caller, name, null, stable, userId); 8960 } 8961 8962 public ContentProviderHolder getContentProviderExternal( 8963 String name, int userId, IBinder token) { 8964 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8965 "Do not have permission in call getContentProviderExternal()"); 8966 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8967 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8968 return getContentProviderExternalUnchecked(name, token, userId); 8969 } 8970 8971 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8972 IBinder token, int userId) { 8973 return getContentProviderImpl(null, name, token, true, userId); 8974 } 8975 8976 /** 8977 * Drop a content provider from a ProcessRecord's bookkeeping 8978 */ 8979 public void removeContentProvider(IBinder connection, boolean stable) { 8980 enforceNotIsolatedCaller("removeContentProvider"); 8981 long ident = Binder.clearCallingIdentity(); 8982 try { 8983 synchronized (this) { 8984 ContentProviderConnection conn; 8985 try { 8986 conn = (ContentProviderConnection)connection; 8987 } catch (ClassCastException e) { 8988 String msg ="removeContentProvider: " + connection 8989 + " not a ContentProviderConnection"; 8990 Slog.w(TAG, msg); 8991 throw new IllegalArgumentException(msg); 8992 } 8993 if (conn == null) { 8994 throw new NullPointerException("connection is null"); 8995 } 8996 if (decProviderCountLocked(conn, null, null, stable)) { 8997 updateOomAdjLocked(); 8998 } 8999 } 9000 } finally { 9001 Binder.restoreCallingIdentity(ident); 9002 } 9003 } 9004 9005 public void removeContentProviderExternal(String name, IBinder token) { 9006 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9007 "Do not have permission in call removeContentProviderExternal()"); 9008 int userId = UserHandle.getCallingUserId(); 9009 long ident = Binder.clearCallingIdentity(); 9010 try { 9011 removeContentProviderExternalUnchecked(name, token, userId); 9012 } finally { 9013 Binder.restoreCallingIdentity(ident); 9014 } 9015 } 9016 9017 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9018 synchronized (this) { 9019 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9020 if(cpr == null) { 9021 //remove from mProvidersByClass 9022 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9023 return; 9024 } 9025 9026 //update content provider record entry info 9027 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9028 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9029 if (localCpr.hasExternalProcessHandles()) { 9030 if (localCpr.removeExternalProcessHandleLocked(token)) { 9031 updateOomAdjLocked(); 9032 } else { 9033 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9034 + " with no external reference for token: " 9035 + token + "."); 9036 } 9037 } else { 9038 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9039 + " with no external references."); 9040 } 9041 } 9042 } 9043 9044 public final void publishContentProviders(IApplicationThread caller, 9045 List<ContentProviderHolder> providers) { 9046 if (providers == null) { 9047 return; 9048 } 9049 9050 enforceNotIsolatedCaller("publishContentProviders"); 9051 synchronized (this) { 9052 final ProcessRecord r = getRecordForAppLocked(caller); 9053 if (DEBUG_MU) 9054 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9055 if (r == null) { 9056 throw new SecurityException( 9057 "Unable to find app for caller " + caller 9058 + " (pid=" + Binder.getCallingPid() 9059 + ") when publishing content providers"); 9060 } 9061 9062 final long origId = Binder.clearCallingIdentity(); 9063 9064 final int N = providers.size(); 9065 for (int i=0; i<N; i++) { 9066 ContentProviderHolder src = providers.get(i); 9067 if (src == null || src.info == null || src.provider == null) { 9068 continue; 9069 } 9070 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9071 if (DEBUG_MU) 9072 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9073 if (dst != null) { 9074 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9075 mProviderMap.putProviderByClass(comp, dst); 9076 String names[] = dst.info.authority.split(";"); 9077 for (int j = 0; j < names.length; j++) { 9078 mProviderMap.putProviderByName(names[j], dst); 9079 } 9080 9081 int NL = mLaunchingProviders.size(); 9082 int j; 9083 for (j=0; j<NL; j++) { 9084 if (mLaunchingProviders.get(j) == dst) { 9085 mLaunchingProviders.remove(j); 9086 j--; 9087 NL--; 9088 } 9089 } 9090 synchronized (dst) { 9091 dst.provider = src.provider; 9092 dst.proc = r; 9093 dst.notifyAll(); 9094 } 9095 updateOomAdjLocked(r); 9096 } 9097 } 9098 9099 Binder.restoreCallingIdentity(origId); 9100 } 9101 } 9102 9103 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9104 ContentProviderConnection conn; 9105 try { 9106 conn = (ContentProviderConnection)connection; 9107 } catch (ClassCastException e) { 9108 String msg ="refContentProvider: " + connection 9109 + " not a ContentProviderConnection"; 9110 Slog.w(TAG, msg); 9111 throw new IllegalArgumentException(msg); 9112 } 9113 if (conn == null) { 9114 throw new NullPointerException("connection is null"); 9115 } 9116 9117 synchronized (this) { 9118 if (stable > 0) { 9119 conn.numStableIncs += stable; 9120 } 9121 stable = conn.stableCount + stable; 9122 if (stable < 0) { 9123 throw new IllegalStateException("stableCount < 0: " + stable); 9124 } 9125 9126 if (unstable > 0) { 9127 conn.numUnstableIncs += unstable; 9128 } 9129 unstable = conn.unstableCount + unstable; 9130 if (unstable < 0) { 9131 throw new IllegalStateException("unstableCount < 0: " + unstable); 9132 } 9133 9134 if ((stable+unstable) <= 0) { 9135 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9136 + stable + " unstable=" + unstable); 9137 } 9138 conn.stableCount = stable; 9139 conn.unstableCount = unstable; 9140 return !conn.dead; 9141 } 9142 } 9143 9144 public void unstableProviderDied(IBinder connection) { 9145 ContentProviderConnection conn; 9146 try { 9147 conn = (ContentProviderConnection)connection; 9148 } catch (ClassCastException e) { 9149 String msg ="refContentProvider: " + connection 9150 + " not a ContentProviderConnection"; 9151 Slog.w(TAG, msg); 9152 throw new IllegalArgumentException(msg); 9153 } 9154 if (conn == null) { 9155 throw new NullPointerException("connection is null"); 9156 } 9157 9158 // Safely retrieve the content provider associated with the connection. 9159 IContentProvider provider; 9160 synchronized (this) { 9161 provider = conn.provider.provider; 9162 } 9163 9164 if (provider == null) { 9165 // Um, yeah, we're way ahead of you. 9166 return; 9167 } 9168 9169 // Make sure the caller is being honest with us. 9170 if (provider.asBinder().pingBinder()) { 9171 // Er, no, still looks good to us. 9172 synchronized (this) { 9173 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9174 + " says " + conn + " died, but we don't agree"); 9175 return; 9176 } 9177 } 9178 9179 // Well look at that! It's dead! 9180 synchronized (this) { 9181 if (conn.provider.provider != provider) { 9182 // But something changed... good enough. 9183 return; 9184 } 9185 9186 ProcessRecord proc = conn.provider.proc; 9187 if (proc == null || proc.thread == null) { 9188 // Seems like the process is already cleaned up. 9189 return; 9190 } 9191 9192 // As far as we're concerned, this is just like receiving a 9193 // death notification... just a bit prematurely. 9194 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9195 + ") early provider death"); 9196 final long ident = Binder.clearCallingIdentity(); 9197 try { 9198 appDiedLocked(proc); 9199 } finally { 9200 Binder.restoreCallingIdentity(ident); 9201 } 9202 } 9203 } 9204 9205 @Override 9206 public void appNotRespondingViaProvider(IBinder connection) { 9207 enforceCallingPermission( 9208 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9209 9210 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9211 if (conn == null) { 9212 Slog.w(TAG, "ContentProviderConnection is null"); 9213 return; 9214 } 9215 9216 final ProcessRecord host = conn.provider.proc; 9217 if (host == null) { 9218 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9219 return; 9220 } 9221 9222 final long token = Binder.clearCallingIdentity(); 9223 try { 9224 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9225 } finally { 9226 Binder.restoreCallingIdentity(token); 9227 } 9228 } 9229 9230 public final void installSystemProviders() { 9231 List<ProviderInfo> providers; 9232 synchronized (this) { 9233 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9234 providers = generateApplicationProvidersLocked(app); 9235 if (providers != null) { 9236 for (int i=providers.size()-1; i>=0; i--) { 9237 ProviderInfo pi = (ProviderInfo)providers.get(i); 9238 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9239 Slog.w(TAG, "Not installing system proc provider " + pi.name 9240 + ": not system .apk"); 9241 providers.remove(i); 9242 } 9243 } 9244 } 9245 } 9246 if (providers != null) { 9247 mSystemThread.installSystemProviders(providers); 9248 } 9249 9250 mCoreSettingsObserver = new CoreSettingsObserver(this); 9251 9252 //mUsageStatsService.monitorPackages(); 9253 } 9254 9255 /** 9256 * Allows apps to retrieve the MIME type of a URI. 9257 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9258 * users, then it does not need permission to access the ContentProvider. 9259 * Either, it needs cross-user uri grants. 9260 * 9261 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9262 * 9263 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9264 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9265 */ 9266 public String getProviderMimeType(Uri uri, int userId) { 9267 enforceNotIsolatedCaller("getProviderMimeType"); 9268 final String name = uri.getAuthority(); 9269 int callingUid = Binder.getCallingUid(); 9270 int callingPid = Binder.getCallingPid(); 9271 long ident = 0; 9272 boolean clearedIdentity = false; 9273 userId = unsafeConvertIncomingUser(userId); 9274 if (canClearIdentity(callingPid, callingUid, userId)) { 9275 clearedIdentity = true; 9276 ident = Binder.clearCallingIdentity(); 9277 } 9278 ContentProviderHolder holder = null; 9279 try { 9280 holder = getContentProviderExternalUnchecked(name, null, userId); 9281 if (holder != null) { 9282 return holder.provider.getType(uri); 9283 } 9284 } catch (RemoteException e) { 9285 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9286 return null; 9287 } finally { 9288 // We need to clear the identity to call removeContentProviderExternalUnchecked 9289 if (!clearedIdentity) { 9290 ident = Binder.clearCallingIdentity(); 9291 } 9292 try { 9293 if (holder != null) { 9294 removeContentProviderExternalUnchecked(name, null, userId); 9295 } 9296 } finally { 9297 Binder.restoreCallingIdentity(ident); 9298 } 9299 } 9300 9301 return null; 9302 } 9303 9304 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9305 if (UserHandle.getUserId(callingUid) == userId) { 9306 return true; 9307 } 9308 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9309 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9310 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9311 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9312 return true; 9313 } 9314 return false; 9315 } 9316 9317 // ========================================================= 9318 // GLOBAL MANAGEMENT 9319 // ========================================================= 9320 9321 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9322 boolean isolated, int isolatedUid) { 9323 String proc = customProcess != null ? customProcess : info.processName; 9324 BatteryStatsImpl.Uid.Proc ps = null; 9325 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9326 int uid = info.uid; 9327 if (isolated) { 9328 if (isolatedUid == 0) { 9329 int userId = UserHandle.getUserId(uid); 9330 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9331 while (true) { 9332 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9333 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9334 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9335 } 9336 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9337 mNextIsolatedProcessUid++; 9338 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9339 // No process for this uid, use it. 9340 break; 9341 } 9342 stepsLeft--; 9343 if (stepsLeft <= 0) { 9344 return null; 9345 } 9346 } 9347 } else { 9348 // Special case for startIsolatedProcess (internal only), where 9349 // the uid of the isolated process is specified by the caller. 9350 uid = isolatedUid; 9351 } 9352 } 9353 return new ProcessRecord(stats, info, proc, uid); 9354 } 9355 9356 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9357 String abiOverride) { 9358 ProcessRecord app; 9359 if (!isolated) { 9360 app = getProcessRecordLocked(info.processName, info.uid, true); 9361 } else { 9362 app = null; 9363 } 9364 9365 if (app == null) { 9366 app = newProcessRecordLocked(info, null, isolated, 0); 9367 mProcessNames.put(info.processName, app.uid, app); 9368 if (isolated) { 9369 mIsolatedProcesses.put(app.uid, app); 9370 } 9371 updateLruProcessLocked(app, false, null); 9372 updateOomAdjLocked(); 9373 } 9374 9375 // This package really, really can not be stopped. 9376 try { 9377 AppGlobals.getPackageManager().setPackageStoppedState( 9378 info.packageName, false, UserHandle.getUserId(app.uid)); 9379 } catch (RemoteException e) { 9380 } catch (IllegalArgumentException e) { 9381 Slog.w(TAG, "Failed trying to unstop package " 9382 + info.packageName + ": " + e); 9383 } 9384 9385 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9386 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9387 app.persistent = true; 9388 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9389 } 9390 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9391 mPersistentStartingProcesses.add(app); 9392 startProcessLocked(app, "added application", app.processName, abiOverride, 9393 null /* entryPoint */, null /* entryPointArgs */); 9394 } 9395 9396 return app; 9397 } 9398 9399 public void unhandledBack() { 9400 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9401 "unhandledBack()"); 9402 9403 synchronized(this) { 9404 final long origId = Binder.clearCallingIdentity(); 9405 try { 9406 getFocusedStack().unhandledBackLocked(); 9407 } finally { 9408 Binder.restoreCallingIdentity(origId); 9409 } 9410 } 9411 } 9412 9413 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9414 enforceNotIsolatedCaller("openContentUri"); 9415 final int userId = UserHandle.getCallingUserId(); 9416 String name = uri.getAuthority(); 9417 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9418 ParcelFileDescriptor pfd = null; 9419 if (cph != null) { 9420 // We record the binder invoker's uid in thread-local storage before 9421 // going to the content provider to open the file. Later, in the code 9422 // that handles all permissions checks, we look for this uid and use 9423 // that rather than the Activity Manager's own uid. The effect is that 9424 // we do the check against the caller's permissions even though it looks 9425 // to the content provider like the Activity Manager itself is making 9426 // the request. 9427 Binder token = new Binder(); 9428 sCallerIdentity.set(new Identity( 9429 token, Binder.getCallingPid(), Binder.getCallingUid())); 9430 try { 9431 pfd = cph.provider.openFile(null, uri, "r", null, token); 9432 } catch (FileNotFoundException e) { 9433 // do nothing; pfd will be returned null 9434 } finally { 9435 // Ensure that whatever happens, we clean up the identity state 9436 sCallerIdentity.remove(); 9437 // Ensure we're done with the provider. 9438 removeContentProviderExternalUnchecked(name, null, userId); 9439 } 9440 } else { 9441 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9442 } 9443 return pfd; 9444 } 9445 9446 // Actually is sleeping or shutting down or whatever else in the future 9447 // is an inactive state. 9448 public boolean isSleepingOrShuttingDown() { 9449 return isSleeping() || mShuttingDown; 9450 } 9451 9452 public boolean isSleeping() { 9453 return mSleeping; 9454 } 9455 9456 void onWakefulnessChanged(int wakefulness) { 9457 synchronized(this) { 9458 mWakefulness = wakefulness; 9459 updateSleepIfNeededLocked(); 9460 } 9461 } 9462 9463 void finishRunningVoiceLocked() { 9464 if (mRunningVoice) { 9465 mRunningVoice = false; 9466 updateSleepIfNeededLocked(); 9467 } 9468 } 9469 9470 void updateSleepIfNeededLocked() { 9471 if (mSleeping && !shouldSleepLocked()) { 9472 mSleeping = false; 9473 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9474 } else if (!mSleeping && shouldSleepLocked()) { 9475 mSleeping = true; 9476 mStackSupervisor.goingToSleepLocked(); 9477 9478 // Initialize the wake times of all processes. 9479 checkExcessivePowerUsageLocked(false); 9480 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9481 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9482 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9483 } 9484 } 9485 9486 private boolean shouldSleepLocked() { 9487 // Resume applications while running a voice interactor. 9488 if (mRunningVoice) { 9489 return false; 9490 } 9491 9492 switch (mWakefulness) { 9493 case PowerManagerInternal.WAKEFULNESS_AWAKE: 9494 case PowerManagerInternal.WAKEFULNESS_DREAMING: 9495 // If we're interactive but applications are already paused then defer 9496 // resuming them until the lock screen is hidden. 9497 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 9498 case PowerManagerInternal.WAKEFULNESS_DOZING: 9499 // If we're dozing then pause applications whenever the lock screen is shown. 9500 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 9501 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 9502 default: 9503 // If we're asleep then pause applications unconditionally. 9504 return true; 9505 } 9506 } 9507 9508 /** Pokes the task persister. */ 9509 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9510 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9511 // Never persist the home stack. 9512 return; 9513 } 9514 mTaskPersister.wakeup(task, flush); 9515 } 9516 9517 /** Notifies all listeners when the task stack has changed. */ 9518 void notifyTaskStackChangedLocked() { 9519 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 9520 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 9521 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 9522 } 9523 9524 @Override 9525 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 9526 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 9527 } 9528 9529 @Override 9530 public boolean shutdown(int timeout) { 9531 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9532 != PackageManager.PERMISSION_GRANTED) { 9533 throw new SecurityException("Requires permission " 9534 + android.Manifest.permission.SHUTDOWN); 9535 } 9536 9537 boolean timedout = false; 9538 9539 synchronized(this) { 9540 mShuttingDown = true; 9541 updateEventDispatchingLocked(); 9542 timedout = mStackSupervisor.shutdownLocked(timeout); 9543 } 9544 9545 mAppOpsService.shutdown(); 9546 if (mUsageStatsService != null) { 9547 mUsageStatsService.prepareShutdown(); 9548 } 9549 mBatteryStatsService.shutdown(); 9550 synchronized (this) { 9551 mProcessStats.shutdownLocked(); 9552 notifyTaskPersisterLocked(null, true); 9553 } 9554 9555 return timedout; 9556 } 9557 9558 public final void activitySlept(IBinder token) { 9559 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9560 9561 final long origId = Binder.clearCallingIdentity(); 9562 9563 synchronized (this) { 9564 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9565 if (r != null) { 9566 mStackSupervisor.activitySleptLocked(r); 9567 } 9568 } 9569 9570 Binder.restoreCallingIdentity(origId); 9571 } 9572 9573 private String lockScreenShownToString() { 9574 switch (mLockScreenShown) { 9575 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 9576 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 9577 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 9578 default: return "Unknown=" + mLockScreenShown; 9579 } 9580 } 9581 9582 void logLockScreen(String msg) { 9583 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 9584 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 9585 + PowerManagerInternal.wakefulnessToString(mWakefulness) 9586 + " mSleeping=" + mSleeping); 9587 } 9588 9589 void startRunningVoiceLocked() { 9590 if (!mRunningVoice) { 9591 mRunningVoice = true; 9592 updateSleepIfNeededLocked(); 9593 } 9594 } 9595 9596 private void updateEventDispatchingLocked() { 9597 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9598 } 9599 9600 public void setLockScreenShown(boolean shown) { 9601 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9602 != PackageManager.PERMISSION_GRANTED) { 9603 throw new SecurityException("Requires permission " 9604 + android.Manifest.permission.DEVICE_POWER); 9605 } 9606 9607 synchronized(this) { 9608 long ident = Binder.clearCallingIdentity(); 9609 try { 9610 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9611 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 9612 updateSleepIfNeededLocked(); 9613 } finally { 9614 Binder.restoreCallingIdentity(ident); 9615 } 9616 } 9617 } 9618 9619 @Override 9620 public void stopAppSwitches() { 9621 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9622 != PackageManager.PERMISSION_GRANTED) { 9623 throw new SecurityException("Requires permission " 9624 + android.Manifest.permission.STOP_APP_SWITCHES); 9625 } 9626 9627 synchronized(this) { 9628 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9629 + APP_SWITCH_DELAY_TIME; 9630 mDidAppSwitch = false; 9631 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9632 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9633 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9634 } 9635 } 9636 9637 public void resumeAppSwitches() { 9638 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9639 != PackageManager.PERMISSION_GRANTED) { 9640 throw new SecurityException("Requires permission " 9641 + android.Manifest.permission.STOP_APP_SWITCHES); 9642 } 9643 9644 synchronized(this) { 9645 // Note that we don't execute any pending app switches... we will 9646 // let those wait until either the timeout, or the next start 9647 // activity request. 9648 mAppSwitchesAllowedTime = 0; 9649 } 9650 } 9651 9652 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 9653 int callingPid, int callingUid, String name) { 9654 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9655 return true; 9656 } 9657 9658 int perm = checkComponentPermission( 9659 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 9660 sourceUid, -1, true); 9661 if (perm == PackageManager.PERMISSION_GRANTED) { 9662 return true; 9663 } 9664 9665 // If the actual IPC caller is different from the logical source, then 9666 // also see if they are allowed to control app switches. 9667 if (callingUid != -1 && callingUid != sourceUid) { 9668 perm = checkComponentPermission( 9669 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9670 callingUid, -1, true); 9671 if (perm == PackageManager.PERMISSION_GRANTED) { 9672 return true; 9673 } 9674 } 9675 9676 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 9677 return false; 9678 } 9679 9680 public void setDebugApp(String packageName, boolean waitForDebugger, 9681 boolean persistent) { 9682 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9683 "setDebugApp()"); 9684 9685 long ident = Binder.clearCallingIdentity(); 9686 try { 9687 // Note that this is not really thread safe if there are multiple 9688 // callers into it at the same time, but that's not a situation we 9689 // care about. 9690 if (persistent) { 9691 final ContentResolver resolver = mContext.getContentResolver(); 9692 Settings.Global.putString( 9693 resolver, Settings.Global.DEBUG_APP, 9694 packageName); 9695 Settings.Global.putInt( 9696 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9697 waitForDebugger ? 1 : 0); 9698 } 9699 9700 synchronized (this) { 9701 if (!persistent) { 9702 mOrigDebugApp = mDebugApp; 9703 mOrigWaitForDebugger = mWaitForDebugger; 9704 } 9705 mDebugApp = packageName; 9706 mWaitForDebugger = waitForDebugger; 9707 mDebugTransient = !persistent; 9708 if (packageName != null) { 9709 forceStopPackageLocked(packageName, -1, false, false, true, true, 9710 false, UserHandle.USER_ALL, "set debug app"); 9711 } 9712 } 9713 } finally { 9714 Binder.restoreCallingIdentity(ident); 9715 } 9716 } 9717 9718 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9719 synchronized (this) { 9720 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9721 if (!isDebuggable) { 9722 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9723 throw new SecurityException("Process not debuggable: " + app.packageName); 9724 } 9725 } 9726 9727 mOpenGlTraceApp = processName; 9728 } 9729 } 9730 9731 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 9732 synchronized (this) { 9733 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9734 if (!isDebuggable) { 9735 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9736 throw new SecurityException("Process not debuggable: " + app.packageName); 9737 } 9738 } 9739 mProfileApp = processName; 9740 mProfileFile = profilerInfo.profileFile; 9741 if (mProfileFd != null) { 9742 try { 9743 mProfileFd.close(); 9744 } catch (IOException e) { 9745 } 9746 mProfileFd = null; 9747 } 9748 mProfileFd = profilerInfo.profileFd; 9749 mSamplingInterval = profilerInfo.samplingInterval; 9750 mAutoStopProfiler = profilerInfo.autoStopProfiler; 9751 mProfileType = 0; 9752 } 9753 } 9754 9755 @Override 9756 public void setAlwaysFinish(boolean enabled) { 9757 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9758 "setAlwaysFinish()"); 9759 9760 Settings.Global.putInt( 9761 mContext.getContentResolver(), 9762 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9763 9764 synchronized (this) { 9765 mAlwaysFinishActivities = enabled; 9766 } 9767 } 9768 9769 @Override 9770 public void setActivityController(IActivityController controller) { 9771 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9772 "setActivityController()"); 9773 synchronized (this) { 9774 mController = controller; 9775 Watchdog.getInstance().setActivityController(controller); 9776 } 9777 } 9778 9779 @Override 9780 public void setUserIsMonkey(boolean userIsMonkey) { 9781 synchronized (this) { 9782 synchronized (mPidsSelfLocked) { 9783 final int callingPid = Binder.getCallingPid(); 9784 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9785 if (precessRecord == null) { 9786 throw new SecurityException("Unknown process: " + callingPid); 9787 } 9788 if (precessRecord.instrumentationUiAutomationConnection == null) { 9789 throw new SecurityException("Only an instrumentation process " 9790 + "with a UiAutomation can call setUserIsMonkey"); 9791 } 9792 } 9793 mUserIsMonkey = userIsMonkey; 9794 } 9795 } 9796 9797 @Override 9798 public boolean isUserAMonkey() { 9799 synchronized (this) { 9800 // If there is a controller also implies the user is a monkey. 9801 return (mUserIsMonkey || mController != null); 9802 } 9803 } 9804 9805 public void requestBugReport() { 9806 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9807 SystemProperties.set("ctl.start", "bugreport"); 9808 } 9809 9810 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9811 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9812 } 9813 9814 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9815 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9816 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9817 } 9818 return KEY_DISPATCHING_TIMEOUT; 9819 } 9820 9821 @Override 9822 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9823 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9824 != PackageManager.PERMISSION_GRANTED) { 9825 throw new SecurityException("Requires permission " 9826 + android.Manifest.permission.FILTER_EVENTS); 9827 } 9828 ProcessRecord proc; 9829 long timeout; 9830 synchronized (this) { 9831 synchronized (mPidsSelfLocked) { 9832 proc = mPidsSelfLocked.get(pid); 9833 } 9834 timeout = getInputDispatchingTimeoutLocked(proc); 9835 } 9836 9837 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9838 return -1; 9839 } 9840 9841 return timeout; 9842 } 9843 9844 /** 9845 * Handle input dispatching timeouts. 9846 * Returns whether input dispatching should be aborted or not. 9847 */ 9848 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9849 final ActivityRecord activity, final ActivityRecord parent, 9850 final boolean aboveSystem, String reason) { 9851 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9852 != PackageManager.PERMISSION_GRANTED) { 9853 throw new SecurityException("Requires permission " 9854 + android.Manifest.permission.FILTER_EVENTS); 9855 } 9856 9857 final String annotation; 9858 if (reason == null) { 9859 annotation = "Input dispatching timed out"; 9860 } else { 9861 annotation = "Input dispatching timed out (" + reason + ")"; 9862 } 9863 9864 if (proc != null) { 9865 synchronized (this) { 9866 if (proc.debugging) { 9867 return false; 9868 } 9869 9870 if (mDidDexOpt) { 9871 // Give more time since we were dexopting. 9872 mDidDexOpt = false; 9873 return false; 9874 } 9875 9876 if (proc.instrumentationClass != null) { 9877 Bundle info = new Bundle(); 9878 info.putString("shortMsg", "keyDispatchingTimedOut"); 9879 info.putString("longMsg", annotation); 9880 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9881 return true; 9882 } 9883 } 9884 mHandler.post(new Runnable() { 9885 @Override 9886 public void run() { 9887 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9888 } 9889 }); 9890 } 9891 9892 return true; 9893 } 9894 9895 public Bundle getAssistContextExtras(int requestType) { 9896 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 9897 UserHandle.getCallingUserId()); 9898 if (pae == null) { 9899 return null; 9900 } 9901 synchronized (pae) { 9902 while (!pae.haveResult) { 9903 try { 9904 pae.wait(); 9905 } catch (InterruptedException e) { 9906 } 9907 } 9908 if (pae.result != null) { 9909 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9910 } 9911 } 9912 synchronized (this) { 9913 mPendingAssistExtras.remove(pae); 9914 mHandler.removeCallbacks(pae); 9915 } 9916 return pae.extras; 9917 } 9918 9919 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 9920 int userHandle) { 9921 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9922 "getAssistContextExtras()"); 9923 PendingAssistExtras pae; 9924 Bundle extras = new Bundle(); 9925 synchronized (this) { 9926 ActivityRecord activity = getFocusedStack().mResumedActivity; 9927 if (activity == null) { 9928 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9929 return null; 9930 } 9931 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9932 if (activity.app == null || activity.app.thread == null) { 9933 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9934 return null; 9935 } 9936 if (activity.app.pid == Binder.getCallingPid()) { 9937 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9938 return null; 9939 } 9940 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 9941 try { 9942 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9943 requestType); 9944 mPendingAssistExtras.add(pae); 9945 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9946 } catch (RemoteException e) { 9947 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9948 return null; 9949 } 9950 return pae; 9951 } 9952 } 9953 9954 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9955 PendingAssistExtras pae = (PendingAssistExtras)token; 9956 synchronized (pae) { 9957 pae.result = extras; 9958 pae.haveResult = true; 9959 pae.notifyAll(); 9960 if (pae.intent == null) { 9961 // Caller is just waiting for the result. 9962 return; 9963 } 9964 } 9965 9966 // We are now ready to launch the assist activity. 9967 synchronized (this) { 9968 boolean exists = mPendingAssistExtras.remove(pae); 9969 mHandler.removeCallbacks(pae); 9970 if (!exists) { 9971 // Timed out. 9972 return; 9973 } 9974 } 9975 pae.intent.replaceExtras(extras); 9976 if (pae.hint != null) { 9977 pae.intent.putExtra(pae.hint, true); 9978 } 9979 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 9980 | Intent.FLAG_ACTIVITY_SINGLE_TOP 9981 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 9982 closeSystemDialogs("assist"); 9983 try { 9984 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 9985 } catch (ActivityNotFoundException e) { 9986 Slog.w(TAG, "No activity to handle assist action.", e); 9987 } 9988 } 9989 9990 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 9991 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 9992 } 9993 9994 public void registerProcessObserver(IProcessObserver observer) { 9995 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9996 "registerProcessObserver()"); 9997 synchronized (this) { 9998 mProcessObservers.register(observer); 9999 } 10000 } 10001 10002 @Override 10003 public void unregisterProcessObserver(IProcessObserver observer) { 10004 synchronized (this) { 10005 mProcessObservers.unregister(observer); 10006 } 10007 } 10008 10009 @Override 10010 public boolean convertFromTranslucent(IBinder token) { 10011 final long origId = Binder.clearCallingIdentity(); 10012 try { 10013 synchronized (this) { 10014 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10015 if (r == null) { 10016 return false; 10017 } 10018 final boolean translucentChanged = r.changeWindowTranslucency(true); 10019 if (translucentChanged) { 10020 r.task.stack.releaseBackgroundResources(); 10021 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10022 } 10023 mWindowManager.setAppFullscreen(token, true); 10024 return translucentChanged; 10025 } 10026 } finally { 10027 Binder.restoreCallingIdentity(origId); 10028 } 10029 } 10030 10031 @Override 10032 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10033 final long origId = Binder.clearCallingIdentity(); 10034 try { 10035 synchronized (this) { 10036 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10037 if (r == null) { 10038 return false; 10039 } 10040 int index = r.task.mActivities.lastIndexOf(r); 10041 if (index > 0) { 10042 ActivityRecord under = r.task.mActivities.get(index - 1); 10043 under.returningOptions = options; 10044 } 10045 final boolean translucentChanged = r.changeWindowTranslucency(false); 10046 if (translucentChanged) { 10047 r.task.stack.convertToTranslucent(r); 10048 } 10049 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10050 mWindowManager.setAppFullscreen(token, false); 10051 return translucentChanged; 10052 } 10053 } finally { 10054 Binder.restoreCallingIdentity(origId); 10055 } 10056 } 10057 10058 @Override 10059 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10060 final long origId = Binder.clearCallingIdentity(); 10061 try { 10062 synchronized (this) { 10063 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10064 if (r != null) { 10065 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10066 } 10067 } 10068 return false; 10069 } finally { 10070 Binder.restoreCallingIdentity(origId); 10071 } 10072 } 10073 10074 @Override 10075 public boolean isBackgroundVisibleBehind(IBinder token) { 10076 final long origId = Binder.clearCallingIdentity(); 10077 try { 10078 synchronized (this) { 10079 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10080 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10081 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10082 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10083 return visible; 10084 } 10085 } finally { 10086 Binder.restoreCallingIdentity(origId); 10087 } 10088 } 10089 10090 @Override 10091 public ActivityOptions getActivityOptions(IBinder token) { 10092 final long origId = Binder.clearCallingIdentity(); 10093 try { 10094 synchronized (this) { 10095 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10096 if (r != null) { 10097 final ActivityOptions activityOptions = r.pendingOptions; 10098 r.pendingOptions = null; 10099 return activityOptions; 10100 } 10101 return null; 10102 } 10103 } finally { 10104 Binder.restoreCallingIdentity(origId); 10105 } 10106 } 10107 10108 @Override 10109 public void setImmersive(IBinder token, boolean immersive) { 10110 synchronized(this) { 10111 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10112 if (r == null) { 10113 throw new IllegalArgumentException(); 10114 } 10115 r.immersive = immersive; 10116 10117 // update associated state if we're frontmost 10118 if (r == mFocusedActivity) { 10119 if (DEBUG_IMMERSIVE) { 10120 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10121 } 10122 applyUpdateLockStateLocked(r); 10123 } 10124 } 10125 } 10126 10127 @Override 10128 public boolean isImmersive(IBinder token) { 10129 synchronized (this) { 10130 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10131 if (r == null) { 10132 throw new IllegalArgumentException(); 10133 } 10134 return r.immersive; 10135 } 10136 } 10137 10138 public boolean isTopActivityImmersive() { 10139 enforceNotIsolatedCaller("startActivity"); 10140 synchronized (this) { 10141 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10142 return (r != null) ? r.immersive : false; 10143 } 10144 } 10145 10146 @Override 10147 public boolean isTopOfTask(IBinder token) { 10148 synchronized (this) { 10149 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10150 if (r == null) { 10151 throw new IllegalArgumentException(); 10152 } 10153 return r.task.getTopActivity() == r; 10154 } 10155 } 10156 10157 public final void enterSafeMode() { 10158 synchronized(this) { 10159 // It only makes sense to do this before the system is ready 10160 // and started launching other packages. 10161 if (!mSystemReady) { 10162 try { 10163 AppGlobals.getPackageManager().enterSafeMode(); 10164 } catch (RemoteException e) { 10165 } 10166 } 10167 10168 mSafeMode = true; 10169 } 10170 } 10171 10172 public final void showSafeModeOverlay() { 10173 View v = LayoutInflater.from(mContext).inflate( 10174 com.android.internal.R.layout.safe_mode, null); 10175 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10176 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10177 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10178 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10179 lp.gravity = Gravity.BOTTOM | Gravity.START; 10180 lp.format = v.getBackground().getOpacity(); 10181 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10182 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10183 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10184 ((WindowManager)mContext.getSystemService( 10185 Context.WINDOW_SERVICE)).addView(v, lp); 10186 } 10187 10188 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10189 if (!(sender instanceof PendingIntentRecord)) { 10190 return; 10191 } 10192 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10193 synchronized (stats) { 10194 if (mBatteryStatsService.isOnBattery()) { 10195 mBatteryStatsService.enforceCallingPermission(); 10196 PendingIntentRecord rec = (PendingIntentRecord)sender; 10197 int MY_UID = Binder.getCallingUid(); 10198 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10199 BatteryStatsImpl.Uid.Pkg pkg = 10200 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10201 sourcePkg != null ? sourcePkg : rec.key.packageName); 10202 pkg.incWakeupsLocked(); 10203 } 10204 } 10205 } 10206 10207 public boolean killPids(int[] pids, String pReason, boolean secure) { 10208 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10209 throw new SecurityException("killPids only available to the system"); 10210 } 10211 String reason = (pReason == null) ? "Unknown" : pReason; 10212 // XXX Note: don't acquire main activity lock here, because the window 10213 // manager calls in with its locks held. 10214 10215 boolean killed = false; 10216 synchronized (mPidsSelfLocked) { 10217 int[] types = new int[pids.length]; 10218 int worstType = 0; 10219 for (int i=0; i<pids.length; i++) { 10220 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10221 if (proc != null) { 10222 int type = proc.setAdj; 10223 types[i] = type; 10224 if (type > worstType) { 10225 worstType = type; 10226 } 10227 } 10228 } 10229 10230 // If the worst oom_adj is somewhere in the cached proc LRU range, 10231 // then constrain it so we will kill all cached procs. 10232 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10233 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10234 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10235 } 10236 10237 // If this is not a secure call, don't let it kill processes that 10238 // are important. 10239 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10240 worstType = ProcessList.SERVICE_ADJ; 10241 } 10242 10243 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10244 for (int i=0; i<pids.length; i++) { 10245 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10246 if (proc == null) { 10247 continue; 10248 } 10249 int adj = proc.setAdj; 10250 if (adj >= worstType && !proc.killedByAm) { 10251 proc.kill(reason, true); 10252 killed = true; 10253 } 10254 } 10255 } 10256 return killed; 10257 } 10258 10259 @Override 10260 public void killUid(int uid, String reason) { 10261 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10262 throw new SecurityException("killUid only available to the system"); 10263 } 10264 synchronized (this) { 10265 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10266 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10267 reason != null ? reason : "kill uid"); 10268 } 10269 } 10270 10271 @Override 10272 public boolean killProcessesBelowForeground(String reason) { 10273 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10274 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10275 } 10276 10277 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10278 } 10279 10280 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10281 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10282 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10283 } 10284 10285 boolean killed = false; 10286 synchronized (mPidsSelfLocked) { 10287 final int size = mPidsSelfLocked.size(); 10288 for (int i = 0; i < size; i++) { 10289 final int pid = mPidsSelfLocked.keyAt(i); 10290 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10291 if (proc == null) continue; 10292 10293 final int adj = proc.setAdj; 10294 if (adj > belowAdj && !proc.killedByAm) { 10295 proc.kill(reason, true); 10296 killed = true; 10297 } 10298 } 10299 } 10300 return killed; 10301 } 10302 10303 @Override 10304 public void hang(final IBinder who, boolean allowRestart) { 10305 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10306 != PackageManager.PERMISSION_GRANTED) { 10307 throw new SecurityException("Requires permission " 10308 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10309 } 10310 10311 final IBinder.DeathRecipient death = new DeathRecipient() { 10312 @Override 10313 public void binderDied() { 10314 synchronized (this) { 10315 notifyAll(); 10316 } 10317 } 10318 }; 10319 10320 try { 10321 who.linkToDeath(death, 0); 10322 } catch (RemoteException e) { 10323 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10324 return; 10325 } 10326 10327 synchronized (this) { 10328 Watchdog.getInstance().setAllowRestart(allowRestart); 10329 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10330 synchronized (death) { 10331 while (who.isBinderAlive()) { 10332 try { 10333 death.wait(); 10334 } catch (InterruptedException e) { 10335 } 10336 } 10337 } 10338 Watchdog.getInstance().setAllowRestart(true); 10339 } 10340 } 10341 10342 @Override 10343 public void restart() { 10344 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10345 != PackageManager.PERMISSION_GRANTED) { 10346 throw new SecurityException("Requires permission " 10347 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10348 } 10349 10350 Log.i(TAG, "Sending shutdown broadcast..."); 10351 10352 BroadcastReceiver br = new BroadcastReceiver() { 10353 @Override public void onReceive(Context context, Intent intent) { 10354 // Now the broadcast is done, finish up the low-level shutdown. 10355 Log.i(TAG, "Shutting down activity manager..."); 10356 shutdown(10000); 10357 Log.i(TAG, "Shutdown complete, restarting!"); 10358 Process.killProcess(Process.myPid()); 10359 System.exit(10); 10360 } 10361 }; 10362 10363 // First send the high-level shut down broadcast. 10364 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10365 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10366 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10367 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10368 mContext.sendOrderedBroadcastAsUser(intent, 10369 UserHandle.ALL, null, br, mHandler, 0, null, null); 10370 */ 10371 br.onReceive(mContext, intent); 10372 } 10373 10374 private long getLowRamTimeSinceIdle(long now) { 10375 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10376 } 10377 10378 @Override 10379 public void performIdleMaintenance() { 10380 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10381 != PackageManager.PERMISSION_GRANTED) { 10382 throw new SecurityException("Requires permission " 10383 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10384 } 10385 10386 synchronized (this) { 10387 final long now = SystemClock.uptimeMillis(); 10388 final long timeSinceLastIdle = now - mLastIdleTime; 10389 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10390 mLastIdleTime = now; 10391 mLowRamTimeSinceLastIdle = 0; 10392 if (mLowRamStartTime != 0) { 10393 mLowRamStartTime = now; 10394 } 10395 10396 StringBuilder sb = new StringBuilder(128); 10397 sb.append("Idle maintenance over "); 10398 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10399 sb.append(" low RAM for "); 10400 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10401 Slog.i(TAG, sb.toString()); 10402 10403 // If at least 1/3 of our time since the last idle period has been spent 10404 // with RAM low, then we want to kill processes. 10405 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10406 10407 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10408 ProcessRecord proc = mLruProcesses.get(i); 10409 if (proc.notCachedSinceIdle) { 10410 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10411 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10412 if (doKilling && proc.initialIdlePss != 0 10413 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10414 sb = new StringBuilder(128); 10415 sb.append("Kill"); 10416 sb.append(proc.processName); 10417 sb.append(" in idle maint: pss="); 10418 sb.append(proc.lastPss); 10419 sb.append(", initialPss="); 10420 sb.append(proc.initialIdlePss); 10421 sb.append(", period="); 10422 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10423 sb.append(", lowRamPeriod="); 10424 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10425 Slog.wtfQuiet(TAG, sb.toString()); 10426 proc.kill("idle maint (pss " + proc.lastPss 10427 + " from " + proc.initialIdlePss + ")", true); 10428 } 10429 } 10430 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10431 proc.notCachedSinceIdle = true; 10432 proc.initialIdlePss = 0; 10433 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10434 mTestPssMode, isSleeping(), now); 10435 } 10436 } 10437 10438 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10439 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10440 } 10441 } 10442 10443 private void retrieveSettings() { 10444 final ContentResolver resolver = mContext.getContentResolver(); 10445 String debugApp = Settings.Global.getString( 10446 resolver, Settings.Global.DEBUG_APP); 10447 boolean waitForDebugger = Settings.Global.getInt( 10448 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10449 boolean alwaysFinishActivities = Settings.Global.getInt( 10450 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10451 boolean forceRtl = Settings.Global.getInt( 10452 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10453 // Transfer any global setting for forcing RTL layout, into a System Property 10454 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10455 10456 Configuration configuration = new Configuration(); 10457 Settings.System.getConfiguration(resolver, configuration); 10458 if (forceRtl) { 10459 // This will take care of setting the correct layout direction flags 10460 configuration.setLayoutDirection(configuration.locale); 10461 } 10462 10463 synchronized (this) { 10464 mDebugApp = mOrigDebugApp = debugApp; 10465 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10466 mAlwaysFinishActivities = alwaysFinishActivities; 10467 // This happens before any activities are started, so we can 10468 // change mConfiguration in-place. 10469 updateConfigurationLocked(configuration, null, false, true); 10470 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10471 } 10472 } 10473 10474 /** Loads resources after the current configuration has been set. */ 10475 private void loadResourcesOnSystemReady() { 10476 final Resources res = mContext.getResources(); 10477 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10478 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10479 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10480 } 10481 10482 public boolean testIsSystemReady() { 10483 // no need to synchronize(this) just to read & return the value 10484 return mSystemReady; 10485 } 10486 10487 private static File getCalledPreBootReceiversFile() { 10488 File dataDir = Environment.getDataDirectory(); 10489 File systemDir = new File(dataDir, "system"); 10490 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10491 return fname; 10492 } 10493 10494 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10495 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10496 File file = getCalledPreBootReceiversFile(); 10497 FileInputStream fis = null; 10498 try { 10499 fis = new FileInputStream(file); 10500 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10501 int fvers = dis.readInt(); 10502 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10503 String vers = dis.readUTF(); 10504 String codename = dis.readUTF(); 10505 String build = dis.readUTF(); 10506 if (android.os.Build.VERSION.RELEASE.equals(vers) 10507 && android.os.Build.VERSION.CODENAME.equals(codename) 10508 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10509 int num = dis.readInt(); 10510 while (num > 0) { 10511 num--; 10512 String pkg = dis.readUTF(); 10513 String cls = dis.readUTF(); 10514 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10515 } 10516 } 10517 } 10518 } catch (FileNotFoundException e) { 10519 } catch (IOException e) { 10520 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10521 } finally { 10522 if (fis != null) { 10523 try { 10524 fis.close(); 10525 } catch (IOException e) { 10526 } 10527 } 10528 } 10529 return lastDoneReceivers; 10530 } 10531 10532 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10533 File file = getCalledPreBootReceiversFile(); 10534 FileOutputStream fos = null; 10535 DataOutputStream dos = null; 10536 try { 10537 fos = new FileOutputStream(file); 10538 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10539 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10540 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10541 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10542 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10543 dos.writeInt(list.size()); 10544 for (int i=0; i<list.size(); i++) { 10545 dos.writeUTF(list.get(i).getPackageName()); 10546 dos.writeUTF(list.get(i).getClassName()); 10547 } 10548 } catch (IOException e) { 10549 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10550 file.delete(); 10551 } finally { 10552 FileUtils.sync(fos); 10553 if (dos != null) { 10554 try { 10555 dos.close(); 10556 } catch (IOException e) { 10557 // TODO Auto-generated catch block 10558 e.printStackTrace(); 10559 } 10560 } 10561 } 10562 } 10563 10564 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10565 ArrayList<ComponentName> doneReceivers, int userId) { 10566 boolean waitingUpdate = false; 10567 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10568 List<ResolveInfo> ris = null; 10569 try { 10570 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10571 intent, null, 0, userId); 10572 } catch (RemoteException e) { 10573 } 10574 if (ris != null) { 10575 for (int i=ris.size()-1; i>=0; i--) { 10576 if ((ris.get(i).activityInfo.applicationInfo.flags 10577 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10578 ris.remove(i); 10579 } 10580 } 10581 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10582 10583 // For User 0, load the version number. When delivering to a new user, deliver 10584 // to all receivers. 10585 if (userId == UserHandle.USER_OWNER) { 10586 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10587 for (int i=0; i<ris.size(); i++) { 10588 ActivityInfo ai = ris.get(i).activityInfo; 10589 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10590 if (lastDoneReceivers.contains(comp)) { 10591 // We already did the pre boot receiver for this app with the current 10592 // platform version, so don't do it again... 10593 ris.remove(i); 10594 i--; 10595 // ...however, do keep it as one that has been done, so we don't 10596 // forget about it when rewriting the file of last done receivers. 10597 doneReceivers.add(comp); 10598 } 10599 } 10600 } 10601 10602 // If primary user, send broadcast to all available users, else just to userId 10603 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10604 : new int[] { userId }; 10605 for (int i = 0; i < ris.size(); i++) { 10606 ActivityInfo ai = ris.get(i).activityInfo; 10607 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10608 doneReceivers.add(comp); 10609 intent.setComponent(comp); 10610 for (int j=0; j<users.length; j++) { 10611 IIntentReceiver finisher = null; 10612 // On last receiver and user, set up a completion callback 10613 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10614 finisher = new IIntentReceiver.Stub() { 10615 public void performReceive(Intent intent, int resultCode, 10616 String data, Bundle extras, boolean ordered, 10617 boolean sticky, int sendingUser) { 10618 // The raw IIntentReceiver interface is called 10619 // with the AM lock held, so redispatch to 10620 // execute our code without the lock. 10621 mHandler.post(onFinishCallback); 10622 } 10623 }; 10624 } 10625 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10626 + " for user " + users[j]); 10627 broadcastIntentLocked(null, null, intent, null, finisher, 10628 0, null, null, null, AppOpsManager.OP_NONE, 10629 true, false, MY_PID, Process.SYSTEM_UID, 10630 users[j]); 10631 if (finisher != null) { 10632 waitingUpdate = true; 10633 } 10634 } 10635 } 10636 } 10637 10638 return waitingUpdate; 10639 } 10640 10641 public void systemReady(final Runnable goingCallback) { 10642 synchronized(this) { 10643 if (mSystemReady) { 10644 // If we're done calling all the receivers, run the next "boot phase" passed in 10645 // by the SystemServer 10646 if (goingCallback != null) { 10647 goingCallback.run(); 10648 } 10649 return; 10650 } 10651 10652 // Make sure we have the current profile info, since it is needed for 10653 // security checks. 10654 updateCurrentProfileIdsLocked(); 10655 10656 mRecentTasks.clear(); 10657 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked()); 10658 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 10659 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 10660 mTaskPersister.startPersisting(); 10661 10662 // Check to see if there are any update receivers to run. 10663 if (!mDidUpdate) { 10664 if (mWaitingUpdate) { 10665 return; 10666 } 10667 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10668 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10669 public void run() { 10670 synchronized (ActivityManagerService.this) { 10671 mDidUpdate = true; 10672 } 10673 writeLastDonePreBootReceivers(doneReceivers); 10674 showBootMessage(mContext.getText( 10675 R.string.android_upgrading_complete), 10676 false); 10677 systemReady(goingCallback); 10678 } 10679 }, doneReceivers, UserHandle.USER_OWNER); 10680 10681 if (mWaitingUpdate) { 10682 return; 10683 } 10684 mDidUpdate = true; 10685 } 10686 10687 mAppOpsService.systemReady(); 10688 mSystemReady = true; 10689 } 10690 10691 ArrayList<ProcessRecord> procsToKill = null; 10692 synchronized(mPidsSelfLocked) { 10693 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10694 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10695 if (!isAllowedWhileBooting(proc.info)){ 10696 if (procsToKill == null) { 10697 procsToKill = new ArrayList<ProcessRecord>(); 10698 } 10699 procsToKill.add(proc); 10700 } 10701 } 10702 } 10703 10704 synchronized(this) { 10705 if (procsToKill != null) { 10706 for (int i=procsToKill.size()-1; i>=0; i--) { 10707 ProcessRecord proc = procsToKill.get(i); 10708 Slog.i(TAG, "Removing system update proc: " + proc); 10709 removeProcessLocked(proc, true, false, "system update done"); 10710 } 10711 } 10712 10713 // Now that we have cleaned up any update processes, we 10714 // are ready to start launching real processes and know that 10715 // we won't trample on them any more. 10716 mProcessesReady = true; 10717 } 10718 10719 Slog.i(TAG, "System now ready"); 10720 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10721 SystemClock.uptimeMillis()); 10722 10723 synchronized(this) { 10724 // Make sure we have no pre-ready processes sitting around. 10725 10726 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10727 ResolveInfo ri = mContext.getPackageManager() 10728 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10729 STOCK_PM_FLAGS); 10730 CharSequence errorMsg = null; 10731 if (ri != null) { 10732 ActivityInfo ai = ri.activityInfo; 10733 ApplicationInfo app = ai.applicationInfo; 10734 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10735 mTopAction = Intent.ACTION_FACTORY_TEST; 10736 mTopData = null; 10737 mTopComponent = new ComponentName(app.packageName, 10738 ai.name); 10739 } else { 10740 errorMsg = mContext.getResources().getText( 10741 com.android.internal.R.string.factorytest_not_system); 10742 } 10743 } else { 10744 errorMsg = mContext.getResources().getText( 10745 com.android.internal.R.string.factorytest_no_action); 10746 } 10747 if (errorMsg != null) { 10748 mTopAction = null; 10749 mTopData = null; 10750 mTopComponent = null; 10751 Message msg = Message.obtain(); 10752 msg.what = SHOW_FACTORY_ERROR_MSG; 10753 msg.getData().putCharSequence("msg", errorMsg); 10754 mHandler.sendMessage(msg); 10755 } 10756 } 10757 } 10758 10759 retrieveSettings(); 10760 loadResourcesOnSystemReady(); 10761 10762 synchronized (this) { 10763 readGrantedUriPermissionsLocked(); 10764 } 10765 10766 if (goingCallback != null) goingCallback.run(); 10767 10768 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10769 Integer.toString(mCurrentUserId), mCurrentUserId); 10770 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10771 Integer.toString(mCurrentUserId), mCurrentUserId); 10772 mSystemServiceManager.startUser(mCurrentUserId); 10773 10774 synchronized (this) { 10775 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10776 try { 10777 List apps = AppGlobals.getPackageManager(). 10778 getPersistentApplications(STOCK_PM_FLAGS); 10779 if (apps != null) { 10780 int N = apps.size(); 10781 int i; 10782 for (i=0; i<N; i++) { 10783 ApplicationInfo info 10784 = (ApplicationInfo)apps.get(i); 10785 if (info != null && 10786 !info.packageName.equals("android")) { 10787 addAppLocked(info, false, null /* ABI override */); 10788 } 10789 } 10790 } 10791 } catch (RemoteException ex) { 10792 // pm is in same process, this will never happen. 10793 } 10794 } 10795 10796 // Start up initial activity. 10797 mBooting = true; 10798 startHomeActivityLocked(mCurrentUserId); 10799 10800 try { 10801 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10802 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 10803 + " data partition or your device will be unstable."); 10804 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 10805 } 10806 } catch (RemoteException e) { 10807 } 10808 10809 if (!Build.isFingerprintConsistent()) { 10810 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 10811 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 10812 } 10813 10814 long ident = Binder.clearCallingIdentity(); 10815 try { 10816 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10817 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10818 | Intent.FLAG_RECEIVER_FOREGROUND); 10819 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10820 broadcastIntentLocked(null, null, intent, 10821 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10822 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10823 intent = new Intent(Intent.ACTION_USER_STARTING); 10824 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10825 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10826 broadcastIntentLocked(null, null, intent, 10827 null, new IIntentReceiver.Stub() { 10828 @Override 10829 public void performReceive(Intent intent, int resultCode, String data, 10830 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10831 throws RemoteException { 10832 } 10833 }, 0, null, null, 10834 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10835 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10836 } catch (Throwable t) { 10837 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10838 } finally { 10839 Binder.restoreCallingIdentity(ident); 10840 } 10841 mStackSupervisor.resumeTopActivitiesLocked(); 10842 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10843 } 10844 } 10845 10846 private boolean makeAppCrashingLocked(ProcessRecord app, 10847 String shortMsg, String longMsg, String stackTrace) { 10848 app.crashing = true; 10849 app.crashingReport = generateProcessError(app, 10850 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10851 startAppProblemLocked(app); 10852 app.stopFreezingAllLocked(); 10853 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace); 10854 } 10855 10856 private void makeAppNotRespondingLocked(ProcessRecord app, 10857 String activity, String shortMsg, String longMsg) { 10858 app.notResponding = true; 10859 app.notRespondingReport = generateProcessError(app, 10860 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10861 activity, shortMsg, longMsg, null); 10862 startAppProblemLocked(app); 10863 app.stopFreezingAllLocked(); 10864 } 10865 10866 /** 10867 * Generate a process error record, suitable for attachment to a ProcessRecord. 10868 * 10869 * @param app The ProcessRecord in which the error occurred. 10870 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10871 * ActivityManager.AppErrorStateInfo 10872 * @param activity The activity associated with the crash, if known. 10873 * @param shortMsg Short message describing the crash. 10874 * @param longMsg Long message describing the crash. 10875 * @param stackTrace Full crash stack trace, may be null. 10876 * 10877 * @return Returns a fully-formed AppErrorStateInfo record. 10878 */ 10879 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10880 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10881 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10882 10883 report.condition = condition; 10884 report.processName = app.processName; 10885 report.pid = app.pid; 10886 report.uid = app.info.uid; 10887 report.tag = activity; 10888 report.shortMsg = shortMsg; 10889 report.longMsg = longMsg; 10890 report.stackTrace = stackTrace; 10891 10892 return report; 10893 } 10894 10895 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10896 synchronized (this) { 10897 app.crashing = false; 10898 app.crashingReport = null; 10899 app.notResponding = false; 10900 app.notRespondingReport = null; 10901 if (app.anrDialog == fromDialog) { 10902 app.anrDialog = null; 10903 } 10904 if (app.waitDialog == fromDialog) { 10905 app.waitDialog = null; 10906 } 10907 if (app.pid > 0 && app.pid != MY_PID) { 10908 handleAppCrashLocked(app, "user-terminated" /*reason*/, 10909 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/); 10910 app.kill("user request after error", true); 10911 } 10912 } 10913 } 10914 10915 private boolean handleAppCrashLocked(ProcessRecord app, String reason, 10916 String shortMsg, String longMsg, String stackTrace) { 10917 long now = SystemClock.uptimeMillis(); 10918 10919 Long crashTime; 10920 if (!app.isolated) { 10921 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10922 } else { 10923 crashTime = null; 10924 } 10925 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10926 // This process loses! 10927 Slog.w(TAG, "Process " + app.info.processName 10928 + " has crashed too many times: killing!"); 10929 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10930 app.userId, app.info.processName, app.uid); 10931 mStackSupervisor.handleAppCrashLocked(app); 10932 if (!app.persistent) { 10933 // We don't want to start this process again until the user 10934 // explicitly does so... but for persistent process, we really 10935 // need to keep it running. If a persistent process is actually 10936 // repeatedly crashing, then badness for everyone. 10937 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10938 app.info.processName); 10939 if (!app.isolated) { 10940 // XXX We don't have a way to mark isolated processes 10941 // as bad, since they don't have a peristent identity. 10942 mBadProcesses.put(app.info.processName, app.uid, 10943 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10944 mProcessCrashTimes.remove(app.info.processName, app.uid); 10945 } 10946 app.bad = true; 10947 app.removed = true; 10948 // Don't let services in this process be restarted and potentially 10949 // annoy the user repeatedly. Unless it is persistent, since those 10950 // processes run critical code. 10951 removeProcessLocked(app, false, false, "crash"); 10952 mStackSupervisor.resumeTopActivitiesLocked(); 10953 return false; 10954 } 10955 mStackSupervisor.resumeTopActivitiesLocked(); 10956 } else { 10957 mStackSupervisor.finishTopRunningActivityLocked(app, reason); 10958 } 10959 10960 // Bump up the crash count of any services currently running in the proc. 10961 for (int i=app.services.size()-1; i>=0; i--) { 10962 // Any services running in the application need to be placed 10963 // back in the pending list. 10964 ServiceRecord sr = app.services.valueAt(i); 10965 sr.crashCount++; 10966 } 10967 10968 // If the crashing process is what we consider to be the "home process" and it has been 10969 // replaced by a third-party app, clear the package preferred activities from packages 10970 // with a home activity running in the process to prevent a repeatedly crashing app 10971 // from blocking the user to manually clear the list. 10972 final ArrayList<ActivityRecord> activities = app.activities; 10973 if (app == mHomeProcess && activities.size() > 0 10974 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10975 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10976 final ActivityRecord r = activities.get(activityNdx); 10977 if (r.isHomeActivity()) { 10978 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10979 try { 10980 ActivityThread.getPackageManager() 10981 .clearPackagePreferredActivities(r.packageName); 10982 } catch (RemoteException c) { 10983 // pm is in same process, this will never happen. 10984 } 10985 } 10986 } 10987 } 10988 10989 if (!app.isolated) { 10990 // XXX Can't keep track of crash times for isolated processes, 10991 // because they don't have a perisistent identity. 10992 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10993 } 10994 10995 if (app.crashHandler != null) mHandler.post(app.crashHandler); 10996 return true; 10997 } 10998 10999 void startAppProblemLocked(ProcessRecord app) { 11000 // If this app is not running under the current user, then we 11001 // can't give it a report button because that would require 11002 // launching the report UI under a different user. 11003 app.errorReportReceiver = null; 11004 11005 for (int userId : mCurrentProfileIds) { 11006 if (app.userId == userId) { 11007 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11008 mContext, app.info.packageName, app.info.flags); 11009 } 11010 } 11011 skipCurrentReceiverLocked(app); 11012 } 11013 11014 void skipCurrentReceiverLocked(ProcessRecord app) { 11015 for (BroadcastQueue queue : mBroadcastQueues) { 11016 queue.skipCurrentReceiverLocked(app); 11017 } 11018 } 11019 11020 /** 11021 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11022 * The application process will exit immediately after this call returns. 11023 * @param app object of the crashing app, null for the system server 11024 * @param crashInfo describing the exception 11025 */ 11026 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11027 ProcessRecord r = findAppProcess(app, "Crash"); 11028 final String processName = app == null ? "system_server" 11029 : (r == null ? "unknown" : r.processName); 11030 11031 handleApplicationCrashInner("crash", r, processName, crashInfo); 11032 } 11033 11034 /* Native crash reporting uses this inner version because it needs to be somewhat 11035 * decoupled from the AM-managed cleanup lifecycle 11036 */ 11037 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11038 ApplicationErrorReport.CrashInfo crashInfo) { 11039 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11040 UserHandle.getUserId(Binder.getCallingUid()), processName, 11041 r == null ? -1 : r.info.flags, 11042 crashInfo.exceptionClassName, 11043 crashInfo.exceptionMessage, 11044 crashInfo.throwFileName, 11045 crashInfo.throwLineNumber); 11046 11047 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11048 11049 crashApplication(r, crashInfo); 11050 } 11051 11052 public void handleApplicationStrictModeViolation( 11053 IBinder app, 11054 int violationMask, 11055 StrictMode.ViolationInfo info) { 11056 ProcessRecord r = findAppProcess(app, "StrictMode"); 11057 if (r == null) { 11058 return; 11059 } 11060 11061 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11062 Integer stackFingerprint = info.hashCode(); 11063 boolean logIt = true; 11064 synchronized (mAlreadyLoggedViolatedStacks) { 11065 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11066 logIt = false; 11067 // TODO: sub-sample into EventLog for these, with 11068 // the info.durationMillis? Then we'd get 11069 // the relative pain numbers, without logging all 11070 // the stack traces repeatedly. We'd want to do 11071 // likewise in the client code, which also does 11072 // dup suppression, before the Binder call. 11073 } else { 11074 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11075 mAlreadyLoggedViolatedStacks.clear(); 11076 } 11077 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11078 } 11079 } 11080 if (logIt) { 11081 logStrictModeViolationToDropBox(r, info); 11082 } 11083 } 11084 11085 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11086 AppErrorResult result = new AppErrorResult(); 11087 synchronized (this) { 11088 final long origId = Binder.clearCallingIdentity(); 11089 11090 Message msg = Message.obtain(); 11091 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11092 HashMap<String, Object> data = new HashMap<String, Object>(); 11093 data.put("result", result); 11094 data.put("app", r); 11095 data.put("violationMask", violationMask); 11096 data.put("info", info); 11097 msg.obj = data; 11098 mHandler.sendMessage(msg); 11099 11100 Binder.restoreCallingIdentity(origId); 11101 } 11102 int res = result.get(); 11103 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11104 } 11105 } 11106 11107 // Depending on the policy in effect, there could be a bunch of 11108 // these in quick succession so we try to batch these together to 11109 // minimize disk writes, number of dropbox entries, and maximize 11110 // compression, by having more fewer, larger records. 11111 private void logStrictModeViolationToDropBox( 11112 ProcessRecord process, 11113 StrictMode.ViolationInfo info) { 11114 if (info == null) { 11115 return; 11116 } 11117 final boolean isSystemApp = process == null || 11118 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11119 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11120 final String processName = process == null ? "unknown" : process.processName; 11121 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11122 final DropBoxManager dbox = (DropBoxManager) 11123 mContext.getSystemService(Context.DROPBOX_SERVICE); 11124 11125 // Exit early if the dropbox isn't configured to accept this report type. 11126 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11127 11128 boolean bufferWasEmpty; 11129 boolean needsFlush; 11130 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11131 synchronized (sb) { 11132 bufferWasEmpty = sb.length() == 0; 11133 appendDropBoxProcessHeaders(process, processName, sb); 11134 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11135 sb.append("System-App: ").append(isSystemApp).append("\n"); 11136 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11137 if (info.violationNumThisLoop != 0) { 11138 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11139 } 11140 if (info.numAnimationsRunning != 0) { 11141 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11142 } 11143 if (info.broadcastIntentAction != null) { 11144 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11145 } 11146 if (info.durationMillis != -1) { 11147 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11148 } 11149 if (info.numInstances != -1) { 11150 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11151 } 11152 if (info.tags != null) { 11153 for (String tag : info.tags) { 11154 sb.append("Span-Tag: ").append(tag).append("\n"); 11155 } 11156 } 11157 sb.append("\n"); 11158 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11159 sb.append(info.crashInfo.stackTrace); 11160 sb.append("\n"); 11161 } 11162 if (info.message != null) { 11163 sb.append(info.message); 11164 sb.append("\n"); 11165 } 11166 11167 // Only buffer up to ~64k. Various logging bits truncate 11168 // things at 128k. 11169 needsFlush = (sb.length() > 64 * 1024); 11170 } 11171 11172 // Flush immediately if the buffer's grown too large, or this 11173 // is a non-system app. Non-system apps are isolated with a 11174 // different tag & policy and not batched. 11175 // 11176 // Batching is useful during internal testing with 11177 // StrictMode settings turned up high. Without batching, 11178 // thousands of separate files could be created on boot. 11179 if (!isSystemApp || needsFlush) { 11180 new Thread("Error dump: " + dropboxTag) { 11181 @Override 11182 public void run() { 11183 String report; 11184 synchronized (sb) { 11185 report = sb.toString(); 11186 sb.delete(0, sb.length()); 11187 sb.trimToSize(); 11188 } 11189 if (report.length() != 0) { 11190 dbox.addText(dropboxTag, report); 11191 } 11192 } 11193 }.start(); 11194 return; 11195 } 11196 11197 // System app batching: 11198 if (!bufferWasEmpty) { 11199 // An existing dropbox-writing thread is outstanding, so 11200 // we don't need to start it up. The existing thread will 11201 // catch the buffer appends we just did. 11202 return; 11203 } 11204 11205 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11206 // (After this point, we shouldn't access AMS internal data structures.) 11207 new Thread("Error dump: " + dropboxTag) { 11208 @Override 11209 public void run() { 11210 // 5 second sleep to let stacks arrive and be batched together 11211 try { 11212 Thread.sleep(5000); // 5 seconds 11213 } catch (InterruptedException e) {} 11214 11215 String errorReport; 11216 synchronized (mStrictModeBuffer) { 11217 errorReport = mStrictModeBuffer.toString(); 11218 if (errorReport.length() == 0) { 11219 return; 11220 } 11221 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11222 mStrictModeBuffer.trimToSize(); 11223 } 11224 dbox.addText(dropboxTag, errorReport); 11225 } 11226 }.start(); 11227 } 11228 11229 /** 11230 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11231 * @param app object of the crashing app, null for the system server 11232 * @param tag reported by the caller 11233 * @param system whether this wtf is coming from the system 11234 * @param crashInfo describing the context of the error 11235 * @return true if the process should exit immediately (WTF is fatal) 11236 */ 11237 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11238 final ApplicationErrorReport.CrashInfo crashInfo) { 11239 final int callingUid = Binder.getCallingUid(); 11240 final int callingPid = Binder.getCallingPid(); 11241 11242 if (system) { 11243 // If this is coming from the system, we could very well have low-level 11244 // system locks held, so we want to do this all asynchronously. And we 11245 // never want this to become fatal, so there is that too. 11246 mHandler.post(new Runnable() { 11247 @Override public void run() { 11248 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11249 } 11250 }); 11251 return false; 11252 } 11253 11254 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11255 crashInfo); 11256 11257 if (r != null && r.pid != Process.myPid() && 11258 Settings.Global.getInt(mContext.getContentResolver(), 11259 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11260 crashApplication(r, crashInfo); 11261 return true; 11262 } else { 11263 return false; 11264 } 11265 } 11266 11267 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11268 final ApplicationErrorReport.CrashInfo crashInfo) { 11269 final ProcessRecord r = findAppProcess(app, "WTF"); 11270 final String processName = app == null ? "system_server" 11271 : (r == null ? "unknown" : r.processName); 11272 11273 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11274 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11275 11276 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11277 11278 return r; 11279 } 11280 11281 /** 11282 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11283 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11284 */ 11285 private ProcessRecord findAppProcess(IBinder app, String reason) { 11286 if (app == null) { 11287 return null; 11288 } 11289 11290 synchronized (this) { 11291 final int NP = mProcessNames.getMap().size(); 11292 for (int ip=0; ip<NP; ip++) { 11293 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11294 final int NA = apps.size(); 11295 for (int ia=0; ia<NA; ia++) { 11296 ProcessRecord p = apps.valueAt(ia); 11297 if (p.thread != null && p.thread.asBinder() == app) { 11298 return p; 11299 } 11300 } 11301 } 11302 11303 Slog.w(TAG, "Can't find mystery application for " + reason 11304 + " from pid=" + Binder.getCallingPid() 11305 + " uid=" + Binder.getCallingUid() + ": " + app); 11306 return null; 11307 } 11308 } 11309 11310 /** 11311 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11312 * to append various headers to the dropbox log text. 11313 */ 11314 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11315 StringBuilder sb) { 11316 // Watchdog thread ends up invoking this function (with 11317 // a null ProcessRecord) to add the stack file to dropbox. 11318 // Do not acquire a lock on this (am) in such cases, as it 11319 // could cause a potential deadlock, if and when watchdog 11320 // is invoked due to unavailability of lock on am and it 11321 // would prevent watchdog from killing system_server. 11322 if (process == null) { 11323 sb.append("Process: ").append(processName).append("\n"); 11324 return; 11325 } 11326 // Note: ProcessRecord 'process' is guarded by the service 11327 // instance. (notably process.pkgList, which could otherwise change 11328 // concurrently during execution of this method) 11329 synchronized (this) { 11330 sb.append("Process: ").append(processName).append("\n"); 11331 int flags = process.info.flags; 11332 IPackageManager pm = AppGlobals.getPackageManager(); 11333 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11334 for (int ip=0; ip<process.pkgList.size(); ip++) { 11335 String pkg = process.pkgList.keyAt(ip); 11336 sb.append("Package: ").append(pkg); 11337 try { 11338 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11339 if (pi != null) { 11340 sb.append(" v").append(pi.versionCode); 11341 if (pi.versionName != null) { 11342 sb.append(" (").append(pi.versionName).append(")"); 11343 } 11344 } 11345 } catch (RemoteException e) { 11346 Slog.e(TAG, "Error getting package info: " + pkg, e); 11347 } 11348 sb.append("\n"); 11349 } 11350 } 11351 } 11352 11353 private static String processClass(ProcessRecord process) { 11354 if (process == null || process.pid == MY_PID) { 11355 return "system_server"; 11356 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11357 return "system_app"; 11358 } else { 11359 return "data_app"; 11360 } 11361 } 11362 11363 /** 11364 * Write a description of an error (crash, WTF, ANR) to the drop box. 11365 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11366 * @param process which caused the error, null means the system server 11367 * @param activity which triggered the error, null if unknown 11368 * @param parent activity related to the error, null if unknown 11369 * @param subject line related to the error, null if absent 11370 * @param report in long form describing the error, null if absent 11371 * @param logFile to include in the report, null if none 11372 * @param crashInfo giving an application stack trace, null if absent 11373 */ 11374 public void addErrorToDropBox(String eventType, 11375 ProcessRecord process, String processName, ActivityRecord activity, 11376 ActivityRecord parent, String subject, 11377 final String report, final File logFile, 11378 final ApplicationErrorReport.CrashInfo crashInfo) { 11379 // NOTE -- this must never acquire the ActivityManagerService lock, 11380 // otherwise the watchdog may be prevented from resetting the system. 11381 11382 final String dropboxTag = processClass(process) + "_" + eventType; 11383 final DropBoxManager dbox = (DropBoxManager) 11384 mContext.getSystemService(Context.DROPBOX_SERVICE); 11385 11386 // Exit early if the dropbox isn't configured to accept this report type. 11387 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11388 11389 final StringBuilder sb = new StringBuilder(1024); 11390 appendDropBoxProcessHeaders(process, processName, sb); 11391 if (activity != null) { 11392 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11393 } 11394 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11395 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11396 } 11397 if (parent != null && parent != activity) { 11398 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11399 } 11400 if (subject != null) { 11401 sb.append("Subject: ").append(subject).append("\n"); 11402 } 11403 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11404 if (Debug.isDebuggerConnected()) { 11405 sb.append("Debugger: Connected\n"); 11406 } 11407 sb.append("\n"); 11408 11409 // Do the rest in a worker thread to avoid blocking the caller on I/O 11410 // (After this point, we shouldn't access AMS internal data structures.) 11411 Thread worker = new Thread("Error dump: " + dropboxTag) { 11412 @Override 11413 public void run() { 11414 if (report != null) { 11415 sb.append(report); 11416 } 11417 if (logFile != null) { 11418 try { 11419 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11420 "\n\n[[TRUNCATED]]")); 11421 } catch (IOException e) { 11422 Slog.e(TAG, "Error reading " + logFile, e); 11423 } 11424 } 11425 if (crashInfo != null && crashInfo.stackTrace != null) { 11426 sb.append(crashInfo.stackTrace); 11427 } 11428 11429 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11430 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11431 if (lines > 0) { 11432 sb.append("\n"); 11433 11434 // Merge several logcat streams, and take the last N lines 11435 InputStreamReader input = null; 11436 try { 11437 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11438 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11439 "-b", "crash", 11440 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11441 11442 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11443 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11444 input = new InputStreamReader(logcat.getInputStream()); 11445 11446 int num; 11447 char[] buf = new char[8192]; 11448 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11449 } catch (IOException e) { 11450 Slog.e(TAG, "Error running logcat", e); 11451 } finally { 11452 if (input != null) try { input.close(); } catch (IOException e) {} 11453 } 11454 } 11455 11456 dbox.addText(dropboxTag, sb.toString()); 11457 } 11458 }; 11459 11460 if (process == null) { 11461 // If process is null, we are being called from some internal code 11462 // and may be about to die -- run this synchronously. 11463 worker.run(); 11464 } else { 11465 worker.start(); 11466 } 11467 } 11468 11469 /** 11470 * Bring up the "unexpected error" dialog box for a crashing app. 11471 * Deal with edge cases (intercepts from instrumented applications, 11472 * ActivityController, error intent receivers, that sort of thing). 11473 * @param r the application crashing 11474 * @param crashInfo describing the failure 11475 */ 11476 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11477 long timeMillis = System.currentTimeMillis(); 11478 String shortMsg = crashInfo.exceptionClassName; 11479 String longMsg = crashInfo.exceptionMessage; 11480 String stackTrace = crashInfo.stackTrace; 11481 if (shortMsg != null && longMsg != null) { 11482 longMsg = shortMsg + ": " + longMsg; 11483 } else if (shortMsg != null) { 11484 longMsg = shortMsg; 11485 } 11486 11487 AppErrorResult result = new AppErrorResult(); 11488 synchronized (this) { 11489 if (mController != null) { 11490 try { 11491 String name = r != null ? r.processName : null; 11492 int pid = r != null ? r.pid : Binder.getCallingPid(); 11493 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11494 if (!mController.appCrashed(name, pid, 11495 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11496 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11497 && "Native crash".equals(crashInfo.exceptionClassName)) { 11498 Slog.w(TAG, "Skip killing native crashed app " + name 11499 + "(" + pid + ") during testing"); 11500 } else { 11501 Slog.w(TAG, "Force-killing crashed app " + name 11502 + " at watcher's request"); 11503 if (r != null) { 11504 r.kill("crash", true); 11505 } else { 11506 // Huh. 11507 Process.killProcess(pid); 11508 Process.killProcessGroup(uid, pid); 11509 } 11510 } 11511 return; 11512 } 11513 } catch (RemoteException e) { 11514 mController = null; 11515 Watchdog.getInstance().setActivityController(null); 11516 } 11517 } 11518 11519 final long origId = Binder.clearCallingIdentity(); 11520 11521 // If this process is running instrumentation, finish it. 11522 if (r != null && r.instrumentationClass != null) { 11523 Slog.w(TAG, "Error in app " + r.processName 11524 + " running instrumentation " + r.instrumentationClass + ":"); 11525 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11526 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11527 Bundle info = new Bundle(); 11528 info.putString("shortMsg", shortMsg); 11529 info.putString("longMsg", longMsg); 11530 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11531 Binder.restoreCallingIdentity(origId); 11532 return; 11533 } 11534 11535 // Log crash in battery stats. 11536 if (r != null) { 11537 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 11538 } 11539 11540 // If we can't identify the process or it's already exceeded its crash quota, 11541 // quit right away without showing a crash dialog. 11542 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11543 Binder.restoreCallingIdentity(origId); 11544 return; 11545 } 11546 11547 Message msg = Message.obtain(); 11548 msg.what = SHOW_ERROR_MSG; 11549 HashMap data = new HashMap(); 11550 data.put("result", result); 11551 data.put("app", r); 11552 msg.obj = data; 11553 mHandler.sendMessage(msg); 11554 11555 Binder.restoreCallingIdentity(origId); 11556 } 11557 11558 int res = result.get(); 11559 11560 Intent appErrorIntent = null; 11561 synchronized (this) { 11562 if (r != null && !r.isolated) { 11563 // XXX Can't keep track of crash time for isolated processes, 11564 // since they don't have a persistent identity. 11565 mProcessCrashTimes.put(r.info.processName, r.uid, 11566 SystemClock.uptimeMillis()); 11567 } 11568 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11569 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11570 } 11571 } 11572 11573 if (appErrorIntent != null) { 11574 try { 11575 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11576 } catch (ActivityNotFoundException e) { 11577 Slog.w(TAG, "bug report receiver dissappeared", e); 11578 } 11579 } 11580 } 11581 11582 Intent createAppErrorIntentLocked(ProcessRecord r, 11583 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11584 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11585 if (report == null) { 11586 return null; 11587 } 11588 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11589 result.setComponent(r.errorReportReceiver); 11590 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11591 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11592 return result; 11593 } 11594 11595 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11596 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11597 if (r.errorReportReceiver == null) { 11598 return null; 11599 } 11600 11601 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11602 return null; 11603 } 11604 11605 ApplicationErrorReport report = new ApplicationErrorReport(); 11606 report.packageName = r.info.packageName; 11607 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11608 report.processName = r.processName; 11609 report.time = timeMillis; 11610 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11611 11612 if (r.crashing || r.forceCrashReport) { 11613 report.type = ApplicationErrorReport.TYPE_CRASH; 11614 report.crashInfo = crashInfo; 11615 } else if (r.notResponding) { 11616 report.type = ApplicationErrorReport.TYPE_ANR; 11617 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11618 11619 report.anrInfo.activity = r.notRespondingReport.tag; 11620 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11621 report.anrInfo.info = r.notRespondingReport.longMsg; 11622 } 11623 11624 return report; 11625 } 11626 11627 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11628 enforceNotIsolatedCaller("getProcessesInErrorState"); 11629 // assume our apps are happy - lazy create the list 11630 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11631 11632 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11633 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11634 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11635 11636 synchronized (this) { 11637 11638 // iterate across all processes 11639 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11640 ProcessRecord app = mLruProcesses.get(i); 11641 if (!allUsers && app.userId != userId) { 11642 continue; 11643 } 11644 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11645 // This one's in trouble, so we'll generate a report for it 11646 // crashes are higher priority (in case there's a crash *and* an anr) 11647 ActivityManager.ProcessErrorStateInfo report = null; 11648 if (app.crashing) { 11649 report = app.crashingReport; 11650 } else if (app.notResponding) { 11651 report = app.notRespondingReport; 11652 } 11653 11654 if (report != null) { 11655 if (errList == null) { 11656 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11657 } 11658 errList.add(report); 11659 } else { 11660 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11661 " crashing = " + app.crashing + 11662 " notResponding = " + app.notResponding); 11663 } 11664 } 11665 } 11666 } 11667 11668 return errList; 11669 } 11670 11671 static int procStateToImportance(int procState, int memAdj, 11672 ActivityManager.RunningAppProcessInfo currApp) { 11673 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11674 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11675 currApp.lru = memAdj; 11676 } else { 11677 currApp.lru = 0; 11678 } 11679 return imp; 11680 } 11681 11682 private void fillInProcMemInfo(ProcessRecord app, 11683 ActivityManager.RunningAppProcessInfo outInfo) { 11684 outInfo.pid = app.pid; 11685 outInfo.uid = app.info.uid; 11686 if (mHeavyWeightProcess == app) { 11687 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11688 } 11689 if (app.persistent) { 11690 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11691 } 11692 if (app.activities.size() > 0) { 11693 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11694 } 11695 outInfo.lastTrimLevel = app.trimMemoryLevel; 11696 int adj = app.curAdj; 11697 int procState = app.curProcState; 11698 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11699 outInfo.importanceReasonCode = app.adjTypeCode; 11700 outInfo.processState = app.curProcState; 11701 } 11702 11703 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11704 enforceNotIsolatedCaller("getRunningAppProcesses"); 11705 // Lazy instantiation of list 11706 List<ActivityManager.RunningAppProcessInfo> runList = null; 11707 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11708 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11709 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11710 synchronized (this) { 11711 // Iterate across all processes 11712 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11713 ProcessRecord app = mLruProcesses.get(i); 11714 if (!allUsers && app.userId != userId) { 11715 continue; 11716 } 11717 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11718 // Generate process state info for running application 11719 ActivityManager.RunningAppProcessInfo currApp = 11720 new ActivityManager.RunningAppProcessInfo(app.processName, 11721 app.pid, app.getPackageList()); 11722 fillInProcMemInfo(app, currApp); 11723 if (app.adjSource instanceof ProcessRecord) { 11724 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11725 currApp.importanceReasonImportance = 11726 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11727 app.adjSourceProcState); 11728 } else if (app.adjSource instanceof ActivityRecord) { 11729 ActivityRecord r = (ActivityRecord)app.adjSource; 11730 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11731 } 11732 if (app.adjTarget instanceof ComponentName) { 11733 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11734 } 11735 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11736 // + " lru=" + currApp.lru); 11737 if (runList == null) { 11738 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11739 } 11740 runList.add(currApp); 11741 } 11742 } 11743 } 11744 return runList; 11745 } 11746 11747 public List<ApplicationInfo> getRunningExternalApplications() { 11748 enforceNotIsolatedCaller("getRunningExternalApplications"); 11749 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11750 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11751 if (runningApps != null && runningApps.size() > 0) { 11752 Set<String> extList = new HashSet<String>(); 11753 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11754 if (app.pkgList != null) { 11755 for (String pkg : app.pkgList) { 11756 extList.add(pkg); 11757 } 11758 } 11759 } 11760 IPackageManager pm = AppGlobals.getPackageManager(); 11761 for (String pkg : extList) { 11762 try { 11763 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11764 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11765 retList.add(info); 11766 } 11767 } catch (RemoteException e) { 11768 } 11769 } 11770 } 11771 return retList; 11772 } 11773 11774 @Override 11775 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11776 enforceNotIsolatedCaller("getMyMemoryState"); 11777 synchronized (this) { 11778 ProcessRecord proc; 11779 synchronized (mPidsSelfLocked) { 11780 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11781 } 11782 fillInProcMemInfo(proc, outInfo); 11783 } 11784 } 11785 11786 @Override 11787 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11788 if (checkCallingPermission(android.Manifest.permission.DUMP) 11789 != PackageManager.PERMISSION_GRANTED) { 11790 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11791 + Binder.getCallingPid() 11792 + ", uid=" + Binder.getCallingUid() 11793 + " without permission " 11794 + android.Manifest.permission.DUMP); 11795 return; 11796 } 11797 11798 boolean dumpAll = false; 11799 boolean dumpClient = false; 11800 String dumpPackage = null; 11801 11802 int opti = 0; 11803 while (opti < args.length) { 11804 String opt = args[opti]; 11805 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11806 break; 11807 } 11808 opti++; 11809 if ("-a".equals(opt)) { 11810 dumpAll = true; 11811 } else if ("-c".equals(opt)) { 11812 dumpClient = true; 11813 } else if ("-p".equals(opt)) { 11814 if (opti < args.length) { 11815 dumpPackage = args[opti]; 11816 opti++; 11817 } else { 11818 pw.println("Error: -p option requires package argument"); 11819 return; 11820 } 11821 dumpClient = true; 11822 } else if ("-h".equals(opt)) { 11823 pw.println("Activity manager dump options:"); 11824 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 11825 pw.println(" cmd may be one of:"); 11826 pw.println(" a[ctivities]: activity stack state"); 11827 pw.println(" r[recents]: recent activities state"); 11828 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11829 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11830 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11831 pw.println(" o[om]: out of memory management"); 11832 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11833 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11834 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11835 pw.println(" as[sociations]: tracked app associations"); 11836 pw.println(" service [COMP_SPEC]: service client-side state"); 11837 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11838 pw.println(" all: dump all activities"); 11839 pw.println(" top: dump the top activity"); 11840 pw.println(" write: write all pending state to storage"); 11841 pw.println(" track-associations: enable association tracking"); 11842 pw.println(" untrack-associations: disable and clear association tracking"); 11843 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11844 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11845 pw.println(" a partial substring in a component name, a"); 11846 pw.println(" hex object identifier."); 11847 pw.println(" -a: include all available server state."); 11848 pw.println(" -c: include client state."); 11849 pw.println(" -p: limit output to given package."); 11850 return; 11851 } else { 11852 pw.println("Unknown argument: " + opt + "; use -h for help"); 11853 } 11854 } 11855 11856 long origId = Binder.clearCallingIdentity(); 11857 boolean more = false; 11858 // Is the caller requesting to dump a particular piece of data? 11859 if (opti < args.length) { 11860 String cmd = args[opti]; 11861 opti++; 11862 if ("activities".equals(cmd) || "a".equals(cmd)) { 11863 synchronized (this) { 11864 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 11865 } 11866 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 11867 synchronized (this) { 11868 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 11869 } 11870 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11871 String[] newArgs; 11872 String name; 11873 if (opti >= args.length) { 11874 name = null; 11875 newArgs = EMPTY_STRING_ARRAY; 11876 } else { 11877 dumpPackage = args[opti]; 11878 opti++; 11879 newArgs = new String[args.length - opti]; 11880 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11881 args.length - opti); 11882 } 11883 synchronized (this) { 11884 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 11885 } 11886 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11887 String[] newArgs; 11888 String name; 11889 if (opti >= args.length) { 11890 name = null; 11891 newArgs = EMPTY_STRING_ARRAY; 11892 } else { 11893 dumpPackage = args[opti]; 11894 opti++; 11895 newArgs = new String[args.length - opti]; 11896 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11897 args.length - opti); 11898 } 11899 synchronized (this) { 11900 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 11901 } 11902 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11903 String[] newArgs; 11904 String name; 11905 if (opti >= args.length) { 11906 name = null; 11907 newArgs = EMPTY_STRING_ARRAY; 11908 } else { 11909 dumpPackage = args[opti]; 11910 opti++; 11911 newArgs = new String[args.length - opti]; 11912 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11913 args.length - opti); 11914 } 11915 synchronized (this) { 11916 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 11917 } 11918 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11919 synchronized (this) { 11920 dumpOomLocked(fd, pw, args, opti, true); 11921 } 11922 } else if ("provider".equals(cmd)) { 11923 String[] newArgs; 11924 String name; 11925 if (opti >= args.length) { 11926 name = null; 11927 newArgs = EMPTY_STRING_ARRAY; 11928 } else { 11929 name = args[opti]; 11930 opti++; 11931 newArgs = new String[args.length - opti]; 11932 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11933 } 11934 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11935 pw.println("No providers match: " + name); 11936 pw.println("Use -h for help."); 11937 } 11938 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11939 synchronized (this) { 11940 dumpProvidersLocked(fd, pw, args, opti, true, null); 11941 } 11942 } else if ("service".equals(cmd)) { 11943 String[] newArgs; 11944 String name; 11945 if (opti >= args.length) { 11946 name = null; 11947 newArgs = EMPTY_STRING_ARRAY; 11948 } else { 11949 name = args[opti]; 11950 opti++; 11951 newArgs = new String[args.length - opti]; 11952 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11953 args.length - opti); 11954 } 11955 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11956 pw.println("No services match: " + name); 11957 pw.println("Use -h for help."); 11958 } 11959 } else if ("package".equals(cmd)) { 11960 String[] newArgs; 11961 if (opti >= args.length) { 11962 pw.println("package: no package name specified"); 11963 pw.println("Use -h for help."); 11964 } else { 11965 dumpPackage = args[opti]; 11966 opti++; 11967 newArgs = new String[args.length - opti]; 11968 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11969 args.length - opti); 11970 args = newArgs; 11971 opti = 0; 11972 more = true; 11973 } 11974 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 11975 synchronized (this) { 11976 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 11977 } 11978 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11979 synchronized (this) { 11980 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 11981 } 11982 } else if ("write".equals(cmd)) { 11983 mTaskPersister.flush(); 11984 pw.println("All tasks persisted."); 11985 return; 11986 } else if ("track-associations".equals(cmd)) { 11987 synchronized (this) { 11988 if (!mTrackingAssociations) { 11989 mTrackingAssociations = true; 11990 pw.println("Association tracking started."); 11991 } else { 11992 pw.println("Association tracking already enabled."); 11993 } 11994 } 11995 return; 11996 } else if ("untrack-associations".equals(cmd)) { 11997 synchronized (this) { 11998 if (mTrackingAssociations) { 11999 mTrackingAssociations = false; 12000 mAssociations.clear(); 12001 pw.println("Association tracking stopped."); 12002 } else { 12003 pw.println("Association tracking not running."); 12004 } 12005 } 12006 return; 12007 } else { 12008 // Dumping a single activity? 12009 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12010 pw.println("Bad activity command, or no activities match: " + cmd); 12011 pw.println("Use -h for help."); 12012 } 12013 } 12014 if (!more) { 12015 Binder.restoreCallingIdentity(origId); 12016 return; 12017 } 12018 } 12019 12020 // No piece of data specified, dump everything. 12021 synchronized (this) { 12022 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12023 pw.println(); 12024 if (dumpAll) { 12025 pw.println("-------------------------------------------------------------------------------"); 12026 } 12027 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12028 pw.println(); 12029 if (dumpAll) { 12030 pw.println("-------------------------------------------------------------------------------"); 12031 } 12032 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12033 pw.println(); 12034 if (dumpAll) { 12035 pw.println("-------------------------------------------------------------------------------"); 12036 } 12037 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12038 pw.println(); 12039 if (dumpAll) { 12040 pw.println("-------------------------------------------------------------------------------"); 12041 } 12042 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12043 pw.println(); 12044 if (dumpAll) { 12045 pw.println("-------------------------------------------------------------------------------"); 12046 } 12047 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12048 if (mAssociations.size() > 0) { 12049 pw.println(); 12050 if (dumpAll) { 12051 pw.println("-------------------------------------------------------------------------------"); 12052 } 12053 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12054 } 12055 pw.println(); 12056 if (dumpAll) { 12057 pw.println("-------------------------------------------------------------------------------"); 12058 } 12059 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12060 } 12061 Binder.restoreCallingIdentity(origId); 12062 } 12063 12064 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12065 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12066 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12067 12068 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12069 dumpPackage); 12070 boolean needSep = printedAnything; 12071 12072 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12073 dumpPackage, needSep, " mFocusedActivity: "); 12074 if (printed) { 12075 printedAnything = true; 12076 needSep = false; 12077 } 12078 12079 if (dumpPackage == null) { 12080 if (needSep) { 12081 pw.println(); 12082 } 12083 needSep = true; 12084 printedAnything = true; 12085 mStackSupervisor.dump(pw, " "); 12086 } 12087 12088 if (!printedAnything) { 12089 pw.println(" (nothing)"); 12090 } 12091 } 12092 12093 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12094 int opti, boolean dumpAll, String dumpPackage) { 12095 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12096 12097 boolean printedAnything = false; 12098 12099 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12100 boolean printedHeader = false; 12101 12102 final int N = mRecentTasks.size(); 12103 for (int i=0; i<N; i++) { 12104 TaskRecord tr = mRecentTasks.get(i); 12105 if (dumpPackage != null) { 12106 if (tr.realActivity == null || 12107 !dumpPackage.equals(tr.realActivity)) { 12108 continue; 12109 } 12110 } 12111 if (!printedHeader) { 12112 pw.println(" Recent tasks:"); 12113 printedHeader = true; 12114 printedAnything = true; 12115 } 12116 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12117 pw.println(tr); 12118 if (dumpAll) { 12119 mRecentTasks.get(i).dump(pw, " "); 12120 } 12121 } 12122 } 12123 12124 if (!printedAnything) { 12125 pw.println(" (nothing)"); 12126 } 12127 } 12128 12129 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12130 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12131 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12132 12133 int dumpUid = 0; 12134 if (dumpPackage != null) { 12135 IPackageManager pm = AppGlobals.getPackageManager(); 12136 try { 12137 dumpUid = pm.getPackageUid(dumpPackage, 0); 12138 } catch (RemoteException e) { 12139 } 12140 } 12141 12142 boolean printedAnything = false; 12143 12144 final long now = SystemClock.uptimeMillis(); 12145 12146 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12147 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12148 = mAssociations.valueAt(i1); 12149 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12150 SparseArray<ArrayMap<String, Association>> sourceUids 12151 = targetComponents.valueAt(i2); 12152 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12153 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12154 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12155 Association ass = sourceProcesses.valueAt(i4); 12156 if (dumpPackage != null) { 12157 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12158 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12159 continue; 12160 } 12161 } 12162 printedAnything = true; 12163 pw.print(" "); 12164 pw.print(ass.mTargetProcess); 12165 pw.print("/"); 12166 UserHandle.formatUid(pw, ass.mTargetUid); 12167 pw.print(" <- "); 12168 pw.print(ass.mSourceProcess); 12169 pw.print("/"); 12170 UserHandle.formatUid(pw, ass.mSourceUid); 12171 pw.println(); 12172 pw.print(" via "); 12173 pw.print(ass.mTargetComponent.flattenToShortString()); 12174 pw.println(); 12175 pw.print(" "); 12176 long dur = ass.mTime; 12177 if (ass.mNesting > 0) { 12178 dur += now - ass.mStartTime; 12179 } 12180 TimeUtils.formatDuration(dur, pw); 12181 pw.print(" ("); 12182 pw.print(ass.mCount); 12183 pw.println(" times)"); 12184 if (ass.mNesting > 0) { 12185 pw.print(" "); 12186 pw.print(" Currently active: "); 12187 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12188 pw.println(); 12189 } 12190 } 12191 } 12192 } 12193 12194 } 12195 12196 if (!printedAnything) { 12197 pw.println(" (nothing)"); 12198 } 12199 } 12200 12201 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12202 int opti, boolean dumpAll, String dumpPackage) { 12203 boolean needSep = false; 12204 boolean printedAnything = false; 12205 int numPers = 0; 12206 12207 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12208 12209 if (dumpAll) { 12210 final int NP = mProcessNames.getMap().size(); 12211 for (int ip=0; ip<NP; ip++) { 12212 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12213 final int NA = procs.size(); 12214 for (int ia=0; ia<NA; ia++) { 12215 ProcessRecord r = procs.valueAt(ia); 12216 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12217 continue; 12218 } 12219 if (!needSep) { 12220 pw.println(" All known processes:"); 12221 needSep = true; 12222 printedAnything = true; 12223 } 12224 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12225 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12226 pw.print(" "); pw.println(r); 12227 r.dump(pw, " "); 12228 if (r.persistent) { 12229 numPers++; 12230 } 12231 } 12232 } 12233 } 12234 12235 if (mIsolatedProcesses.size() > 0) { 12236 boolean printed = false; 12237 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12238 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12239 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12240 continue; 12241 } 12242 if (!printed) { 12243 if (needSep) { 12244 pw.println(); 12245 } 12246 pw.println(" Isolated process list (sorted by uid):"); 12247 printedAnything = true; 12248 printed = true; 12249 needSep = true; 12250 } 12251 pw.println(String.format("%sIsolated #%2d: %s", 12252 " ", i, r.toString())); 12253 } 12254 } 12255 12256 if (mLruProcesses.size() > 0) { 12257 if (needSep) { 12258 pw.println(); 12259 } 12260 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12261 pw.print(" total, non-act at "); 12262 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12263 pw.print(", non-svc at "); 12264 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12265 pw.println("):"); 12266 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12267 needSep = true; 12268 printedAnything = true; 12269 } 12270 12271 if (dumpAll || dumpPackage != null) { 12272 synchronized (mPidsSelfLocked) { 12273 boolean printed = false; 12274 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12275 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12276 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12277 continue; 12278 } 12279 if (!printed) { 12280 if (needSep) pw.println(); 12281 needSep = true; 12282 pw.println(" PID mappings:"); 12283 printed = true; 12284 printedAnything = true; 12285 } 12286 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12287 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12288 } 12289 } 12290 } 12291 12292 if (mForegroundProcesses.size() > 0) { 12293 synchronized (mPidsSelfLocked) { 12294 boolean printed = false; 12295 for (int i=0; i<mForegroundProcesses.size(); i++) { 12296 ProcessRecord r = mPidsSelfLocked.get( 12297 mForegroundProcesses.valueAt(i).pid); 12298 if (dumpPackage != null && (r == null 12299 || !r.pkgList.containsKey(dumpPackage))) { 12300 continue; 12301 } 12302 if (!printed) { 12303 if (needSep) pw.println(); 12304 needSep = true; 12305 pw.println(" Foreground Processes:"); 12306 printed = true; 12307 printedAnything = true; 12308 } 12309 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12310 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12311 } 12312 } 12313 } 12314 12315 if (mPersistentStartingProcesses.size() > 0) { 12316 if (needSep) pw.println(); 12317 needSep = true; 12318 printedAnything = true; 12319 pw.println(" Persisent processes that are starting:"); 12320 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12321 "Starting Norm", "Restarting PERS", dumpPackage); 12322 } 12323 12324 if (mRemovedProcesses.size() > 0) { 12325 if (needSep) pw.println(); 12326 needSep = true; 12327 printedAnything = true; 12328 pw.println(" Processes that are being removed:"); 12329 dumpProcessList(pw, this, mRemovedProcesses, " ", 12330 "Removed Norm", "Removed PERS", dumpPackage); 12331 } 12332 12333 if (mProcessesOnHold.size() > 0) { 12334 if (needSep) pw.println(); 12335 needSep = true; 12336 printedAnything = true; 12337 pw.println(" Processes that are on old until the system is ready:"); 12338 dumpProcessList(pw, this, mProcessesOnHold, " ", 12339 "OnHold Norm", "OnHold PERS", dumpPackage); 12340 } 12341 12342 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12343 12344 if (mProcessCrashTimes.getMap().size() > 0) { 12345 boolean printed = false; 12346 long now = SystemClock.uptimeMillis(); 12347 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12348 final int NP = pmap.size(); 12349 for (int ip=0; ip<NP; ip++) { 12350 String pname = pmap.keyAt(ip); 12351 SparseArray<Long> uids = pmap.valueAt(ip); 12352 final int N = uids.size(); 12353 for (int i=0; i<N; i++) { 12354 int puid = uids.keyAt(i); 12355 ProcessRecord r = mProcessNames.get(pname, puid); 12356 if (dumpPackage != null && (r == null 12357 || !r.pkgList.containsKey(dumpPackage))) { 12358 continue; 12359 } 12360 if (!printed) { 12361 if (needSep) pw.println(); 12362 needSep = true; 12363 pw.println(" Time since processes crashed:"); 12364 printed = true; 12365 printedAnything = true; 12366 } 12367 pw.print(" Process "); pw.print(pname); 12368 pw.print(" uid "); pw.print(puid); 12369 pw.print(": last crashed "); 12370 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12371 pw.println(" ago"); 12372 } 12373 } 12374 } 12375 12376 if (mBadProcesses.getMap().size() > 0) { 12377 boolean printed = false; 12378 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12379 final int NP = pmap.size(); 12380 for (int ip=0; ip<NP; ip++) { 12381 String pname = pmap.keyAt(ip); 12382 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12383 final int N = uids.size(); 12384 for (int i=0; i<N; i++) { 12385 int puid = uids.keyAt(i); 12386 ProcessRecord r = mProcessNames.get(pname, puid); 12387 if (dumpPackage != null && (r == null 12388 || !r.pkgList.containsKey(dumpPackage))) { 12389 continue; 12390 } 12391 if (!printed) { 12392 if (needSep) pw.println(); 12393 needSep = true; 12394 pw.println(" Bad processes:"); 12395 printedAnything = true; 12396 } 12397 BadProcessInfo info = uids.valueAt(i); 12398 pw.print(" Bad process "); pw.print(pname); 12399 pw.print(" uid "); pw.print(puid); 12400 pw.print(": crashed at time "); pw.println(info.time); 12401 if (info.shortMsg != null) { 12402 pw.print(" Short msg: "); pw.println(info.shortMsg); 12403 } 12404 if (info.longMsg != null) { 12405 pw.print(" Long msg: "); pw.println(info.longMsg); 12406 } 12407 if (info.stack != null) { 12408 pw.println(" Stack:"); 12409 int lastPos = 0; 12410 for (int pos=0; pos<info.stack.length(); pos++) { 12411 if (info.stack.charAt(pos) == '\n') { 12412 pw.print(" "); 12413 pw.write(info.stack, lastPos, pos-lastPos); 12414 pw.println(); 12415 lastPos = pos+1; 12416 } 12417 } 12418 if (lastPos < info.stack.length()) { 12419 pw.print(" "); 12420 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12421 pw.println(); 12422 } 12423 } 12424 } 12425 } 12426 } 12427 12428 if (dumpPackage == null) { 12429 pw.println(); 12430 needSep = false; 12431 pw.println(" mStartedUsers:"); 12432 for (int i=0; i<mStartedUsers.size(); i++) { 12433 UserStartedState uss = mStartedUsers.valueAt(i); 12434 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12435 pw.print(": "); uss.dump("", pw); 12436 } 12437 pw.print(" mStartedUserArray: ["); 12438 for (int i=0; i<mStartedUserArray.length; i++) { 12439 if (i > 0) pw.print(", "); 12440 pw.print(mStartedUserArray[i]); 12441 } 12442 pw.println("]"); 12443 pw.print(" mUserLru: ["); 12444 for (int i=0; i<mUserLru.size(); i++) { 12445 if (i > 0) pw.print(", "); 12446 pw.print(mUserLru.get(i)); 12447 } 12448 pw.println("]"); 12449 if (dumpAll) { 12450 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12451 } 12452 synchronized (mUserProfileGroupIdsSelfLocked) { 12453 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12454 pw.println(" mUserProfileGroupIds:"); 12455 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12456 pw.print(" User #"); 12457 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12458 pw.print(" -> profile #"); 12459 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12460 } 12461 } 12462 } 12463 } 12464 if (mHomeProcess != null && (dumpPackage == null 12465 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12466 if (needSep) { 12467 pw.println(); 12468 needSep = false; 12469 } 12470 pw.println(" mHomeProcess: " + mHomeProcess); 12471 } 12472 if (mPreviousProcess != null && (dumpPackage == null 12473 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12474 if (needSep) { 12475 pw.println(); 12476 needSep = false; 12477 } 12478 pw.println(" mPreviousProcess: " + mPreviousProcess); 12479 } 12480 if (dumpAll) { 12481 StringBuilder sb = new StringBuilder(128); 12482 sb.append(" mPreviousProcessVisibleTime: "); 12483 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12484 pw.println(sb); 12485 } 12486 if (mHeavyWeightProcess != null && (dumpPackage == null 12487 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12488 if (needSep) { 12489 pw.println(); 12490 needSep = false; 12491 } 12492 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12493 } 12494 if (dumpPackage == null) { 12495 pw.println(" mConfiguration: " + mConfiguration); 12496 } 12497 if (dumpAll) { 12498 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12499 if (mCompatModePackages.getPackages().size() > 0) { 12500 boolean printed = false; 12501 for (Map.Entry<String, Integer> entry 12502 : mCompatModePackages.getPackages().entrySet()) { 12503 String pkg = entry.getKey(); 12504 int mode = entry.getValue(); 12505 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12506 continue; 12507 } 12508 if (!printed) { 12509 pw.println(" mScreenCompatPackages:"); 12510 printed = true; 12511 } 12512 pw.print(" "); pw.print(pkg); pw.print(": "); 12513 pw.print(mode); pw.println(); 12514 } 12515 } 12516 } 12517 if (dumpPackage == null) { 12518 pw.println(" mWakefulness=" 12519 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12520 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12521 + lockScreenShownToString()); 12522 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 12523 + " mTestPssMode=" + mTestPssMode); 12524 } 12525 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12526 || mOrigWaitForDebugger) { 12527 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12528 || dumpPackage.equals(mOrigDebugApp)) { 12529 if (needSep) { 12530 pw.println(); 12531 needSep = false; 12532 } 12533 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12534 + " mDebugTransient=" + mDebugTransient 12535 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12536 } 12537 } 12538 if (mOpenGlTraceApp != null) { 12539 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12540 if (needSep) { 12541 pw.println(); 12542 needSep = false; 12543 } 12544 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12545 } 12546 } 12547 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12548 || mProfileFd != null) { 12549 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12550 if (needSep) { 12551 pw.println(); 12552 needSep = false; 12553 } 12554 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12555 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12556 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12557 + mAutoStopProfiler); 12558 pw.println(" mProfileType=" + mProfileType); 12559 } 12560 } 12561 if (dumpPackage == null) { 12562 if (mAlwaysFinishActivities || mController != null) { 12563 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12564 + " mController=" + mController); 12565 } 12566 if (dumpAll) { 12567 pw.println(" Total persistent processes: " + numPers); 12568 pw.println(" mProcessesReady=" + mProcessesReady 12569 + " mSystemReady=" + mSystemReady 12570 + " mBooted=" + mBooted 12571 + " mFactoryTest=" + mFactoryTest); 12572 pw.println(" mBooting=" + mBooting 12573 + " mCallFinishBooting=" + mCallFinishBooting 12574 + " mBootAnimationComplete=" + mBootAnimationComplete); 12575 pw.print(" mLastPowerCheckRealtime="); 12576 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12577 pw.println(""); 12578 pw.print(" mLastPowerCheckUptime="); 12579 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12580 pw.println(""); 12581 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12582 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12583 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12584 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12585 + " (" + mLruProcesses.size() + " total)" 12586 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12587 + " mNumServiceProcs=" + mNumServiceProcs 12588 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12589 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12590 + " mLastMemoryLevel" + mLastMemoryLevel 12591 + " mLastNumProcesses" + mLastNumProcesses); 12592 long now = SystemClock.uptimeMillis(); 12593 pw.print(" mLastIdleTime="); 12594 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12595 pw.print(" mLowRamSinceLastIdle="); 12596 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12597 pw.println(); 12598 } 12599 } 12600 12601 if (!printedAnything) { 12602 pw.println(" (nothing)"); 12603 } 12604 } 12605 12606 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12607 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12608 if (mProcessesToGc.size() > 0) { 12609 boolean printed = false; 12610 long now = SystemClock.uptimeMillis(); 12611 for (int i=0; i<mProcessesToGc.size(); i++) { 12612 ProcessRecord proc = mProcessesToGc.get(i); 12613 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12614 continue; 12615 } 12616 if (!printed) { 12617 if (needSep) pw.println(); 12618 needSep = true; 12619 pw.println(" Processes that are waiting to GC:"); 12620 printed = true; 12621 } 12622 pw.print(" Process "); pw.println(proc); 12623 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12624 pw.print(", last gced="); 12625 pw.print(now-proc.lastRequestedGc); 12626 pw.print(" ms ago, last lowMem="); 12627 pw.print(now-proc.lastLowMemory); 12628 pw.println(" ms ago"); 12629 12630 } 12631 } 12632 return needSep; 12633 } 12634 12635 void printOomLevel(PrintWriter pw, String name, int adj) { 12636 pw.print(" "); 12637 if (adj >= 0) { 12638 pw.print(' '); 12639 if (adj < 10) pw.print(' '); 12640 } else { 12641 if (adj > -10) pw.print(' '); 12642 } 12643 pw.print(adj); 12644 pw.print(": "); 12645 pw.print(name); 12646 pw.print(" ("); 12647 pw.print(mProcessList.getMemLevel(adj)/1024); 12648 pw.println(" kB)"); 12649 } 12650 12651 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12652 int opti, boolean dumpAll) { 12653 boolean needSep = false; 12654 12655 if (mLruProcesses.size() > 0) { 12656 if (needSep) pw.println(); 12657 needSep = true; 12658 pw.println(" OOM levels:"); 12659 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12660 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12661 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12662 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12663 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12664 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12665 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12666 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12667 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12668 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12669 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12670 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12671 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12672 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12673 12674 if (needSep) pw.println(); 12675 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12676 pw.print(" total, non-act at "); 12677 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12678 pw.print(", non-svc at "); 12679 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12680 pw.println("):"); 12681 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12682 needSep = true; 12683 } 12684 12685 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12686 12687 pw.println(); 12688 pw.println(" mHomeProcess: " + mHomeProcess); 12689 pw.println(" mPreviousProcess: " + mPreviousProcess); 12690 if (mHeavyWeightProcess != null) { 12691 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12692 } 12693 12694 return true; 12695 } 12696 12697 /** 12698 * There are three ways to call this: 12699 * - no provider specified: dump all the providers 12700 * - a flattened component name that matched an existing provider was specified as the 12701 * first arg: dump that one provider 12702 * - the first arg isn't the flattened component name of an existing provider: 12703 * dump all providers whose component contains the first arg as a substring 12704 */ 12705 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12706 int opti, boolean dumpAll) { 12707 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12708 } 12709 12710 static class ItemMatcher { 12711 ArrayList<ComponentName> components; 12712 ArrayList<String> strings; 12713 ArrayList<Integer> objects; 12714 boolean all; 12715 12716 ItemMatcher() { 12717 all = true; 12718 } 12719 12720 void build(String name) { 12721 ComponentName componentName = ComponentName.unflattenFromString(name); 12722 if (componentName != null) { 12723 if (components == null) { 12724 components = new ArrayList<ComponentName>(); 12725 } 12726 components.add(componentName); 12727 all = false; 12728 } else { 12729 int objectId = 0; 12730 // Not a '/' separated full component name; maybe an object ID? 12731 try { 12732 objectId = Integer.parseInt(name, 16); 12733 if (objects == null) { 12734 objects = new ArrayList<Integer>(); 12735 } 12736 objects.add(objectId); 12737 all = false; 12738 } catch (RuntimeException e) { 12739 // Not an integer; just do string match. 12740 if (strings == null) { 12741 strings = new ArrayList<String>(); 12742 } 12743 strings.add(name); 12744 all = false; 12745 } 12746 } 12747 } 12748 12749 int build(String[] args, int opti) { 12750 for (; opti<args.length; opti++) { 12751 String name = args[opti]; 12752 if ("--".equals(name)) { 12753 return opti+1; 12754 } 12755 build(name); 12756 } 12757 return opti; 12758 } 12759 12760 boolean match(Object object, ComponentName comp) { 12761 if (all) { 12762 return true; 12763 } 12764 if (components != null) { 12765 for (int i=0; i<components.size(); i++) { 12766 if (components.get(i).equals(comp)) { 12767 return true; 12768 } 12769 } 12770 } 12771 if (objects != null) { 12772 for (int i=0; i<objects.size(); i++) { 12773 if (System.identityHashCode(object) == objects.get(i)) { 12774 return true; 12775 } 12776 } 12777 } 12778 if (strings != null) { 12779 String flat = comp.flattenToString(); 12780 for (int i=0; i<strings.size(); i++) { 12781 if (flat.contains(strings.get(i))) { 12782 return true; 12783 } 12784 } 12785 } 12786 return false; 12787 } 12788 } 12789 12790 /** 12791 * There are three things that cmd can be: 12792 * - a flattened component name that matches an existing activity 12793 * - the cmd arg isn't the flattened component name of an existing activity: 12794 * dump all activity whose component contains the cmd as a substring 12795 * - A hex number of the ActivityRecord object instance. 12796 */ 12797 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12798 int opti, boolean dumpAll) { 12799 ArrayList<ActivityRecord> activities; 12800 12801 synchronized (this) { 12802 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12803 } 12804 12805 if (activities.size() <= 0) { 12806 return false; 12807 } 12808 12809 String[] newArgs = new String[args.length - opti]; 12810 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12811 12812 TaskRecord lastTask = null; 12813 boolean needSep = false; 12814 for (int i=activities.size()-1; i>=0; i--) { 12815 ActivityRecord r = activities.get(i); 12816 if (needSep) { 12817 pw.println(); 12818 } 12819 needSep = true; 12820 synchronized (this) { 12821 if (lastTask != r.task) { 12822 lastTask = r.task; 12823 pw.print("TASK "); pw.print(lastTask.affinity); 12824 pw.print(" id="); pw.println(lastTask.taskId); 12825 if (dumpAll) { 12826 lastTask.dump(pw, " "); 12827 } 12828 } 12829 } 12830 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12831 } 12832 return true; 12833 } 12834 12835 /** 12836 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12837 * there is a thread associated with the activity. 12838 */ 12839 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12840 final ActivityRecord r, String[] args, boolean dumpAll) { 12841 String innerPrefix = prefix + " "; 12842 synchronized (this) { 12843 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12844 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12845 pw.print(" pid="); 12846 if (r.app != null) pw.println(r.app.pid); 12847 else pw.println("(not running)"); 12848 if (dumpAll) { 12849 r.dump(pw, innerPrefix); 12850 } 12851 } 12852 if (r.app != null && r.app.thread != null) { 12853 // flush anything that is already in the PrintWriter since the thread is going 12854 // to write to the file descriptor directly 12855 pw.flush(); 12856 try { 12857 TransferPipe tp = new TransferPipe(); 12858 try { 12859 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12860 r.appToken, innerPrefix, args); 12861 tp.go(fd); 12862 } finally { 12863 tp.kill(); 12864 } 12865 } catch (IOException e) { 12866 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12867 } catch (RemoteException e) { 12868 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12869 } 12870 } 12871 } 12872 12873 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12874 int opti, boolean dumpAll, String dumpPackage) { 12875 boolean needSep = false; 12876 boolean onlyHistory = false; 12877 boolean printedAnything = false; 12878 12879 if ("history".equals(dumpPackage)) { 12880 if (opti < args.length && "-s".equals(args[opti])) { 12881 dumpAll = false; 12882 } 12883 onlyHistory = true; 12884 dumpPackage = null; 12885 } 12886 12887 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12888 if (!onlyHistory && dumpAll) { 12889 if (mRegisteredReceivers.size() > 0) { 12890 boolean printed = false; 12891 Iterator it = mRegisteredReceivers.values().iterator(); 12892 while (it.hasNext()) { 12893 ReceiverList r = (ReceiverList)it.next(); 12894 if (dumpPackage != null && (r.app == null || 12895 !dumpPackage.equals(r.app.info.packageName))) { 12896 continue; 12897 } 12898 if (!printed) { 12899 pw.println(" Registered Receivers:"); 12900 needSep = true; 12901 printed = true; 12902 printedAnything = true; 12903 } 12904 pw.print(" * "); pw.println(r); 12905 r.dump(pw, " "); 12906 } 12907 } 12908 12909 if (mReceiverResolver.dump(pw, needSep ? 12910 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12911 " ", dumpPackage, false, false)) { 12912 needSep = true; 12913 printedAnything = true; 12914 } 12915 } 12916 12917 for (BroadcastQueue q : mBroadcastQueues) { 12918 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12919 printedAnything |= needSep; 12920 } 12921 12922 needSep = true; 12923 12924 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12925 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12926 if (needSep) { 12927 pw.println(); 12928 } 12929 needSep = true; 12930 printedAnything = true; 12931 pw.print(" Sticky broadcasts for user "); 12932 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12933 StringBuilder sb = new StringBuilder(128); 12934 for (Map.Entry<String, ArrayList<Intent>> ent 12935 : mStickyBroadcasts.valueAt(user).entrySet()) { 12936 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12937 if (dumpAll) { 12938 pw.println(":"); 12939 ArrayList<Intent> intents = ent.getValue(); 12940 final int N = intents.size(); 12941 for (int i=0; i<N; i++) { 12942 sb.setLength(0); 12943 sb.append(" Intent: "); 12944 intents.get(i).toShortString(sb, false, true, false, false); 12945 pw.println(sb.toString()); 12946 Bundle bundle = intents.get(i).getExtras(); 12947 if (bundle != null) { 12948 pw.print(" "); 12949 pw.println(bundle.toString()); 12950 } 12951 } 12952 } else { 12953 pw.println(""); 12954 } 12955 } 12956 } 12957 } 12958 12959 if (!onlyHistory && dumpAll) { 12960 pw.println(); 12961 for (BroadcastQueue queue : mBroadcastQueues) { 12962 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12963 + queue.mBroadcastsScheduled); 12964 } 12965 pw.println(" mHandler:"); 12966 mHandler.dump(new PrintWriterPrinter(pw), " "); 12967 needSep = true; 12968 printedAnything = true; 12969 } 12970 12971 if (!printedAnything) { 12972 pw.println(" (nothing)"); 12973 } 12974 } 12975 12976 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12977 int opti, boolean dumpAll, String dumpPackage) { 12978 boolean needSep; 12979 boolean printedAnything = false; 12980 12981 ItemMatcher matcher = new ItemMatcher(); 12982 matcher.build(args, opti); 12983 12984 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12985 12986 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12987 printedAnything |= needSep; 12988 12989 if (mLaunchingProviders.size() > 0) { 12990 boolean printed = false; 12991 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12992 ContentProviderRecord r = mLaunchingProviders.get(i); 12993 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12994 continue; 12995 } 12996 if (!printed) { 12997 if (needSep) pw.println(); 12998 needSep = true; 12999 pw.println(" Launching content providers:"); 13000 printed = true; 13001 printedAnything = true; 13002 } 13003 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13004 pw.println(r); 13005 } 13006 } 13007 13008 if (mGrantedUriPermissions.size() > 0) { 13009 boolean printed = false; 13010 int dumpUid = -2; 13011 if (dumpPackage != null) { 13012 try { 13013 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13014 } catch (NameNotFoundException e) { 13015 dumpUid = -1; 13016 } 13017 } 13018 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13019 int uid = mGrantedUriPermissions.keyAt(i); 13020 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13021 continue; 13022 } 13023 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13024 if (!printed) { 13025 if (needSep) pw.println(); 13026 needSep = true; 13027 pw.println(" Granted Uri Permissions:"); 13028 printed = true; 13029 printedAnything = true; 13030 } 13031 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13032 for (UriPermission perm : perms.values()) { 13033 pw.print(" "); pw.println(perm); 13034 if (dumpAll) { 13035 perm.dump(pw, " "); 13036 } 13037 } 13038 } 13039 } 13040 13041 if (!printedAnything) { 13042 pw.println(" (nothing)"); 13043 } 13044 } 13045 13046 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13047 int opti, boolean dumpAll, String dumpPackage) { 13048 boolean printed = false; 13049 13050 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13051 13052 if (mIntentSenderRecords.size() > 0) { 13053 Iterator<WeakReference<PendingIntentRecord>> it 13054 = mIntentSenderRecords.values().iterator(); 13055 while (it.hasNext()) { 13056 WeakReference<PendingIntentRecord> ref = it.next(); 13057 PendingIntentRecord rec = ref != null ? ref.get(): null; 13058 if (dumpPackage != null && (rec == null 13059 || !dumpPackage.equals(rec.key.packageName))) { 13060 continue; 13061 } 13062 printed = true; 13063 if (rec != null) { 13064 pw.print(" * "); pw.println(rec); 13065 if (dumpAll) { 13066 rec.dump(pw, " "); 13067 } 13068 } else { 13069 pw.print(" * "); pw.println(ref); 13070 } 13071 } 13072 } 13073 13074 if (!printed) { 13075 pw.println(" (nothing)"); 13076 } 13077 } 13078 13079 private static final int dumpProcessList(PrintWriter pw, 13080 ActivityManagerService service, List list, 13081 String prefix, String normalLabel, String persistentLabel, 13082 String dumpPackage) { 13083 int numPers = 0; 13084 final int N = list.size()-1; 13085 for (int i=N; i>=0; i--) { 13086 ProcessRecord r = (ProcessRecord)list.get(i); 13087 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13088 continue; 13089 } 13090 pw.println(String.format("%s%s #%2d: %s", 13091 prefix, (r.persistent ? persistentLabel : normalLabel), 13092 i, r.toString())); 13093 if (r.persistent) { 13094 numPers++; 13095 } 13096 } 13097 return numPers; 13098 } 13099 13100 private static final boolean dumpProcessOomList(PrintWriter pw, 13101 ActivityManagerService service, List<ProcessRecord> origList, 13102 String prefix, String normalLabel, String persistentLabel, 13103 boolean inclDetails, String dumpPackage) { 13104 13105 ArrayList<Pair<ProcessRecord, Integer>> list 13106 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13107 for (int i=0; i<origList.size(); i++) { 13108 ProcessRecord r = origList.get(i); 13109 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13110 continue; 13111 } 13112 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13113 } 13114 13115 if (list.size() <= 0) { 13116 return false; 13117 } 13118 13119 Comparator<Pair<ProcessRecord, Integer>> comparator 13120 = new Comparator<Pair<ProcessRecord, Integer>>() { 13121 @Override 13122 public int compare(Pair<ProcessRecord, Integer> object1, 13123 Pair<ProcessRecord, Integer> object2) { 13124 if (object1.first.setAdj != object2.first.setAdj) { 13125 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13126 } 13127 if (object1.second.intValue() != object2.second.intValue()) { 13128 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13129 } 13130 return 0; 13131 } 13132 }; 13133 13134 Collections.sort(list, comparator); 13135 13136 final long curRealtime = SystemClock.elapsedRealtime(); 13137 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13138 final long curUptime = SystemClock.uptimeMillis(); 13139 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13140 13141 for (int i=list.size()-1; i>=0; i--) { 13142 ProcessRecord r = list.get(i).first; 13143 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13144 char schedGroup; 13145 switch (r.setSchedGroup) { 13146 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13147 schedGroup = 'B'; 13148 break; 13149 case Process.THREAD_GROUP_DEFAULT: 13150 schedGroup = 'F'; 13151 break; 13152 default: 13153 schedGroup = '?'; 13154 break; 13155 } 13156 char foreground; 13157 if (r.foregroundActivities) { 13158 foreground = 'A'; 13159 } else if (r.foregroundServices) { 13160 foreground = 'S'; 13161 } else { 13162 foreground = ' '; 13163 } 13164 String procState = ProcessList.makeProcStateString(r.curProcState); 13165 pw.print(prefix); 13166 pw.print(r.persistent ? persistentLabel : normalLabel); 13167 pw.print(" #"); 13168 int num = (origList.size()-1)-list.get(i).second; 13169 if (num < 10) pw.print(' '); 13170 pw.print(num); 13171 pw.print(": "); 13172 pw.print(oomAdj); 13173 pw.print(' '); 13174 pw.print(schedGroup); 13175 pw.print('/'); 13176 pw.print(foreground); 13177 pw.print('/'); 13178 pw.print(procState); 13179 pw.print(" trm:"); 13180 if (r.trimMemoryLevel < 10) pw.print(' '); 13181 pw.print(r.trimMemoryLevel); 13182 pw.print(' '); 13183 pw.print(r.toShortString()); 13184 pw.print(" ("); 13185 pw.print(r.adjType); 13186 pw.println(')'); 13187 if (r.adjSource != null || r.adjTarget != null) { 13188 pw.print(prefix); 13189 pw.print(" "); 13190 if (r.adjTarget instanceof ComponentName) { 13191 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13192 } else if (r.adjTarget != null) { 13193 pw.print(r.adjTarget.toString()); 13194 } else { 13195 pw.print("{null}"); 13196 } 13197 pw.print("<="); 13198 if (r.adjSource instanceof ProcessRecord) { 13199 pw.print("Proc{"); 13200 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13201 pw.println("}"); 13202 } else if (r.adjSource != null) { 13203 pw.println(r.adjSource.toString()); 13204 } else { 13205 pw.println("{null}"); 13206 } 13207 } 13208 if (inclDetails) { 13209 pw.print(prefix); 13210 pw.print(" "); 13211 pw.print("oom: max="); pw.print(r.maxAdj); 13212 pw.print(" curRaw="); pw.print(r.curRawAdj); 13213 pw.print(" setRaw="); pw.print(r.setRawAdj); 13214 pw.print(" cur="); pw.print(r.curAdj); 13215 pw.print(" set="); pw.println(r.setAdj); 13216 pw.print(prefix); 13217 pw.print(" "); 13218 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13219 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13220 pw.print(" lastPss="); pw.print(r.lastPss); 13221 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13222 pw.print(prefix); 13223 pw.print(" "); 13224 pw.print("cached="); pw.print(r.cached); 13225 pw.print(" empty="); pw.print(r.empty); 13226 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13227 13228 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13229 if (r.lastWakeTime != 0) { 13230 long wtime; 13231 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13232 synchronized (stats) { 13233 wtime = stats.getProcessWakeTime(r.info.uid, 13234 r.pid, curRealtime); 13235 } 13236 long timeUsed = wtime - r.lastWakeTime; 13237 pw.print(prefix); 13238 pw.print(" "); 13239 pw.print("keep awake over "); 13240 TimeUtils.formatDuration(realtimeSince, pw); 13241 pw.print(" used "); 13242 TimeUtils.formatDuration(timeUsed, pw); 13243 pw.print(" ("); 13244 pw.print((timeUsed*100)/realtimeSince); 13245 pw.println("%)"); 13246 } 13247 if (r.lastCpuTime != 0) { 13248 long timeUsed = r.curCpuTime - r.lastCpuTime; 13249 pw.print(prefix); 13250 pw.print(" "); 13251 pw.print("run cpu over "); 13252 TimeUtils.formatDuration(uptimeSince, pw); 13253 pw.print(" used "); 13254 TimeUtils.formatDuration(timeUsed, pw); 13255 pw.print(" ("); 13256 pw.print((timeUsed*100)/uptimeSince); 13257 pw.println("%)"); 13258 } 13259 } 13260 } 13261 } 13262 return true; 13263 } 13264 13265 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13266 String[] args) { 13267 ArrayList<ProcessRecord> procs; 13268 synchronized (this) { 13269 if (args != null && args.length > start 13270 && args[start].charAt(0) != '-') { 13271 procs = new ArrayList<ProcessRecord>(); 13272 int pid = -1; 13273 try { 13274 pid = Integer.parseInt(args[start]); 13275 } catch (NumberFormatException e) { 13276 } 13277 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13278 ProcessRecord proc = mLruProcesses.get(i); 13279 if (proc.pid == pid) { 13280 procs.add(proc); 13281 } else if (allPkgs && proc.pkgList != null 13282 && proc.pkgList.containsKey(args[start])) { 13283 procs.add(proc); 13284 } else if (proc.processName.equals(args[start])) { 13285 procs.add(proc); 13286 } 13287 } 13288 if (procs.size() <= 0) { 13289 return null; 13290 } 13291 } else { 13292 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13293 } 13294 } 13295 return procs; 13296 } 13297 13298 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13299 PrintWriter pw, String[] args) { 13300 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13301 if (procs == null) { 13302 pw.println("No process found for: " + args[0]); 13303 return; 13304 } 13305 13306 long uptime = SystemClock.uptimeMillis(); 13307 long realtime = SystemClock.elapsedRealtime(); 13308 pw.println("Applications Graphics Acceleration Info:"); 13309 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13310 13311 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13312 ProcessRecord r = procs.get(i); 13313 if (r.thread != null) { 13314 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13315 pw.flush(); 13316 try { 13317 TransferPipe tp = new TransferPipe(); 13318 try { 13319 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13320 tp.go(fd); 13321 } finally { 13322 tp.kill(); 13323 } 13324 } catch (IOException e) { 13325 pw.println("Failure while dumping the app: " + r); 13326 pw.flush(); 13327 } catch (RemoteException e) { 13328 pw.println("Got a RemoteException while dumping the app " + r); 13329 pw.flush(); 13330 } 13331 } 13332 } 13333 } 13334 13335 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13336 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13337 if (procs == null) { 13338 pw.println("No process found for: " + args[0]); 13339 return; 13340 } 13341 13342 pw.println("Applications Database Info:"); 13343 13344 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13345 ProcessRecord r = procs.get(i); 13346 if (r.thread != null) { 13347 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13348 pw.flush(); 13349 try { 13350 TransferPipe tp = new TransferPipe(); 13351 try { 13352 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13353 tp.go(fd); 13354 } finally { 13355 tp.kill(); 13356 } 13357 } catch (IOException e) { 13358 pw.println("Failure while dumping the app: " + r); 13359 pw.flush(); 13360 } catch (RemoteException e) { 13361 pw.println("Got a RemoteException while dumping the app " + r); 13362 pw.flush(); 13363 } 13364 } 13365 } 13366 } 13367 13368 final static class MemItem { 13369 final boolean isProc; 13370 final String label; 13371 final String shortLabel; 13372 final long pss; 13373 final int id; 13374 final boolean hasActivities; 13375 ArrayList<MemItem> subitems; 13376 13377 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13378 boolean _hasActivities) { 13379 isProc = true; 13380 label = _label; 13381 shortLabel = _shortLabel; 13382 pss = _pss; 13383 id = _id; 13384 hasActivities = _hasActivities; 13385 } 13386 13387 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13388 isProc = false; 13389 label = _label; 13390 shortLabel = _shortLabel; 13391 pss = _pss; 13392 id = _id; 13393 hasActivities = false; 13394 } 13395 } 13396 13397 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13398 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13399 if (sort && !isCompact) { 13400 Collections.sort(items, new Comparator<MemItem>() { 13401 @Override 13402 public int compare(MemItem lhs, MemItem rhs) { 13403 if (lhs.pss < rhs.pss) { 13404 return 1; 13405 } else if (lhs.pss > rhs.pss) { 13406 return -1; 13407 } 13408 return 0; 13409 } 13410 }); 13411 } 13412 13413 for (int i=0; i<items.size(); i++) { 13414 MemItem mi = items.get(i); 13415 if (!isCompact) { 13416 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13417 } else if (mi.isProc) { 13418 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13419 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13420 pw.println(mi.hasActivities ? ",a" : ",e"); 13421 } else { 13422 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13423 pw.println(mi.pss); 13424 } 13425 if (mi.subitems != null) { 13426 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13427 true, isCompact); 13428 } 13429 } 13430 } 13431 13432 // These are in KB. 13433 static final long[] DUMP_MEM_BUCKETS = new long[] { 13434 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13435 120*1024, 160*1024, 200*1024, 13436 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13437 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13438 }; 13439 13440 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13441 boolean stackLike) { 13442 int start = label.lastIndexOf('.'); 13443 if (start >= 0) start++; 13444 else start = 0; 13445 int end = label.length(); 13446 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13447 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13448 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13449 out.append(bucket); 13450 out.append(stackLike ? "MB." : "MB "); 13451 out.append(label, start, end); 13452 return; 13453 } 13454 } 13455 out.append(memKB/1024); 13456 out.append(stackLike ? "MB." : "MB "); 13457 out.append(label, start, end); 13458 } 13459 13460 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13461 ProcessList.NATIVE_ADJ, 13462 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13463 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13464 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13465 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13466 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13467 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13468 }; 13469 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13470 "Native", 13471 "System", "Persistent", "Persistent Service", "Foreground", 13472 "Visible", "Perceptible", 13473 "Heavy Weight", "Backup", 13474 "A Services", "Home", 13475 "Previous", "B Services", "Cached" 13476 }; 13477 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13478 "native", 13479 "sys", "pers", "persvc", "fore", 13480 "vis", "percept", 13481 "heavy", "backup", 13482 "servicea", "home", 13483 "prev", "serviceb", "cached" 13484 }; 13485 13486 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13487 long realtime, boolean isCheckinRequest, boolean isCompact) { 13488 if (isCheckinRequest || isCompact) { 13489 // short checkin version 13490 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13491 } else { 13492 pw.println("Applications Memory Usage (kB):"); 13493 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13494 } 13495 } 13496 13497 private static final int KSM_SHARED = 0; 13498 private static final int KSM_SHARING = 1; 13499 private static final int KSM_UNSHARED = 2; 13500 private static final int KSM_VOLATILE = 3; 13501 13502 private final long[] getKsmInfo() { 13503 long[] longOut = new long[4]; 13504 final int[] SINGLE_LONG_FORMAT = new int[] { 13505 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13506 }; 13507 long[] longTmp = new long[1]; 13508 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13509 SINGLE_LONG_FORMAT, null, longTmp, null); 13510 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13511 longTmp[0] = 0; 13512 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13513 SINGLE_LONG_FORMAT, null, longTmp, null); 13514 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13515 longTmp[0] = 0; 13516 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13517 SINGLE_LONG_FORMAT, null, longTmp, null); 13518 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13519 longTmp[0] = 0; 13520 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13521 SINGLE_LONG_FORMAT, null, longTmp, null); 13522 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13523 return longOut; 13524 } 13525 13526 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13527 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13528 boolean dumpDetails = false; 13529 boolean dumpFullDetails = false; 13530 boolean dumpDalvik = false; 13531 boolean oomOnly = false; 13532 boolean isCompact = false; 13533 boolean localOnly = false; 13534 boolean packages = false; 13535 13536 int opti = 0; 13537 while (opti < args.length) { 13538 String opt = args[opti]; 13539 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13540 break; 13541 } 13542 opti++; 13543 if ("-a".equals(opt)) { 13544 dumpDetails = true; 13545 dumpFullDetails = true; 13546 dumpDalvik = true; 13547 } else if ("-d".equals(opt)) { 13548 dumpDalvik = true; 13549 } else if ("-c".equals(opt)) { 13550 isCompact = true; 13551 } else if ("--oom".equals(opt)) { 13552 oomOnly = true; 13553 } else if ("--local".equals(opt)) { 13554 localOnly = true; 13555 } else if ("--package".equals(opt)) { 13556 packages = true; 13557 } else if ("-h".equals(opt)) { 13558 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13559 pw.println(" -a: include all available information for each process."); 13560 pw.println(" -d: include dalvik details when dumping process details."); 13561 pw.println(" -c: dump in a compact machine-parseable representation."); 13562 pw.println(" --oom: only show processes organized by oom adj."); 13563 pw.println(" --local: only collect details locally, don't call process."); 13564 pw.println(" --package: interpret process arg as package, dumping all"); 13565 pw.println(" processes that have loaded that package."); 13566 pw.println("If [process] is specified it can be the name or "); 13567 pw.println("pid of a specific process to dump."); 13568 return; 13569 } else { 13570 pw.println("Unknown argument: " + opt + "; use -h for help"); 13571 } 13572 } 13573 13574 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13575 long uptime = SystemClock.uptimeMillis(); 13576 long realtime = SystemClock.elapsedRealtime(); 13577 final long[] tmpLong = new long[1]; 13578 13579 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13580 if (procs == null) { 13581 // No Java processes. Maybe they want to print a native process. 13582 if (args != null && args.length > opti 13583 && args[opti].charAt(0) != '-') { 13584 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13585 = new ArrayList<ProcessCpuTracker.Stats>(); 13586 updateCpuStatsNow(); 13587 int findPid = -1; 13588 try { 13589 findPid = Integer.parseInt(args[opti]); 13590 } catch (NumberFormatException e) { 13591 } 13592 synchronized (mProcessCpuTracker) { 13593 final int N = mProcessCpuTracker.countStats(); 13594 for (int i=0; i<N; i++) { 13595 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13596 if (st.pid == findPid || (st.baseName != null 13597 && st.baseName.equals(args[opti]))) { 13598 nativeProcs.add(st); 13599 } 13600 } 13601 } 13602 if (nativeProcs.size() > 0) { 13603 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13604 isCompact); 13605 Debug.MemoryInfo mi = null; 13606 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13607 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13608 final int pid = r.pid; 13609 if (!isCheckinRequest && dumpDetails) { 13610 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13611 } 13612 if (mi == null) { 13613 mi = new Debug.MemoryInfo(); 13614 } 13615 if (dumpDetails || (!brief && !oomOnly)) { 13616 Debug.getMemoryInfo(pid, mi); 13617 } else { 13618 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 13619 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13620 } 13621 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13622 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13623 if (isCheckinRequest) { 13624 pw.println(); 13625 } 13626 } 13627 return; 13628 } 13629 } 13630 pw.println("No process found for: " + args[opti]); 13631 return; 13632 } 13633 13634 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13635 dumpDetails = true; 13636 } 13637 13638 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13639 13640 String[] innerArgs = new String[args.length-opti]; 13641 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13642 13643 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13644 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13645 long nativePss = 0; 13646 long dalvikPss = 0; 13647 long otherPss = 0; 13648 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13649 13650 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13651 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13652 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13653 13654 long totalPss = 0; 13655 long cachedPss = 0; 13656 13657 Debug.MemoryInfo mi = null; 13658 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13659 final ProcessRecord r = procs.get(i); 13660 final IApplicationThread thread; 13661 final int pid; 13662 final int oomAdj; 13663 final boolean hasActivities; 13664 synchronized (this) { 13665 thread = r.thread; 13666 pid = r.pid; 13667 oomAdj = r.getSetAdjWithServices(); 13668 hasActivities = r.activities.size() > 0; 13669 } 13670 if (thread != null) { 13671 if (!isCheckinRequest && dumpDetails) { 13672 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13673 } 13674 if (mi == null) { 13675 mi = new Debug.MemoryInfo(); 13676 } 13677 if (dumpDetails || (!brief && !oomOnly)) { 13678 Debug.getMemoryInfo(pid, mi); 13679 } else { 13680 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 13681 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13682 } 13683 if (dumpDetails) { 13684 if (localOnly) { 13685 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13686 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13687 if (isCheckinRequest) { 13688 pw.println(); 13689 } 13690 } else { 13691 try { 13692 pw.flush(); 13693 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13694 dumpDalvik, innerArgs); 13695 } catch (RemoteException e) { 13696 if (!isCheckinRequest) { 13697 pw.println("Got RemoteException!"); 13698 pw.flush(); 13699 } 13700 } 13701 } 13702 } 13703 13704 final long myTotalPss = mi.getTotalPss(); 13705 final long myTotalUss = mi.getTotalUss(); 13706 13707 synchronized (this) { 13708 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13709 // Record this for posterity if the process has been stable. 13710 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13711 } 13712 } 13713 13714 if (!isCheckinRequest && mi != null) { 13715 totalPss += myTotalPss; 13716 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13717 (hasActivities ? " / activities)" : ")"), 13718 r.processName, myTotalPss, pid, hasActivities); 13719 procMems.add(pssItem); 13720 procMemsMap.put(pid, pssItem); 13721 13722 nativePss += mi.nativePss; 13723 dalvikPss += mi.dalvikPss; 13724 otherPss += mi.otherPss; 13725 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13726 long mem = mi.getOtherPss(j); 13727 miscPss[j] += mem; 13728 otherPss -= mem; 13729 } 13730 13731 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13732 cachedPss += myTotalPss; 13733 } 13734 13735 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13736 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13737 || oomIndex == (oomPss.length-1)) { 13738 oomPss[oomIndex] += myTotalPss; 13739 if (oomProcs[oomIndex] == null) { 13740 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13741 } 13742 oomProcs[oomIndex].add(pssItem); 13743 break; 13744 } 13745 } 13746 } 13747 } 13748 } 13749 13750 long nativeProcTotalPss = 0; 13751 13752 if (!isCheckinRequest && procs.size() > 1 && !packages) { 13753 // If we are showing aggregations, also look for native processes to 13754 // include so that our aggregations are more accurate. 13755 updateCpuStatsNow(); 13756 mi = null; 13757 synchronized (mProcessCpuTracker) { 13758 final int N = mProcessCpuTracker.countStats(); 13759 for (int i=0; i<N; i++) { 13760 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13761 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13762 if (mi == null) { 13763 mi = new Debug.MemoryInfo(); 13764 } 13765 if (!brief && !oomOnly) { 13766 Debug.getMemoryInfo(st.pid, mi); 13767 } else { 13768 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 13769 mi.nativePrivateDirty = (int)tmpLong[0]; 13770 } 13771 13772 final long myTotalPss = mi.getTotalPss(); 13773 totalPss += myTotalPss; 13774 nativeProcTotalPss += myTotalPss; 13775 13776 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13777 st.name, myTotalPss, st.pid, false); 13778 procMems.add(pssItem); 13779 13780 nativePss += mi.nativePss; 13781 dalvikPss += mi.dalvikPss; 13782 otherPss += mi.otherPss; 13783 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13784 long mem = mi.getOtherPss(j); 13785 miscPss[j] += mem; 13786 otherPss -= mem; 13787 } 13788 oomPss[0] += myTotalPss; 13789 if (oomProcs[0] == null) { 13790 oomProcs[0] = new ArrayList<MemItem>(); 13791 } 13792 oomProcs[0].add(pssItem); 13793 } 13794 } 13795 } 13796 13797 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13798 13799 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13800 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13801 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13802 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13803 String label = Debug.MemoryInfo.getOtherLabel(j); 13804 catMems.add(new MemItem(label, label, miscPss[j], j)); 13805 } 13806 13807 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13808 for (int j=0; j<oomPss.length; j++) { 13809 if (oomPss[j] != 0) { 13810 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13811 : DUMP_MEM_OOM_LABEL[j]; 13812 MemItem item = new MemItem(label, label, oomPss[j], 13813 DUMP_MEM_OOM_ADJ[j]); 13814 item.subitems = oomProcs[j]; 13815 oomMems.add(item); 13816 } 13817 } 13818 13819 if (!brief && !oomOnly && !isCompact) { 13820 pw.println(); 13821 pw.println("Total PSS by process:"); 13822 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13823 pw.println(); 13824 } 13825 if (!isCompact) { 13826 pw.println("Total PSS by OOM adjustment:"); 13827 } 13828 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13829 if (!brief && !oomOnly) { 13830 PrintWriter out = categoryPw != null ? categoryPw : pw; 13831 if (!isCompact) { 13832 out.println(); 13833 out.println("Total PSS by category:"); 13834 } 13835 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13836 } 13837 if (!isCompact) { 13838 pw.println(); 13839 } 13840 MemInfoReader memInfo = new MemInfoReader(); 13841 memInfo.readMemInfo(); 13842 if (nativeProcTotalPss > 0) { 13843 synchronized (this) { 13844 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13845 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13846 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 13847 } 13848 } 13849 if (!brief) { 13850 if (!isCompact) { 13851 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13852 pw.print(" kB (status "); 13853 switch (mLastMemoryLevel) { 13854 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13855 pw.println("normal)"); 13856 break; 13857 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13858 pw.println("moderate)"); 13859 break; 13860 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13861 pw.println("low)"); 13862 break; 13863 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13864 pw.println("critical)"); 13865 break; 13866 default: 13867 pw.print(mLastMemoryLevel); 13868 pw.println(")"); 13869 break; 13870 } 13871 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13872 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13873 pw.print(cachedPss); pw.print(" cached pss + "); 13874 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 13875 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13876 } else { 13877 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13878 pw.print(cachedPss + memInfo.getCachedSizeKb() 13879 + memInfo.getFreeSizeKb()); pw.print(","); 13880 pw.println(totalPss - cachedPss); 13881 } 13882 } 13883 if (!isCompact) { 13884 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13885 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 13886 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13887 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 13888 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13889 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13890 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 13891 } 13892 if (!brief) { 13893 if (memInfo.getZramTotalSizeKb() != 0) { 13894 if (!isCompact) { 13895 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13896 pw.print(" kB physical used for "); 13897 pw.print(memInfo.getSwapTotalSizeKb() 13898 - memInfo.getSwapFreeSizeKb()); 13899 pw.print(" kB in swap ("); 13900 pw.print(memInfo.getSwapTotalSizeKb()); 13901 pw.println(" kB total swap)"); 13902 } else { 13903 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13904 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13905 pw.println(memInfo.getSwapFreeSizeKb()); 13906 } 13907 } 13908 final long[] ksm = getKsmInfo(); 13909 if (!isCompact) { 13910 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 13911 || ksm[KSM_VOLATILE] != 0) { 13912 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 13913 pw.print(" kB saved from shared "); 13914 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 13915 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 13916 pw.print(" kB unshared; "); 13917 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 13918 } 13919 pw.print(" Tuning: "); 13920 pw.print(ActivityManager.staticGetMemoryClass()); 13921 pw.print(" (large "); 13922 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13923 pw.print("), oom "); 13924 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13925 pw.print(" kB"); 13926 pw.print(", restore limit "); 13927 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13928 pw.print(" kB"); 13929 if (ActivityManager.isLowRamDeviceStatic()) { 13930 pw.print(" (low-ram)"); 13931 } 13932 if (ActivityManager.isHighEndGfx()) { 13933 pw.print(" (high-end-gfx)"); 13934 } 13935 pw.println(); 13936 } else { 13937 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 13938 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 13939 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 13940 pw.print("tuning,"); 13941 pw.print(ActivityManager.staticGetMemoryClass()); 13942 pw.print(','); 13943 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13944 pw.print(','); 13945 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13946 if (ActivityManager.isLowRamDeviceStatic()) { 13947 pw.print(",low-ram"); 13948 } 13949 if (ActivityManager.isHighEndGfx()) { 13950 pw.print(",high-end-gfx"); 13951 } 13952 pw.println(); 13953 } 13954 } 13955 } 13956 } 13957 13958 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 13959 long memtrack, String name) { 13960 sb.append(" "); 13961 sb.append(ProcessList.makeOomAdjString(oomAdj)); 13962 sb.append(' '); 13963 sb.append(ProcessList.makeProcStateString(procState)); 13964 sb.append(' '); 13965 ProcessList.appendRamKb(sb, pss); 13966 sb.append(" kB: "); 13967 sb.append(name); 13968 if (memtrack > 0) { 13969 sb.append(" ("); 13970 sb.append(memtrack); 13971 sb.append(" kB memtrack)"); 13972 } 13973 } 13974 13975 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 13976 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 13977 sb.append(" (pid "); 13978 sb.append(mi.pid); 13979 sb.append(") "); 13980 sb.append(mi.adjType); 13981 sb.append('\n'); 13982 if (mi.adjReason != null) { 13983 sb.append(" "); 13984 sb.append(mi.adjReason); 13985 sb.append('\n'); 13986 } 13987 } 13988 13989 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 13990 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 13991 for (int i=0, N=memInfos.size(); i<N; i++) { 13992 ProcessMemInfo mi = memInfos.get(i); 13993 infoMap.put(mi.pid, mi); 13994 } 13995 updateCpuStatsNow(); 13996 long[] memtrackTmp = new long[1]; 13997 synchronized (mProcessCpuTracker) { 13998 final int N = mProcessCpuTracker.countStats(); 13999 for (int i=0; i<N; i++) { 14000 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14001 if (st.vsize > 0) { 14002 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14003 if (pss > 0) { 14004 if (infoMap.indexOfKey(st.pid) < 0) { 14005 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14006 ProcessList.NATIVE_ADJ, -1, "native", null); 14007 mi.pss = pss; 14008 mi.memtrack = memtrackTmp[0]; 14009 memInfos.add(mi); 14010 } 14011 } 14012 } 14013 } 14014 } 14015 14016 long totalPss = 0; 14017 long totalMemtrack = 0; 14018 for (int i=0, N=memInfos.size(); i<N; i++) { 14019 ProcessMemInfo mi = memInfos.get(i); 14020 if (mi.pss == 0) { 14021 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14022 mi.memtrack = memtrackTmp[0]; 14023 } 14024 totalPss += mi.pss; 14025 totalMemtrack += mi.memtrack; 14026 } 14027 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14028 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14029 if (lhs.oomAdj != rhs.oomAdj) { 14030 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14031 } 14032 if (lhs.pss != rhs.pss) { 14033 return lhs.pss < rhs.pss ? 1 : -1; 14034 } 14035 return 0; 14036 } 14037 }); 14038 14039 StringBuilder tag = new StringBuilder(128); 14040 StringBuilder stack = new StringBuilder(128); 14041 tag.append("Low on memory -- "); 14042 appendMemBucket(tag, totalPss, "total", false); 14043 appendMemBucket(stack, totalPss, "total", true); 14044 14045 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14046 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14047 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14048 14049 boolean firstLine = true; 14050 int lastOomAdj = Integer.MIN_VALUE; 14051 long extraNativeRam = 0; 14052 long extraNativeMemtrack = 0; 14053 long cachedPss = 0; 14054 for (int i=0, N=memInfos.size(); i<N; i++) { 14055 ProcessMemInfo mi = memInfos.get(i); 14056 14057 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14058 cachedPss += mi.pss; 14059 } 14060 14061 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14062 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14063 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14064 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14065 if (lastOomAdj != mi.oomAdj) { 14066 lastOomAdj = mi.oomAdj; 14067 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14068 tag.append(" / "); 14069 } 14070 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14071 if (firstLine) { 14072 stack.append(":"); 14073 firstLine = false; 14074 } 14075 stack.append("\n\t at "); 14076 } else { 14077 stack.append("$"); 14078 } 14079 } else { 14080 tag.append(" "); 14081 stack.append("$"); 14082 } 14083 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14084 appendMemBucket(tag, mi.pss, mi.name, false); 14085 } 14086 appendMemBucket(stack, mi.pss, mi.name, true); 14087 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14088 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14089 stack.append("("); 14090 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14091 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14092 stack.append(DUMP_MEM_OOM_LABEL[k]); 14093 stack.append(":"); 14094 stack.append(DUMP_MEM_OOM_ADJ[k]); 14095 } 14096 } 14097 stack.append(")"); 14098 } 14099 } 14100 14101 appendMemInfo(fullNativeBuilder, mi); 14102 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14103 // The short form only has native processes that are >= 512K. 14104 if (mi.pss >= 512) { 14105 appendMemInfo(shortNativeBuilder, mi); 14106 } else { 14107 extraNativeRam += mi.pss; 14108 extraNativeMemtrack += mi.memtrack; 14109 } 14110 } else { 14111 // Short form has all other details, but if we have collected RAM 14112 // from smaller native processes let's dump a summary of that. 14113 if (extraNativeRam > 0) { 14114 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14115 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14116 shortNativeBuilder.append('\n'); 14117 extraNativeRam = 0; 14118 } 14119 appendMemInfo(fullJavaBuilder, mi); 14120 } 14121 } 14122 14123 fullJavaBuilder.append(" "); 14124 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14125 fullJavaBuilder.append(" kB: TOTAL"); 14126 if (totalMemtrack > 0) { 14127 fullJavaBuilder.append(" ("); 14128 fullJavaBuilder.append(totalMemtrack); 14129 fullJavaBuilder.append(" kB memtrack)"); 14130 } else { 14131 } 14132 fullJavaBuilder.append("\n"); 14133 14134 MemInfoReader memInfo = new MemInfoReader(); 14135 memInfo.readMemInfo(); 14136 final long[] infos = memInfo.getRawInfo(); 14137 14138 StringBuilder memInfoBuilder = new StringBuilder(1024); 14139 Debug.getMemInfo(infos); 14140 memInfoBuilder.append(" MemInfo: "); 14141 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14142 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14143 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14144 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14145 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14146 memInfoBuilder.append(" "); 14147 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14148 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14149 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14150 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14151 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14152 memInfoBuilder.append(" ZRAM: "); 14153 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14154 memInfoBuilder.append(" kB RAM, "); 14155 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14156 memInfoBuilder.append(" kB swap total, "); 14157 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14158 memInfoBuilder.append(" kB swap free\n"); 14159 } 14160 final long[] ksm = getKsmInfo(); 14161 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14162 || ksm[KSM_VOLATILE] != 0) { 14163 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14164 memInfoBuilder.append(" kB saved from shared "); 14165 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14166 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14167 memInfoBuilder.append(" kB unshared; "); 14168 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14169 } 14170 memInfoBuilder.append(" Free RAM: "); 14171 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14172 + memInfo.getFreeSizeKb()); 14173 memInfoBuilder.append(" kB\n"); 14174 memInfoBuilder.append(" Used RAM: "); 14175 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14176 memInfoBuilder.append(" kB\n"); 14177 memInfoBuilder.append(" Lost RAM: "); 14178 memInfoBuilder.append(memInfo.getTotalSizeKb() 14179 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14180 - memInfo.getKernelUsedSizeKb()); 14181 memInfoBuilder.append(" kB\n"); 14182 Slog.i(TAG, "Low on memory:"); 14183 Slog.i(TAG, shortNativeBuilder.toString()); 14184 Slog.i(TAG, fullJavaBuilder.toString()); 14185 Slog.i(TAG, memInfoBuilder.toString()); 14186 14187 StringBuilder dropBuilder = new StringBuilder(1024); 14188 /* 14189 StringWriter oomSw = new StringWriter(); 14190 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14191 StringWriter catSw = new StringWriter(); 14192 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14193 String[] emptyArgs = new String[] { }; 14194 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14195 oomPw.flush(); 14196 String oomString = oomSw.toString(); 14197 */ 14198 dropBuilder.append("Low on memory:"); 14199 dropBuilder.append(stack); 14200 dropBuilder.append('\n'); 14201 dropBuilder.append(fullNativeBuilder); 14202 dropBuilder.append(fullJavaBuilder); 14203 dropBuilder.append('\n'); 14204 dropBuilder.append(memInfoBuilder); 14205 dropBuilder.append('\n'); 14206 /* 14207 dropBuilder.append(oomString); 14208 dropBuilder.append('\n'); 14209 */ 14210 StringWriter catSw = new StringWriter(); 14211 synchronized (ActivityManagerService.this) { 14212 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14213 String[] emptyArgs = new String[] { }; 14214 catPw.println(); 14215 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14216 catPw.println(); 14217 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14218 false, false, null); 14219 catPw.println(); 14220 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14221 catPw.flush(); 14222 } 14223 dropBuilder.append(catSw.toString()); 14224 addErrorToDropBox("lowmem", null, "system_server", null, 14225 null, tag.toString(), dropBuilder.toString(), null, null); 14226 //Slog.i(TAG, "Sent to dropbox:"); 14227 //Slog.i(TAG, dropBuilder.toString()); 14228 synchronized (ActivityManagerService.this) { 14229 long now = SystemClock.uptimeMillis(); 14230 if (mLastMemUsageReportTime < now) { 14231 mLastMemUsageReportTime = now; 14232 } 14233 } 14234 } 14235 14236 /** 14237 * Searches array of arguments for the specified string 14238 * @param args array of argument strings 14239 * @param value value to search for 14240 * @return true if the value is contained in the array 14241 */ 14242 private static boolean scanArgs(String[] args, String value) { 14243 if (args != null) { 14244 for (String arg : args) { 14245 if (value.equals(arg)) { 14246 return true; 14247 } 14248 } 14249 } 14250 return false; 14251 } 14252 14253 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14254 ContentProviderRecord cpr, boolean always) { 14255 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14256 14257 if (!inLaunching || always) { 14258 synchronized (cpr) { 14259 cpr.launchingApp = null; 14260 cpr.notifyAll(); 14261 } 14262 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14263 String names[] = cpr.info.authority.split(";"); 14264 for (int j = 0; j < names.length; j++) { 14265 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14266 } 14267 } 14268 14269 for (int i=0; i<cpr.connections.size(); i++) { 14270 ContentProviderConnection conn = cpr.connections.get(i); 14271 if (conn.waiting) { 14272 // If this connection is waiting for the provider, then we don't 14273 // need to mess with its process unless we are always removing 14274 // or for some reason the provider is not currently launching. 14275 if (inLaunching && !always) { 14276 continue; 14277 } 14278 } 14279 ProcessRecord capp = conn.client; 14280 conn.dead = true; 14281 if (conn.stableCount > 0) { 14282 if (!capp.persistent && capp.thread != null 14283 && capp.pid != 0 14284 && capp.pid != MY_PID) { 14285 capp.kill("depends on provider " 14286 + cpr.name.flattenToShortString() 14287 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14288 } 14289 } else if (capp.thread != null && conn.provider.provider != null) { 14290 try { 14291 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14292 } catch (RemoteException e) { 14293 } 14294 // In the protocol here, we don't expect the client to correctly 14295 // clean up this connection, we'll just remove it. 14296 cpr.connections.remove(i); 14297 if (conn.client.conProviders.remove(conn)) { 14298 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14299 } 14300 } 14301 } 14302 14303 if (inLaunching && always) { 14304 mLaunchingProviders.remove(cpr); 14305 } 14306 return inLaunching; 14307 } 14308 14309 /** 14310 * Main code for cleaning up a process when it has gone away. This is 14311 * called both as a result of the process dying, or directly when stopping 14312 * a process when running in single process mode. 14313 * 14314 * @return Returns true if the given process has been restarted, so the 14315 * app that was passed in must remain on the process lists. 14316 */ 14317 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14318 boolean restarting, boolean allowRestart, int index) { 14319 if (index >= 0) { 14320 removeLruProcessLocked(app); 14321 ProcessList.remove(app.pid); 14322 } 14323 14324 mProcessesToGc.remove(app); 14325 mPendingPssProcesses.remove(app); 14326 14327 // Dismiss any open dialogs. 14328 if (app.crashDialog != null && !app.forceCrashReport) { 14329 app.crashDialog.dismiss(); 14330 app.crashDialog = null; 14331 } 14332 if (app.anrDialog != null) { 14333 app.anrDialog.dismiss(); 14334 app.anrDialog = null; 14335 } 14336 if (app.waitDialog != null) { 14337 app.waitDialog.dismiss(); 14338 app.waitDialog = null; 14339 } 14340 14341 app.crashing = false; 14342 app.notResponding = false; 14343 14344 app.resetPackageList(mProcessStats); 14345 app.unlinkDeathRecipient(); 14346 app.makeInactive(mProcessStats); 14347 app.waitingToKill = null; 14348 app.forcingToForeground = null; 14349 updateProcessForegroundLocked(app, false, false); 14350 app.foregroundActivities = false; 14351 app.hasShownUi = false; 14352 app.treatLikeActivity = false; 14353 app.hasAboveClient = false; 14354 app.hasClientActivities = false; 14355 14356 mServices.killServicesLocked(app, allowRestart); 14357 14358 boolean restart = false; 14359 14360 // Remove published content providers. 14361 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14362 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14363 final boolean always = app.bad || !allowRestart; 14364 if (removeDyingProviderLocked(app, cpr, always) || always) { 14365 // We left the provider in the launching list, need to 14366 // restart it. 14367 restart = true; 14368 } 14369 14370 cpr.provider = null; 14371 cpr.proc = null; 14372 } 14373 app.pubProviders.clear(); 14374 14375 // Take care of any launching providers waiting for this process. 14376 if (checkAppInLaunchingProvidersLocked(app, false)) { 14377 restart = true; 14378 } 14379 14380 // Unregister from connected content providers. 14381 if (!app.conProviders.isEmpty()) { 14382 for (int i=0; i<app.conProviders.size(); i++) { 14383 ContentProviderConnection conn = app.conProviders.get(i); 14384 conn.provider.connections.remove(conn); 14385 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14386 conn.provider.name); 14387 } 14388 app.conProviders.clear(); 14389 } 14390 14391 // At this point there may be remaining entries in mLaunchingProviders 14392 // where we were the only one waiting, so they are no longer of use. 14393 // Look for these and clean up if found. 14394 // XXX Commented out for now. Trying to figure out a way to reproduce 14395 // the actual situation to identify what is actually going on. 14396 if (false) { 14397 for (int i=0; i<mLaunchingProviders.size(); i++) { 14398 ContentProviderRecord cpr = (ContentProviderRecord) 14399 mLaunchingProviders.get(i); 14400 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14401 synchronized (cpr) { 14402 cpr.launchingApp = null; 14403 cpr.notifyAll(); 14404 } 14405 } 14406 } 14407 } 14408 14409 skipCurrentReceiverLocked(app); 14410 14411 // Unregister any receivers. 14412 for (int i=app.receivers.size()-1; i>=0; i--) { 14413 removeReceiverLocked(app.receivers.valueAt(i)); 14414 } 14415 app.receivers.clear(); 14416 14417 // If the app is undergoing backup, tell the backup manager about it 14418 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14419 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14420 + mBackupTarget.appInfo + " died during backup"); 14421 try { 14422 IBackupManager bm = IBackupManager.Stub.asInterface( 14423 ServiceManager.getService(Context.BACKUP_SERVICE)); 14424 bm.agentDisconnected(app.info.packageName); 14425 } catch (RemoteException e) { 14426 // can't happen; backup manager is local 14427 } 14428 } 14429 14430 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14431 ProcessChangeItem item = mPendingProcessChanges.get(i); 14432 if (item.pid == app.pid) { 14433 mPendingProcessChanges.remove(i); 14434 mAvailProcessChanges.add(item); 14435 } 14436 } 14437 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14438 14439 // If the caller is restarting this app, then leave it in its 14440 // current lists and let the caller take care of it. 14441 if (restarting) { 14442 return false; 14443 } 14444 14445 if (!app.persistent || app.isolated) { 14446 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14447 "Removing non-persistent process during cleanup: " + app); 14448 mProcessNames.remove(app.processName, app.uid); 14449 mIsolatedProcesses.remove(app.uid); 14450 if (mHeavyWeightProcess == app) { 14451 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14452 mHeavyWeightProcess.userId, 0)); 14453 mHeavyWeightProcess = null; 14454 } 14455 } else if (!app.removed) { 14456 // This app is persistent, so we need to keep its record around. 14457 // If it is not already on the pending app list, add it there 14458 // and start a new process for it. 14459 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14460 mPersistentStartingProcesses.add(app); 14461 restart = true; 14462 } 14463 } 14464 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14465 "Clean-up removing on hold: " + app); 14466 mProcessesOnHold.remove(app); 14467 14468 if (app == mHomeProcess) { 14469 mHomeProcess = null; 14470 } 14471 if (app == mPreviousProcess) { 14472 mPreviousProcess = null; 14473 } 14474 14475 if (restart && !app.isolated) { 14476 // We have components that still need to be running in the 14477 // process, so re-launch it. 14478 if (index < 0) { 14479 ProcessList.remove(app.pid); 14480 } 14481 mProcessNames.put(app.processName, app.uid, app); 14482 startProcessLocked(app, "restart", app.processName); 14483 return true; 14484 } else if (app.pid > 0 && app.pid != MY_PID) { 14485 // Goodbye! 14486 boolean removed; 14487 synchronized (mPidsSelfLocked) { 14488 mPidsSelfLocked.remove(app.pid); 14489 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14490 } 14491 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14492 if (app.isolated) { 14493 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14494 } 14495 app.setPid(0); 14496 } 14497 return false; 14498 } 14499 14500 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14501 // Look through the content providers we are waiting to have launched, 14502 // and if any run in this process then either schedule a restart of 14503 // the process or kill the client waiting for it if this process has 14504 // gone bad. 14505 int NL = mLaunchingProviders.size(); 14506 boolean restart = false; 14507 for (int i=0; i<NL; i++) { 14508 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14509 if (cpr.launchingApp == app) { 14510 if (!alwaysBad && !app.bad) { 14511 restart = true; 14512 } else { 14513 removeDyingProviderLocked(app, cpr, true); 14514 // cpr should have been removed from mLaunchingProviders 14515 NL = mLaunchingProviders.size(); 14516 i--; 14517 } 14518 } 14519 } 14520 return restart; 14521 } 14522 14523 // ========================================================= 14524 // SERVICES 14525 // ========================================================= 14526 14527 @Override 14528 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14529 int flags) { 14530 enforceNotIsolatedCaller("getServices"); 14531 synchronized (this) { 14532 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14533 } 14534 } 14535 14536 @Override 14537 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14538 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14539 synchronized (this) { 14540 return mServices.getRunningServiceControlPanelLocked(name); 14541 } 14542 } 14543 14544 @Override 14545 public ComponentName startService(IApplicationThread caller, Intent service, 14546 String resolvedType, int userId) { 14547 enforceNotIsolatedCaller("startService"); 14548 // Refuse possible leaked file descriptors 14549 if (service != null && service.hasFileDescriptors() == true) { 14550 throw new IllegalArgumentException("File descriptors passed in Intent"); 14551 } 14552 14553 if (DEBUG_SERVICE) 14554 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14555 synchronized(this) { 14556 final int callingPid = Binder.getCallingPid(); 14557 final int callingUid = Binder.getCallingUid(); 14558 final long origId = Binder.clearCallingIdentity(); 14559 ComponentName res = mServices.startServiceLocked(caller, service, 14560 resolvedType, callingPid, callingUid, userId); 14561 Binder.restoreCallingIdentity(origId); 14562 return res; 14563 } 14564 } 14565 14566 ComponentName startServiceInPackage(int uid, 14567 Intent service, String resolvedType, int userId) { 14568 synchronized(this) { 14569 if (DEBUG_SERVICE) 14570 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14571 final long origId = Binder.clearCallingIdentity(); 14572 ComponentName res = mServices.startServiceLocked(null, service, 14573 resolvedType, -1, uid, userId); 14574 Binder.restoreCallingIdentity(origId); 14575 return res; 14576 } 14577 } 14578 14579 @Override 14580 public int stopService(IApplicationThread caller, Intent service, 14581 String resolvedType, int userId) { 14582 enforceNotIsolatedCaller("stopService"); 14583 // Refuse possible leaked file descriptors 14584 if (service != null && service.hasFileDescriptors() == true) { 14585 throw new IllegalArgumentException("File descriptors passed in Intent"); 14586 } 14587 14588 synchronized(this) { 14589 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14590 } 14591 } 14592 14593 @Override 14594 public IBinder peekService(Intent service, String resolvedType) { 14595 enforceNotIsolatedCaller("peekService"); 14596 // Refuse possible leaked file descriptors 14597 if (service != null && service.hasFileDescriptors() == true) { 14598 throw new IllegalArgumentException("File descriptors passed in Intent"); 14599 } 14600 synchronized(this) { 14601 return mServices.peekServiceLocked(service, resolvedType); 14602 } 14603 } 14604 14605 @Override 14606 public boolean stopServiceToken(ComponentName className, IBinder token, 14607 int startId) { 14608 synchronized(this) { 14609 return mServices.stopServiceTokenLocked(className, token, startId); 14610 } 14611 } 14612 14613 @Override 14614 public void setServiceForeground(ComponentName className, IBinder token, 14615 int id, Notification notification, boolean removeNotification) { 14616 synchronized(this) { 14617 mServices.setServiceForegroundLocked(className, token, id, notification, 14618 removeNotification); 14619 } 14620 } 14621 14622 @Override 14623 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14624 boolean requireFull, String name, String callerPackage) { 14625 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14626 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14627 } 14628 14629 int unsafeConvertIncomingUser(int userId) { 14630 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14631 ? mCurrentUserId : userId; 14632 } 14633 14634 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14635 int allowMode, String name, String callerPackage) { 14636 final int callingUserId = UserHandle.getUserId(callingUid); 14637 if (callingUserId == userId) { 14638 return userId; 14639 } 14640 14641 // Note that we may be accessing mCurrentUserId outside of a lock... 14642 // shouldn't be a big deal, if this is being called outside 14643 // of a locked context there is intrinsically a race with 14644 // the value the caller will receive and someone else changing it. 14645 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14646 // we will switch to the calling user if access to the current user fails. 14647 int targetUserId = unsafeConvertIncomingUser(userId); 14648 14649 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14650 final boolean allow; 14651 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14652 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14653 // If the caller has this permission, they always pass go. And collect $200. 14654 allow = true; 14655 } else if (allowMode == ALLOW_FULL_ONLY) { 14656 // We require full access, sucks to be you. 14657 allow = false; 14658 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14659 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14660 // If the caller does not have either permission, they are always doomed. 14661 allow = false; 14662 } else if (allowMode == ALLOW_NON_FULL) { 14663 // We are blanket allowing non-full access, you lucky caller! 14664 allow = true; 14665 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14666 // We may or may not allow this depending on whether the two users are 14667 // in the same profile. 14668 synchronized (mUserProfileGroupIdsSelfLocked) { 14669 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14670 UserInfo.NO_PROFILE_GROUP_ID); 14671 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14672 UserInfo.NO_PROFILE_GROUP_ID); 14673 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14674 && callingProfile == targetProfile; 14675 } 14676 } else { 14677 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14678 } 14679 if (!allow) { 14680 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14681 // In this case, they would like to just execute as their 14682 // owner user instead of failing. 14683 targetUserId = callingUserId; 14684 } else { 14685 StringBuilder builder = new StringBuilder(128); 14686 builder.append("Permission Denial: "); 14687 builder.append(name); 14688 if (callerPackage != null) { 14689 builder.append(" from "); 14690 builder.append(callerPackage); 14691 } 14692 builder.append(" asks to run as user "); 14693 builder.append(userId); 14694 builder.append(" but is calling from user "); 14695 builder.append(UserHandle.getUserId(callingUid)); 14696 builder.append("; this requires "); 14697 builder.append(INTERACT_ACROSS_USERS_FULL); 14698 if (allowMode != ALLOW_FULL_ONLY) { 14699 builder.append(" or "); 14700 builder.append(INTERACT_ACROSS_USERS); 14701 } 14702 String msg = builder.toString(); 14703 Slog.w(TAG, msg); 14704 throw new SecurityException(msg); 14705 } 14706 } 14707 } 14708 if (!allowAll && targetUserId < 0) { 14709 throw new IllegalArgumentException( 14710 "Call does not support special user #" + targetUserId); 14711 } 14712 // Check shell permission 14713 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14714 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14715 targetUserId)) { 14716 throw new SecurityException("Shell does not have permission to access user " 14717 + targetUserId + "\n " + Debug.getCallers(3)); 14718 } 14719 } 14720 return targetUserId; 14721 } 14722 14723 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14724 String className, int flags) { 14725 boolean result = false; 14726 // For apps that don't have pre-defined UIDs, check for permission 14727 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14728 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14729 if (ActivityManager.checkUidPermission( 14730 INTERACT_ACROSS_USERS, 14731 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14732 ComponentName comp = new ComponentName(aInfo.packageName, className); 14733 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14734 + " requests FLAG_SINGLE_USER, but app does not hold " 14735 + INTERACT_ACROSS_USERS; 14736 Slog.w(TAG, msg); 14737 throw new SecurityException(msg); 14738 } 14739 // Permission passed 14740 result = true; 14741 } 14742 } else if ("system".equals(componentProcessName)) { 14743 result = true; 14744 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14745 // Phone app and persistent apps are allowed to export singleuser providers. 14746 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14747 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14748 } 14749 if (DEBUG_MU) { 14750 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14751 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14752 } 14753 return result; 14754 } 14755 14756 /** 14757 * Checks to see if the caller is in the same app as the singleton 14758 * component, or the component is in a special app. It allows special apps 14759 * to export singleton components but prevents exporting singleton 14760 * components for regular apps. 14761 */ 14762 boolean isValidSingletonCall(int callingUid, int componentUid) { 14763 int componentAppId = UserHandle.getAppId(componentUid); 14764 return UserHandle.isSameApp(callingUid, componentUid) 14765 || componentAppId == Process.SYSTEM_UID 14766 || componentAppId == Process.PHONE_UID 14767 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14768 == PackageManager.PERMISSION_GRANTED; 14769 } 14770 14771 public int bindService(IApplicationThread caller, IBinder token, 14772 Intent service, String resolvedType, 14773 IServiceConnection connection, int flags, int userId) { 14774 enforceNotIsolatedCaller("bindService"); 14775 14776 // Refuse possible leaked file descriptors 14777 if (service != null && service.hasFileDescriptors() == true) { 14778 throw new IllegalArgumentException("File descriptors passed in Intent"); 14779 } 14780 14781 synchronized(this) { 14782 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14783 connection, flags, userId); 14784 } 14785 } 14786 14787 public boolean unbindService(IServiceConnection connection) { 14788 synchronized (this) { 14789 return mServices.unbindServiceLocked(connection); 14790 } 14791 } 14792 14793 public void publishService(IBinder token, Intent intent, IBinder service) { 14794 // Refuse possible leaked file descriptors 14795 if (intent != null && intent.hasFileDescriptors() == true) { 14796 throw new IllegalArgumentException("File descriptors passed in Intent"); 14797 } 14798 14799 synchronized(this) { 14800 if (!(token instanceof ServiceRecord)) { 14801 throw new IllegalArgumentException("Invalid service token"); 14802 } 14803 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14804 } 14805 } 14806 14807 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14808 // Refuse possible leaked file descriptors 14809 if (intent != null && intent.hasFileDescriptors() == true) { 14810 throw new IllegalArgumentException("File descriptors passed in Intent"); 14811 } 14812 14813 synchronized(this) { 14814 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14815 } 14816 } 14817 14818 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14819 synchronized(this) { 14820 if (!(token instanceof ServiceRecord)) { 14821 throw new IllegalArgumentException("Invalid service token"); 14822 } 14823 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14824 } 14825 } 14826 14827 // ========================================================= 14828 // BACKUP AND RESTORE 14829 // ========================================================= 14830 14831 // Cause the target app to be launched if necessary and its backup agent 14832 // instantiated. The backup agent will invoke backupAgentCreated() on the 14833 // activity manager to announce its creation. 14834 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14835 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14836 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14837 14838 synchronized(this) { 14839 // !!! TODO: currently no check here that we're already bound 14840 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14841 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14842 synchronized (stats) { 14843 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14844 } 14845 14846 // Backup agent is now in use, its package can't be stopped. 14847 try { 14848 AppGlobals.getPackageManager().setPackageStoppedState( 14849 app.packageName, false, UserHandle.getUserId(app.uid)); 14850 } catch (RemoteException e) { 14851 } catch (IllegalArgumentException e) { 14852 Slog.w(TAG, "Failed trying to unstop package " 14853 + app.packageName + ": " + e); 14854 } 14855 14856 BackupRecord r = new BackupRecord(ss, app, backupMode); 14857 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14858 ? new ComponentName(app.packageName, app.backupAgentName) 14859 : new ComponentName("android", "FullBackupAgent"); 14860 // startProcessLocked() returns existing proc's record if it's already running 14861 ProcessRecord proc = startProcessLocked(app.processName, app, 14862 false, 0, "backup", hostingName, false, false, false); 14863 if (proc == null) { 14864 Slog.e(TAG, "Unable to start backup agent process " + r); 14865 return false; 14866 } 14867 14868 r.app = proc; 14869 mBackupTarget = r; 14870 mBackupAppName = app.packageName; 14871 14872 // Try not to kill the process during backup 14873 updateOomAdjLocked(proc); 14874 14875 // If the process is already attached, schedule the creation of the backup agent now. 14876 // If it is not yet live, this will be done when it attaches to the framework. 14877 if (proc.thread != null) { 14878 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14879 try { 14880 proc.thread.scheduleCreateBackupAgent(app, 14881 compatibilityInfoForPackageLocked(app), backupMode); 14882 } catch (RemoteException e) { 14883 // Will time out on the backup manager side 14884 } 14885 } else { 14886 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14887 } 14888 // Invariants: at this point, the target app process exists and the application 14889 // is either already running or in the process of coming up. mBackupTarget and 14890 // mBackupAppName describe the app, so that when it binds back to the AM we 14891 // know that it's scheduled for a backup-agent operation. 14892 } 14893 14894 return true; 14895 } 14896 14897 @Override 14898 public void clearPendingBackup() { 14899 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14900 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14901 14902 synchronized (this) { 14903 mBackupTarget = null; 14904 mBackupAppName = null; 14905 } 14906 } 14907 14908 // A backup agent has just come up 14909 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14910 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14911 + " = " + agent); 14912 14913 synchronized(this) { 14914 if (!agentPackageName.equals(mBackupAppName)) { 14915 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14916 return; 14917 } 14918 } 14919 14920 long oldIdent = Binder.clearCallingIdentity(); 14921 try { 14922 IBackupManager bm = IBackupManager.Stub.asInterface( 14923 ServiceManager.getService(Context.BACKUP_SERVICE)); 14924 bm.agentConnected(agentPackageName, agent); 14925 } catch (RemoteException e) { 14926 // can't happen; the backup manager service is local 14927 } catch (Exception e) { 14928 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14929 e.printStackTrace(); 14930 } finally { 14931 Binder.restoreCallingIdentity(oldIdent); 14932 } 14933 } 14934 14935 // done with this agent 14936 public void unbindBackupAgent(ApplicationInfo appInfo) { 14937 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14938 if (appInfo == null) { 14939 Slog.w(TAG, "unbind backup agent for null app"); 14940 return; 14941 } 14942 14943 synchronized(this) { 14944 try { 14945 if (mBackupAppName == null) { 14946 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14947 return; 14948 } 14949 14950 if (!mBackupAppName.equals(appInfo.packageName)) { 14951 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14952 return; 14953 } 14954 14955 // Not backing this app up any more; reset its OOM adjustment 14956 final ProcessRecord proc = mBackupTarget.app; 14957 updateOomAdjLocked(proc); 14958 14959 // If the app crashed during backup, 'thread' will be null here 14960 if (proc.thread != null) { 14961 try { 14962 proc.thread.scheduleDestroyBackupAgent(appInfo, 14963 compatibilityInfoForPackageLocked(appInfo)); 14964 } catch (Exception e) { 14965 Slog.e(TAG, "Exception when unbinding backup agent:"); 14966 e.printStackTrace(); 14967 } 14968 } 14969 } finally { 14970 mBackupTarget = null; 14971 mBackupAppName = null; 14972 } 14973 } 14974 } 14975 // ========================================================= 14976 // BROADCASTS 14977 // ========================================================= 14978 14979 private final List getStickiesLocked(String action, IntentFilter filter, 14980 List cur, int userId) { 14981 final ContentResolver resolver = mContext.getContentResolver(); 14982 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14983 if (stickies == null) { 14984 return cur; 14985 } 14986 final ArrayList<Intent> list = stickies.get(action); 14987 if (list == null) { 14988 return cur; 14989 } 14990 int N = list.size(); 14991 for (int i=0; i<N; i++) { 14992 Intent intent = list.get(i); 14993 if (filter.match(resolver, intent, true, TAG) >= 0) { 14994 if (cur == null) { 14995 cur = new ArrayList<Intent>(); 14996 } 14997 cur.add(intent); 14998 } 14999 } 15000 return cur; 15001 } 15002 15003 boolean isPendingBroadcastProcessLocked(int pid) { 15004 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15005 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15006 } 15007 15008 void skipPendingBroadcastLocked(int pid) { 15009 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15010 for (BroadcastQueue queue : mBroadcastQueues) { 15011 queue.skipPendingBroadcastLocked(pid); 15012 } 15013 } 15014 15015 // The app just attached; send any pending broadcasts that it should receive 15016 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15017 boolean didSomething = false; 15018 for (BroadcastQueue queue : mBroadcastQueues) { 15019 didSomething |= queue.sendPendingBroadcastsLocked(app); 15020 } 15021 return didSomething; 15022 } 15023 15024 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15025 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15026 enforceNotIsolatedCaller("registerReceiver"); 15027 int callingUid; 15028 int callingPid; 15029 synchronized(this) { 15030 ProcessRecord callerApp = null; 15031 if (caller != null) { 15032 callerApp = getRecordForAppLocked(caller); 15033 if (callerApp == null) { 15034 throw new SecurityException( 15035 "Unable to find app for caller " + caller 15036 + " (pid=" + Binder.getCallingPid() 15037 + ") when registering receiver " + receiver); 15038 } 15039 if (callerApp.info.uid != Process.SYSTEM_UID && 15040 !callerApp.pkgList.containsKey(callerPackage) && 15041 !"android".equals(callerPackage)) { 15042 throw new SecurityException("Given caller package " + callerPackage 15043 + " is not running in process " + callerApp); 15044 } 15045 callingUid = callerApp.info.uid; 15046 callingPid = callerApp.pid; 15047 } else { 15048 callerPackage = null; 15049 callingUid = Binder.getCallingUid(); 15050 callingPid = Binder.getCallingPid(); 15051 } 15052 15053 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15054 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15055 15056 List allSticky = null; 15057 15058 // Look for any matching sticky broadcasts... 15059 Iterator actions = filter.actionsIterator(); 15060 if (actions != null) { 15061 while (actions.hasNext()) { 15062 String action = (String)actions.next(); 15063 allSticky = getStickiesLocked(action, filter, allSticky, 15064 UserHandle.USER_ALL); 15065 allSticky = getStickiesLocked(action, filter, allSticky, 15066 UserHandle.getUserId(callingUid)); 15067 } 15068 } else { 15069 allSticky = getStickiesLocked(null, filter, allSticky, 15070 UserHandle.USER_ALL); 15071 allSticky = getStickiesLocked(null, filter, allSticky, 15072 UserHandle.getUserId(callingUid)); 15073 } 15074 15075 // The first sticky in the list is returned directly back to 15076 // the client. 15077 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15078 15079 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15080 + ": " + sticky); 15081 15082 if (receiver == null) { 15083 return sticky; 15084 } 15085 15086 ReceiverList rl 15087 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15088 if (rl == null) { 15089 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15090 userId, receiver); 15091 if (rl.app != null) { 15092 rl.app.receivers.add(rl); 15093 } else { 15094 try { 15095 receiver.asBinder().linkToDeath(rl, 0); 15096 } catch (RemoteException e) { 15097 return sticky; 15098 } 15099 rl.linkedToDeath = true; 15100 } 15101 mRegisteredReceivers.put(receiver.asBinder(), rl); 15102 } else if (rl.uid != callingUid) { 15103 throw new IllegalArgumentException( 15104 "Receiver requested to register for uid " + callingUid 15105 + " was previously registered for uid " + rl.uid); 15106 } else if (rl.pid != callingPid) { 15107 throw new IllegalArgumentException( 15108 "Receiver requested to register for pid " + callingPid 15109 + " was previously registered for pid " + rl.pid); 15110 } else if (rl.userId != userId) { 15111 throw new IllegalArgumentException( 15112 "Receiver requested to register for user " + userId 15113 + " was previously registered for user " + rl.userId); 15114 } 15115 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15116 permission, callingUid, userId); 15117 rl.add(bf); 15118 if (!bf.debugCheck()) { 15119 Slog.w(TAG, "==> For Dynamic broadast"); 15120 } 15121 mReceiverResolver.addFilter(bf); 15122 15123 // Enqueue broadcasts for all existing stickies that match 15124 // this filter. 15125 if (allSticky != null) { 15126 ArrayList receivers = new ArrayList(); 15127 receivers.add(bf); 15128 15129 int N = allSticky.size(); 15130 for (int i=0; i<N; i++) { 15131 Intent intent = (Intent)allSticky.get(i); 15132 BroadcastQueue queue = broadcastQueueForIntent(intent); 15133 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15134 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15135 null, null, false, true, true, -1); 15136 queue.enqueueParallelBroadcastLocked(r); 15137 queue.scheduleBroadcastsLocked(); 15138 } 15139 } 15140 15141 return sticky; 15142 } 15143 } 15144 15145 public void unregisterReceiver(IIntentReceiver receiver) { 15146 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15147 15148 final long origId = Binder.clearCallingIdentity(); 15149 try { 15150 boolean doTrim = false; 15151 15152 synchronized(this) { 15153 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15154 if (rl != null) { 15155 final BroadcastRecord r = rl.curBroadcast; 15156 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 15157 final boolean doNext = r.queue.finishReceiverLocked( 15158 r, r.resultCode, r.resultData, r.resultExtras, 15159 r.resultAbort, false); 15160 if (doNext) { 15161 doTrim = true; 15162 r.queue.processNextBroadcast(false); 15163 } 15164 } 15165 15166 if (rl.app != null) { 15167 rl.app.receivers.remove(rl); 15168 } 15169 removeReceiverLocked(rl); 15170 if (rl.linkedToDeath) { 15171 rl.linkedToDeath = false; 15172 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15173 } 15174 } 15175 } 15176 15177 // If we actually concluded any broadcasts, we might now be able 15178 // to trim the recipients' apps from our working set 15179 if (doTrim) { 15180 trimApplications(); 15181 return; 15182 } 15183 15184 } finally { 15185 Binder.restoreCallingIdentity(origId); 15186 } 15187 } 15188 15189 void removeReceiverLocked(ReceiverList rl) { 15190 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15191 int N = rl.size(); 15192 for (int i=0; i<N; i++) { 15193 mReceiverResolver.removeFilter(rl.get(i)); 15194 } 15195 } 15196 15197 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15198 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15199 ProcessRecord r = mLruProcesses.get(i); 15200 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15201 try { 15202 r.thread.dispatchPackageBroadcast(cmd, packages); 15203 } catch (RemoteException ex) { 15204 } 15205 } 15206 } 15207 } 15208 15209 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15210 int callingUid, int[] users) { 15211 List<ResolveInfo> receivers = null; 15212 try { 15213 HashSet<ComponentName> singleUserReceivers = null; 15214 boolean scannedFirstReceivers = false; 15215 for (int user : users) { 15216 // Skip users that have Shell restrictions 15217 if (callingUid == Process.SHELL_UID 15218 && getUserManagerLocked().hasUserRestriction( 15219 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15220 continue; 15221 } 15222 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15223 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15224 if (user != 0 && newReceivers != null) { 15225 // If this is not the primary user, we need to check for 15226 // any receivers that should be filtered out. 15227 for (int i=0; i<newReceivers.size(); i++) { 15228 ResolveInfo ri = newReceivers.get(i); 15229 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15230 newReceivers.remove(i); 15231 i--; 15232 } 15233 } 15234 } 15235 if (newReceivers != null && newReceivers.size() == 0) { 15236 newReceivers = null; 15237 } 15238 if (receivers == null) { 15239 receivers = newReceivers; 15240 } else if (newReceivers != null) { 15241 // We need to concatenate the additional receivers 15242 // found with what we have do far. This would be easy, 15243 // but we also need to de-dup any receivers that are 15244 // singleUser. 15245 if (!scannedFirstReceivers) { 15246 // Collect any single user receivers we had already retrieved. 15247 scannedFirstReceivers = true; 15248 for (int i=0; i<receivers.size(); i++) { 15249 ResolveInfo ri = receivers.get(i); 15250 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15251 ComponentName cn = new ComponentName( 15252 ri.activityInfo.packageName, ri.activityInfo.name); 15253 if (singleUserReceivers == null) { 15254 singleUserReceivers = new HashSet<ComponentName>(); 15255 } 15256 singleUserReceivers.add(cn); 15257 } 15258 } 15259 } 15260 // Add the new results to the existing results, tracking 15261 // and de-dupping single user receivers. 15262 for (int i=0; i<newReceivers.size(); i++) { 15263 ResolveInfo ri = newReceivers.get(i); 15264 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15265 ComponentName cn = new ComponentName( 15266 ri.activityInfo.packageName, ri.activityInfo.name); 15267 if (singleUserReceivers == null) { 15268 singleUserReceivers = new HashSet<ComponentName>(); 15269 } 15270 if (!singleUserReceivers.contains(cn)) { 15271 singleUserReceivers.add(cn); 15272 receivers.add(ri); 15273 } 15274 } else { 15275 receivers.add(ri); 15276 } 15277 } 15278 } 15279 } 15280 } catch (RemoteException ex) { 15281 // pm is in same process, this will never happen. 15282 } 15283 return receivers; 15284 } 15285 15286 private final int broadcastIntentLocked(ProcessRecord callerApp, 15287 String callerPackage, Intent intent, String resolvedType, 15288 IIntentReceiver resultTo, int resultCode, String resultData, 15289 Bundle map, String requiredPermission, int appOp, 15290 boolean ordered, boolean sticky, int callingPid, int callingUid, 15291 int userId) { 15292 intent = new Intent(intent); 15293 15294 // By default broadcasts do not go to stopped apps. 15295 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15296 15297 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15298 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15299 + " ordered=" + ordered + " userid=" + userId); 15300 if ((resultTo != null) && !ordered) { 15301 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15302 } 15303 15304 userId = handleIncomingUser(callingPid, callingUid, userId, 15305 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15306 15307 // Make sure that the user who is receiving this broadcast is running. 15308 // If not, we will just skip it. Make an exception for shutdown broadcasts 15309 // and upgrade steps. 15310 15311 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15312 if ((callingUid != Process.SYSTEM_UID 15313 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15314 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15315 Slog.w(TAG, "Skipping broadcast of " + intent 15316 + ": user " + userId + " is stopped"); 15317 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15318 } 15319 } 15320 15321 /* 15322 * Prevent non-system code (defined here to be non-persistent 15323 * processes) from sending protected broadcasts. 15324 */ 15325 int callingAppId = UserHandle.getAppId(callingUid); 15326 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15327 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15328 || callingAppId == Process.NFC_UID || callingUid == 0) { 15329 // Always okay. 15330 } else if (callerApp == null || !callerApp.persistent) { 15331 try { 15332 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15333 intent.getAction())) { 15334 String msg = "Permission Denial: not allowed to send broadcast " 15335 + intent.getAction() + " from pid=" 15336 + callingPid + ", uid=" + callingUid; 15337 Slog.w(TAG, msg); 15338 throw new SecurityException(msg); 15339 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15340 // Special case for compatibility: we don't want apps to send this, 15341 // but historically it has not been protected and apps may be using it 15342 // to poke their own app widget. So, instead of making it protected, 15343 // just limit it to the caller. 15344 if (callerApp == null) { 15345 String msg = "Permission Denial: not allowed to send broadcast " 15346 + intent.getAction() + " from unknown caller."; 15347 Slog.w(TAG, msg); 15348 throw new SecurityException(msg); 15349 } else if (intent.getComponent() != null) { 15350 // They are good enough to send to an explicit component... verify 15351 // it is being sent to the calling app. 15352 if (!intent.getComponent().getPackageName().equals( 15353 callerApp.info.packageName)) { 15354 String msg = "Permission Denial: not allowed to send broadcast " 15355 + intent.getAction() + " to " 15356 + intent.getComponent().getPackageName() + " from " 15357 + callerApp.info.packageName; 15358 Slog.w(TAG, msg); 15359 throw new SecurityException(msg); 15360 } 15361 } else { 15362 // Limit broadcast to their own package. 15363 intent.setPackage(callerApp.info.packageName); 15364 } 15365 } 15366 } catch (RemoteException e) { 15367 Slog.w(TAG, "Remote exception", e); 15368 return ActivityManager.BROADCAST_SUCCESS; 15369 } 15370 } 15371 15372 final String action = intent.getAction(); 15373 if (action != null) { 15374 switch (action) { 15375 case Intent.ACTION_UID_REMOVED: 15376 case Intent.ACTION_PACKAGE_REMOVED: 15377 case Intent.ACTION_PACKAGE_CHANGED: 15378 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15379 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15380 // Handle special intents: if this broadcast is from the package 15381 // manager about a package being removed, we need to remove all of 15382 // its activities from the history stack. 15383 if (checkComponentPermission( 15384 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15385 callingPid, callingUid, -1, true) 15386 != PackageManager.PERMISSION_GRANTED) { 15387 String msg = "Permission Denial: " + intent.getAction() 15388 + " broadcast from " + callerPackage + " (pid=" + callingPid 15389 + ", uid=" + callingUid + ")" 15390 + " requires " 15391 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15392 Slog.w(TAG, msg); 15393 throw new SecurityException(msg); 15394 } 15395 switch (action) { 15396 case Intent.ACTION_UID_REMOVED: 15397 final Bundle intentExtras = intent.getExtras(); 15398 final int uid = intentExtras != null 15399 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15400 if (uid >= 0) { 15401 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15402 synchronized (bs) { 15403 bs.removeUidStatsLocked(uid); 15404 } 15405 mAppOpsService.uidRemoved(uid); 15406 } 15407 break; 15408 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15409 // If resources are unavailable just force stop all those packages 15410 // and flush the attribute cache as well. 15411 String list[] = 15412 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15413 if (list != null && list.length > 0) { 15414 for (int i = 0; i < list.length; i++) { 15415 forceStopPackageLocked(list[i], -1, false, true, true, 15416 false, false, userId, "storage unmount"); 15417 } 15418 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 15419 sendPackageBroadcastLocked( 15420 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15421 userId); 15422 } 15423 break; 15424 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15425 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 15426 break; 15427 case Intent.ACTION_PACKAGE_REMOVED: 15428 case Intent.ACTION_PACKAGE_CHANGED: 15429 Uri data = intent.getData(); 15430 String ssp; 15431 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15432 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15433 boolean fullUninstall = removed && 15434 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15435 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15436 forceStopPackageLocked(ssp, UserHandle.getAppId( 15437 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15438 false, true, true, false, fullUninstall, userId, 15439 removed ? "pkg removed" : "pkg changed"); 15440 } 15441 if (removed) { 15442 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15443 new String[] {ssp}, userId); 15444 if (fullUninstall) { 15445 mAppOpsService.packageRemoved( 15446 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15447 15448 // Remove all permissions granted from/to this package 15449 removeUriPermissionsForPackageLocked(ssp, userId, true); 15450 15451 removeTasksByPackageNameLocked(ssp, userId); 15452 } 15453 } else { 15454 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15455 if (userId == UserHandle.USER_OWNER) { 15456 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15457 } 15458 } 15459 } 15460 break; 15461 } 15462 break; 15463 case Intent.ACTION_PACKAGE_ADDED: 15464 // Special case for adding a package: by default turn on compatibility mode. 15465 Uri data = intent.getData(); 15466 String ssp; 15467 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15468 final boolean replacing = 15469 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15470 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15471 15472 if (replacing) { 15473 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15474 } 15475 if (userId == UserHandle.USER_OWNER) { 15476 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15477 } 15478 } 15479 break; 15480 case Intent.ACTION_TIMEZONE_CHANGED: 15481 // If this is the time zone changed action, queue up a message that will reset 15482 // the timezone of all currently running processes. This message will get 15483 // queued up before the broadcast happens. 15484 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15485 break; 15486 case Intent.ACTION_TIME_CHANGED: 15487 // If the user set the time, let all running processes know. 15488 final int is24Hour = 15489 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15490 : 0; 15491 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15492 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15493 synchronized (stats) { 15494 stats.noteCurrentTimeChangedLocked(); 15495 } 15496 break; 15497 case Intent.ACTION_CLEAR_DNS_CACHE: 15498 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15499 break; 15500 case Proxy.PROXY_CHANGE_ACTION: 15501 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15502 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15503 break; 15504 } 15505 } 15506 15507 // Add to the sticky list if requested. 15508 if (sticky) { 15509 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15510 callingPid, callingUid) 15511 != PackageManager.PERMISSION_GRANTED) { 15512 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15513 + callingPid + ", uid=" + callingUid 15514 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15515 Slog.w(TAG, msg); 15516 throw new SecurityException(msg); 15517 } 15518 if (requiredPermission != null) { 15519 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15520 + " and enforce permission " + requiredPermission); 15521 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15522 } 15523 if (intent.getComponent() != null) { 15524 throw new SecurityException( 15525 "Sticky broadcasts can't target a specific component"); 15526 } 15527 // We use userId directly here, since the "all" target is maintained 15528 // as a separate set of sticky broadcasts. 15529 if (userId != UserHandle.USER_ALL) { 15530 // But first, if this is not a broadcast to all users, then 15531 // make sure it doesn't conflict with an existing broadcast to 15532 // all users. 15533 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15534 UserHandle.USER_ALL); 15535 if (stickies != null) { 15536 ArrayList<Intent> list = stickies.get(intent.getAction()); 15537 if (list != null) { 15538 int N = list.size(); 15539 int i; 15540 for (i=0; i<N; i++) { 15541 if (intent.filterEquals(list.get(i))) { 15542 throw new IllegalArgumentException( 15543 "Sticky broadcast " + intent + " for user " 15544 + userId + " conflicts with existing global broadcast"); 15545 } 15546 } 15547 } 15548 } 15549 } 15550 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15551 if (stickies == null) { 15552 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15553 mStickyBroadcasts.put(userId, stickies); 15554 } 15555 ArrayList<Intent> list = stickies.get(intent.getAction()); 15556 if (list == null) { 15557 list = new ArrayList<Intent>(); 15558 stickies.put(intent.getAction(), list); 15559 } 15560 int N = list.size(); 15561 int i; 15562 for (i=0; i<N; i++) { 15563 if (intent.filterEquals(list.get(i))) { 15564 // This sticky already exists, replace it. 15565 list.set(i, new Intent(intent)); 15566 break; 15567 } 15568 } 15569 if (i >= N) { 15570 list.add(new Intent(intent)); 15571 } 15572 } 15573 15574 int[] users; 15575 if (userId == UserHandle.USER_ALL) { 15576 // Caller wants broadcast to go to all started users. 15577 users = mStartedUserArray; 15578 } else { 15579 // Caller wants broadcast to go to one specific user. 15580 users = new int[] {userId}; 15581 } 15582 15583 // Figure out who all will receive this broadcast. 15584 List receivers = null; 15585 List<BroadcastFilter> registeredReceivers = null; 15586 // Need to resolve the intent to interested receivers... 15587 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15588 == 0) { 15589 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15590 } 15591 if (intent.getComponent() == null) { 15592 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15593 // Query one target user at a time, excluding shell-restricted users 15594 UserManagerService ums = getUserManagerLocked(); 15595 for (int i = 0; i < users.length; i++) { 15596 if (ums.hasUserRestriction( 15597 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15598 continue; 15599 } 15600 List<BroadcastFilter> registeredReceiversForUser = 15601 mReceiverResolver.queryIntent(intent, 15602 resolvedType, false, users[i]); 15603 if (registeredReceivers == null) { 15604 registeredReceivers = registeredReceiversForUser; 15605 } else if (registeredReceiversForUser != null) { 15606 registeredReceivers.addAll(registeredReceiversForUser); 15607 } 15608 } 15609 } else { 15610 registeredReceivers = mReceiverResolver.queryIntent(intent, 15611 resolvedType, false, userId); 15612 } 15613 } 15614 15615 final boolean replacePending = 15616 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15617 15618 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15619 + " replacePending=" + replacePending); 15620 15621 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15622 if (!ordered && NR > 0) { 15623 // If we are not serializing this broadcast, then send the 15624 // registered receivers separately so they don't wait for the 15625 // components to be launched. 15626 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15627 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15628 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15629 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15630 ordered, sticky, false, userId); 15631 if (DEBUG_BROADCAST) Slog.v( 15632 TAG, "Enqueueing parallel broadcast " + r); 15633 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15634 if (!replaced) { 15635 queue.enqueueParallelBroadcastLocked(r); 15636 queue.scheduleBroadcastsLocked(); 15637 } 15638 registeredReceivers = null; 15639 NR = 0; 15640 } 15641 15642 // Merge into one list. 15643 int ir = 0; 15644 if (receivers != null) { 15645 // A special case for PACKAGE_ADDED: do not allow the package 15646 // being added to see this broadcast. This prevents them from 15647 // using this as a back door to get run as soon as they are 15648 // installed. Maybe in the future we want to have a special install 15649 // broadcast or such for apps, but we'd like to deliberately make 15650 // this decision. 15651 String skipPackages[] = null; 15652 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15653 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15654 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15655 Uri data = intent.getData(); 15656 if (data != null) { 15657 String pkgName = data.getSchemeSpecificPart(); 15658 if (pkgName != null) { 15659 skipPackages = new String[] { pkgName }; 15660 } 15661 } 15662 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15663 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15664 } 15665 if (skipPackages != null && (skipPackages.length > 0)) { 15666 for (String skipPackage : skipPackages) { 15667 if (skipPackage != null) { 15668 int NT = receivers.size(); 15669 for (int it=0; it<NT; it++) { 15670 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15671 if (curt.activityInfo.packageName.equals(skipPackage)) { 15672 receivers.remove(it); 15673 it--; 15674 NT--; 15675 } 15676 } 15677 } 15678 } 15679 } 15680 15681 int NT = receivers != null ? receivers.size() : 0; 15682 int it = 0; 15683 ResolveInfo curt = null; 15684 BroadcastFilter curr = null; 15685 while (it < NT && ir < NR) { 15686 if (curt == null) { 15687 curt = (ResolveInfo)receivers.get(it); 15688 } 15689 if (curr == null) { 15690 curr = registeredReceivers.get(ir); 15691 } 15692 if (curr.getPriority() >= curt.priority) { 15693 // Insert this broadcast record into the final list. 15694 receivers.add(it, curr); 15695 ir++; 15696 curr = null; 15697 it++; 15698 NT++; 15699 } else { 15700 // Skip to the next ResolveInfo in the final list. 15701 it++; 15702 curt = null; 15703 } 15704 } 15705 } 15706 while (ir < NR) { 15707 if (receivers == null) { 15708 receivers = new ArrayList(); 15709 } 15710 receivers.add(registeredReceivers.get(ir)); 15711 ir++; 15712 } 15713 15714 if ((receivers != null && receivers.size() > 0) 15715 || resultTo != null) { 15716 BroadcastQueue queue = broadcastQueueForIntent(intent); 15717 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15718 callerPackage, callingPid, callingUid, resolvedType, 15719 requiredPermission, appOp, receivers, resultTo, resultCode, 15720 resultData, map, ordered, sticky, false, userId); 15721 if (DEBUG_BROADCAST) Slog.v( 15722 TAG, "Enqueueing ordered broadcast " + r 15723 + ": prev had " + queue.mOrderedBroadcasts.size()); 15724 if (DEBUG_BROADCAST) { 15725 int seq = r.intent.getIntExtra("seq", -1); 15726 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15727 } 15728 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15729 if (!replaced) { 15730 queue.enqueueOrderedBroadcastLocked(r); 15731 queue.scheduleBroadcastsLocked(); 15732 } 15733 } 15734 15735 return ActivityManager.BROADCAST_SUCCESS; 15736 } 15737 15738 final Intent verifyBroadcastLocked(Intent intent) { 15739 // Refuse possible leaked file descriptors 15740 if (intent != null && intent.hasFileDescriptors() == true) { 15741 throw new IllegalArgumentException("File descriptors passed in Intent"); 15742 } 15743 15744 int flags = intent.getFlags(); 15745 15746 if (!mProcessesReady) { 15747 // if the caller really truly claims to know what they're doing, go 15748 // ahead and allow the broadcast without launching any receivers 15749 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15750 intent = new Intent(intent); 15751 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15752 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15753 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15754 + " before boot completion"); 15755 throw new IllegalStateException("Cannot broadcast before boot completed"); 15756 } 15757 } 15758 15759 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15760 throw new IllegalArgumentException( 15761 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15762 } 15763 15764 return intent; 15765 } 15766 15767 public final int broadcastIntent(IApplicationThread caller, 15768 Intent intent, String resolvedType, IIntentReceiver resultTo, 15769 int resultCode, String resultData, Bundle map, 15770 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15771 enforceNotIsolatedCaller("broadcastIntent"); 15772 synchronized(this) { 15773 intent = verifyBroadcastLocked(intent); 15774 15775 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15776 final int callingPid = Binder.getCallingPid(); 15777 final int callingUid = Binder.getCallingUid(); 15778 final long origId = Binder.clearCallingIdentity(); 15779 int res = broadcastIntentLocked(callerApp, 15780 callerApp != null ? callerApp.info.packageName : null, 15781 intent, resolvedType, resultTo, 15782 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15783 callingPid, callingUid, userId); 15784 Binder.restoreCallingIdentity(origId); 15785 return res; 15786 } 15787 } 15788 15789 int broadcastIntentInPackage(String packageName, int uid, 15790 Intent intent, String resolvedType, IIntentReceiver resultTo, 15791 int resultCode, String resultData, Bundle map, 15792 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15793 synchronized(this) { 15794 intent = verifyBroadcastLocked(intent); 15795 15796 final long origId = Binder.clearCallingIdentity(); 15797 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15798 resultTo, resultCode, resultData, map, requiredPermission, 15799 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15800 Binder.restoreCallingIdentity(origId); 15801 return res; 15802 } 15803 } 15804 15805 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15806 // Refuse possible leaked file descriptors 15807 if (intent != null && intent.hasFileDescriptors() == true) { 15808 throw new IllegalArgumentException("File descriptors passed in Intent"); 15809 } 15810 15811 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15812 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15813 15814 synchronized(this) { 15815 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15816 != PackageManager.PERMISSION_GRANTED) { 15817 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15818 + Binder.getCallingPid() 15819 + ", uid=" + Binder.getCallingUid() 15820 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15821 Slog.w(TAG, msg); 15822 throw new SecurityException(msg); 15823 } 15824 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15825 if (stickies != null) { 15826 ArrayList<Intent> list = stickies.get(intent.getAction()); 15827 if (list != null) { 15828 int N = list.size(); 15829 int i; 15830 for (i=0; i<N; i++) { 15831 if (intent.filterEquals(list.get(i))) { 15832 list.remove(i); 15833 break; 15834 } 15835 } 15836 if (list.size() <= 0) { 15837 stickies.remove(intent.getAction()); 15838 } 15839 } 15840 if (stickies.size() <= 0) { 15841 mStickyBroadcasts.remove(userId); 15842 } 15843 } 15844 } 15845 } 15846 15847 void backgroundServicesFinishedLocked(int userId) { 15848 for (BroadcastQueue queue : mBroadcastQueues) { 15849 queue.backgroundServicesFinishedLocked(userId); 15850 } 15851 } 15852 15853 public void finishReceiver(IBinder who, int resultCode, String resultData, 15854 Bundle resultExtras, boolean resultAbort, int flags) { 15855 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15856 15857 // Refuse possible leaked file descriptors 15858 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15859 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15860 } 15861 15862 final long origId = Binder.clearCallingIdentity(); 15863 try { 15864 boolean doNext = false; 15865 BroadcastRecord r; 15866 15867 synchronized(this) { 15868 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 15869 ? mFgBroadcastQueue : mBgBroadcastQueue; 15870 r = queue.getMatchingOrderedReceiver(who); 15871 if (r != null) { 15872 doNext = r.queue.finishReceiverLocked(r, resultCode, 15873 resultData, resultExtras, resultAbort, true); 15874 } 15875 } 15876 15877 if (doNext) { 15878 r.queue.processNextBroadcast(false); 15879 } 15880 trimApplications(); 15881 } finally { 15882 Binder.restoreCallingIdentity(origId); 15883 } 15884 } 15885 15886 // ========================================================= 15887 // INSTRUMENTATION 15888 // ========================================================= 15889 15890 public boolean startInstrumentation(ComponentName className, 15891 String profileFile, int flags, Bundle arguments, 15892 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15893 int userId, String abiOverride) { 15894 enforceNotIsolatedCaller("startInstrumentation"); 15895 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15896 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15897 // Refuse possible leaked file descriptors 15898 if (arguments != null && arguments.hasFileDescriptors()) { 15899 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15900 } 15901 15902 synchronized(this) { 15903 InstrumentationInfo ii = null; 15904 ApplicationInfo ai = null; 15905 try { 15906 ii = mContext.getPackageManager().getInstrumentationInfo( 15907 className, STOCK_PM_FLAGS); 15908 ai = AppGlobals.getPackageManager().getApplicationInfo( 15909 ii.targetPackage, STOCK_PM_FLAGS, userId); 15910 } catch (PackageManager.NameNotFoundException e) { 15911 } catch (RemoteException e) { 15912 } 15913 if (ii == null) { 15914 reportStartInstrumentationFailure(watcher, className, 15915 "Unable to find instrumentation info for: " + className); 15916 return false; 15917 } 15918 if (ai == null) { 15919 reportStartInstrumentationFailure(watcher, className, 15920 "Unable to find instrumentation target package: " + ii.targetPackage); 15921 return false; 15922 } 15923 15924 int match = mContext.getPackageManager().checkSignatures( 15925 ii.targetPackage, ii.packageName); 15926 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15927 String msg = "Permission Denial: starting instrumentation " 15928 + className + " from pid=" 15929 + Binder.getCallingPid() 15930 + ", uid=" + Binder.getCallingPid() 15931 + " not allowed because package " + ii.packageName 15932 + " does not have a signature matching the target " 15933 + ii.targetPackage; 15934 reportStartInstrumentationFailure(watcher, className, msg); 15935 throw new SecurityException(msg); 15936 } 15937 15938 final long origId = Binder.clearCallingIdentity(); 15939 // Instrumentation can kill and relaunch even persistent processes 15940 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15941 "start instr"); 15942 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15943 app.instrumentationClass = className; 15944 app.instrumentationInfo = ai; 15945 app.instrumentationProfileFile = profileFile; 15946 app.instrumentationArguments = arguments; 15947 app.instrumentationWatcher = watcher; 15948 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15949 app.instrumentationResultClass = className; 15950 Binder.restoreCallingIdentity(origId); 15951 } 15952 15953 return true; 15954 } 15955 15956 /** 15957 * Report errors that occur while attempting to start Instrumentation. Always writes the 15958 * error to the logs, but if somebody is watching, send the report there too. This enables 15959 * the "am" command to report errors with more information. 15960 * 15961 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15962 * @param cn The component name of the instrumentation. 15963 * @param report The error report. 15964 */ 15965 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15966 ComponentName cn, String report) { 15967 Slog.w(TAG, report); 15968 try { 15969 if (watcher != null) { 15970 Bundle results = new Bundle(); 15971 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15972 results.putString("Error", report); 15973 watcher.instrumentationStatus(cn, -1, results); 15974 } 15975 } catch (RemoteException e) { 15976 Slog.w(TAG, e); 15977 } 15978 } 15979 15980 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15981 if (app.instrumentationWatcher != null) { 15982 try { 15983 // NOTE: IInstrumentationWatcher *must* be oneway here 15984 app.instrumentationWatcher.instrumentationFinished( 15985 app.instrumentationClass, 15986 resultCode, 15987 results); 15988 } catch (RemoteException e) { 15989 } 15990 } 15991 if (app.instrumentationUiAutomationConnection != null) { 15992 try { 15993 app.instrumentationUiAutomationConnection.shutdown(); 15994 } catch (RemoteException re) { 15995 /* ignore */ 15996 } 15997 // Only a UiAutomation can set this flag and now that 15998 // it is finished we make sure it is reset to its default. 15999 mUserIsMonkey = false; 16000 } 16001 app.instrumentationWatcher = null; 16002 app.instrumentationUiAutomationConnection = null; 16003 app.instrumentationClass = null; 16004 app.instrumentationInfo = null; 16005 app.instrumentationProfileFile = null; 16006 app.instrumentationArguments = null; 16007 16008 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16009 "finished inst"); 16010 } 16011 16012 public void finishInstrumentation(IApplicationThread target, 16013 int resultCode, Bundle results) { 16014 int userId = UserHandle.getCallingUserId(); 16015 // Refuse possible leaked file descriptors 16016 if (results != null && results.hasFileDescriptors()) { 16017 throw new IllegalArgumentException("File descriptors passed in Intent"); 16018 } 16019 16020 synchronized(this) { 16021 ProcessRecord app = getRecordForAppLocked(target); 16022 if (app == null) { 16023 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16024 return; 16025 } 16026 final long origId = Binder.clearCallingIdentity(); 16027 finishInstrumentationLocked(app, resultCode, results); 16028 Binder.restoreCallingIdentity(origId); 16029 } 16030 } 16031 16032 // ========================================================= 16033 // CONFIGURATION 16034 // ========================================================= 16035 16036 public ConfigurationInfo getDeviceConfigurationInfo() { 16037 ConfigurationInfo config = new ConfigurationInfo(); 16038 synchronized (this) { 16039 config.reqTouchScreen = mConfiguration.touchscreen; 16040 config.reqKeyboardType = mConfiguration.keyboard; 16041 config.reqNavigation = mConfiguration.navigation; 16042 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16043 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16044 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16045 } 16046 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16047 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16048 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16049 } 16050 config.reqGlEsVersion = GL_ES_VERSION; 16051 } 16052 return config; 16053 } 16054 16055 ActivityStack getFocusedStack() { 16056 return mStackSupervisor.getFocusedStack(); 16057 } 16058 16059 public Configuration getConfiguration() { 16060 Configuration ci; 16061 synchronized(this) { 16062 ci = new Configuration(mConfiguration); 16063 ci.userSetLocale = false; 16064 } 16065 return ci; 16066 } 16067 16068 public void updatePersistentConfiguration(Configuration values) { 16069 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16070 "updateConfiguration()"); 16071 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16072 "updateConfiguration()"); 16073 if (values == null) { 16074 throw new NullPointerException("Configuration must not be null"); 16075 } 16076 16077 synchronized(this) { 16078 final long origId = Binder.clearCallingIdentity(); 16079 updateConfigurationLocked(values, null, true, false); 16080 Binder.restoreCallingIdentity(origId); 16081 } 16082 } 16083 16084 public void updateConfiguration(Configuration values) { 16085 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16086 "updateConfiguration()"); 16087 16088 synchronized(this) { 16089 if (values == null && mWindowManager != null) { 16090 // sentinel: fetch the current configuration from the window manager 16091 values = mWindowManager.computeNewConfiguration(); 16092 } 16093 16094 if (mWindowManager != null) { 16095 mProcessList.applyDisplaySize(mWindowManager); 16096 } 16097 16098 final long origId = Binder.clearCallingIdentity(); 16099 if (values != null) { 16100 Settings.System.clearConfiguration(values); 16101 } 16102 updateConfigurationLocked(values, null, false, false); 16103 Binder.restoreCallingIdentity(origId); 16104 } 16105 } 16106 16107 /** 16108 * Do either or both things: (1) change the current configuration, and (2) 16109 * make sure the given activity is running with the (now) current 16110 * configuration. Returns true if the activity has been left running, or 16111 * false if <var>starting</var> is being destroyed to match the new 16112 * configuration. 16113 * @param persistent TODO 16114 */ 16115 boolean updateConfigurationLocked(Configuration values, 16116 ActivityRecord starting, boolean persistent, boolean initLocale) { 16117 int changes = 0; 16118 16119 if (values != null) { 16120 Configuration newConfig = new Configuration(mConfiguration); 16121 changes = newConfig.updateFrom(values); 16122 if (changes != 0) { 16123 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16124 Slog.i(TAG, "Updating configuration to: " + values); 16125 } 16126 16127 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16128 16129 if (values.locale != null && !initLocale) { 16130 saveLocaleLocked(values.locale, 16131 !values.locale.equals(mConfiguration.locale), 16132 values.userSetLocale); 16133 } 16134 16135 mConfigurationSeq++; 16136 if (mConfigurationSeq <= 0) { 16137 mConfigurationSeq = 1; 16138 } 16139 newConfig.seq = mConfigurationSeq; 16140 mConfiguration = newConfig; 16141 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16142 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16143 //mUsageStatsService.noteStartConfig(newConfig); 16144 16145 final Configuration configCopy = new Configuration(mConfiguration); 16146 16147 // TODO: If our config changes, should we auto dismiss any currently 16148 // showing dialogs? 16149 mShowDialogs = shouldShowDialogs(newConfig); 16150 16151 AttributeCache ac = AttributeCache.instance(); 16152 if (ac != null) { 16153 ac.updateConfiguration(configCopy); 16154 } 16155 16156 // Make sure all resources in our process are updated 16157 // right now, so that anyone who is going to retrieve 16158 // resource values after we return will be sure to get 16159 // the new ones. This is especially important during 16160 // boot, where the first config change needs to guarantee 16161 // all resources have that config before following boot 16162 // code is executed. 16163 mSystemThread.applyConfigurationToResources(configCopy); 16164 16165 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16166 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16167 msg.obj = new Configuration(configCopy); 16168 mHandler.sendMessage(msg); 16169 } 16170 16171 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16172 ProcessRecord app = mLruProcesses.get(i); 16173 try { 16174 if (app.thread != null) { 16175 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16176 + app.processName + " new config " + mConfiguration); 16177 app.thread.scheduleConfigurationChanged(configCopy); 16178 } 16179 } catch (Exception e) { 16180 } 16181 } 16182 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16183 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16184 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16185 | Intent.FLAG_RECEIVER_FOREGROUND); 16186 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16187 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16188 Process.SYSTEM_UID, UserHandle.USER_ALL); 16189 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16190 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16191 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16192 broadcastIntentLocked(null, null, intent, 16193 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16194 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16195 } 16196 } 16197 } 16198 16199 boolean kept = true; 16200 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16201 // mainStack is null during startup. 16202 if (mainStack != null) { 16203 if (changes != 0 && starting == null) { 16204 // If the configuration changed, and the caller is not already 16205 // in the process of starting an activity, then find the top 16206 // activity to check if its configuration needs to change. 16207 starting = mainStack.topRunningActivityLocked(null); 16208 } 16209 16210 if (starting != null) { 16211 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16212 // And we need to make sure at this point that all other activities 16213 // are made visible with the correct configuration. 16214 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16215 } 16216 } 16217 16218 if (values != null && mWindowManager != null) { 16219 mWindowManager.setNewConfiguration(mConfiguration); 16220 } 16221 16222 return kept; 16223 } 16224 16225 /** 16226 * Decide based on the configuration whether we should shouw the ANR, 16227 * crash, etc dialogs. The idea is that if there is no affordnace to 16228 * press the on-screen buttons, we shouldn't show the dialog. 16229 * 16230 * A thought: SystemUI might also want to get told about this, the Power 16231 * dialog / global actions also might want different behaviors. 16232 */ 16233 private static final boolean shouldShowDialogs(Configuration config) { 16234 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16235 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16236 } 16237 16238 /** 16239 * Save the locale. You must be inside a synchronized (this) block. 16240 */ 16241 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16242 if(isDiff) { 16243 SystemProperties.set("user.language", l.getLanguage()); 16244 SystemProperties.set("user.region", l.getCountry()); 16245 } 16246 16247 if(isPersist) { 16248 SystemProperties.set("persist.sys.language", l.getLanguage()); 16249 SystemProperties.set("persist.sys.country", l.getCountry()); 16250 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16251 16252 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16253 } 16254 } 16255 16256 @Override 16257 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16258 synchronized (this) { 16259 ActivityRecord srec = ActivityRecord.forToken(token); 16260 if (srec.task != null && srec.task.stack != null) { 16261 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16262 } 16263 } 16264 return false; 16265 } 16266 16267 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16268 Intent resultData) { 16269 16270 synchronized (this) { 16271 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16272 if (stack != null) { 16273 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16274 } 16275 return false; 16276 } 16277 } 16278 16279 public int getLaunchedFromUid(IBinder activityToken) { 16280 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16281 if (srec == null) { 16282 return -1; 16283 } 16284 return srec.launchedFromUid; 16285 } 16286 16287 public String getLaunchedFromPackage(IBinder activityToken) { 16288 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16289 if (srec == null) { 16290 return null; 16291 } 16292 return srec.launchedFromPackage; 16293 } 16294 16295 // ========================================================= 16296 // LIFETIME MANAGEMENT 16297 // ========================================================= 16298 16299 // Returns which broadcast queue the app is the current [or imminent] receiver 16300 // on, or 'null' if the app is not an active broadcast recipient. 16301 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16302 BroadcastRecord r = app.curReceiver; 16303 if (r != null) { 16304 return r.queue; 16305 } 16306 16307 // It's not the current receiver, but it might be starting up to become one 16308 synchronized (this) { 16309 for (BroadcastQueue queue : mBroadcastQueues) { 16310 r = queue.mPendingBroadcast; 16311 if (r != null && r.curApp == app) { 16312 // found it; report which queue it's in 16313 return queue; 16314 } 16315 } 16316 } 16317 16318 return null; 16319 } 16320 16321 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16322 ComponentName targetComponent, String targetProcess) { 16323 if (!mTrackingAssociations) { 16324 return null; 16325 } 16326 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16327 = mAssociations.get(targetUid); 16328 if (components == null) { 16329 components = new ArrayMap<>(); 16330 mAssociations.put(targetUid, components); 16331 } 16332 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16333 if (sourceUids == null) { 16334 sourceUids = new SparseArray<>(); 16335 components.put(targetComponent, sourceUids); 16336 } 16337 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16338 if (sourceProcesses == null) { 16339 sourceProcesses = new ArrayMap<>(); 16340 sourceUids.put(sourceUid, sourceProcesses); 16341 } 16342 Association ass = sourceProcesses.get(sourceProcess); 16343 if (ass == null) { 16344 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16345 targetProcess); 16346 sourceProcesses.put(sourceProcess, ass); 16347 } 16348 ass.mCount++; 16349 ass.mNesting++; 16350 if (ass.mNesting == 1) { 16351 ass.mStartTime = SystemClock.uptimeMillis(); 16352 } 16353 return ass; 16354 } 16355 16356 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16357 ComponentName targetComponent) { 16358 if (!mTrackingAssociations) { 16359 return; 16360 } 16361 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16362 = mAssociations.get(targetUid); 16363 if (components == null) { 16364 return; 16365 } 16366 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16367 if (sourceUids == null) { 16368 return; 16369 } 16370 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16371 if (sourceProcesses == null) { 16372 return; 16373 } 16374 Association ass = sourceProcesses.get(sourceProcess); 16375 if (ass == null || ass.mNesting <= 0) { 16376 return; 16377 } 16378 ass.mNesting--; 16379 if (ass.mNesting == 0) { 16380 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16381 } 16382 } 16383 16384 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16385 boolean doingAll, long now) { 16386 if (mAdjSeq == app.adjSeq) { 16387 // This adjustment has already been computed. 16388 return app.curRawAdj; 16389 } 16390 16391 if (app.thread == null) { 16392 app.adjSeq = mAdjSeq; 16393 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16394 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16395 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16396 } 16397 16398 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16399 app.adjSource = null; 16400 app.adjTarget = null; 16401 app.empty = false; 16402 app.cached = false; 16403 16404 final int activitiesSize = app.activities.size(); 16405 16406 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16407 // The max adjustment doesn't allow this app to be anything 16408 // below foreground, so it is not worth doing work for it. 16409 app.adjType = "fixed"; 16410 app.adjSeq = mAdjSeq; 16411 app.curRawAdj = app.maxAdj; 16412 app.foregroundActivities = false; 16413 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16414 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16415 // System processes can do UI, and when they do we want to have 16416 // them trim their memory after the user leaves the UI. To 16417 // facilitate this, here we need to determine whether or not it 16418 // is currently showing UI. 16419 app.systemNoUi = true; 16420 if (app == TOP_APP) { 16421 app.systemNoUi = false; 16422 } else if (activitiesSize > 0) { 16423 for (int j = 0; j < activitiesSize; j++) { 16424 final ActivityRecord r = app.activities.get(j); 16425 if (r.visible) { 16426 app.systemNoUi = false; 16427 } 16428 } 16429 } 16430 if (!app.systemNoUi) { 16431 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16432 } 16433 return (app.curAdj=app.maxAdj); 16434 } 16435 16436 app.systemNoUi = false; 16437 16438 // Determine the importance of the process, starting with most 16439 // important to least, and assign an appropriate OOM adjustment. 16440 int adj; 16441 int schedGroup; 16442 int procState; 16443 boolean foregroundActivities = false; 16444 BroadcastQueue queue; 16445 if (app == TOP_APP) { 16446 // The last app on the list is the foreground app. 16447 adj = ProcessList.FOREGROUND_APP_ADJ; 16448 schedGroup = Process.THREAD_GROUP_DEFAULT; 16449 app.adjType = "top-activity"; 16450 foregroundActivities = true; 16451 procState = ActivityManager.PROCESS_STATE_TOP; 16452 } else if (app.instrumentationClass != null) { 16453 // Don't want to kill running instrumentation. 16454 adj = ProcessList.FOREGROUND_APP_ADJ; 16455 schedGroup = Process.THREAD_GROUP_DEFAULT; 16456 app.adjType = "instrumentation"; 16457 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16458 } else if ((queue = isReceivingBroadcast(app)) != null) { 16459 // An app that is currently receiving a broadcast also 16460 // counts as being in the foreground for OOM killer purposes. 16461 // It's placed in a sched group based on the nature of the 16462 // broadcast as reflected by which queue it's active in. 16463 adj = ProcessList.FOREGROUND_APP_ADJ; 16464 schedGroup = (queue == mFgBroadcastQueue) 16465 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16466 app.adjType = "broadcast"; 16467 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16468 } else if (app.executingServices.size() > 0) { 16469 // An app that is currently executing a service callback also 16470 // counts as being in the foreground. 16471 adj = ProcessList.FOREGROUND_APP_ADJ; 16472 schedGroup = app.execServicesFg ? 16473 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16474 app.adjType = "exec-service"; 16475 procState = ActivityManager.PROCESS_STATE_SERVICE; 16476 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16477 } else { 16478 // As far as we know the process is empty. We may change our mind later. 16479 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16480 // At this point we don't actually know the adjustment. Use the cached adj 16481 // value that the caller wants us to. 16482 adj = cachedAdj; 16483 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16484 app.cached = true; 16485 app.empty = true; 16486 app.adjType = "cch-empty"; 16487 } 16488 16489 // Examine all activities if not already foreground. 16490 if (!foregroundActivities && activitiesSize > 0) { 16491 for (int j = 0; j < activitiesSize; j++) { 16492 final ActivityRecord r = app.activities.get(j); 16493 if (r.app != app) { 16494 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16495 + app + "?!?"); 16496 continue; 16497 } 16498 if (r.visible) { 16499 // App has a visible activity; only upgrade adjustment. 16500 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16501 adj = ProcessList.VISIBLE_APP_ADJ; 16502 app.adjType = "visible"; 16503 } 16504 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16505 procState = ActivityManager.PROCESS_STATE_TOP; 16506 } 16507 schedGroup = Process.THREAD_GROUP_DEFAULT; 16508 app.cached = false; 16509 app.empty = false; 16510 foregroundActivities = true; 16511 break; 16512 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16513 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16514 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16515 app.adjType = "pausing"; 16516 } 16517 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16518 procState = ActivityManager.PROCESS_STATE_TOP; 16519 } 16520 schedGroup = Process.THREAD_GROUP_DEFAULT; 16521 app.cached = false; 16522 app.empty = false; 16523 foregroundActivities = true; 16524 } else if (r.state == ActivityState.STOPPING) { 16525 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16526 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16527 app.adjType = "stopping"; 16528 } 16529 // For the process state, we will at this point consider the 16530 // process to be cached. It will be cached either as an activity 16531 // or empty depending on whether the activity is finishing. We do 16532 // this so that we can treat the process as cached for purposes of 16533 // memory trimming (determing current memory level, trim command to 16534 // send to process) since there can be an arbitrary number of stopping 16535 // processes and they should soon all go into the cached state. 16536 if (!r.finishing) { 16537 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16538 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16539 } 16540 } 16541 app.cached = false; 16542 app.empty = false; 16543 foregroundActivities = true; 16544 } else { 16545 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16546 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16547 app.adjType = "cch-act"; 16548 } 16549 } 16550 } 16551 } 16552 16553 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16554 if (app.foregroundServices) { 16555 // The user is aware of this app, so make it visible. 16556 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16557 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16558 app.cached = false; 16559 app.adjType = "fg-service"; 16560 schedGroup = Process.THREAD_GROUP_DEFAULT; 16561 } else if (app.forcingToForeground != null) { 16562 // The user is aware of this app, so make it visible. 16563 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16564 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16565 app.cached = false; 16566 app.adjType = "force-fg"; 16567 app.adjSource = app.forcingToForeground; 16568 schedGroup = Process.THREAD_GROUP_DEFAULT; 16569 } 16570 } 16571 16572 if (app == mHeavyWeightProcess) { 16573 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16574 // We don't want to kill the current heavy-weight process. 16575 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16576 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16577 app.cached = false; 16578 app.adjType = "heavy"; 16579 } 16580 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16581 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16582 } 16583 } 16584 16585 if (app == mHomeProcess) { 16586 if (adj > ProcessList.HOME_APP_ADJ) { 16587 // This process is hosting what we currently consider to be the 16588 // home app, so we don't want to let it go into the background. 16589 adj = ProcessList.HOME_APP_ADJ; 16590 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16591 app.cached = false; 16592 app.adjType = "home"; 16593 } 16594 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16595 procState = ActivityManager.PROCESS_STATE_HOME; 16596 } 16597 } 16598 16599 if (app == mPreviousProcess && app.activities.size() > 0) { 16600 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16601 // This was the previous process that showed UI to the user. 16602 // We want to try to keep it around more aggressively, to give 16603 // a good experience around switching between two apps. 16604 adj = ProcessList.PREVIOUS_APP_ADJ; 16605 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16606 app.cached = false; 16607 app.adjType = "previous"; 16608 } 16609 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16610 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16611 } 16612 } 16613 16614 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16615 + " reason=" + app.adjType); 16616 16617 // By default, we use the computed adjustment. It may be changed if 16618 // there are applications dependent on our services or providers, but 16619 // this gives us a baseline and makes sure we don't get into an 16620 // infinite recursion. 16621 app.adjSeq = mAdjSeq; 16622 app.curRawAdj = adj; 16623 app.hasStartedServices = false; 16624 16625 if (mBackupTarget != null && app == mBackupTarget.app) { 16626 // If possible we want to avoid killing apps while they're being backed up 16627 if (adj > ProcessList.BACKUP_APP_ADJ) { 16628 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16629 adj = ProcessList.BACKUP_APP_ADJ; 16630 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16631 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16632 } 16633 app.adjType = "backup"; 16634 app.cached = false; 16635 } 16636 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16637 procState = ActivityManager.PROCESS_STATE_BACKUP; 16638 } 16639 } 16640 16641 boolean mayBeTop = false; 16642 16643 for (int is = app.services.size()-1; 16644 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16645 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16646 || procState > ActivityManager.PROCESS_STATE_TOP); 16647 is--) { 16648 ServiceRecord s = app.services.valueAt(is); 16649 if (s.startRequested) { 16650 app.hasStartedServices = true; 16651 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16652 procState = ActivityManager.PROCESS_STATE_SERVICE; 16653 } 16654 if (app.hasShownUi && app != mHomeProcess) { 16655 // If this process has shown some UI, let it immediately 16656 // go to the LRU list because it may be pretty heavy with 16657 // UI stuff. We'll tag it with a label just to help 16658 // debug and understand what is going on. 16659 if (adj > ProcessList.SERVICE_ADJ) { 16660 app.adjType = "cch-started-ui-services"; 16661 } 16662 } else { 16663 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16664 // This service has seen some activity within 16665 // recent memory, so we will keep its process ahead 16666 // of the background processes. 16667 if (adj > ProcessList.SERVICE_ADJ) { 16668 adj = ProcessList.SERVICE_ADJ; 16669 app.adjType = "started-services"; 16670 app.cached = false; 16671 } 16672 } 16673 // If we have let the service slide into the background 16674 // state, still have some text describing what it is doing 16675 // even though the service no longer has an impact. 16676 if (adj > ProcessList.SERVICE_ADJ) { 16677 app.adjType = "cch-started-services"; 16678 } 16679 } 16680 } 16681 for (int conni = s.connections.size()-1; 16682 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16683 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16684 || procState > ActivityManager.PROCESS_STATE_TOP); 16685 conni--) { 16686 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16687 for (int i = 0; 16688 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16689 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16690 || procState > ActivityManager.PROCESS_STATE_TOP); 16691 i++) { 16692 // XXX should compute this based on the max of 16693 // all connected clients. 16694 ConnectionRecord cr = clist.get(i); 16695 if (cr.binding.client == app) { 16696 // Binding to ourself is not interesting. 16697 continue; 16698 } 16699 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16700 ProcessRecord client = cr.binding.client; 16701 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16702 TOP_APP, doingAll, now); 16703 int clientProcState = client.curProcState; 16704 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16705 // If the other app is cached for any reason, for purposes here 16706 // we are going to consider it empty. The specific cached state 16707 // doesn't propagate except under certain conditions. 16708 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16709 } 16710 String adjType = null; 16711 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16712 // Not doing bind OOM management, so treat 16713 // this guy more like a started service. 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 > clientAdj) { 16720 adjType = "cch-bound-ui-services"; 16721 } 16722 app.cached = false; 16723 clientAdj = adj; 16724 clientProcState = procState; 16725 } else { 16726 if (now >= (s.lastActivity 16727 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16728 // This service has not seen activity within 16729 // recent memory, so allow it to drop to the 16730 // LRU list if there is no other reason to keep 16731 // it around. We'll also tag it with a label just 16732 // to help debug and undertand what is going on. 16733 if (adj > clientAdj) { 16734 adjType = "cch-bound-services"; 16735 } 16736 clientAdj = adj; 16737 } 16738 } 16739 } 16740 if (adj > clientAdj) { 16741 // If this process has recently shown UI, and 16742 // the process that is binding to it is less 16743 // important than being visible, then we don't 16744 // care about the binding as much as we care 16745 // about letting this process get into the LRU 16746 // list to be killed and restarted if needed for 16747 // memory. 16748 if (app.hasShownUi && app != mHomeProcess 16749 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16750 adjType = "cch-bound-ui-services"; 16751 } else { 16752 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16753 |Context.BIND_IMPORTANT)) != 0) { 16754 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16755 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16756 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16757 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16758 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16759 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16760 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16761 adj = clientAdj; 16762 } else { 16763 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16764 adj = ProcessList.VISIBLE_APP_ADJ; 16765 } 16766 } 16767 if (!client.cached) { 16768 app.cached = false; 16769 } 16770 adjType = "service"; 16771 } 16772 } 16773 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16774 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16775 schedGroup = Process.THREAD_GROUP_DEFAULT; 16776 } 16777 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16778 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16779 // Special handling of clients who are in the top state. 16780 // We *may* want to consider this process to be in the 16781 // top state as well, but only if there is not another 16782 // reason for it to be running. Being on the top is a 16783 // special state, meaning you are specifically running 16784 // for the current top app. If the process is already 16785 // running in the background for some other reason, it 16786 // is more important to continue considering it to be 16787 // in the background state. 16788 mayBeTop = true; 16789 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16790 } else { 16791 // Special handling for above-top states (persistent 16792 // processes). These should not bring the current process 16793 // into the top state, since they are not on top. Instead 16794 // give them the best state after that. 16795 clientProcState = 16796 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16797 } 16798 } 16799 } else { 16800 if (clientProcState < 16801 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16802 clientProcState = 16803 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16804 } 16805 } 16806 if (procState > clientProcState) { 16807 procState = clientProcState; 16808 } 16809 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16810 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16811 app.pendingUiClean = true; 16812 } 16813 if (adjType != null) { 16814 app.adjType = adjType; 16815 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16816 .REASON_SERVICE_IN_USE; 16817 app.adjSource = cr.binding.client; 16818 app.adjSourceProcState = clientProcState; 16819 app.adjTarget = s.name; 16820 } 16821 } 16822 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16823 app.treatLikeActivity = true; 16824 } 16825 final ActivityRecord a = cr.activity; 16826 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16827 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16828 (a.visible || a.state == ActivityState.RESUMED 16829 || a.state == ActivityState.PAUSING)) { 16830 adj = ProcessList.FOREGROUND_APP_ADJ; 16831 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16832 schedGroup = Process.THREAD_GROUP_DEFAULT; 16833 } 16834 app.cached = false; 16835 app.adjType = "service"; 16836 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16837 .REASON_SERVICE_IN_USE; 16838 app.adjSource = a; 16839 app.adjSourceProcState = procState; 16840 app.adjTarget = s.name; 16841 } 16842 } 16843 } 16844 } 16845 } 16846 16847 for (int provi = app.pubProviders.size()-1; 16848 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16849 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16850 || procState > ActivityManager.PROCESS_STATE_TOP); 16851 provi--) { 16852 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16853 for (int i = cpr.connections.size()-1; 16854 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16855 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16856 || procState > ActivityManager.PROCESS_STATE_TOP); 16857 i--) { 16858 ContentProviderConnection conn = cpr.connections.get(i); 16859 ProcessRecord client = conn.client; 16860 if (client == app) { 16861 // Being our own client is not interesting. 16862 continue; 16863 } 16864 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16865 int clientProcState = client.curProcState; 16866 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16867 // If the other app is cached for any reason, for purposes here 16868 // we are going to consider it empty. 16869 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16870 } 16871 if (adj > clientAdj) { 16872 if (app.hasShownUi && app != mHomeProcess 16873 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16874 app.adjType = "cch-ui-provider"; 16875 } else { 16876 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16877 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16878 app.adjType = "provider"; 16879 } 16880 app.cached &= client.cached; 16881 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16882 .REASON_PROVIDER_IN_USE; 16883 app.adjSource = client; 16884 app.adjSourceProcState = clientProcState; 16885 app.adjTarget = cpr.name; 16886 } 16887 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16888 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16889 // Special handling of clients who are in the top state. 16890 // We *may* want to consider this process to be in the 16891 // top state as well, but only if there is not another 16892 // reason for it to be running. Being on the top is a 16893 // special state, meaning you are specifically running 16894 // for the current top app. If the process is already 16895 // running in the background for some other reason, it 16896 // is more important to continue considering it to be 16897 // in the background state. 16898 mayBeTop = true; 16899 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16900 } else { 16901 // Special handling for above-top states (persistent 16902 // processes). These should not bring the current process 16903 // into the top state, since they are not on top. Instead 16904 // give them the best state after that. 16905 clientProcState = 16906 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16907 } 16908 } 16909 if (procState > clientProcState) { 16910 procState = clientProcState; 16911 } 16912 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16913 schedGroup = Process.THREAD_GROUP_DEFAULT; 16914 } 16915 } 16916 // If the provider has external (non-framework) process 16917 // dependencies, ensure that its adjustment is at least 16918 // FOREGROUND_APP_ADJ. 16919 if (cpr.hasExternalProcessHandles()) { 16920 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16921 adj = ProcessList.FOREGROUND_APP_ADJ; 16922 schedGroup = Process.THREAD_GROUP_DEFAULT; 16923 app.cached = false; 16924 app.adjType = "provider"; 16925 app.adjTarget = cpr.name; 16926 } 16927 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16928 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16929 } 16930 } 16931 } 16932 16933 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16934 // A client of one of our services or providers is in the top state. We 16935 // *may* want to be in the top state, but not if we are already running in 16936 // the background for some other reason. For the decision here, we are going 16937 // to pick out a few specific states that we want to remain in when a client 16938 // is top (states that tend to be longer-term) and otherwise allow it to go 16939 // to the top state. 16940 switch (procState) { 16941 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16942 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16943 case ActivityManager.PROCESS_STATE_SERVICE: 16944 // These all are longer-term states, so pull them up to the top 16945 // of the background states, but not all the way to the top state. 16946 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16947 break; 16948 default: 16949 // Otherwise, top is a better choice, so take it. 16950 procState = ActivityManager.PROCESS_STATE_TOP; 16951 break; 16952 } 16953 } 16954 16955 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16956 if (app.hasClientActivities) { 16957 // This is a cached process, but with client activities. Mark it so. 16958 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16959 app.adjType = "cch-client-act"; 16960 } else if (app.treatLikeActivity) { 16961 // This is a cached process, but somebody wants us to treat it like it has 16962 // an activity, okay! 16963 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16964 app.adjType = "cch-as-act"; 16965 } 16966 } 16967 16968 if (adj == ProcessList.SERVICE_ADJ) { 16969 if (doingAll) { 16970 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16971 mNewNumServiceProcs++; 16972 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16973 if (!app.serviceb) { 16974 // This service isn't far enough down on the LRU list to 16975 // normally be a B service, but if we are low on RAM and it 16976 // is large we want to force it down since we would prefer to 16977 // keep launcher over it. 16978 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16979 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16980 app.serviceHighRam = true; 16981 app.serviceb = true; 16982 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16983 } else { 16984 mNewNumAServiceProcs++; 16985 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16986 } 16987 } else { 16988 app.serviceHighRam = false; 16989 } 16990 } 16991 if (app.serviceb) { 16992 adj = ProcessList.SERVICE_B_ADJ; 16993 } 16994 } 16995 16996 app.curRawAdj = adj; 16997 16998 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16999 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17000 if (adj > app.maxAdj) { 17001 adj = app.maxAdj; 17002 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17003 schedGroup = Process.THREAD_GROUP_DEFAULT; 17004 } 17005 } 17006 17007 // Do final modification to adj. Everything we do between here and applying 17008 // the final setAdj must be done in this function, because we will also use 17009 // it when computing the final cached adj later. Note that we don't need to 17010 // worry about this for max adj above, since max adj will always be used to 17011 // keep it out of the cached vaues. 17012 app.curAdj = app.modifyRawOomAdj(adj); 17013 app.curSchedGroup = schedGroup; 17014 app.curProcState = procState; 17015 app.foregroundActivities = foregroundActivities; 17016 17017 return app.curRawAdj; 17018 } 17019 17020 /** 17021 * Record new PSS sample for a process. 17022 */ 17023 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17024 proc.lastPssTime = now; 17025 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17026 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17027 + ": " + pss + " lastPss=" + proc.lastPss 17028 + " state=" + ProcessList.makeProcStateString(procState)); 17029 if (proc.initialIdlePss == 0) { 17030 proc.initialIdlePss = pss; 17031 } 17032 proc.lastPss = pss; 17033 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17034 proc.lastCachedPss = pss; 17035 } 17036 } 17037 17038 /** 17039 * Schedule PSS collection of a process. 17040 */ 17041 void requestPssLocked(ProcessRecord proc, int procState) { 17042 if (mPendingPssProcesses.contains(proc)) { 17043 return; 17044 } 17045 if (mPendingPssProcesses.size() == 0) { 17046 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17047 } 17048 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17049 proc.pssProcState = procState; 17050 mPendingPssProcesses.add(proc); 17051 } 17052 17053 /** 17054 * Schedule PSS collection of all processes. 17055 */ 17056 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17057 if (!always) { 17058 if (now < (mLastFullPssTime + 17059 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17060 return; 17061 } 17062 } 17063 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17064 mLastFullPssTime = now; 17065 mFullPssPending = true; 17066 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17067 mPendingPssProcesses.clear(); 17068 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17069 ProcessRecord app = mLruProcesses.get(i); 17070 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17071 app.pssProcState = app.setProcState; 17072 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17073 mTestPssMode, isSleeping(), now); 17074 mPendingPssProcesses.add(app); 17075 } 17076 } 17077 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17078 } 17079 17080 public void setTestPssMode(boolean enabled) { 17081 synchronized (this) { 17082 mTestPssMode = enabled; 17083 if (enabled) { 17084 // Whenever we enable the mode, we want to take a snapshot all of current 17085 // process mem use. 17086 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17087 } 17088 } 17089 } 17090 17091 /** 17092 * Ask a given process to GC right now. 17093 */ 17094 final void performAppGcLocked(ProcessRecord app) { 17095 try { 17096 app.lastRequestedGc = SystemClock.uptimeMillis(); 17097 if (app.thread != null) { 17098 if (app.reportLowMemory) { 17099 app.reportLowMemory = false; 17100 app.thread.scheduleLowMemory(); 17101 } else { 17102 app.thread.processInBackground(); 17103 } 17104 } 17105 } catch (Exception e) { 17106 // whatever. 17107 } 17108 } 17109 17110 /** 17111 * Returns true if things are idle enough to perform GCs. 17112 */ 17113 private final boolean canGcNowLocked() { 17114 boolean processingBroadcasts = false; 17115 for (BroadcastQueue q : mBroadcastQueues) { 17116 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17117 processingBroadcasts = true; 17118 } 17119 } 17120 return !processingBroadcasts 17121 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17122 } 17123 17124 /** 17125 * Perform GCs on all processes that are waiting for it, but only 17126 * if things are idle. 17127 */ 17128 final void performAppGcsLocked() { 17129 final int N = mProcessesToGc.size(); 17130 if (N <= 0) { 17131 return; 17132 } 17133 if (canGcNowLocked()) { 17134 while (mProcessesToGc.size() > 0) { 17135 ProcessRecord proc = mProcessesToGc.remove(0); 17136 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17137 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17138 <= SystemClock.uptimeMillis()) { 17139 // To avoid spamming the system, we will GC processes one 17140 // at a time, waiting a few seconds between each. 17141 performAppGcLocked(proc); 17142 scheduleAppGcsLocked(); 17143 return; 17144 } else { 17145 // It hasn't been long enough since we last GCed this 17146 // process... put it in the list to wait for its time. 17147 addProcessToGcListLocked(proc); 17148 break; 17149 } 17150 } 17151 } 17152 17153 scheduleAppGcsLocked(); 17154 } 17155 } 17156 17157 /** 17158 * If all looks good, perform GCs on all processes waiting for them. 17159 */ 17160 final void performAppGcsIfAppropriateLocked() { 17161 if (canGcNowLocked()) { 17162 performAppGcsLocked(); 17163 return; 17164 } 17165 // Still not idle, wait some more. 17166 scheduleAppGcsLocked(); 17167 } 17168 17169 /** 17170 * Schedule the execution of all pending app GCs. 17171 */ 17172 final void scheduleAppGcsLocked() { 17173 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17174 17175 if (mProcessesToGc.size() > 0) { 17176 // Schedule a GC for the time to the next process. 17177 ProcessRecord proc = mProcessesToGc.get(0); 17178 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17179 17180 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17181 long now = SystemClock.uptimeMillis(); 17182 if (when < (now+GC_TIMEOUT)) { 17183 when = now + GC_TIMEOUT; 17184 } 17185 mHandler.sendMessageAtTime(msg, when); 17186 } 17187 } 17188 17189 /** 17190 * Add a process to the array of processes waiting to be GCed. Keeps the 17191 * list in sorted order by the last GC time. The process can't already be 17192 * on the list. 17193 */ 17194 final void addProcessToGcListLocked(ProcessRecord proc) { 17195 boolean added = false; 17196 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17197 if (mProcessesToGc.get(i).lastRequestedGc < 17198 proc.lastRequestedGc) { 17199 added = true; 17200 mProcessesToGc.add(i+1, proc); 17201 break; 17202 } 17203 } 17204 if (!added) { 17205 mProcessesToGc.add(0, proc); 17206 } 17207 } 17208 17209 /** 17210 * Set up to ask a process to GC itself. This will either do it 17211 * immediately, or put it on the list of processes to gc the next 17212 * time things are idle. 17213 */ 17214 final void scheduleAppGcLocked(ProcessRecord app) { 17215 long now = SystemClock.uptimeMillis(); 17216 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17217 return; 17218 } 17219 if (!mProcessesToGc.contains(app)) { 17220 addProcessToGcListLocked(app); 17221 scheduleAppGcsLocked(); 17222 } 17223 } 17224 17225 final void checkExcessivePowerUsageLocked(boolean doKills) { 17226 updateCpuStatsNow(); 17227 17228 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17229 boolean doWakeKills = doKills; 17230 boolean doCpuKills = doKills; 17231 if (mLastPowerCheckRealtime == 0) { 17232 doWakeKills = false; 17233 } 17234 if (mLastPowerCheckUptime == 0) { 17235 doCpuKills = false; 17236 } 17237 if (stats.isScreenOn()) { 17238 doWakeKills = false; 17239 } 17240 final long curRealtime = SystemClock.elapsedRealtime(); 17241 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17242 final long curUptime = SystemClock.uptimeMillis(); 17243 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17244 mLastPowerCheckRealtime = curRealtime; 17245 mLastPowerCheckUptime = curUptime; 17246 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17247 doWakeKills = false; 17248 } 17249 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17250 doCpuKills = false; 17251 } 17252 int i = mLruProcesses.size(); 17253 while (i > 0) { 17254 i--; 17255 ProcessRecord app = mLruProcesses.get(i); 17256 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17257 long wtime; 17258 synchronized (stats) { 17259 wtime = stats.getProcessWakeTime(app.info.uid, 17260 app.pid, curRealtime); 17261 } 17262 long wtimeUsed = wtime - app.lastWakeTime; 17263 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17264 if (DEBUG_POWER) { 17265 StringBuilder sb = new StringBuilder(128); 17266 sb.append("Wake for "); 17267 app.toShortString(sb); 17268 sb.append(": over "); 17269 TimeUtils.formatDuration(realtimeSince, sb); 17270 sb.append(" used "); 17271 TimeUtils.formatDuration(wtimeUsed, sb); 17272 sb.append(" ("); 17273 sb.append((wtimeUsed*100)/realtimeSince); 17274 sb.append("%)"); 17275 Slog.i(TAG, sb.toString()); 17276 sb.setLength(0); 17277 sb.append("CPU for "); 17278 app.toShortString(sb); 17279 sb.append(": over "); 17280 TimeUtils.formatDuration(uptimeSince, sb); 17281 sb.append(" used "); 17282 TimeUtils.formatDuration(cputimeUsed, sb); 17283 sb.append(" ("); 17284 sb.append((cputimeUsed*100)/uptimeSince); 17285 sb.append("%)"); 17286 Slog.i(TAG, sb.toString()); 17287 } 17288 // If a process has held a wake lock for more 17289 // than 50% of the time during this period, 17290 // that sounds bad. Kill! 17291 if (doWakeKills && realtimeSince > 0 17292 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17293 synchronized (stats) { 17294 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17295 realtimeSince, wtimeUsed); 17296 } 17297 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17298 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17299 } else if (doCpuKills && uptimeSince > 0 17300 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17301 synchronized (stats) { 17302 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17303 uptimeSince, cputimeUsed); 17304 } 17305 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17306 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17307 } else { 17308 app.lastWakeTime = wtime; 17309 app.lastCpuTime = app.curCpuTime; 17310 } 17311 } 17312 } 17313 } 17314 17315 private final boolean applyOomAdjLocked(ProcessRecord app, 17316 ProcessRecord TOP_APP, boolean doingAll, long now) { 17317 boolean success = true; 17318 17319 if (app.curRawAdj != app.setRawAdj) { 17320 app.setRawAdj = app.curRawAdj; 17321 } 17322 17323 int changes = 0; 17324 17325 if (app.curAdj != app.setAdj) { 17326 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17327 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17328 TAG, "Set " + app.pid + " " + app.processName + 17329 " adj " + app.curAdj + ": " + app.adjType); 17330 app.setAdj = app.curAdj; 17331 } 17332 17333 if (app.setSchedGroup != app.curSchedGroup) { 17334 app.setSchedGroup = app.curSchedGroup; 17335 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17336 "Setting process group of " + app.processName 17337 + " to " + app.curSchedGroup); 17338 if (app.waitingToKill != null && 17339 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17340 app.kill(app.waitingToKill, true); 17341 success = false; 17342 } else { 17343 if (true) { 17344 long oldId = Binder.clearCallingIdentity(); 17345 try { 17346 Process.setProcessGroup(app.pid, app.curSchedGroup); 17347 } catch (Exception e) { 17348 Slog.w(TAG, "Failed setting process group of " + app.pid 17349 + " to " + app.curSchedGroup); 17350 e.printStackTrace(); 17351 } finally { 17352 Binder.restoreCallingIdentity(oldId); 17353 } 17354 } else { 17355 if (app.thread != null) { 17356 try { 17357 app.thread.setSchedulingGroup(app.curSchedGroup); 17358 } catch (RemoteException e) { 17359 } 17360 } 17361 } 17362 Process.setSwappiness(app.pid, 17363 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17364 } 17365 } 17366 if (app.repForegroundActivities != app.foregroundActivities) { 17367 app.repForegroundActivities = app.foregroundActivities; 17368 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17369 } 17370 if (app.repProcState != app.curProcState) { 17371 app.repProcState = app.curProcState; 17372 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17373 if (app.thread != null) { 17374 try { 17375 if (false) { 17376 //RuntimeException h = new RuntimeException("here"); 17377 Slog.i(TAG, "Sending new process state " + app.repProcState 17378 + " to " + app /*, h*/); 17379 } 17380 app.thread.setProcessState(app.repProcState); 17381 } catch (RemoteException e) { 17382 } 17383 } 17384 } 17385 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17386 app.setProcState)) { 17387 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17388 // Experimental code to more aggressively collect pss while 17389 // running test... the problem is that this tends to collect 17390 // the data right when a process is transitioning between process 17391 // states, which well tend to give noisy data. 17392 long start = SystemClock.uptimeMillis(); 17393 long pss = Debug.getPss(app.pid, mTmpLong, null); 17394 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17395 mPendingPssProcesses.remove(app); 17396 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17397 + " to " + app.curProcState + ": " 17398 + (SystemClock.uptimeMillis()-start) + "ms"); 17399 } 17400 app.lastStateTime = now; 17401 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17402 mTestPssMode, isSleeping(), now); 17403 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17404 + ProcessList.makeProcStateString(app.setProcState) + " to " 17405 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17406 + (app.nextPssTime-now) + ": " + app); 17407 } else { 17408 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17409 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17410 mTestPssMode)))) { 17411 requestPssLocked(app, app.setProcState); 17412 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17413 mTestPssMode, isSleeping(), now); 17414 } else if (false && DEBUG_PSS) { 17415 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17416 } 17417 } 17418 if (app.setProcState != app.curProcState) { 17419 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17420 "Proc state change of " + app.processName 17421 + " to " + app.curProcState); 17422 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17423 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17424 if (setImportant && !curImportant) { 17425 // This app is no longer something we consider important enough to allow to 17426 // use arbitrary amounts of battery power. Note 17427 // its current wake lock time to later know to kill it if 17428 // it is not behaving well. 17429 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17430 synchronized (stats) { 17431 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17432 app.pid, SystemClock.elapsedRealtime()); 17433 } 17434 app.lastCpuTime = app.curCpuTime; 17435 17436 } 17437 app.setProcState = app.curProcState; 17438 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17439 app.notCachedSinceIdle = false; 17440 } 17441 if (!doingAll) { 17442 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17443 } else { 17444 app.procStateChanged = true; 17445 } 17446 } 17447 17448 if (changes != 0) { 17449 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17450 int i = mPendingProcessChanges.size()-1; 17451 ProcessChangeItem item = null; 17452 while (i >= 0) { 17453 item = mPendingProcessChanges.get(i); 17454 if (item.pid == app.pid) { 17455 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17456 break; 17457 } 17458 i--; 17459 } 17460 if (i < 0) { 17461 // No existing item in pending changes; need a new one. 17462 final int NA = mAvailProcessChanges.size(); 17463 if (NA > 0) { 17464 item = mAvailProcessChanges.remove(NA-1); 17465 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17466 } else { 17467 item = new ProcessChangeItem(); 17468 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17469 } 17470 item.changes = 0; 17471 item.pid = app.pid; 17472 item.uid = app.info.uid; 17473 if (mPendingProcessChanges.size() == 0) { 17474 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17475 "*** Enqueueing dispatch processes changed!"); 17476 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17477 } 17478 mPendingProcessChanges.add(item); 17479 } 17480 item.changes |= changes; 17481 item.processState = app.repProcState; 17482 item.foregroundActivities = app.repForegroundActivities; 17483 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17484 + Integer.toHexString(System.identityHashCode(item)) 17485 + " " + app.toShortString() + ": changes=" + item.changes 17486 + " procState=" + item.processState 17487 + " foreground=" + item.foregroundActivities 17488 + " type=" + app.adjType + " source=" + app.adjSource 17489 + " target=" + app.adjTarget); 17490 } 17491 17492 return success; 17493 } 17494 17495 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17496 if (proc.thread != null) { 17497 if (proc.baseProcessTracker != null) { 17498 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17499 } 17500 if (proc.repProcState >= 0) { 17501 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17502 proc.repProcState); 17503 } 17504 } 17505 } 17506 17507 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17508 ProcessRecord TOP_APP, boolean doingAll, long now) { 17509 if (app.thread == null) { 17510 return false; 17511 } 17512 17513 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17514 17515 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17516 } 17517 17518 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17519 boolean oomAdj) { 17520 if (isForeground != proc.foregroundServices) { 17521 proc.foregroundServices = isForeground; 17522 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17523 proc.info.uid); 17524 if (isForeground) { 17525 if (curProcs == null) { 17526 curProcs = new ArrayList<ProcessRecord>(); 17527 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17528 } 17529 if (!curProcs.contains(proc)) { 17530 curProcs.add(proc); 17531 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17532 proc.info.packageName, proc.info.uid); 17533 } 17534 } else { 17535 if (curProcs != null) { 17536 if (curProcs.remove(proc)) { 17537 mBatteryStatsService.noteEvent( 17538 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17539 proc.info.packageName, proc.info.uid); 17540 if (curProcs.size() <= 0) { 17541 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17542 } 17543 } 17544 } 17545 } 17546 if (oomAdj) { 17547 updateOomAdjLocked(); 17548 } 17549 } 17550 } 17551 17552 private final ActivityRecord resumedAppLocked() { 17553 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17554 String pkg; 17555 int uid; 17556 if (act != null) { 17557 pkg = act.packageName; 17558 uid = act.info.applicationInfo.uid; 17559 } else { 17560 pkg = null; 17561 uid = -1; 17562 } 17563 // Has the UID or resumed package name changed? 17564 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17565 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17566 if (mCurResumedPackage != null) { 17567 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17568 mCurResumedPackage, mCurResumedUid); 17569 } 17570 mCurResumedPackage = pkg; 17571 mCurResumedUid = uid; 17572 if (mCurResumedPackage != null) { 17573 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17574 mCurResumedPackage, mCurResumedUid); 17575 } 17576 } 17577 return act; 17578 } 17579 17580 final boolean updateOomAdjLocked(ProcessRecord app) { 17581 final ActivityRecord TOP_ACT = resumedAppLocked(); 17582 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17583 final boolean wasCached = app.cached; 17584 17585 mAdjSeq++; 17586 17587 // This is the desired cached adjusment we want to tell it to use. 17588 // If our app is currently cached, we know it, and that is it. Otherwise, 17589 // we don't know it yet, and it needs to now be cached we will then 17590 // need to do a complete oom adj. 17591 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17592 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17593 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17594 SystemClock.uptimeMillis()); 17595 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17596 // Changed to/from cached state, so apps after it in the LRU 17597 // list may also be changed. 17598 updateOomAdjLocked(); 17599 } 17600 return success; 17601 } 17602 17603 final void updateOomAdjLocked() { 17604 final ActivityRecord TOP_ACT = resumedAppLocked(); 17605 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17606 final long now = SystemClock.uptimeMillis(); 17607 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17608 final int N = mLruProcesses.size(); 17609 17610 if (false) { 17611 RuntimeException e = new RuntimeException(); 17612 e.fillInStackTrace(); 17613 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17614 } 17615 17616 mAdjSeq++; 17617 mNewNumServiceProcs = 0; 17618 mNewNumAServiceProcs = 0; 17619 17620 final int emptyProcessLimit; 17621 final int cachedProcessLimit; 17622 if (mProcessLimit <= 0) { 17623 emptyProcessLimit = cachedProcessLimit = 0; 17624 } else if (mProcessLimit == 1) { 17625 emptyProcessLimit = 1; 17626 cachedProcessLimit = 0; 17627 } else { 17628 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17629 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17630 } 17631 17632 // Let's determine how many processes we have running vs. 17633 // how many slots we have for background processes; we may want 17634 // to put multiple processes in a slot of there are enough of 17635 // them. 17636 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17637 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17638 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17639 if (numEmptyProcs > cachedProcessLimit) { 17640 // If there are more empty processes than our limit on cached 17641 // processes, then use the cached process limit for the factor. 17642 // This ensures that the really old empty processes get pushed 17643 // down to the bottom, so if we are running low on memory we will 17644 // have a better chance at keeping around more cached processes 17645 // instead of a gazillion empty processes. 17646 numEmptyProcs = cachedProcessLimit; 17647 } 17648 int emptyFactor = numEmptyProcs/numSlots; 17649 if (emptyFactor < 1) emptyFactor = 1; 17650 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17651 if (cachedFactor < 1) cachedFactor = 1; 17652 int stepCached = 0; 17653 int stepEmpty = 0; 17654 int numCached = 0; 17655 int numEmpty = 0; 17656 int numTrimming = 0; 17657 17658 mNumNonCachedProcs = 0; 17659 mNumCachedHiddenProcs = 0; 17660 17661 // First update the OOM adjustment for each of the 17662 // application processes based on their current state. 17663 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17664 int nextCachedAdj = curCachedAdj+1; 17665 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17666 int nextEmptyAdj = curEmptyAdj+2; 17667 for (int i=N-1; i>=0; i--) { 17668 ProcessRecord app = mLruProcesses.get(i); 17669 if (!app.killedByAm && app.thread != null) { 17670 app.procStateChanged = false; 17671 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17672 17673 // If we haven't yet assigned the final cached adj 17674 // to the process, do that now. 17675 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17676 switch (app.curProcState) { 17677 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17678 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17679 // This process is a cached process holding activities... 17680 // assign it the next cached value for that type, and then 17681 // step that cached level. 17682 app.curRawAdj = curCachedAdj; 17683 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17684 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17685 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17686 + ")"); 17687 if (curCachedAdj != nextCachedAdj) { 17688 stepCached++; 17689 if (stepCached >= cachedFactor) { 17690 stepCached = 0; 17691 curCachedAdj = nextCachedAdj; 17692 nextCachedAdj += 2; 17693 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17694 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17695 } 17696 } 17697 } 17698 break; 17699 default: 17700 // For everything else, assign next empty cached process 17701 // level and bump that up. Note that this means that 17702 // long-running services that have dropped down to the 17703 // cached level will be treated as empty (since their process 17704 // state is still as a service), which is what we want. 17705 app.curRawAdj = curEmptyAdj; 17706 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17707 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17708 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17709 + ")"); 17710 if (curEmptyAdj != nextEmptyAdj) { 17711 stepEmpty++; 17712 if (stepEmpty >= emptyFactor) { 17713 stepEmpty = 0; 17714 curEmptyAdj = nextEmptyAdj; 17715 nextEmptyAdj += 2; 17716 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17717 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17718 } 17719 } 17720 } 17721 break; 17722 } 17723 } 17724 17725 applyOomAdjLocked(app, TOP_APP, true, now); 17726 17727 // Count the number of process types. 17728 switch (app.curProcState) { 17729 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17730 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17731 mNumCachedHiddenProcs++; 17732 numCached++; 17733 if (numCached > cachedProcessLimit) { 17734 app.kill("cached #" + numCached, true); 17735 } 17736 break; 17737 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17738 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17739 && app.lastActivityTime < oldTime) { 17740 app.kill("empty for " 17741 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17742 / 1000) + "s", true); 17743 } else { 17744 numEmpty++; 17745 if (numEmpty > emptyProcessLimit) { 17746 app.kill("empty #" + numEmpty, true); 17747 } 17748 } 17749 break; 17750 default: 17751 mNumNonCachedProcs++; 17752 break; 17753 } 17754 17755 if (app.isolated && app.services.size() <= 0) { 17756 // If this is an isolated process, and there are no 17757 // services running in it, then the process is no longer 17758 // needed. We agressively kill these because we can by 17759 // definition not re-use the same process again, and it is 17760 // good to avoid having whatever code was running in them 17761 // left sitting around after no longer needed. 17762 app.kill("isolated not needed", true); 17763 } 17764 17765 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17766 && !app.killedByAm) { 17767 numTrimming++; 17768 } 17769 } 17770 } 17771 17772 mNumServiceProcs = mNewNumServiceProcs; 17773 17774 // Now determine the memory trimming level of background processes. 17775 // Unfortunately we need to start at the back of the list to do this 17776 // properly. We only do this if the number of background apps we 17777 // are managing to keep around is less than half the maximum we desire; 17778 // if we are keeping a good number around, we'll let them use whatever 17779 // memory they want. 17780 final int numCachedAndEmpty = numCached + numEmpty; 17781 int memFactor; 17782 if (numCached <= ProcessList.TRIM_CACHED_APPS 17783 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17784 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17785 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17786 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17787 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17788 } else { 17789 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17790 } 17791 } else { 17792 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17793 } 17794 // We always allow the memory level to go up (better). We only allow it to go 17795 // down if we are in a state where that is allowed, *and* the total number of processes 17796 // has gone down since last time. 17797 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17798 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17799 + " last=" + mLastNumProcesses); 17800 if (memFactor > mLastMemoryLevel) { 17801 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17802 memFactor = mLastMemoryLevel; 17803 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17804 } 17805 } 17806 mLastMemoryLevel = memFactor; 17807 mLastNumProcesses = mLruProcesses.size(); 17808 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17809 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17810 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17811 if (mLowRamStartTime == 0) { 17812 mLowRamStartTime = now; 17813 } 17814 int step = 0; 17815 int fgTrimLevel; 17816 switch (memFactor) { 17817 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17818 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17819 break; 17820 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17821 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17822 break; 17823 default: 17824 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17825 break; 17826 } 17827 int factor = numTrimming/3; 17828 int minFactor = 2; 17829 if (mHomeProcess != null) minFactor++; 17830 if (mPreviousProcess != null) minFactor++; 17831 if (factor < minFactor) factor = minFactor; 17832 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17833 for (int i=N-1; i>=0; i--) { 17834 ProcessRecord app = mLruProcesses.get(i); 17835 if (allChanged || app.procStateChanged) { 17836 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17837 app.procStateChanged = false; 17838 } 17839 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17840 && !app.killedByAm) { 17841 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17842 try { 17843 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17844 "Trimming memory of " + app.processName 17845 + " to " + curLevel); 17846 app.thread.scheduleTrimMemory(curLevel); 17847 } catch (RemoteException e) { 17848 } 17849 if (false) { 17850 // For now we won't do this; our memory trimming seems 17851 // to be good enough at this point that destroying 17852 // activities causes more harm than good. 17853 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17854 && app != mHomeProcess && app != mPreviousProcess) { 17855 // Need to do this on its own message because the stack may not 17856 // be in a consistent state at this point. 17857 // For these apps we will also finish their activities 17858 // to help them free memory. 17859 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17860 } 17861 } 17862 } 17863 app.trimMemoryLevel = curLevel; 17864 step++; 17865 if (step >= factor) { 17866 step = 0; 17867 switch (curLevel) { 17868 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17869 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17870 break; 17871 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17872 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17873 break; 17874 } 17875 } 17876 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17877 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17878 && app.thread != null) { 17879 try { 17880 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17881 "Trimming memory of heavy-weight " + app.processName 17882 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17883 app.thread.scheduleTrimMemory( 17884 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17885 } catch (RemoteException e) { 17886 } 17887 } 17888 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17889 } else { 17890 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17891 || app.systemNoUi) && app.pendingUiClean) { 17892 // If this application is now in the background and it 17893 // had done UI, then give it the special trim level to 17894 // have it free UI resources. 17895 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17896 if (app.trimMemoryLevel < level && app.thread != null) { 17897 try { 17898 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17899 "Trimming memory of bg-ui " + app.processName 17900 + " to " + level); 17901 app.thread.scheduleTrimMemory(level); 17902 } catch (RemoteException e) { 17903 } 17904 } 17905 app.pendingUiClean = false; 17906 } 17907 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17908 try { 17909 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17910 "Trimming memory of fg " + app.processName 17911 + " to " + fgTrimLevel); 17912 app.thread.scheduleTrimMemory(fgTrimLevel); 17913 } catch (RemoteException e) { 17914 } 17915 } 17916 app.trimMemoryLevel = fgTrimLevel; 17917 } 17918 } 17919 } else { 17920 if (mLowRamStartTime != 0) { 17921 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17922 mLowRamStartTime = 0; 17923 } 17924 for (int i=N-1; i>=0; i--) { 17925 ProcessRecord app = mLruProcesses.get(i); 17926 if (allChanged || app.procStateChanged) { 17927 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17928 app.procStateChanged = false; 17929 } 17930 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17931 || app.systemNoUi) && app.pendingUiClean) { 17932 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17933 && app.thread != null) { 17934 try { 17935 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17936 "Trimming memory of ui hidden " + app.processName 17937 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17938 app.thread.scheduleTrimMemory( 17939 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17940 } catch (RemoteException e) { 17941 } 17942 } 17943 app.pendingUiClean = false; 17944 } 17945 app.trimMemoryLevel = 0; 17946 } 17947 } 17948 17949 if (mAlwaysFinishActivities) { 17950 // Need to do this on its own message because the stack may not 17951 // be in a consistent state at this point. 17952 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17953 } 17954 17955 if (allChanged) { 17956 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17957 } 17958 17959 if (mProcessStats.shouldWriteNowLocked(now)) { 17960 mHandler.post(new Runnable() { 17961 @Override public void run() { 17962 synchronized (ActivityManagerService.this) { 17963 mProcessStats.writeStateAsyncLocked(); 17964 } 17965 } 17966 }); 17967 } 17968 17969 if (DEBUG_OOM_ADJ) { 17970 if (false) { 17971 RuntimeException here = new RuntimeException("here"); 17972 here.fillInStackTrace(); 17973 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17974 } else { 17975 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17976 } 17977 } 17978 } 17979 17980 final void trimApplications() { 17981 synchronized (this) { 17982 int i; 17983 17984 // First remove any unused application processes whose package 17985 // has been removed. 17986 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17987 final ProcessRecord app = mRemovedProcesses.get(i); 17988 if (app.activities.size() == 0 17989 && app.curReceiver == null && app.services.size() == 0) { 17990 Slog.i( 17991 TAG, "Exiting empty application process " 17992 + app.processName + " (" 17993 + (app.thread != null ? app.thread.asBinder() : null) 17994 + ")\n"); 17995 if (app.pid > 0 && app.pid != MY_PID) { 17996 app.kill("empty", false); 17997 } else { 17998 try { 17999 app.thread.scheduleExit(); 18000 } catch (Exception e) { 18001 // Ignore exceptions. 18002 } 18003 } 18004 cleanUpApplicationRecordLocked(app, false, true, -1); 18005 mRemovedProcesses.remove(i); 18006 18007 if (app.persistent) { 18008 addAppLocked(app.info, false, null /* ABI override */); 18009 } 18010 } 18011 } 18012 18013 // Now update the oom adj for all processes. 18014 updateOomAdjLocked(); 18015 } 18016 } 18017 18018 /** This method sends the specified signal to each of the persistent apps */ 18019 public void signalPersistentProcesses(int sig) throws RemoteException { 18020 if (sig != Process.SIGNAL_USR1) { 18021 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18022 } 18023 18024 synchronized (this) { 18025 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18026 != PackageManager.PERMISSION_GRANTED) { 18027 throw new SecurityException("Requires permission " 18028 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18029 } 18030 18031 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18032 ProcessRecord r = mLruProcesses.get(i); 18033 if (r.thread != null && r.persistent) { 18034 Process.sendSignal(r.pid, sig); 18035 } 18036 } 18037 } 18038 } 18039 18040 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18041 if (proc == null || proc == mProfileProc) { 18042 proc = mProfileProc; 18043 profileType = mProfileType; 18044 clearProfilerLocked(); 18045 } 18046 if (proc == null) { 18047 return; 18048 } 18049 try { 18050 proc.thread.profilerControl(false, null, profileType); 18051 } catch (RemoteException e) { 18052 throw new IllegalStateException("Process disappeared"); 18053 } 18054 } 18055 18056 private void clearProfilerLocked() { 18057 if (mProfileFd != null) { 18058 try { 18059 mProfileFd.close(); 18060 } catch (IOException e) { 18061 } 18062 } 18063 mProfileApp = null; 18064 mProfileProc = null; 18065 mProfileFile = null; 18066 mProfileType = 0; 18067 mAutoStopProfiler = false; 18068 mSamplingInterval = 0; 18069 } 18070 18071 public boolean profileControl(String process, int userId, boolean start, 18072 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18073 18074 try { 18075 synchronized (this) { 18076 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18077 // its own permission. 18078 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18079 != PackageManager.PERMISSION_GRANTED) { 18080 throw new SecurityException("Requires permission " 18081 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18082 } 18083 18084 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18085 throw new IllegalArgumentException("null profile info or fd"); 18086 } 18087 18088 ProcessRecord proc = null; 18089 if (process != null) { 18090 proc = findProcessLocked(process, userId, "profileControl"); 18091 } 18092 18093 if (start && (proc == null || proc.thread == null)) { 18094 throw new IllegalArgumentException("Unknown process: " + process); 18095 } 18096 18097 if (start) { 18098 stopProfilerLocked(null, 0); 18099 setProfileApp(proc.info, proc.processName, profilerInfo); 18100 mProfileProc = proc; 18101 mProfileType = profileType; 18102 ParcelFileDescriptor fd = profilerInfo.profileFd; 18103 try { 18104 fd = fd.dup(); 18105 } catch (IOException e) { 18106 fd = null; 18107 } 18108 profilerInfo.profileFd = fd; 18109 proc.thread.profilerControl(start, profilerInfo, profileType); 18110 fd = null; 18111 mProfileFd = null; 18112 } else { 18113 stopProfilerLocked(proc, profileType); 18114 if (profilerInfo != null && profilerInfo.profileFd != null) { 18115 try { 18116 profilerInfo.profileFd.close(); 18117 } catch (IOException e) { 18118 } 18119 } 18120 } 18121 18122 return true; 18123 } 18124 } catch (RemoteException e) { 18125 throw new IllegalStateException("Process disappeared"); 18126 } finally { 18127 if (profilerInfo != null && profilerInfo.profileFd != null) { 18128 try { 18129 profilerInfo.profileFd.close(); 18130 } catch (IOException e) { 18131 } 18132 } 18133 } 18134 } 18135 18136 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18137 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18138 userId, true, ALLOW_FULL_ONLY, callName, null); 18139 ProcessRecord proc = null; 18140 try { 18141 int pid = Integer.parseInt(process); 18142 synchronized (mPidsSelfLocked) { 18143 proc = mPidsSelfLocked.get(pid); 18144 } 18145 } catch (NumberFormatException e) { 18146 } 18147 18148 if (proc == null) { 18149 ArrayMap<String, SparseArray<ProcessRecord>> all 18150 = mProcessNames.getMap(); 18151 SparseArray<ProcessRecord> procs = all.get(process); 18152 if (procs != null && procs.size() > 0) { 18153 proc = procs.valueAt(0); 18154 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18155 for (int i=1; i<procs.size(); i++) { 18156 ProcessRecord thisProc = procs.valueAt(i); 18157 if (thisProc.userId == userId) { 18158 proc = thisProc; 18159 break; 18160 } 18161 } 18162 } 18163 } 18164 } 18165 18166 return proc; 18167 } 18168 18169 public boolean dumpHeap(String process, int userId, boolean managed, 18170 String path, ParcelFileDescriptor fd) throws RemoteException { 18171 18172 try { 18173 synchronized (this) { 18174 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18175 // its own permission (same as profileControl). 18176 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18177 != PackageManager.PERMISSION_GRANTED) { 18178 throw new SecurityException("Requires permission " 18179 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18180 } 18181 18182 if (fd == null) { 18183 throw new IllegalArgumentException("null fd"); 18184 } 18185 18186 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18187 if (proc == null || proc.thread == null) { 18188 throw new IllegalArgumentException("Unknown process: " + process); 18189 } 18190 18191 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18192 if (!isDebuggable) { 18193 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18194 throw new SecurityException("Process not debuggable: " + proc); 18195 } 18196 } 18197 18198 proc.thread.dumpHeap(managed, path, fd); 18199 fd = null; 18200 return true; 18201 } 18202 } catch (RemoteException e) { 18203 throw new IllegalStateException("Process disappeared"); 18204 } finally { 18205 if (fd != null) { 18206 try { 18207 fd.close(); 18208 } catch (IOException e) { 18209 } 18210 } 18211 } 18212 } 18213 18214 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18215 public void monitor() { 18216 synchronized (this) { } 18217 } 18218 18219 void onCoreSettingsChange(Bundle settings) { 18220 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18221 ProcessRecord processRecord = mLruProcesses.get(i); 18222 try { 18223 if (processRecord.thread != null) { 18224 processRecord.thread.setCoreSettings(settings); 18225 } 18226 } catch (RemoteException re) { 18227 /* ignore */ 18228 } 18229 } 18230 } 18231 18232 // Multi-user methods 18233 18234 /** 18235 * Start user, if its not already running, but don't bring it to foreground. 18236 */ 18237 @Override 18238 public boolean startUserInBackground(final int userId) { 18239 return startUser(userId, /* foreground */ false); 18240 } 18241 18242 /** 18243 * Start user, if its not already running, and bring it to foreground. 18244 */ 18245 boolean startUserInForeground(final int userId, Dialog dlg) { 18246 boolean result = startUser(userId, /* foreground */ true); 18247 dlg.dismiss(); 18248 return result; 18249 } 18250 18251 /** 18252 * Refreshes the list of users related to the current user when either a 18253 * user switch happens or when a new related user is started in the 18254 * background. 18255 */ 18256 private void updateCurrentProfileIdsLocked() { 18257 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18258 mCurrentUserId, false /* enabledOnly */); 18259 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18260 for (int i = 0; i < currentProfileIds.length; i++) { 18261 currentProfileIds[i] = profiles.get(i).id; 18262 } 18263 mCurrentProfileIds = currentProfileIds; 18264 18265 synchronized (mUserProfileGroupIdsSelfLocked) { 18266 mUserProfileGroupIdsSelfLocked.clear(); 18267 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18268 for (int i = 0; i < users.size(); i++) { 18269 UserInfo user = users.get(i); 18270 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18271 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18272 } 18273 } 18274 } 18275 } 18276 18277 private Set getProfileIdsLocked(int userId) { 18278 Set userIds = new HashSet<Integer>(); 18279 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18280 userId, false /* enabledOnly */); 18281 for (UserInfo user : profiles) { 18282 userIds.add(Integer.valueOf(user.id)); 18283 } 18284 return userIds; 18285 } 18286 18287 @Override 18288 public boolean switchUser(final int userId) { 18289 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18290 String userName; 18291 synchronized (this) { 18292 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18293 if (userInfo == null) { 18294 Slog.w(TAG, "No user info for user #" + userId); 18295 return false; 18296 } 18297 if (userInfo.isManagedProfile()) { 18298 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18299 return false; 18300 } 18301 userName = userInfo.name; 18302 mTargetUserId = userId; 18303 } 18304 mHandler.removeMessages(START_USER_SWITCH_MSG); 18305 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18306 return true; 18307 } 18308 18309 private void showUserSwitchDialog(int userId, String userName) { 18310 // The dialog will show and then initiate the user switch by calling startUserInForeground 18311 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18312 true /* above system */); 18313 d.show(); 18314 } 18315 18316 private boolean startUser(final int userId, final boolean foreground) { 18317 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18318 != PackageManager.PERMISSION_GRANTED) { 18319 String msg = "Permission Denial: switchUser() from pid=" 18320 + Binder.getCallingPid() 18321 + ", uid=" + Binder.getCallingUid() 18322 + " requires " + INTERACT_ACROSS_USERS_FULL; 18323 Slog.w(TAG, msg); 18324 throw new SecurityException(msg); 18325 } 18326 18327 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18328 18329 final long ident = Binder.clearCallingIdentity(); 18330 try { 18331 synchronized (this) { 18332 final int oldUserId = mCurrentUserId; 18333 if (oldUserId == userId) { 18334 return true; 18335 } 18336 18337 mStackSupervisor.setLockTaskModeLocked(null, false); 18338 18339 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18340 if (userInfo == null) { 18341 Slog.w(TAG, "No user info for user #" + userId); 18342 return false; 18343 } 18344 if (foreground && userInfo.isManagedProfile()) { 18345 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18346 return false; 18347 } 18348 18349 if (foreground) { 18350 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18351 R.anim.screen_user_enter); 18352 } 18353 18354 boolean needStart = false; 18355 18356 // If the user we are switching to is not currently started, then 18357 // we need to start it now. 18358 if (mStartedUsers.get(userId) == null) { 18359 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18360 updateStartedUserArrayLocked(); 18361 needStart = true; 18362 } 18363 18364 final Integer userIdInt = Integer.valueOf(userId); 18365 mUserLru.remove(userIdInt); 18366 mUserLru.add(userIdInt); 18367 18368 if (foreground) { 18369 mCurrentUserId = userId; 18370 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18371 updateCurrentProfileIdsLocked(); 18372 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18373 // Once the internal notion of the active user has switched, we lock the device 18374 // with the option to show the user switcher on the keyguard. 18375 mWindowManager.lockNow(null); 18376 } else { 18377 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18378 updateCurrentProfileIdsLocked(); 18379 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18380 mUserLru.remove(currentUserIdInt); 18381 mUserLru.add(currentUserIdInt); 18382 } 18383 18384 final UserStartedState uss = mStartedUsers.get(userId); 18385 18386 // Make sure user is in the started state. If it is currently 18387 // stopping, we need to knock that off. 18388 if (uss.mState == UserStartedState.STATE_STOPPING) { 18389 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18390 // so we can just fairly silently bring the user back from 18391 // the almost-dead. 18392 uss.mState = UserStartedState.STATE_RUNNING; 18393 updateStartedUserArrayLocked(); 18394 needStart = true; 18395 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18396 // This means ACTION_SHUTDOWN has been sent, so we will 18397 // need to treat this as a new boot of the user. 18398 uss.mState = UserStartedState.STATE_BOOTING; 18399 updateStartedUserArrayLocked(); 18400 needStart = true; 18401 } 18402 18403 if (uss.mState == UserStartedState.STATE_BOOTING) { 18404 // Booting up a new user, need to tell system services about it. 18405 // Note that this is on the same handler as scheduling of broadcasts, 18406 // which is important because it needs to go first. 18407 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18408 } 18409 18410 if (foreground) { 18411 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18412 oldUserId)); 18413 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18414 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18415 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18416 oldUserId, userId, uss)); 18417 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18418 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18419 } 18420 18421 if (needStart) { 18422 // Send USER_STARTED broadcast 18423 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18424 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18425 | Intent.FLAG_RECEIVER_FOREGROUND); 18426 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18427 broadcastIntentLocked(null, null, intent, 18428 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18429 false, false, MY_PID, Process.SYSTEM_UID, userId); 18430 } 18431 18432 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18433 if (userId != UserHandle.USER_OWNER) { 18434 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18435 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18436 broadcastIntentLocked(null, null, intent, null, 18437 new IIntentReceiver.Stub() { 18438 public void performReceive(Intent intent, int resultCode, 18439 String data, Bundle extras, boolean ordered, 18440 boolean sticky, int sendingUser) { 18441 onUserInitialized(uss, foreground, oldUserId, userId); 18442 } 18443 }, 0, null, null, null, AppOpsManager.OP_NONE, 18444 true, false, MY_PID, Process.SYSTEM_UID, 18445 userId); 18446 uss.initializing = true; 18447 } else { 18448 getUserManagerLocked().makeInitialized(userInfo.id); 18449 } 18450 } 18451 18452 if (foreground) { 18453 if (!uss.initializing) { 18454 moveUserToForeground(uss, oldUserId, userId); 18455 } 18456 } else { 18457 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18458 } 18459 18460 if (needStart) { 18461 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18462 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18463 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18464 broadcastIntentLocked(null, null, intent, 18465 null, new IIntentReceiver.Stub() { 18466 @Override 18467 public void performReceive(Intent intent, int resultCode, String data, 18468 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18469 throws RemoteException { 18470 } 18471 }, 0, null, null, 18472 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18473 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18474 } 18475 } 18476 } finally { 18477 Binder.restoreCallingIdentity(ident); 18478 } 18479 18480 return true; 18481 } 18482 18483 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18484 long ident = Binder.clearCallingIdentity(); 18485 try { 18486 Intent intent; 18487 if (oldUserId >= 0) { 18488 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18489 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18490 int count = profiles.size(); 18491 for (int i = 0; i < count; i++) { 18492 int profileUserId = profiles.get(i).id; 18493 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18494 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18495 | Intent.FLAG_RECEIVER_FOREGROUND); 18496 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18497 broadcastIntentLocked(null, null, intent, 18498 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18499 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18500 } 18501 } 18502 if (newUserId >= 0) { 18503 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18504 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18505 int count = profiles.size(); 18506 for (int i = 0; i < count; i++) { 18507 int profileUserId = profiles.get(i).id; 18508 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18509 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18510 | Intent.FLAG_RECEIVER_FOREGROUND); 18511 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18512 broadcastIntentLocked(null, null, intent, 18513 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18514 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18515 } 18516 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18518 | Intent.FLAG_RECEIVER_FOREGROUND); 18519 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18520 broadcastIntentLocked(null, null, intent, 18521 null, null, 0, null, null, 18522 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18523 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18524 } 18525 } finally { 18526 Binder.restoreCallingIdentity(ident); 18527 } 18528 } 18529 18530 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18531 final int newUserId) { 18532 final int N = mUserSwitchObservers.beginBroadcast(); 18533 if (N > 0) { 18534 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18535 int mCount = 0; 18536 @Override 18537 public void sendResult(Bundle data) throws RemoteException { 18538 synchronized (ActivityManagerService.this) { 18539 if (mCurUserSwitchCallback == this) { 18540 mCount++; 18541 if (mCount == N) { 18542 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18543 } 18544 } 18545 } 18546 } 18547 }; 18548 synchronized (this) { 18549 uss.switching = true; 18550 mCurUserSwitchCallback = callback; 18551 } 18552 for (int i=0; i<N; i++) { 18553 try { 18554 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18555 newUserId, callback); 18556 } catch (RemoteException e) { 18557 } 18558 } 18559 } else { 18560 synchronized (this) { 18561 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18562 } 18563 } 18564 mUserSwitchObservers.finishBroadcast(); 18565 } 18566 18567 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18568 synchronized (this) { 18569 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18570 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18571 } 18572 } 18573 18574 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18575 mCurUserSwitchCallback = null; 18576 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18577 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18578 oldUserId, newUserId, uss)); 18579 } 18580 18581 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18582 synchronized (this) { 18583 if (foreground) { 18584 moveUserToForeground(uss, oldUserId, newUserId); 18585 } 18586 } 18587 18588 completeSwitchAndInitalize(uss, newUserId, true, false); 18589 } 18590 18591 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18592 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18593 if (homeInFront) { 18594 startHomeActivityLocked(newUserId); 18595 } else { 18596 mStackSupervisor.resumeTopActivitiesLocked(); 18597 } 18598 EventLogTags.writeAmSwitchUser(newUserId); 18599 getUserManagerLocked().userForeground(newUserId); 18600 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18601 } 18602 18603 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18604 completeSwitchAndInitalize(uss, newUserId, false, true); 18605 } 18606 18607 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18608 boolean clearInitializing, boolean clearSwitching) { 18609 boolean unfrozen = false; 18610 synchronized (this) { 18611 if (clearInitializing) { 18612 uss.initializing = false; 18613 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18614 } 18615 if (clearSwitching) { 18616 uss.switching = false; 18617 } 18618 if (!uss.switching && !uss.initializing) { 18619 mWindowManager.stopFreezingScreen(); 18620 unfrozen = true; 18621 } 18622 } 18623 if (unfrozen) { 18624 final int N = mUserSwitchObservers.beginBroadcast(); 18625 for (int i=0; i<N; i++) { 18626 try { 18627 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18628 } catch (RemoteException e) { 18629 } 18630 } 18631 mUserSwitchObservers.finishBroadcast(); 18632 } 18633 stopGuestUserIfBackground(); 18634 } 18635 18636 /** 18637 * Stops the guest user if it has gone to the background. 18638 */ 18639 private void stopGuestUserIfBackground() { 18640 synchronized (this) { 18641 final int num = mUserLru.size(); 18642 for (int i = 0; i < num; i++) { 18643 Integer oldUserId = mUserLru.get(i); 18644 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18645 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 18646 || oldUss.mState == UserStartedState.STATE_STOPPING 18647 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18648 continue; 18649 } 18650 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 18651 if (userInfo.isGuest()) { 18652 // This is a user to be stopped. 18653 stopUserLocked(oldUserId, null); 18654 break; 18655 } 18656 } 18657 } 18658 } 18659 18660 void scheduleStartProfilesLocked() { 18661 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18662 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18663 DateUtils.SECOND_IN_MILLIS); 18664 } 18665 } 18666 18667 void startProfilesLocked() { 18668 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18669 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18670 mCurrentUserId, false /* enabledOnly */); 18671 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18672 for (UserInfo user : profiles) { 18673 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18674 && user.id != mCurrentUserId) { 18675 toStart.add(user); 18676 } 18677 } 18678 final int n = toStart.size(); 18679 int i = 0; 18680 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18681 startUserInBackground(toStart.get(i).id); 18682 } 18683 if (i < n) { 18684 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18685 } 18686 } 18687 18688 void finishUserBoot(UserStartedState uss) { 18689 synchronized (this) { 18690 if (uss.mState == UserStartedState.STATE_BOOTING 18691 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18692 uss.mState = UserStartedState.STATE_RUNNING; 18693 final int userId = uss.mHandle.getIdentifier(); 18694 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18695 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18696 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18697 broadcastIntentLocked(null, null, intent, 18698 null, null, 0, null, null, 18699 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18700 true, false, MY_PID, Process.SYSTEM_UID, userId); 18701 } 18702 } 18703 } 18704 18705 void finishUserSwitch(UserStartedState uss) { 18706 synchronized (this) { 18707 finishUserBoot(uss); 18708 18709 startProfilesLocked(); 18710 18711 int num = mUserLru.size(); 18712 int i = 0; 18713 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18714 Integer oldUserId = mUserLru.get(i); 18715 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18716 if (oldUss == null) { 18717 // Shouldn't happen, but be sane if it does. 18718 mUserLru.remove(i); 18719 num--; 18720 continue; 18721 } 18722 if (oldUss.mState == UserStartedState.STATE_STOPPING 18723 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18724 // This user is already stopping, doesn't count. 18725 num--; 18726 i++; 18727 continue; 18728 } 18729 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18730 // Owner and current can't be stopped, but count as running. 18731 i++; 18732 continue; 18733 } 18734 // This is a user to be stopped. 18735 stopUserLocked(oldUserId, null); 18736 num--; 18737 i++; 18738 } 18739 } 18740 } 18741 18742 @Override 18743 public int stopUser(final int userId, final IStopUserCallback callback) { 18744 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18745 != PackageManager.PERMISSION_GRANTED) { 18746 String msg = "Permission Denial: switchUser() from pid=" 18747 + Binder.getCallingPid() 18748 + ", uid=" + Binder.getCallingUid() 18749 + " requires " + INTERACT_ACROSS_USERS_FULL; 18750 Slog.w(TAG, msg); 18751 throw new SecurityException(msg); 18752 } 18753 if (userId <= 0) { 18754 throw new IllegalArgumentException("Can't stop primary user " + userId); 18755 } 18756 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18757 synchronized (this) { 18758 return stopUserLocked(userId, callback); 18759 } 18760 } 18761 18762 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18763 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18764 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18765 return ActivityManager.USER_OP_IS_CURRENT; 18766 } 18767 18768 final UserStartedState uss = mStartedUsers.get(userId); 18769 if (uss == null) { 18770 // User is not started, nothing to do... but we do need to 18771 // callback if requested. 18772 if (callback != null) { 18773 mHandler.post(new Runnable() { 18774 @Override 18775 public void run() { 18776 try { 18777 callback.userStopped(userId); 18778 } catch (RemoteException e) { 18779 } 18780 } 18781 }); 18782 } 18783 return ActivityManager.USER_OP_SUCCESS; 18784 } 18785 18786 if (callback != null) { 18787 uss.mStopCallbacks.add(callback); 18788 } 18789 18790 if (uss.mState != UserStartedState.STATE_STOPPING 18791 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18792 uss.mState = UserStartedState.STATE_STOPPING; 18793 updateStartedUserArrayLocked(); 18794 18795 long ident = Binder.clearCallingIdentity(); 18796 try { 18797 // We are going to broadcast ACTION_USER_STOPPING and then 18798 // once that is done send a final ACTION_SHUTDOWN and then 18799 // stop the user. 18800 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18801 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18802 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18803 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18804 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18805 // This is the result receiver for the final shutdown broadcast. 18806 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18807 @Override 18808 public void performReceive(Intent intent, int resultCode, String data, 18809 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18810 finishUserStop(uss); 18811 } 18812 }; 18813 // This is the result receiver for the initial stopping broadcast. 18814 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18815 @Override 18816 public void performReceive(Intent intent, int resultCode, String data, 18817 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18818 // On to the next. 18819 synchronized (ActivityManagerService.this) { 18820 if (uss.mState != UserStartedState.STATE_STOPPING) { 18821 // Whoops, we are being started back up. Abort, abort! 18822 return; 18823 } 18824 uss.mState = UserStartedState.STATE_SHUTDOWN; 18825 } 18826 mBatteryStatsService.noteEvent( 18827 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18828 Integer.toString(userId), userId); 18829 mSystemServiceManager.stopUser(userId); 18830 broadcastIntentLocked(null, null, shutdownIntent, 18831 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18832 true, false, MY_PID, Process.SYSTEM_UID, userId); 18833 } 18834 }; 18835 // Kick things off. 18836 broadcastIntentLocked(null, null, stoppingIntent, 18837 null, stoppingReceiver, 0, null, null, 18838 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18839 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18840 } finally { 18841 Binder.restoreCallingIdentity(ident); 18842 } 18843 } 18844 18845 return ActivityManager.USER_OP_SUCCESS; 18846 } 18847 18848 void finishUserStop(UserStartedState uss) { 18849 final int userId = uss.mHandle.getIdentifier(); 18850 boolean stopped; 18851 ArrayList<IStopUserCallback> callbacks; 18852 synchronized (this) { 18853 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18854 if (mStartedUsers.get(userId) != uss) { 18855 stopped = false; 18856 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18857 stopped = false; 18858 } else { 18859 stopped = true; 18860 // User can no longer run. 18861 mStartedUsers.remove(userId); 18862 mUserLru.remove(Integer.valueOf(userId)); 18863 updateStartedUserArrayLocked(); 18864 18865 // Clean up all state and processes associated with the user. 18866 // Kill all the processes for the user. 18867 forceStopUserLocked(userId, "finish user"); 18868 } 18869 18870 // Explicitly remove the old information in mRecentTasks. 18871 mRecentTasks.removeTasksForUserLocked(userId); 18872 } 18873 18874 for (int i=0; i<callbacks.size(); i++) { 18875 try { 18876 if (stopped) callbacks.get(i).userStopped(userId); 18877 else callbacks.get(i).userStopAborted(userId); 18878 } catch (RemoteException e) { 18879 } 18880 } 18881 18882 if (stopped) { 18883 mSystemServiceManager.cleanupUser(userId); 18884 synchronized (this) { 18885 mStackSupervisor.removeUserLocked(userId); 18886 } 18887 } 18888 } 18889 18890 @Override 18891 public UserInfo getCurrentUser() { 18892 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18893 != PackageManager.PERMISSION_GRANTED) && ( 18894 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18895 != PackageManager.PERMISSION_GRANTED)) { 18896 String msg = "Permission Denial: getCurrentUser() from pid=" 18897 + Binder.getCallingPid() 18898 + ", uid=" + Binder.getCallingUid() 18899 + " requires " + INTERACT_ACROSS_USERS; 18900 Slog.w(TAG, msg); 18901 throw new SecurityException(msg); 18902 } 18903 synchronized (this) { 18904 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18905 return getUserManagerLocked().getUserInfo(userId); 18906 } 18907 } 18908 18909 int getCurrentUserIdLocked() { 18910 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18911 } 18912 18913 @Override 18914 public boolean isUserRunning(int userId, boolean orStopped) { 18915 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18916 != PackageManager.PERMISSION_GRANTED) { 18917 String msg = "Permission Denial: isUserRunning() from pid=" 18918 + Binder.getCallingPid() 18919 + ", uid=" + Binder.getCallingUid() 18920 + " requires " + INTERACT_ACROSS_USERS; 18921 Slog.w(TAG, msg); 18922 throw new SecurityException(msg); 18923 } 18924 synchronized (this) { 18925 return isUserRunningLocked(userId, orStopped); 18926 } 18927 } 18928 18929 boolean isUserRunningLocked(int userId, boolean orStopped) { 18930 UserStartedState state = mStartedUsers.get(userId); 18931 if (state == null) { 18932 return false; 18933 } 18934 if (orStopped) { 18935 return true; 18936 } 18937 return state.mState != UserStartedState.STATE_STOPPING 18938 && state.mState != UserStartedState.STATE_SHUTDOWN; 18939 } 18940 18941 @Override 18942 public int[] getRunningUserIds() { 18943 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18944 != PackageManager.PERMISSION_GRANTED) { 18945 String msg = "Permission Denial: isUserRunning() from pid=" 18946 + Binder.getCallingPid() 18947 + ", uid=" + Binder.getCallingUid() 18948 + " requires " + INTERACT_ACROSS_USERS; 18949 Slog.w(TAG, msg); 18950 throw new SecurityException(msg); 18951 } 18952 synchronized (this) { 18953 return mStartedUserArray; 18954 } 18955 } 18956 18957 private void updateStartedUserArrayLocked() { 18958 int num = 0; 18959 for (int i=0; i<mStartedUsers.size(); i++) { 18960 UserStartedState uss = mStartedUsers.valueAt(i); 18961 // This list does not include stopping users. 18962 if (uss.mState != UserStartedState.STATE_STOPPING 18963 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18964 num++; 18965 } 18966 } 18967 mStartedUserArray = new int[num]; 18968 num = 0; 18969 for (int i=0; i<mStartedUsers.size(); i++) { 18970 UserStartedState uss = mStartedUsers.valueAt(i); 18971 if (uss.mState != UserStartedState.STATE_STOPPING 18972 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18973 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18974 num++; 18975 } 18976 } 18977 } 18978 18979 @Override 18980 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18981 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18982 != PackageManager.PERMISSION_GRANTED) { 18983 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18984 + Binder.getCallingPid() 18985 + ", uid=" + Binder.getCallingUid() 18986 + " requires " + INTERACT_ACROSS_USERS_FULL; 18987 Slog.w(TAG, msg); 18988 throw new SecurityException(msg); 18989 } 18990 18991 mUserSwitchObservers.register(observer); 18992 } 18993 18994 @Override 18995 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18996 mUserSwitchObservers.unregister(observer); 18997 } 18998 18999 private boolean userExists(int userId) { 19000 if (userId == 0) { 19001 return true; 19002 } 19003 UserManagerService ums = getUserManagerLocked(); 19004 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19005 } 19006 19007 int[] getUsersLocked() { 19008 UserManagerService ums = getUserManagerLocked(); 19009 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19010 } 19011 19012 UserManagerService getUserManagerLocked() { 19013 if (mUserManager == null) { 19014 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19015 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19016 } 19017 return mUserManager; 19018 } 19019 19020 private int applyUserId(int uid, int userId) { 19021 return UserHandle.getUid(userId, uid); 19022 } 19023 19024 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19025 if (info == null) return null; 19026 ApplicationInfo newInfo = new ApplicationInfo(info); 19027 newInfo.uid = applyUserId(info.uid, userId); 19028 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19029 + info.packageName; 19030 return newInfo; 19031 } 19032 19033 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19034 if (aInfo == null 19035 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19036 return aInfo; 19037 } 19038 19039 ActivityInfo info = new ActivityInfo(aInfo); 19040 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19041 return info; 19042 } 19043 19044 private final class LocalService extends ActivityManagerInternal { 19045 @Override 19046 public void onWakefulnessChanged(int wakefulness) { 19047 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19048 } 19049 19050 @Override 19051 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19052 String processName, String abiOverride, int uid, Runnable crashHandler) { 19053 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19054 processName, abiOverride, uid, crashHandler); 19055 } 19056 } 19057 19058 /** 19059 * An implementation of IAppTask, that allows an app to manage its own tasks via 19060 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19061 * only the process that calls getAppTasks() can call the AppTask methods. 19062 */ 19063 class AppTaskImpl extends IAppTask.Stub { 19064 private int mTaskId; 19065 private int mCallingUid; 19066 19067 public AppTaskImpl(int taskId, int callingUid) { 19068 mTaskId = taskId; 19069 mCallingUid = callingUid; 19070 } 19071 19072 private void checkCaller() { 19073 if (mCallingUid != Binder.getCallingUid()) { 19074 throw new SecurityException("Caller " + mCallingUid 19075 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19076 } 19077 } 19078 19079 @Override 19080 public void finishAndRemoveTask() { 19081 checkCaller(); 19082 19083 synchronized (ActivityManagerService.this) { 19084 long origId = Binder.clearCallingIdentity(); 19085 try { 19086 if (!removeTaskByIdLocked(mTaskId, false)) { 19087 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19088 } 19089 } finally { 19090 Binder.restoreCallingIdentity(origId); 19091 } 19092 } 19093 } 19094 19095 @Override 19096 public ActivityManager.RecentTaskInfo getTaskInfo() { 19097 checkCaller(); 19098 19099 synchronized (ActivityManagerService.this) { 19100 long origId = Binder.clearCallingIdentity(); 19101 try { 19102 TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId); 19103 if (tr == null) { 19104 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19105 } 19106 return createRecentTaskInfoFromTaskRecord(tr); 19107 } finally { 19108 Binder.restoreCallingIdentity(origId); 19109 } 19110 } 19111 } 19112 19113 @Override 19114 public void moveToFront() { 19115 checkCaller(); 19116 // Will bring task to front if it already has a root activity. 19117 startActivityFromRecentsInner(mTaskId, null); 19118 } 19119 19120 @Override 19121 public int startActivity(IBinder whoThread, String callingPackage, 19122 Intent intent, String resolvedType, Bundle options) { 19123 checkCaller(); 19124 19125 int callingUser = UserHandle.getCallingUserId(); 19126 TaskRecord tr; 19127 IApplicationThread appThread; 19128 synchronized (ActivityManagerService.this) { 19129 tr = mRecentTasks.taskForIdLocked(mTaskId); 19130 if (tr == null) { 19131 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19132 } 19133 appThread = ApplicationThreadNative.asInterface(whoThread); 19134 if (appThread == null) { 19135 throw new IllegalArgumentException("Bad app thread " + appThread); 19136 } 19137 } 19138 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19139 resolvedType, null, null, null, null, 0, 0, null, null, 19140 null, options, callingUser, null, tr); 19141 } 19142 19143 @Override 19144 public void setExcludeFromRecents(boolean exclude) { 19145 checkCaller(); 19146 19147 synchronized (ActivityManagerService.this) { 19148 long origId = Binder.clearCallingIdentity(); 19149 try { 19150 TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId); 19151 if (tr == null) { 19152 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19153 } 19154 Intent intent = tr.getBaseIntent(); 19155 if (exclude) { 19156 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19157 } else { 19158 intent.setFlags(intent.getFlags() 19159 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19160 } 19161 } finally { 19162 Binder.restoreCallingIdentity(origId); 19163 } 19164 } 19165 } 19166 } 19167} 19168