ActivityManagerService.java revision 7de0535701351d76b634ab18577269e8130749ea
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 // Maximum number recent bitmaps to keep in memory. 297 static final int MAX_RECENT_BITMAPS = 3; 298 299 // Amount of time after a call to stopAppSwitches() during which we will 300 // prevent further untrusted switches from happening. 301 static final long APP_SWITCH_DELAY_TIME = 5*1000; 302 303 // How long we wait for a launched process to attach to the activity manager 304 // before we decide it's never going to come up for real. 305 static final int PROC_START_TIMEOUT = 10*1000; 306 307 // How long we wait for a launched process to attach to the activity manager 308 // before we decide it's never going to come up for real, when the process was 309 // started with a wrapper for instrumentation (such as Valgrind) because it 310 // could take much longer than usual. 311 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 312 313 // How long to wait after going idle before forcing apps to GC. 314 static final int GC_TIMEOUT = 5*1000; 315 316 // The minimum amount of time between successive GC requests for a process. 317 static final int GC_MIN_INTERVAL = 60*1000; 318 319 // The minimum amount of time between successive PSS requests for a process. 320 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 321 322 // The minimum amount of time between successive PSS requests for a process 323 // when the request is due to the memory state being lowered. 324 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 325 326 // The rate at which we check for apps using excessive power -- 15 mins. 327 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on wake locks to start killing things. 331 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // The minimum sample duration we will allow before deciding we have 334 // enough data on CPU usage to start killing things. 335 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 336 337 // How long we allow a receiver to run before giving up on it. 338 static final int BROADCAST_FG_TIMEOUT = 10*1000; 339 static final int BROADCAST_BG_TIMEOUT = 60*1000; 340 341 // How long we wait until we timeout on key dispatching. 342 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 343 344 // How long we wait until we timeout on key dispatching during instrumentation. 345 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 346 347 // Amount of time we wait for observers to handle a user switch before 348 // giving up on them and unfreezing the screen. 349 static final int USER_SWITCH_TIMEOUT = 2*1000; 350 351 // Maximum number of users we allow to be running at a time. 352 static final int MAX_RUNNING_USERS = 3; 353 354 // How long to wait in getAssistContextExtras for the activity and foreground services 355 // to respond with the result. 356 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 357 358 // Maximum number of persisted Uri grants a package is allowed 359 static final int MAX_PERSISTED_URI_GRANTS = 128; 360 361 static final int MY_PID = Process.myPid(); 362 363 static final String[] EMPTY_STRING_ARRAY = new String[0]; 364 365 // How many bytes to write into the dropbox log before truncating 366 static final int DROPBOX_MAX_SIZE = 256 * 1024; 367 368 // Access modes for handleIncomingUser. 369 static final int ALLOW_NON_FULL = 0; 370 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 371 static final int ALLOW_FULL_ONLY = 2; 372 373 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 374 375 // Delay in notifying task stack change listeners (in millis) 376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 377 378 /** All system services */ 379 SystemServiceManager mSystemServiceManager; 380 381 private Installer mInstaller; 382 383 /** Run all ActivityStacks through this */ 384 ActivityStackSupervisor mStackSupervisor; 385 386 /** Task stack change listeners. */ 387 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 388 new RemoteCallbackList<ITaskStackListener>(); 389 390 public IntentFirewall mIntentFirewall; 391 392 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 393 // default actuion automatically. Important for devices without direct input 394 // devices. 395 private boolean mShowDialogs = true; 396 397 BroadcastQueue mFgBroadcastQueue; 398 BroadcastQueue mBgBroadcastQueue; 399 // Convenient for easy iteration over the queues. Foreground is first 400 // so that dispatch of foreground broadcasts gets precedence. 401 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 402 403 BroadcastQueue broadcastQueueForIntent(Intent intent) { 404 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 405 if (DEBUG_BACKGROUND_BROADCAST) { 406 Slog.i(TAG, "Broadcast intent " + intent + " on " 407 + (isFg ? "foreground" : "background") 408 + " queue"); 409 } 410 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 411 } 412 413 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 414 for (BroadcastQueue queue : mBroadcastQueues) { 415 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 416 if (r != null) { 417 return r; 418 } 419 } 420 return null; 421 } 422 423 /** 424 * Activity we have told the window manager to have key focus. 425 */ 426 ActivityRecord mFocusedActivity = null; 427 428 /** 429 * List of intents that were used to start the most recent tasks. 430 */ 431 ArrayList<TaskRecord> mRecentTasks; 432 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 433 434 /** 435 * For addAppTask: cached of the last activity component that was added. 436 */ 437 ComponentName mLastAddedTaskComponent; 438 439 /** 440 * For addAppTask: cached of the last activity uid that was added. 441 */ 442 int mLastAddedTaskUid; 443 444 /** 445 * For addAppTask: cached of the last ActivityInfo that was added. 446 */ 447 ActivityInfo mLastAddedTaskActivity; 448 449 public class PendingAssistExtras extends Binder implements Runnable { 450 public final ActivityRecord activity; 451 public final Bundle extras; 452 public final Intent intent; 453 public final String hint; 454 public final int userHandle; 455 public boolean haveResult = false; 456 public Bundle result = null; 457 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 458 String _hint, int _userHandle) { 459 activity = _activity; 460 extras = _extras; 461 intent = _intent; 462 hint = _hint; 463 userHandle = _userHandle; 464 } 465 @Override 466 public void run() { 467 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 468 synchronized (this) { 469 haveResult = true; 470 notifyAll(); 471 } 472 } 473 } 474 475 final ArrayList<PendingAssistExtras> mPendingAssistExtras 476 = new ArrayList<PendingAssistExtras>(); 477 478 /** 479 * Process management. 480 */ 481 final ProcessList mProcessList = new ProcessList(); 482 483 /** 484 * All of the applications we currently have running organized by name. 485 * The keys are strings of the application package name (as 486 * returned by the package manager), and the keys are ApplicationRecord 487 * objects. 488 */ 489 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 490 491 /** 492 * Tracking long-term execution of processes to look for abuse and other 493 * bad app behavior. 494 */ 495 final ProcessStatsService mProcessStats; 496 497 /** 498 * The currently running isolated processes. 499 */ 500 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 501 502 /** 503 * Counter for assigning isolated process uids, to avoid frequently reusing the 504 * same ones. 505 */ 506 int mNextIsolatedProcessUid = 0; 507 508 /** 509 * The currently running heavy-weight process, if any. 510 */ 511 ProcessRecord mHeavyWeightProcess = null; 512 513 /** 514 * The last time that various processes have crashed. 515 */ 516 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 517 518 /** 519 * Information about a process that is currently marked as bad. 520 */ 521 static final class BadProcessInfo { 522 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 523 this.time = time; 524 this.shortMsg = shortMsg; 525 this.longMsg = longMsg; 526 this.stack = stack; 527 } 528 529 final long time; 530 final String shortMsg; 531 final String longMsg; 532 final String stack; 533 } 534 535 /** 536 * Set of applications that we consider to be bad, and will reject 537 * incoming broadcasts from (which the user has no control over). 538 * Processes are added to this set when they have crashed twice within 539 * a minimum amount of time; they are removed from it when they are 540 * later restarted (hopefully due to some user action). The value is the 541 * time it was added to the list. 542 */ 543 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 544 545 /** 546 * All of the processes we currently have running organized by pid. 547 * The keys are the pid running the application. 548 * 549 * <p>NOTE: This object is protected by its own lock, NOT the global 550 * activity manager lock! 551 */ 552 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 553 554 /** 555 * All of the processes that have been forced to be foreground. The key 556 * is the pid of the caller who requested it (we hold a death 557 * link on it). 558 */ 559 abstract class ForegroundToken implements IBinder.DeathRecipient { 560 int pid; 561 IBinder token; 562 } 563 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 564 565 /** 566 * List of records for processes that someone had tried to start before the 567 * system was ready. We don't start them at that point, but ensure they 568 * are started by the time booting is complete. 569 */ 570 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of persistent applications that are in the process 574 * of being started. 575 */ 576 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes that are being forcibly torn down. 580 */ 581 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * List of running applications, sorted by recent usage. 585 * The first entry in the list is the least recently used. 586 */ 587 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 588 589 /** 590 * Where in mLruProcesses that the processes hosting activities start. 591 */ 592 int mLruProcessActivityStart = 0; 593 594 /** 595 * Where in mLruProcesses that the processes hosting services start. 596 * This is after (lower index) than mLruProcessesActivityStart. 597 */ 598 int mLruProcessServiceStart = 0; 599 600 /** 601 * List of processes that should gc as soon as things are idle. 602 */ 603 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 604 605 /** 606 * Processes we want to collect PSS data from. 607 */ 608 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 609 610 /** 611 * Last time we requested PSS data of all processes. 612 */ 613 long mLastFullPssTime = SystemClock.uptimeMillis(); 614 615 /** 616 * If set, the next time we collect PSS data we should do a full collection 617 * with data from native processes and the kernel. 618 */ 619 boolean mFullPssPending = false; 620 621 /** 622 * This is the process holding what we currently consider to be 623 * the "home" activity. 624 */ 625 ProcessRecord mHomeProcess; 626 627 /** 628 * This is the process holding the activity the user last visited that 629 * is in a different process from the one they are currently in. 630 */ 631 ProcessRecord mPreviousProcess; 632 633 /** 634 * The time at which the previous process was last visible. 635 */ 636 long mPreviousProcessVisibleTime; 637 638 /** 639 * Which uses have been started, so are allowed to run code. 640 */ 641 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 642 643 /** 644 * LRU list of history of current users. Most recently current is at the end. 645 */ 646 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 647 648 /** 649 * Constant array of the users that are currently started. 650 */ 651 int[] mStartedUserArray = new int[] { 0 }; 652 653 /** 654 * Registered observers of the user switching mechanics. 655 */ 656 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 657 = new RemoteCallbackList<IUserSwitchObserver>(); 658 659 /** 660 * Currently active user switch. 661 */ 662 Object mCurUserSwitchCallback; 663 664 /** 665 * Packages that the user has asked to have run in screen size 666 * compatibility mode instead of filling the screen. 667 */ 668 final CompatModePackages mCompatModePackages; 669 670 /** 671 * Set of IntentSenderRecord objects that are currently active. 672 */ 673 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 674 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 675 676 /** 677 * Fingerprints (hashCode()) of stack traces that we've 678 * already logged DropBox entries for. Guarded by itself. If 679 * something (rogue user app) forces this over 680 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 681 */ 682 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 683 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 684 685 /** 686 * Strict Mode background batched logging state. 687 * 688 * The string buffer is guarded by itself, and its lock is also 689 * used to determine if another batched write is already 690 * in-flight. 691 */ 692 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 693 694 /** 695 * Keeps track of all IIntentReceivers that have been registered for 696 * broadcasts. Hash keys are the receiver IBinder, hash value is 697 * a ReceiverList. 698 */ 699 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 700 new HashMap<IBinder, ReceiverList>(); 701 702 /** 703 * Resolver for broadcast intents to registered receivers. 704 * Holds BroadcastFilter (subclass of IntentFilter). 705 */ 706 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 707 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 708 @Override 709 protected boolean allowFilterResult( 710 BroadcastFilter filter, List<BroadcastFilter> dest) { 711 IBinder target = filter.receiverList.receiver.asBinder(); 712 for (int i=dest.size()-1; i>=0; i--) { 713 if (dest.get(i).receiverList.receiver.asBinder() == target) { 714 return false; 715 } 716 } 717 return true; 718 } 719 720 @Override 721 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 722 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 723 || userId == filter.owningUserId) { 724 return super.newResult(filter, match, userId); 725 } 726 return null; 727 } 728 729 @Override 730 protected BroadcastFilter[] newArray(int size) { 731 return new BroadcastFilter[size]; 732 } 733 734 @Override 735 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 736 return packageName.equals(filter.packageName); 737 } 738 }; 739 740 /** 741 * State of all active sticky broadcasts per user. Keys are the action of the 742 * sticky Intent, values are an ArrayList of all broadcasted intents with 743 * that action (which should usually be one). The SparseArray is keyed 744 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 745 * for stickies that are sent to all users. 746 */ 747 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 748 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 749 750 final ActiveServices mServices; 751 752 /** 753 * Backup/restore process management 754 */ 755 String mBackupAppName = null; 756 BackupRecord mBackupTarget = null; 757 758 final ProviderMap mProviderMap; 759 760 /** 761 * List of content providers who have clients waiting for them. The 762 * application is currently being launched and the provider will be 763 * removed from this list once it is published. 764 */ 765 final ArrayList<ContentProviderRecord> mLaunchingProviders 766 = new ArrayList<ContentProviderRecord>(); 767 768 /** 769 * File storing persisted {@link #mGrantedUriPermissions}. 770 */ 771 private final AtomicFile mGrantFile; 772 773 /** XML constants used in {@link #mGrantFile} */ 774 private static final String TAG_URI_GRANTS = "uri-grants"; 775 private static final String TAG_URI_GRANT = "uri-grant"; 776 private static final String ATTR_USER_HANDLE = "userHandle"; 777 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 778 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 779 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 780 private static final String ATTR_TARGET_PKG = "targetPkg"; 781 private static final String ATTR_URI = "uri"; 782 private static final String ATTR_MODE_FLAGS = "modeFlags"; 783 private static final String ATTR_CREATED_TIME = "createdTime"; 784 private static final String ATTR_PREFIX = "prefix"; 785 786 /** 787 * Global set of specific {@link Uri} permissions that have been granted. 788 * This optimized lookup structure maps from {@link UriPermission#targetUid} 789 * to {@link UriPermission#uri} to {@link UriPermission}. 790 */ 791 @GuardedBy("this") 792 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 793 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 794 795 public static class GrantUri { 796 public final int sourceUserId; 797 public final Uri uri; 798 public boolean prefix; 799 800 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 801 this.sourceUserId = sourceUserId; 802 this.uri = uri; 803 this.prefix = prefix; 804 } 805 806 @Override 807 public int hashCode() { 808 int hashCode = 1; 809 hashCode = 31 * hashCode + sourceUserId; 810 hashCode = 31 * hashCode + uri.hashCode(); 811 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 812 return hashCode; 813 } 814 815 @Override 816 public boolean equals(Object o) { 817 if (o instanceof GrantUri) { 818 GrantUri other = (GrantUri) o; 819 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 820 && prefix == other.prefix; 821 } 822 return false; 823 } 824 825 @Override 826 public String toString() { 827 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 828 if (prefix) result += " [prefix]"; 829 return result; 830 } 831 832 public String toSafeString() { 833 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 834 if (prefix) result += " [prefix]"; 835 return result; 836 } 837 838 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 839 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 840 ContentProvider.getUriWithoutUserId(uri), false); 841 } 842 } 843 844 CoreSettingsObserver mCoreSettingsObserver; 845 846 /** 847 * Thread-local storage used to carry caller permissions over through 848 * indirect content-provider access. 849 */ 850 private class Identity { 851 public final IBinder token; 852 public final int pid; 853 public final int uid; 854 855 Identity(IBinder _token, int _pid, int _uid) { 856 token = _token; 857 pid = _pid; 858 uid = _uid; 859 } 860 } 861 862 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 863 864 /** 865 * All information we have collected about the runtime performance of 866 * any user id that can impact battery performance. 867 */ 868 final BatteryStatsService mBatteryStatsService; 869 870 /** 871 * Information about component usage 872 */ 873 UsageStatsManagerInternal mUsageStatsService; 874 875 /** 876 * Information about and control over application operations 877 */ 878 final AppOpsService mAppOpsService; 879 880 /** 881 * Save recent tasks information across reboots. 882 */ 883 final TaskPersister mTaskPersister; 884 885 /** 886 * Current configuration information. HistoryRecord objects are given 887 * a reference to this object to indicate which configuration they are 888 * currently running in, so this object must be kept immutable. 889 */ 890 Configuration mConfiguration = new Configuration(); 891 892 /** 893 * Current sequencing integer of the configuration, for skipping old 894 * configurations. 895 */ 896 int mConfigurationSeq = 0; 897 898 /** 899 * Hardware-reported OpenGLES version. 900 */ 901 final int GL_ES_VERSION; 902 903 /** 904 * List of initialization arguments to pass to all processes when binding applications to them. 905 * For example, references to the commonly used services. 906 */ 907 HashMap<String, IBinder> mAppBindArgs; 908 909 /** 910 * Temporary to avoid allocations. Protected by main lock. 911 */ 912 final StringBuilder mStringBuilder = new StringBuilder(256); 913 914 /** 915 * Used to control how we initialize the service. 916 */ 917 ComponentName mTopComponent; 918 String mTopAction = Intent.ACTION_MAIN; 919 String mTopData; 920 boolean mProcessesReady = false; 921 boolean mSystemReady = false; 922 boolean mBooting = false; 923 boolean mCallFinishBooting = false; 924 boolean mBootAnimationComplete = false; 925 boolean mWaitingUpdate = false; 926 boolean mDidUpdate = false; 927 boolean mOnBattery = false; 928 boolean mLaunchWarningShown = false; 929 930 Context mContext; 931 932 int mFactoryTest; 933 934 boolean mCheckedForSetup; 935 936 /** 937 * The time at which we will allow normal application switches again, 938 * after a call to {@link #stopAppSwitches()}. 939 */ 940 long mAppSwitchesAllowedTime; 941 942 /** 943 * This is set to true after the first switch after mAppSwitchesAllowedTime 944 * is set; any switches after that will clear the time. 945 */ 946 boolean mDidAppSwitch; 947 948 /** 949 * Last time (in realtime) at which we checked for power usage. 950 */ 951 long mLastPowerCheckRealtime; 952 953 /** 954 * Last time (in uptime) at which we checked for power usage. 955 */ 956 long mLastPowerCheckUptime; 957 958 /** 959 * Set while we are wanting to sleep, to prevent any 960 * activities from being started/resumed. 961 */ 962 private boolean mSleeping = false; 963 964 /** 965 * Set while we are running a voice interaction. This overrides 966 * sleeping while it is active. 967 */ 968 private boolean mRunningVoice = false; 969 970 /** 971 * State of external calls telling us if the device is awake or asleep. 972 */ 973 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 974 975 static final int LOCK_SCREEN_HIDDEN = 0; 976 static final int LOCK_SCREEN_LEAVING = 1; 977 static final int LOCK_SCREEN_SHOWN = 2; 978 /** 979 * State of external call telling us if the lock screen is shown. 980 */ 981 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 982 983 /** 984 * Set if we are shutting down the system, similar to sleeping. 985 */ 986 boolean mShuttingDown = false; 987 988 /** 989 * Current sequence id for oom_adj computation traversal. 990 */ 991 int mAdjSeq = 0; 992 993 /** 994 * Current sequence id for process LRU updating. 995 */ 996 int mLruSeq = 0; 997 998 /** 999 * Keep track of the non-cached/empty process we last found, to help 1000 * determine how to distribute cached/empty processes next time. 1001 */ 1002 int mNumNonCachedProcs = 0; 1003 1004 /** 1005 * Keep track of the number of cached hidden procs, to balance oom adj 1006 * distribution between those and empty procs. 1007 */ 1008 int mNumCachedHiddenProcs = 0; 1009 1010 /** 1011 * Keep track of the number of service processes we last found, to 1012 * determine on the next iteration which should be B services. 1013 */ 1014 int mNumServiceProcs = 0; 1015 int mNewNumAServiceProcs = 0; 1016 int mNewNumServiceProcs = 0; 1017 1018 /** 1019 * Allow the current computed overall memory level of the system to go down? 1020 * This is set to false when we are killing processes for reasons other than 1021 * memory management, so that the now smaller process list will not be taken as 1022 * an indication that memory is tighter. 1023 */ 1024 boolean mAllowLowerMemLevel = false; 1025 1026 /** 1027 * The last computed memory level, for holding when we are in a state that 1028 * processes are going away for other reasons. 1029 */ 1030 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1031 1032 /** 1033 * The last total number of process we have, to determine if changes actually look 1034 * like a shrinking number of process due to lower RAM. 1035 */ 1036 int mLastNumProcesses; 1037 1038 /** 1039 * The uptime of the last time we performed idle maintenance. 1040 */ 1041 long mLastIdleTime = SystemClock.uptimeMillis(); 1042 1043 /** 1044 * Total time spent with RAM that has been added in the past since the last idle time. 1045 */ 1046 long mLowRamTimeSinceLastIdle = 0; 1047 1048 /** 1049 * If RAM is currently low, when that horrible situation started. 1050 */ 1051 long mLowRamStartTime = 0; 1052 1053 /** 1054 * For reporting to battery stats the current top application. 1055 */ 1056 private String mCurResumedPackage = null; 1057 private int mCurResumedUid = -1; 1058 1059 /** 1060 * For reporting to battery stats the apps currently running foreground 1061 * service. The ProcessMap is package/uid tuples; each of these contain 1062 * an array of the currently foreground processes. 1063 */ 1064 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1065 = new ProcessMap<ArrayList<ProcessRecord>>(); 1066 1067 /** 1068 * This is set if we had to do a delayed dexopt of an app before launching 1069 * it, to increase the ANR timeouts in that case. 1070 */ 1071 boolean mDidDexOpt; 1072 1073 /** 1074 * Set if the systemServer made a call to enterSafeMode. 1075 */ 1076 boolean mSafeMode; 1077 1078 /** 1079 * If true, we are running under a test environment so will sample PSS from processes 1080 * much more rapidly to try to collect better data when the tests are rapidly 1081 * running through apps. 1082 */ 1083 boolean mTestPssMode = false; 1084 1085 String mDebugApp = null; 1086 boolean mWaitForDebugger = false; 1087 boolean mDebugTransient = false; 1088 String mOrigDebugApp = null; 1089 boolean mOrigWaitForDebugger = false; 1090 boolean mAlwaysFinishActivities = false; 1091 IActivityController mController = null; 1092 String mProfileApp = null; 1093 ProcessRecord mProfileProc = null; 1094 String mProfileFile; 1095 ParcelFileDescriptor mProfileFd; 1096 int mSamplingInterval = 0; 1097 boolean mAutoStopProfiler = false; 1098 int mProfileType = 0; 1099 String mOpenGlTraceApp = null; 1100 1101 final long[] mTmpLong = new long[1]; 1102 1103 static class ProcessChangeItem { 1104 static final int CHANGE_ACTIVITIES = 1<<0; 1105 static final int CHANGE_PROCESS_STATE = 1<<1; 1106 int changes; 1107 int uid; 1108 int pid; 1109 int processState; 1110 boolean foregroundActivities; 1111 } 1112 1113 final RemoteCallbackList<IProcessObserver> mProcessObservers 1114 = new RemoteCallbackList<IProcessObserver>(); 1115 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1116 1117 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1118 = new ArrayList<ProcessChangeItem>(); 1119 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1120 = new ArrayList<ProcessChangeItem>(); 1121 1122 /** 1123 * Runtime CPU use collection thread. This object's lock is used to 1124 * perform synchronization with the thread (notifying it to run). 1125 */ 1126 final Thread mProcessCpuThread; 1127 1128 /** 1129 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1130 * Must acquire this object's lock when accessing it. 1131 * NOTE: this lock will be held while doing long operations (trawling 1132 * through all processes in /proc), so it should never be acquired by 1133 * any critical paths such as when holding the main activity manager lock. 1134 */ 1135 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1136 MONITOR_THREAD_CPU_USAGE); 1137 final AtomicLong mLastCpuTime = new AtomicLong(0); 1138 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1139 1140 long mLastWriteTime = 0; 1141 1142 /** 1143 * Used to retain an update lock when the foreground activity is in 1144 * immersive mode. 1145 */ 1146 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1147 1148 /** 1149 * Set to true after the system has finished booting. 1150 */ 1151 boolean mBooted = false; 1152 1153 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1154 int mProcessLimitOverride = -1; 1155 1156 WindowManagerService mWindowManager; 1157 1158 final ActivityThread mSystemThread; 1159 1160 // Holds the current foreground user's id 1161 int mCurrentUserId = 0; 1162 // Holds the target user's id during a user switch 1163 int mTargetUserId = UserHandle.USER_NULL; 1164 // If there are multiple profiles for the current user, their ids are here 1165 // Currently only the primary user can have managed profiles 1166 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1167 1168 /** 1169 * Mapping from each known user ID to the profile group ID it is associated with. 1170 */ 1171 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1172 1173 private UserManagerService mUserManager; 1174 1175 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1176 final ProcessRecord mApp; 1177 final int mPid; 1178 final IApplicationThread mAppThread; 1179 1180 AppDeathRecipient(ProcessRecord app, int pid, 1181 IApplicationThread thread) { 1182 if (localLOGV) Slog.v( 1183 TAG, "New death recipient " + this 1184 + " for thread " + thread.asBinder()); 1185 mApp = app; 1186 mPid = pid; 1187 mAppThread = thread; 1188 } 1189 1190 @Override 1191 public void binderDied() { 1192 if (localLOGV) Slog.v( 1193 TAG, "Death received in " + this 1194 + " for thread " + mAppThread.asBinder()); 1195 synchronized(ActivityManagerService.this) { 1196 appDiedLocked(mApp, mPid, mAppThread); 1197 } 1198 } 1199 } 1200 1201 static final int SHOW_ERROR_MSG = 1; 1202 static final int SHOW_NOT_RESPONDING_MSG = 2; 1203 static final int SHOW_FACTORY_ERROR_MSG = 3; 1204 static final int UPDATE_CONFIGURATION_MSG = 4; 1205 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1206 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1207 static final int SERVICE_TIMEOUT_MSG = 12; 1208 static final int UPDATE_TIME_ZONE = 13; 1209 static final int SHOW_UID_ERROR_MSG = 14; 1210 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1211 static final int PROC_START_TIMEOUT_MSG = 20; 1212 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1213 static final int KILL_APPLICATION_MSG = 22; 1214 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1215 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1216 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1217 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1218 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1219 static final int CLEAR_DNS_CACHE_MSG = 28; 1220 static final int UPDATE_HTTP_PROXY_MSG = 29; 1221 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1222 static final int DISPATCH_PROCESSES_CHANGED = 31; 1223 static final int DISPATCH_PROCESS_DIED = 32; 1224 static final int REPORT_MEM_USAGE_MSG = 33; 1225 static final int REPORT_USER_SWITCH_MSG = 34; 1226 static final int CONTINUE_USER_SWITCH_MSG = 35; 1227 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1228 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1229 static final int PERSIST_URI_GRANTS_MSG = 38; 1230 static final int REQUEST_ALL_PSS_MSG = 39; 1231 static final int START_PROFILES_MSG = 40; 1232 static final int UPDATE_TIME = 41; 1233 static final int SYSTEM_USER_START_MSG = 42; 1234 static final int SYSTEM_USER_CURRENT_MSG = 43; 1235 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1236 static final int FINISH_BOOTING_MSG = 45; 1237 static final int START_USER_SWITCH_MSG = 46; 1238 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1239 static final int DISMISS_DIALOG_MSG = 48; 1240 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1241 1242 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1243 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1244 static final int FIRST_COMPAT_MODE_MSG = 300; 1245 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1246 1247 CompatModeDialog mCompatModeDialog; 1248 long mLastMemUsageReportTime = 0; 1249 1250 /** 1251 * Flag whether the current user is a "monkey", i.e. whether 1252 * the UI is driven by a UI automation tool. 1253 */ 1254 private boolean mUserIsMonkey; 1255 1256 /** Flag whether the device has a Recents UI */ 1257 boolean mHasRecents; 1258 1259 /** The dimensions of the thumbnails in the Recents UI. */ 1260 int mThumbnailWidth; 1261 int mThumbnailHeight; 1262 1263 final ServiceThread mHandlerThread; 1264 final MainHandler mHandler; 1265 1266 final class MainHandler extends Handler { 1267 public MainHandler(Looper looper) { 1268 super(looper, null, true); 1269 } 1270 1271 @Override 1272 public void handleMessage(Message msg) { 1273 switch (msg.what) { 1274 case SHOW_ERROR_MSG: { 1275 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1276 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1277 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1278 synchronized (ActivityManagerService.this) { 1279 ProcessRecord proc = (ProcessRecord)data.get("app"); 1280 AppErrorResult res = (AppErrorResult) data.get("result"); 1281 if (proc != null && proc.crashDialog != null) { 1282 Slog.e(TAG, "App already has crash dialog: " + proc); 1283 if (res != null) { 1284 res.set(0); 1285 } 1286 return; 1287 } 1288 boolean isBackground = (UserHandle.getAppId(proc.uid) 1289 >= Process.FIRST_APPLICATION_UID 1290 && proc.pid != MY_PID); 1291 for (int userId : mCurrentProfileIds) { 1292 isBackground &= (proc.userId != userId); 1293 } 1294 if (isBackground && !showBackground) { 1295 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1296 if (res != null) { 1297 res.set(0); 1298 } 1299 return; 1300 } 1301 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1302 Dialog d = new AppErrorDialog(mContext, 1303 ActivityManagerService.this, res, proc); 1304 d.show(); 1305 proc.crashDialog = d; 1306 } else { 1307 // The device is asleep, so just pretend that the user 1308 // saw a crash dialog and hit "force quit". 1309 if (res != null) { 1310 res.set(0); 1311 } 1312 } 1313 } 1314 1315 ensureBootCompleted(); 1316 } break; 1317 case SHOW_NOT_RESPONDING_MSG: { 1318 synchronized (ActivityManagerService.this) { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 ProcessRecord proc = (ProcessRecord)data.get("app"); 1321 if (proc != null && proc.anrDialog != null) { 1322 Slog.e(TAG, "App already has anr dialog: " + proc); 1323 return; 1324 } 1325 1326 Intent intent = new Intent("android.intent.action.ANR"); 1327 if (!mProcessesReady) { 1328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1329 | Intent.FLAG_RECEIVER_FOREGROUND); 1330 } 1331 broadcastIntentLocked(null, null, intent, 1332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1333 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1334 1335 if (mShowDialogs) { 1336 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1337 mContext, proc, (ActivityRecord)data.get("activity"), 1338 msg.arg1 != 0); 1339 d.show(); 1340 proc.anrDialog = d; 1341 } else { 1342 // Just kill the app if there is no dialog to be shown. 1343 killAppAtUsersRequest(proc, null); 1344 } 1345 } 1346 1347 ensureBootCompleted(); 1348 } break; 1349 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1350 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1351 synchronized (ActivityManagerService.this) { 1352 ProcessRecord proc = (ProcessRecord) data.get("app"); 1353 if (proc == null) { 1354 Slog.e(TAG, "App not found when showing strict mode dialog."); 1355 break; 1356 } 1357 if (proc.crashDialog != null) { 1358 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1359 return; 1360 } 1361 AppErrorResult res = (AppErrorResult) data.get("result"); 1362 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1363 Dialog d = new StrictModeViolationDialog(mContext, 1364 ActivityManagerService.this, res, proc); 1365 d.show(); 1366 proc.crashDialog = d; 1367 } else { 1368 // The device is asleep, so just pretend that the user 1369 // saw a crash dialog and hit "force quit". 1370 res.set(0); 1371 } 1372 } 1373 ensureBootCompleted(); 1374 } break; 1375 case SHOW_FACTORY_ERROR_MSG: { 1376 Dialog d = new FactoryErrorDialog( 1377 mContext, msg.getData().getCharSequence("msg")); 1378 d.show(); 1379 ensureBootCompleted(); 1380 } break; 1381 case UPDATE_CONFIGURATION_MSG: { 1382 final ContentResolver resolver = mContext.getContentResolver(); 1383 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1384 } break; 1385 case GC_BACKGROUND_PROCESSES_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 performAppGcsIfAppropriateLocked(); 1388 } 1389 } break; 1390 case WAIT_FOR_DEBUGGER_MSG: { 1391 synchronized (ActivityManagerService.this) { 1392 ProcessRecord app = (ProcessRecord)msg.obj; 1393 if (msg.arg1 != 0) { 1394 if (!app.waitedForDebugger) { 1395 Dialog d = new AppWaitingForDebuggerDialog( 1396 ActivityManagerService.this, 1397 mContext, app); 1398 app.waitDialog = d; 1399 app.waitedForDebugger = true; 1400 d.show(); 1401 } 1402 } else { 1403 if (app.waitDialog != null) { 1404 app.waitDialog.dismiss(); 1405 app.waitDialog = null; 1406 } 1407 } 1408 } 1409 } break; 1410 case SERVICE_TIMEOUT_MSG: { 1411 if (mDidDexOpt) { 1412 mDidDexOpt = false; 1413 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1414 nmsg.obj = msg.obj; 1415 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1416 return; 1417 } 1418 mServices.serviceTimeout((ProcessRecord)msg.obj); 1419 } break; 1420 case UPDATE_TIME_ZONE: { 1421 synchronized (ActivityManagerService.this) { 1422 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1423 ProcessRecord r = mLruProcesses.get(i); 1424 if (r.thread != null) { 1425 try { 1426 r.thread.updateTimeZone(); 1427 } catch (RemoteException ex) { 1428 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1429 } 1430 } 1431 } 1432 } 1433 } break; 1434 case CLEAR_DNS_CACHE_MSG: { 1435 synchronized (ActivityManagerService.this) { 1436 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1437 ProcessRecord r = mLruProcesses.get(i); 1438 if (r.thread != null) { 1439 try { 1440 r.thread.clearDnsCache(); 1441 } catch (RemoteException ex) { 1442 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1443 } 1444 } 1445 } 1446 } 1447 } break; 1448 case UPDATE_HTTP_PROXY_MSG: { 1449 ProxyInfo proxy = (ProxyInfo)msg.obj; 1450 String host = ""; 1451 String port = ""; 1452 String exclList = ""; 1453 Uri pacFileUrl = Uri.EMPTY; 1454 if (proxy != null) { 1455 host = proxy.getHost(); 1456 port = Integer.toString(proxy.getPort()); 1457 exclList = proxy.getExclusionListAsString(); 1458 pacFileUrl = proxy.getPacFileUrl(); 1459 } 1460 synchronized (ActivityManagerService.this) { 1461 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1462 ProcessRecord r = mLruProcesses.get(i); 1463 if (r.thread != null) { 1464 try { 1465 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1466 } catch (RemoteException ex) { 1467 Slog.w(TAG, "Failed to update http proxy for: " + 1468 r.info.processName); 1469 } 1470 } 1471 } 1472 } 1473 } break; 1474 case SHOW_UID_ERROR_MSG: { 1475 if (mShowDialogs) { 1476 AlertDialog d = new BaseErrorDialog(mContext); 1477 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1478 d.setCancelable(false); 1479 d.setTitle(mContext.getText(R.string.android_system_label)); 1480 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1481 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1482 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1483 d.show(); 1484 } 1485 } break; 1486 case SHOW_FINGERPRINT_ERROR_MSG: { 1487 if (mShowDialogs) { 1488 AlertDialog d = new BaseErrorDialog(mContext); 1489 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1490 d.setCancelable(false); 1491 d.setTitle(mContext.getText(R.string.android_system_label)); 1492 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1493 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1494 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1495 d.show(); 1496 } 1497 } break; 1498 case PROC_START_TIMEOUT_MSG: { 1499 if (mDidDexOpt) { 1500 mDidDexOpt = false; 1501 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1502 nmsg.obj = msg.obj; 1503 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1504 return; 1505 } 1506 ProcessRecord app = (ProcessRecord)msg.obj; 1507 synchronized (ActivityManagerService.this) { 1508 processStartTimedOutLocked(app); 1509 } 1510 } break; 1511 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1512 synchronized (ActivityManagerService.this) { 1513 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1514 } 1515 } break; 1516 case KILL_APPLICATION_MSG: { 1517 synchronized (ActivityManagerService.this) { 1518 int appid = msg.arg1; 1519 boolean restart = (msg.arg2 == 1); 1520 Bundle bundle = (Bundle)msg.obj; 1521 String pkg = bundle.getString("pkg"); 1522 String reason = bundle.getString("reason"); 1523 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1524 false, UserHandle.USER_ALL, reason); 1525 } 1526 } break; 1527 case FINALIZE_PENDING_INTENT_MSG: { 1528 ((PendingIntentRecord)msg.obj).completeFinalize(); 1529 } break; 1530 case POST_HEAVY_NOTIFICATION_MSG: { 1531 INotificationManager inm = NotificationManager.getService(); 1532 if (inm == null) { 1533 return; 1534 } 1535 1536 ActivityRecord root = (ActivityRecord)msg.obj; 1537 ProcessRecord process = root.app; 1538 if (process == null) { 1539 return; 1540 } 1541 1542 try { 1543 Context context = mContext.createPackageContext(process.info.packageName, 0); 1544 String text = mContext.getString(R.string.heavy_weight_notification, 1545 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1546 Notification notification = new Notification(); 1547 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1548 notification.when = 0; 1549 notification.flags = Notification.FLAG_ONGOING_EVENT; 1550 notification.tickerText = text; 1551 notification.defaults = 0; // please be quiet 1552 notification.sound = null; 1553 notification.vibrate = null; 1554 notification.color = mContext.getResources().getColor( 1555 com.android.internal.R.color.system_notification_accent_color); 1556 notification.setLatestEventInfo(context, text, 1557 mContext.getText(R.string.heavy_weight_notification_detail), 1558 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1559 PendingIntent.FLAG_CANCEL_CURRENT, null, 1560 new UserHandle(root.userId))); 1561 1562 try { 1563 int[] outId = new int[1]; 1564 inm.enqueueNotificationWithTag("android", "android", null, 1565 R.string.heavy_weight_notification, 1566 notification, outId, root.userId); 1567 } catch (RuntimeException e) { 1568 Slog.w(ActivityManagerService.TAG, 1569 "Error showing notification for heavy-weight app", e); 1570 } catch (RemoteException e) { 1571 } 1572 } catch (NameNotFoundException e) { 1573 Slog.w(TAG, "Unable to create context for heavy notification", e); 1574 } 1575 } break; 1576 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1577 INotificationManager inm = NotificationManager.getService(); 1578 if (inm == null) { 1579 return; 1580 } 1581 try { 1582 inm.cancelNotificationWithTag("android", null, 1583 R.string.heavy_weight_notification, msg.arg1); 1584 } catch (RuntimeException e) { 1585 Slog.w(ActivityManagerService.TAG, 1586 "Error canceling notification for service", e); 1587 } catch (RemoteException e) { 1588 } 1589 } break; 1590 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1591 synchronized (ActivityManagerService.this) { 1592 checkExcessivePowerUsageLocked(true); 1593 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1594 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1595 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1596 } 1597 } break; 1598 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1599 synchronized (ActivityManagerService.this) { 1600 ActivityRecord ar = (ActivityRecord)msg.obj; 1601 if (mCompatModeDialog != null) { 1602 if (mCompatModeDialog.mAppInfo.packageName.equals( 1603 ar.info.applicationInfo.packageName)) { 1604 return; 1605 } 1606 mCompatModeDialog.dismiss(); 1607 mCompatModeDialog = null; 1608 } 1609 if (ar != null && false) { 1610 if (mCompatModePackages.getPackageAskCompatModeLocked( 1611 ar.packageName)) { 1612 int mode = mCompatModePackages.computeCompatModeLocked( 1613 ar.info.applicationInfo); 1614 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1615 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1616 mCompatModeDialog = new CompatModeDialog( 1617 ActivityManagerService.this, mContext, 1618 ar.info.applicationInfo); 1619 mCompatModeDialog.show(); 1620 } 1621 } 1622 } 1623 } 1624 break; 1625 } 1626 case DISPATCH_PROCESSES_CHANGED: { 1627 dispatchProcessesChanged(); 1628 break; 1629 } 1630 case DISPATCH_PROCESS_DIED: { 1631 final int pid = msg.arg1; 1632 final int uid = msg.arg2; 1633 dispatchProcessDied(pid, uid); 1634 break; 1635 } 1636 case REPORT_MEM_USAGE_MSG: { 1637 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1638 Thread thread = new Thread() { 1639 @Override public void run() { 1640 reportMemUsage(memInfos); 1641 } 1642 }; 1643 thread.start(); 1644 break; 1645 } 1646 case START_USER_SWITCH_MSG: { 1647 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1648 break; 1649 } 1650 case REPORT_USER_SWITCH_MSG: { 1651 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1652 break; 1653 } 1654 case CONTINUE_USER_SWITCH_MSG: { 1655 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1656 break; 1657 } 1658 case USER_SWITCH_TIMEOUT_MSG: { 1659 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1660 break; 1661 } 1662 case IMMERSIVE_MODE_LOCK_MSG: { 1663 final boolean nextState = (msg.arg1 != 0); 1664 if (mUpdateLock.isHeld() != nextState) { 1665 if (DEBUG_IMMERSIVE) { 1666 final ActivityRecord r = (ActivityRecord) msg.obj; 1667 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1668 } 1669 if (nextState) { 1670 mUpdateLock.acquire(); 1671 } else { 1672 mUpdateLock.release(); 1673 } 1674 } 1675 break; 1676 } 1677 case PERSIST_URI_GRANTS_MSG: { 1678 writeGrantedUriPermissions(); 1679 break; 1680 } 1681 case REQUEST_ALL_PSS_MSG: { 1682 synchronized (ActivityManagerService.this) { 1683 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1684 } 1685 break; 1686 } 1687 case START_PROFILES_MSG: { 1688 synchronized (ActivityManagerService.this) { 1689 startProfilesLocked(); 1690 } 1691 break; 1692 } 1693 case UPDATE_TIME: { 1694 synchronized (ActivityManagerService.this) { 1695 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1696 ProcessRecord r = mLruProcesses.get(i); 1697 if (r.thread != null) { 1698 try { 1699 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1700 } catch (RemoteException ex) { 1701 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1702 } 1703 } 1704 } 1705 } 1706 break; 1707 } 1708 case SYSTEM_USER_START_MSG: { 1709 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1710 Integer.toString(msg.arg1), msg.arg1); 1711 mSystemServiceManager.startUser(msg.arg1); 1712 break; 1713 } 1714 case SYSTEM_USER_CURRENT_MSG: { 1715 mBatteryStatsService.noteEvent( 1716 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1717 Integer.toString(msg.arg2), msg.arg2); 1718 mBatteryStatsService.noteEvent( 1719 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1720 Integer.toString(msg.arg1), msg.arg1); 1721 mSystemServiceManager.switchUser(msg.arg1); 1722 break; 1723 } 1724 case ENTER_ANIMATION_COMPLETE_MSG: { 1725 synchronized (ActivityManagerService.this) { 1726 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1727 if (r != null && r.app != null && r.app.thread != null) { 1728 try { 1729 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1730 } catch (RemoteException e) { 1731 } 1732 } 1733 } 1734 break; 1735 } 1736 case FINISH_BOOTING_MSG: { 1737 if (msg.arg1 != 0) { 1738 finishBooting(); 1739 } 1740 if (msg.arg2 != 0) { 1741 enableScreenAfterBoot(); 1742 } 1743 break; 1744 } 1745 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1746 try { 1747 Locale l = (Locale) msg.obj; 1748 IBinder service = ServiceManager.getService("mount"); 1749 IMountService mountService = IMountService.Stub.asInterface(service); 1750 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1751 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1752 } catch (RemoteException e) { 1753 Log.e(TAG, "Error storing locale for decryption UI", e); 1754 } 1755 break; 1756 } 1757 case DISMISS_DIALOG_MSG: { 1758 final Dialog d = (Dialog) msg.obj; 1759 d.dismiss(); 1760 break; 1761 } 1762 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1763 synchronized (ActivityManagerService.this) { 1764 int i = mTaskStackListeners.beginBroadcast(); 1765 while (i > 0) { 1766 i--; 1767 try { 1768 // Make a one-way callback to the listener 1769 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1770 } catch (RemoteException e){ 1771 // Handled by the RemoteCallbackList 1772 } 1773 } 1774 mTaskStackListeners.finishBroadcast(); 1775 } 1776 break; 1777 } 1778 } 1779 } 1780 }; 1781 1782 static final int COLLECT_PSS_BG_MSG = 1; 1783 1784 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1785 @Override 1786 public void handleMessage(Message msg) { 1787 switch (msg.what) { 1788 case COLLECT_PSS_BG_MSG: { 1789 long start = SystemClock.uptimeMillis(); 1790 MemInfoReader memInfo = null; 1791 synchronized (ActivityManagerService.this) { 1792 if (mFullPssPending) { 1793 mFullPssPending = false; 1794 memInfo = new MemInfoReader(); 1795 } 1796 } 1797 if (memInfo != null) { 1798 updateCpuStatsNow(); 1799 long nativeTotalPss = 0; 1800 synchronized (mProcessCpuTracker) { 1801 final int N = mProcessCpuTracker.countStats(); 1802 for (int j=0; j<N; j++) { 1803 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1804 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1805 // This is definitely an application process; skip it. 1806 continue; 1807 } 1808 synchronized (mPidsSelfLocked) { 1809 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1810 // This is one of our own processes; skip it. 1811 continue; 1812 } 1813 } 1814 nativeTotalPss += Debug.getPss(st.pid, null, null); 1815 } 1816 } 1817 memInfo.readMemInfo(); 1818 synchronized (ActivityManagerService.this) { 1819 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1820 + (SystemClock.uptimeMillis()-start) + "ms"); 1821 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1822 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1823 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1824 } 1825 } 1826 1827 int num = 0; 1828 long[] tmp = new long[1]; 1829 do { 1830 ProcessRecord proc; 1831 int procState; 1832 int pid; 1833 long lastPssTime; 1834 synchronized (ActivityManagerService.this) { 1835 if (mPendingPssProcesses.size() <= 0) { 1836 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1837 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1838 mPendingPssProcesses.clear(); 1839 return; 1840 } 1841 proc = mPendingPssProcesses.remove(0); 1842 procState = proc.pssProcState; 1843 lastPssTime = proc.lastPssTime; 1844 if (proc.thread != null && procState == proc.setProcState 1845 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1846 < SystemClock.uptimeMillis()) { 1847 pid = proc.pid; 1848 } else { 1849 proc = null; 1850 pid = 0; 1851 } 1852 } 1853 if (proc != null) { 1854 long pss = Debug.getPss(pid, tmp, null); 1855 synchronized (ActivityManagerService.this) { 1856 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1857 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1858 num++; 1859 recordPssSample(proc, procState, pss, tmp[0], 1860 SystemClock.uptimeMillis()); 1861 } 1862 } 1863 } 1864 } while (true); 1865 } 1866 } 1867 } 1868 }; 1869 1870 public void setSystemProcess() { 1871 try { 1872 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1873 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1874 ServiceManager.addService("meminfo", new MemBinder(this)); 1875 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1876 ServiceManager.addService("dbinfo", new DbBinder(this)); 1877 if (MONITOR_CPU_USAGE) { 1878 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1879 } 1880 ServiceManager.addService("permission", new PermissionController(this)); 1881 1882 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1883 "android", STOCK_PM_FLAGS); 1884 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1885 1886 synchronized (this) { 1887 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1888 app.persistent = true; 1889 app.pid = MY_PID; 1890 app.maxAdj = ProcessList.SYSTEM_ADJ; 1891 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1892 mProcessNames.put(app.processName, app.uid, app); 1893 synchronized (mPidsSelfLocked) { 1894 mPidsSelfLocked.put(app.pid, app); 1895 } 1896 updateLruProcessLocked(app, false, null); 1897 updateOomAdjLocked(); 1898 } 1899 } catch (PackageManager.NameNotFoundException e) { 1900 throw new RuntimeException( 1901 "Unable to find android system package", e); 1902 } 1903 } 1904 1905 public void setWindowManager(WindowManagerService wm) { 1906 mWindowManager = wm; 1907 mStackSupervisor.setWindowManager(wm); 1908 } 1909 1910 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1911 mUsageStatsService = usageStatsManager; 1912 } 1913 1914 public void startObservingNativeCrashes() { 1915 final NativeCrashListener ncl = new NativeCrashListener(this); 1916 ncl.start(); 1917 } 1918 1919 public IAppOpsService getAppOpsService() { 1920 return mAppOpsService; 1921 } 1922 1923 static class MemBinder extends Binder { 1924 ActivityManagerService mActivityManagerService; 1925 MemBinder(ActivityManagerService activityManagerService) { 1926 mActivityManagerService = activityManagerService; 1927 } 1928 1929 @Override 1930 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1931 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1932 != PackageManager.PERMISSION_GRANTED) { 1933 pw.println("Permission Denial: can't dump meminfo from from pid=" 1934 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1935 + " without permission " + android.Manifest.permission.DUMP); 1936 return; 1937 } 1938 1939 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1940 } 1941 } 1942 1943 static class GraphicsBinder extends Binder { 1944 ActivityManagerService mActivityManagerService; 1945 GraphicsBinder(ActivityManagerService activityManagerService) { 1946 mActivityManagerService = activityManagerService; 1947 } 1948 1949 @Override 1950 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1951 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1952 != PackageManager.PERMISSION_GRANTED) { 1953 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1954 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1955 + " without permission " + android.Manifest.permission.DUMP); 1956 return; 1957 } 1958 1959 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1960 } 1961 } 1962 1963 static class DbBinder extends Binder { 1964 ActivityManagerService mActivityManagerService; 1965 DbBinder(ActivityManagerService activityManagerService) { 1966 mActivityManagerService = activityManagerService; 1967 } 1968 1969 @Override 1970 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1971 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1972 != PackageManager.PERMISSION_GRANTED) { 1973 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1974 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1975 + " without permission " + android.Manifest.permission.DUMP); 1976 return; 1977 } 1978 1979 mActivityManagerService.dumpDbInfo(fd, pw, args); 1980 } 1981 } 1982 1983 static class CpuBinder extends Binder { 1984 ActivityManagerService mActivityManagerService; 1985 CpuBinder(ActivityManagerService activityManagerService) { 1986 mActivityManagerService = activityManagerService; 1987 } 1988 1989 @Override 1990 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1991 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1992 != PackageManager.PERMISSION_GRANTED) { 1993 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1994 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1995 + " without permission " + android.Manifest.permission.DUMP); 1996 return; 1997 } 1998 1999 synchronized (mActivityManagerService.mProcessCpuTracker) { 2000 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2001 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2002 SystemClock.uptimeMillis())); 2003 } 2004 } 2005 } 2006 2007 public static final class Lifecycle extends SystemService { 2008 private final ActivityManagerService mService; 2009 2010 public Lifecycle(Context context) { 2011 super(context); 2012 mService = new ActivityManagerService(context); 2013 } 2014 2015 @Override 2016 public void onStart() { 2017 mService.start(); 2018 } 2019 2020 public ActivityManagerService getService() { 2021 return mService; 2022 } 2023 } 2024 2025 // Note: This method is invoked on the main thread but may need to attach various 2026 // handlers to other threads. So take care to be explicit about the looper. 2027 public ActivityManagerService(Context systemContext) { 2028 mContext = systemContext; 2029 mFactoryTest = FactoryTest.getMode(); 2030 mSystemThread = ActivityThread.currentActivityThread(); 2031 2032 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2033 2034 mHandlerThread = new ServiceThread(TAG, 2035 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2036 mHandlerThread.start(); 2037 mHandler = new MainHandler(mHandlerThread.getLooper()); 2038 2039 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2040 "foreground", BROADCAST_FG_TIMEOUT, false); 2041 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2042 "background", BROADCAST_BG_TIMEOUT, true); 2043 mBroadcastQueues[0] = mFgBroadcastQueue; 2044 mBroadcastQueues[1] = mBgBroadcastQueue; 2045 2046 mServices = new ActiveServices(this); 2047 mProviderMap = new ProviderMap(this); 2048 2049 // TODO: Move creation of battery stats service outside of activity manager service. 2050 File dataDir = Environment.getDataDirectory(); 2051 File systemDir = new File(dataDir, "system"); 2052 systemDir.mkdirs(); 2053 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2054 mBatteryStatsService.getActiveStatistics().readLocked(); 2055 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2056 mOnBattery = DEBUG_POWER ? true 2057 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2058 mBatteryStatsService.getActiveStatistics().setCallback(this); 2059 2060 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2061 2062 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2063 2064 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2065 2066 // User 0 is the first and only user that runs at boot. 2067 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2068 mUserLru.add(Integer.valueOf(0)); 2069 updateStartedUserArrayLocked(); 2070 2071 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2072 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2073 2074 mConfiguration.setToDefaults(); 2075 mConfiguration.setLocale(Locale.getDefault()); 2076 2077 mConfigurationSeq = mConfiguration.seq = 1; 2078 mProcessCpuTracker.init(); 2079 2080 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2081 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2082 mStackSupervisor = new ActivityStackSupervisor(this); 2083 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2084 2085 mProcessCpuThread = new Thread("CpuTracker") { 2086 @Override 2087 public void run() { 2088 while (true) { 2089 try { 2090 try { 2091 synchronized(this) { 2092 final long now = SystemClock.uptimeMillis(); 2093 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2094 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2095 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2096 // + ", write delay=" + nextWriteDelay); 2097 if (nextWriteDelay < nextCpuDelay) { 2098 nextCpuDelay = nextWriteDelay; 2099 } 2100 if (nextCpuDelay > 0) { 2101 mProcessCpuMutexFree.set(true); 2102 this.wait(nextCpuDelay); 2103 } 2104 } 2105 } catch (InterruptedException e) { 2106 } 2107 updateCpuStatsNow(); 2108 } catch (Exception e) { 2109 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2110 } 2111 } 2112 } 2113 }; 2114 2115 Watchdog.getInstance().addMonitor(this); 2116 Watchdog.getInstance().addThread(mHandler); 2117 } 2118 2119 public void setSystemServiceManager(SystemServiceManager mgr) { 2120 mSystemServiceManager = mgr; 2121 } 2122 2123 public void setInstaller(Installer installer) { 2124 mInstaller = installer; 2125 } 2126 2127 private void start() { 2128 Process.removeAllProcessGroups(); 2129 mProcessCpuThread.start(); 2130 2131 mBatteryStatsService.publish(mContext); 2132 mAppOpsService.publish(mContext); 2133 Slog.d("AppOps", "AppOpsService published"); 2134 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2135 } 2136 2137 public void initPowerManagement() { 2138 mStackSupervisor.initPowerManagement(); 2139 mBatteryStatsService.initPowerManagement(); 2140 } 2141 2142 @Override 2143 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2144 throws RemoteException { 2145 if (code == SYSPROPS_TRANSACTION) { 2146 // We need to tell all apps about the system property change. 2147 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2148 synchronized(this) { 2149 final int NP = mProcessNames.getMap().size(); 2150 for (int ip=0; ip<NP; ip++) { 2151 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2152 final int NA = apps.size(); 2153 for (int ia=0; ia<NA; ia++) { 2154 ProcessRecord app = apps.valueAt(ia); 2155 if (app.thread != null) { 2156 procs.add(app.thread.asBinder()); 2157 } 2158 } 2159 } 2160 } 2161 2162 int N = procs.size(); 2163 for (int i=0; i<N; i++) { 2164 Parcel data2 = Parcel.obtain(); 2165 try { 2166 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2167 } catch (RemoteException e) { 2168 } 2169 data2.recycle(); 2170 } 2171 } 2172 try { 2173 return super.onTransact(code, data, reply, flags); 2174 } catch (RuntimeException e) { 2175 // The activity manager only throws security exceptions, so let's 2176 // log all others. 2177 if (!(e instanceof SecurityException)) { 2178 Slog.wtf(TAG, "Activity Manager Crash", e); 2179 } 2180 throw e; 2181 } 2182 } 2183 2184 void updateCpuStats() { 2185 final long now = SystemClock.uptimeMillis(); 2186 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2187 return; 2188 } 2189 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2190 synchronized (mProcessCpuThread) { 2191 mProcessCpuThread.notify(); 2192 } 2193 } 2194 } 2195 2196 void updateCpuStatsNow() { 2197 synchronized (mProcessCpuTracker) { 2198 mProcessCpuMutexFree.set(false); 2199 final long now = SystemClock.uptimeMillis(); 2200 boolean haveNewCpuStats = false; 2201 2202 if (MONITOR_CPU_USAGE && 2203 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2204 mLastCpuTime.set(now); 2205 haveNewCpuStats = true; 2206 mProcessCpuTracker.update(); 2207 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2208 //Slog.i(TAG, "Total CPU usage: " 2209 // + mProcessCpu.getTotalCpuPercent() + "%"); 2210 2211 // Slog the cpu usage if the property is set. 2212 if ("true".equals(SystemProperties.get("events.cpu"))) { 2213 int user = mProcessCpuTracker.getLastUserTime(); 2214 int system = mProcessCpuTracker.getLastSystemTime(); 2215 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2216 int irq = mProcessCpuTracker.getLastIrqTime(); 2217 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2218 int idle = mProcessCpuTracker.getLastIdleTime(); 2219 2220 int total = user + system + iowait + irq + softIrq + idle; 2221 if (total == 0) total = 1; 2222 2223 EventLog.writeEvent(EventLogTags.CPU, 2224 ((user+system+iowait+irq+softIrq) * 100) / total, 2225 (user * 100) / total, 2226 (system * 100) / total, 2227 (iowait * 100) / total, 2228 (irq * 100) / total, 2229 (softIrq * 100) / total); 2230 } 2231 } 2232 2233 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2234 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2235 synchronized(bstats) { 2236 synchronized(mPidsSelfLocked) { 2237 if (haveNewCpuStats) { 2238 if (mOnBattery) { 2239 int perc = bstats.startAddingCpuLocked(); 2240 int totalUTime = 0; 2241 int totalSTime = 0; 2242 final int N = mProcessCpuTracker.countStats(); 2243 for (int i=0; i<N; i++) { 2244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2245 if (!st.working) { 2246 continue; 2247 } 2248 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2249 int otherUTime = (st.rel_utime*perc)/100; 2250 int otherSTime = (st.rel_stime*perc)/100; 2251 totalUTime += otherUTime; 2252 totalSTime += otherSTime; 2253 if (pr != null) { 2254 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2255 if (ps == null || !ps.isActive()) { 2256 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2257 pr.info.uid, pr.processName); 2258 } 2259 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2260 st.rel_stime-otherSTime); 2261 ps.addSpeedStepTimes(cpuSpeedTimes); 2262 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2263 } else { 2264 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2265 if (ps == null || !ps.isActive()) { 2266 st.batteryStats = ps = bstats.getProcessStatsLocked( 2267 bstats.mapUid(st.uid), st.name); 2268 } 2269 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2270 st.rel_stime-otherSTime); 2271 ps.addSpeedStepTimes(cpuSpeedTimes); 2272 } 2273 } 2274 bstats.finishAddingCpuLocked(perc, totalUTime, 2275 totalSTime, cpuSpeedTimes); 2276 } 2277 } 2278 } 2279 2280 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2281 mLastWriteTime = now; 2282 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2283 } 2284 } 2285 } 2286 } 2287 2288 @Override 2289 public void batteryNeedsCpuUpdate() { 2290 updateCpuStatsNow(); 2291 } 2292 2293 @Override 2294 public void batteryPowerChanged(boolean onBattery) { 2295 // When plugging in, update the CPU stats first before changing 2296 // the plug state. 2297 updateCpuStatsNow(); 2298 synchronized (this) { 2299 synchronized(mPidsSelfLocked) { 2300 mOnBattery = DEBUG_POWER ? true : onBattery; 2301 } 2302 } 2303 } 2304 2305 /** 2306 * Initialize the application bind args. These are passed to each 2307 * process when the bindApplication() IPC is sent to the process. They're 2308 * lazily setup to make sure the services are running when they're asked for. 2309 */ 2310 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2311 if (mAppBindArgs == null) { 2312 mAppBindArgs = new HashMap<>(); 2313 2314 // Isolated processes won't get this optimization, so that we don't 2315 // violate the rules about which services they have access to. 2316 if (!isolated) { 2317 // Setup the application init args 2318 mAppBindArgs.put("package", ServiceManager.getService("package")); 2319 mAppBindArgs.put("window", ServiceManager.getService("window")); 2320 mAppBindArgs.put(Context.ALARM_SERVICE, 2321 ServiceManager.getService(Context.ALARM_SERVICE)); 2322 } 2323 } 2324 return mAppBindArgs; 2325 } 2326 2327 final void setFocusedActivityLocked(ActivityRecord r) { 2328 if (mFocusedActivity != r) { 2329 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2330 mFocusedActivity = r; 2331 if (r.task != null && r.task.voiceInteractor != null) { 2332 startRunningVoiceLocked(); 2333 } else { 2334 finishRunningVoiceLocked(); 2335 } 2336 mStackSupervisor.setFocusedStack(r); 2337 if (r != null) { 2338 mWindowManager.setFocusedApp(r.appToken, true); 2339 } 2340 applyUpdateLockStateLocked(r); 2341 } 2342 } 2343 2344 final void clearFocusedActivity(ActivityRecord r) { 2345 if (mFocusedActivity == r) { 2346 mFocusedActivity = null; 2347 } 2348 } 2349 2350 @Override 2351 public void setFocusedStack(int stackId) { 2352 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2353 synchronized (ActivityManagerService.this) { 2354 ActivityStack stack = mStackSupervisor.getStack(stackId); 2355 if (stack != null) { 2356 ActivityRecord r = stack.topRunningActivityLocked(null); 2357 if (r != null) { 2358 setFocusedActivityLocked(r); 2359 } 2360 } 2361 } 2362 } 2363 2364 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2365 @Override 2366 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2367 synchronized (ActivityManagerService.this) { 2368 if (listener != null) { 2369 mTaskStackListeners.register(listener); 2370 } 2371 } 2372 } 2373 2374 @Override 2375 public void notifyActivityDrawn(IBinder token) { 2376 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2377 synchronized (this) { 2378 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2379 if (r != null) { 2380 r.task.stack.notifyActivityDrawnLocked(r); 2381 } 2382 } 2383 } 2384 2385 final void applyUpdateLockStateLocked(ActivityRecord r) { 2386 // Modifications to the UpdateLock state are done on our handler, outside 2387 // the activity manager's locks. The new state is determined based on the 2388 // state *now* of the relevant activity record. The object is passed to 2389 // the handler solely for logging detail, not to be consulted/modified. 2390 final boolean nextState = r != null && r.immersive; 2391 mHandler.sendMessage( 2392 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2393 } 2394 2395 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2396 Message msg = Message.obtain(); 2397 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2398 msg.obj = r.task.askedCompatMode ? null : r; 2399 mHandler.sendMessage(msg); 2400 } 2401 2402 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2403 String what, Object obj, ProcessRecord srcApp) { 2404 app.lastActivityTime = now; 2405 2406 if (app.activities.size() > 0) { 2407 // Don't want to touch dependent processes that are hosting activities. 2408 return index; 2409 } 2410 2411 int lrui = mLruProcesses.lastIndexOf(app); 2412 if (lrui < 0) { 2413 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2414 + what + " " + obj + " from " + srcApp); 2415 return index; 2416 } 2417 2418 if (lrui >= index) { 2419 // Don't want to cause this to move dependent processes *back* in the 2420 // list as if they were less frequently used. 2421 return index; 2422 } 2423 2424 if (lrui >= mLruProcessActivityStart) { 2425 // Don't want to touch dependent processes that are hosting activities. 2426 return index; 2427 } 2428 2429 mLruProcesses.remove(lrui); 2430 if (index > 0) { 2431 index--; 2432 } 2433 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2434 + " in LRU list: " + app); 2435 mLruProcesses.add(index, app); 2436 return index; 2437 } 2438 2439 final void removeLruProcessLocked(ProcessRecord app) { 2440 int lrui = mLruProcesses.lastIndexOf(app); 2441 if (lrui >= 0) { 2442 if (!app.killed) { 2443 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2444 Process.killProcessQuiet(app.pid); 2445 Process.killProcessGroup(app.info.uid, app.pid); 2446 } 2447 if (lrui <= mLruProcessActivityStart) { 2448 mLruProcessActivityStart--; 2449 } 2450 if (lrui <= mLruProcessServiceStart) { 2451 mLruProcessServiceStart--; 2452 } 2453 mLruProcesses.remove(lrui); 2454 } 2455 } 2456 2457 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2458 ProcessRecord client) { 2459 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2460 || app.treatLikeActivity; 2461 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2462 if (!activityChange && hasActivity) { 2463 // The process has activities, so we are only allowing activity-based adjustments 2464 // to move it. It should be kept in the front of the list with other 2465 // processes that have activities, and we don't want those to change their 2466 // order except due to activity operations. 2467 return; 2468 } 2469 2470 mLruSeq++; 2471 final long now = SystemClock.uptimeMillis(); 2472 app.lastActivityTime = now; 2473 2474 // First a quick reject: if the app is already at the position we will 2475 // put it, then there is nothing to do. 2476 if (hasActivity) { 2477 final int N = mLruProcesses.size(); 2478 if (N > 0 && mLruProcesses.get(N-1) == app) { 2479 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2480 return; 2481 } 2482 } else { 2483 if (mLruProcessServiceStart > 0 2484 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2485 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2486 return; 2487 } 2488 } 2489 2490 int lrui = mLruProcesses.lastIndexOf(app); 2491 2492 if (app.persistent && lrui >= 0) { 2493 // We don't care about the position of persistent processes, as long as 2494 // they are in the list. 2495 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2496 return; 2497 } 2498 2499 /* In progress: compute new position first, so we can avoid doing work 2500 if the process is not actually going to move. Not yet working. 2501 int addIndex; 2502 int nextIndex; 2503 boolean inActivity = false, inService = false; 2504 if (hasActivity) { 2505 // Process has activities, put it at the very tipsy-top. 2506 addIndex = mLruProcesses.size(); 2507 nextIndex = mLruProcessServiceStart; 2508 inActivity = true; 2509 } else if (hasService) { 2510 // Process has services, put it at the top of the service list. 2511 addIndex = mLruProcessActivityStart; 2512 nextIndex = mLruProcessServiceStart; 2513 inActivity = true; 2514 inService = true; 2515 } else { 2516 // Process not otherwise of interest, it goes to the top of the non-service area. 2517 addIndex = mLruProcessServiceStart; 2518 if (client != null) { 2519 int clientIndex = mLruProcesses.lastIndexOf(client); 2520 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2521 + app); 2522 if (clientIndex >= 0 && addIndex > clientIndex) { 2523 addIndex = clientIndex; 2524 } 2525 } 2526 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2527 } 2528 2529 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2530 + mLruProcessActivityStart + "): " + app); 2531 */ 2532 2533 if (lrui >= 0) { 2534 if (lrui < mLruProcessActivityStart) { 2535 mLruProcessActivityStart--; 2536 } 2537 if (lrui < mLruProcessServiceStart) { 2538 mLruProcessServiceStart--; 2539 } 2540 /* 2541 if (addIndex > lrui) { 2542 addIndex--; 2543 } 2544 if (nextIndex > lrui) { 2545 nextIndex--; 2546 } 2547 */ 2548 mLruProcesses.remove(lrui); 2549 } 2550 2551 /* 2552 mLruProcesses.add(addIndex, app); 2553 if (inActivity) { 2554 mLruProcessActivityStart++; 2555 } 2556 if (inService) { 2557 mLruProcessActivityStart++; 2558 } 2559 */ 2560 2561 int nextIndex; 2562 if (hasActivity) { 2563 final int N = mLruProcesses.size(); 2564 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2565 // Process doesn't have activities, but has clients with 2566 // activities... move it up, but one below the top (the top 2567 // should always have a real activity). 2568 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2569 mLruProcesses.add(N-1, app); 2570 // To keep it from spamming the LRU list (by making a bunch of clients), 2571 // we will push down any other entries owned by the app. 2572 final int uid = app.info.uid; 2573 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2574 ProcessRecord subProc = mLruProcesses.get(i); 2575 if (subProc.info.uid == uid) { 2576 // We want to push this one down the list. If the process after 2577 // it is for the same uid, however, don't do so, because we don't 2578 // want them internally to be re-ordered. 2579 if (mLruProcesses.get(i-1).info.uid != uid) { 2580 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2581 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2582 ProcessRecord tmp = mLruProcesses.get(i); 2583 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2584 mLruProcesses.set(i-1, tmp); 2585 i--; 2586 } 2587 } else { 2588 // A gap, we can stop here. 2589 break; 2590 } 2591 } 2592 } else { 2593 // Process has activities, put it at the very tipsy-top. 2594 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2595 mLruProcesses.add(app); 2596 } 2597 nextIndex = mLruProcessServiceStart; 2598 } else if (hasService) { 2599 // Process has services, put it at the top of the service list. 2600 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2601 mLruProcesses.add(mLruProcessActivityStart, app); 2602 nextIndex = mLruProcessServiceStart; 2603 mLruProcessActivityStart++; 2604 } else { 2605 // Process not otherwise of interest, it goes to the top of the non-service area. 2606 int index = mLruProcessServiceStart; 2607 if (client != null) { 2608 // If there is a client, don't allow the process to be moved up higher 2609 // in the list than that client. 2610 int clientIndex = mLruProcesses.lastIndexOf(client); 2611 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2612 + " when updating " + app); 2613 if (clientIndex <= lrui) { 2614 // Don't allow the client index restriction to push it down farther in the 2615 // list than it already is. 2616 clientIndex = lrui; 2617 } 2618 if (clientIndex >= 0 && index > clientIndex) { 2619 index = clientIndex; 2620 } 2621 } 2622 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2623 mLruProcesses.add(index, app); 2624 nextIndex = index-1; 2625 mLruProcessActivityStart++; 2626 mLruProcessServiceStart++; 2627 } 2628 2629 // If the app is currently using a content provider or service, 2630 // bump those processes as well. 2631 for (int j=app.connections.size()-1; j>=0; j--) { 2632 ConnectionRecord cr = app.connections.valueAt(j); 2633 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2634 && cr.binding.service.app != null 2635 && cr.binding.service.app.lruSeq != mLruSeq 2636 && !cr.binding.service.app.persistent) { 2637 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2638 "service connection", cr, app); 2639 } 2640 } 2641 for (int j=app.conProviders.size()-1; j>=0; j--) { 2642 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2643 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2644 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2645 "provider reference", cpr, app); 2646 } 2647 } 2648 } 2649 2650 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2651 if (uid == Process.SYSTEM_UID) { 2652 // The system gets to run in any process. If there are multiple 2653 // processes with the same uid, just pick the first (this 2654 // should never happen). 2655 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2656 if (procs == null) return null; 2657 final int N = procs.size(); 2658 for (int i = 0; i < N; i++) { 2659 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2660 } 2661 } 2662 ProcessRecord proc = mProcessNames.get(processName, uid); 2663 if (false && proc != null && !keepIfLarge 2664 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2665 && proc.lastCachedPss >= 4000) { 2666 // Turn this condition on to cause killing to happen regularly, for testing. 2667 if (proc.baseProcessTracker != null) { 2668 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2669 } 2670 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2671 } else if (proc != null && !keepIfLarge 2672 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2673 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2674 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2675 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2676 if (proc.baseProcessTracker != null) { 2677 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2678 } 2679 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2680 } 2681 } 2682 return proc; 2683 } 2684 2685 void ensurePackageDexOpt(String packageName) { 2686 IPackageManager pm = AppGlobals.getPackageManager(); 2687 try { 2688 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2689 mDidDexOpt = true; 2690 } 2691 } catch (RemoteException e) { 2692 } 2693 } 2694 2695 boolean isNextTransitionForward() { 2696 int transit = mWindowManager.getPendingAppTransition(); 2697 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2698 || transit == AppTransition.TRANSIT_TASK_OPEN 2699 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2700 } 2701 2702 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2703 String processName, String abiOverride, int uid, Runnable crashHandler) { 2704 synchronized(this) { 2705 ApplicationInfo info = new ApplicationInfo(); 2706 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2707 // For isolated processes, the former contains the parent's uid and the latter the 2708 // actual uid of the isolated process. 2709 // In the special case introduced by this method (which is, starting an isolated 2710 // process directly from the SystemServer without an actual parent app process) the 2711 // closest thing to a parent's uid is SYSTEM_UID. 2712 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2713 // the |isolated| logic in the ProcessRecord constructor. 2714 info.uid = Process.SYSTEM_UID; 2715 info.processName = processName; 2716 info.className = entryPoint; 2717 info.packageName = "android"; 2718 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2719 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2720 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2721 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2722 crashHandler); 2723 return proc != null ? proc.pid : 0; 2724 } 2725 } 2726 2727 final ProcessRecord startProcessLocked(String processName, 2728 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2729 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2730 boolean isolated, boolean keepIfLarge) { 2731 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2732 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2733 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2734 null /* crashHandler */); 2735 } 2736 2737 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2738 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2739 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2740 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2741 long startTime = SystemClock.elapsedRealtime(); 2742 ProcessRecord app; 2743 if (!isolated) { 2744 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2745 checkTime(startTime, "startProcess: after getProcessRecord"); 2746 } else { 2747 // If this is an isolated process, it can't re-use an existing process. 2748 app = null; 2749 } 2750 // We don't have to do anything more if: 2751 // (1) There is an existing application record; and 2752 // (2) The caller doesn't think it is dead, OR there is no thread 2753 // object attached to it so we know it couldn't have crashed; and 2754 // (3) There is a pid assigned to it, so it is either starting or 2755 // already running. 2756 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2757 + " app=" + app + " knownToBeDead=" + knownToBeDead 2758 + " thread=" + (app != null ? app.thread : null) 2759 + " pid=" + (app != null ? app.pid : -1)); 2760 if (app != null && app.pid > 0) { 2761 if (!knownToBeDead || app.thread == null) { 2762 // We already have the app running, or are waiting for it to 2763 // come up (we have a pid but not yet its thread), so keep it. 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2765 // If this is a new package in the process, add the package to the list 2766 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2767 checkTime(startTime, "startProcess: done, added package to proc"); 2768 return app; 2769 } 2770 2771 // An application record is attached to a previous process, 2772 // clean it up now. 2773 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2774 checkTime(startTime, "startProcess: bad proc running, killing"); 2775 Process.killProcessGroup(app.info.uid, app.pid); 2776 handleAppDiedLocked(app, true, true); 2777 checkTime(startTime, "startProcess: done killing old proc"); 2778 } 2779 2780 String hostingNameStr = hostingName != null 2781 ? hostingName.flattenToShortString() : null; 2782 2783 if (!isolated) { 2784 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2785 // If we are in the background, then check to see if this process 2786 // is bad. If so, we will just silently fail. 2787 if (mBadProcesses.get(info.processName, info.uid) != null) { 2788 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2789 + "/" + info.processName); 2790 return null; 2791 } 2792 } else { 2793 // When the user is explicitly starting a process, then clear its 2794 // crash count so that we won't make it bad until they see at 2795 // least one crash dialog again, and make the process good again 2796 // if it had been bad. 2797 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2798 + "/" + info.processName); 2799 mProcessCrashTimes.remove(info.processName, info.uid); 2800 if (mBadProcesses.get(info.processName, info.uid) != null) { 2801 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2802 UserHandle.getUserId(info.uid), info.uid, 2803 info.processName); 2804 mBadProcesses.remove(info.processName, info.uid); 2805 if (app != null) { 2806 app.bad = false; 2807 } 2808 } 2809 } 2810 } 2811 2812 if (app == null) { 2813 checkTime(startTime, "startProcess: creating new process record"); 2814 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2815 if (app == null) { 2816 Slog.w(TAG, "Failed making new process record for " 2817 + processName + "/" + info.uid + " isolated=" + isolated); 2818 return null; 2819 } 2820 app.crashHandler = crashHandler; 2821 mProcessNames.put(processName, app.uid, app); 2822 if (isolated) { 2823 mIsolatedProcesses.put(app.uid, app); 2824 } 2825 checkTime(startTime, "startProcess: done creating new process record"); 2826 } else { 2827 // If this is a new package in the process, add the package to the list 2828 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2829 checkTime(startTime, "startProcess: added package to existing proc"); 2830 } 2831 2832 // If the system is not ready yet, then hold off on starting this 2833 // process until it is. 2834 if (!mProcessesReady 2835 && !isAllowedWhileBooting(info) 2836 && !allowWhileBooting) { 2837 if (!mProcessesOnHold.contains(app)) { 2838 mProcessesOnHold.add(app); 2839 } 2840 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2841 checkTime(startTime, "startProcess: returning with proc on hold"); 2842 return app; 2843 } 2844 2845 checkTime(startTime, "startProcess: stepping in to startProcess"); 2846 startProcessLocked( 2847 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2848 checkTime(startTime, "startProcess: done starting proc!"); 2849 return (app.pid != 0) ? app : null; 2850 } 2851 2852 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2853 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2854 } 2855 2856 private final void startProcessLocked(ProcessRecord app, 2857 String hostingType, String hostingNameStr) { 2858 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2859 null /* entryPoint */, null /* entryPointArgs */); 2860 } 2861 2862 private final void startProcessLocked(ProcessRecord app, String hostingType, 2863 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2864 long startTime = SystemClock.elapsedRealtime(); 2865 if (app.pid > 0 && app.pid != MY_PID) { 2866 checkTime(startTime, "startProcess: removing from pids map"); 2867 synchronized (mPidsSelfLocked) { 2868 mPidsSelfLocked.remove(app.pid); 2869 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2870 } 2871 checkTime(startTime, "startProcess: done removing from pids map"); 2872 app.setPid(0); 2873 } 2874 2875 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2876 "startProcessLocked removing on hold: " + app); 2877 mProcessesOnHold.remove(app); 2878 2879 checkTime(startTime, "startProcess: starting to update cpu stats"); 2880 updateCpuStats(); 2881 checkTime(startTime, "startProcess: done updating cpu stats"); 2882 2883 try { 2884 int uid = app.uid; 2885 2886 int[] gids = null; 2887 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2888 if (!app.isolated) { 2889 int[] permGids = null; 2890 try { 2891 checkTime(startTime, "startProcess: getting gids from package manager"); 2892 final PackageManager pm = mContext.getPackageManager(); 2893 permGids = pm.getPackageGids(app.info.packageName); 2894 2895 if (Environment.isExternalStorageEmulated()) { 2896 checkTime(startTime, "startProcess: checking external storage perm"); 2897 if (pm.checkPermission( 2898 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2899 app.info.packageName) == PERMISSION_GRANTED) { 2900 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2901 } else { 2902 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2903 } 2904 } 2905 } catch (PackageManager.NameNotFoundException e) { 2906 Slog.w(TAG, "Unable to retrieve gids", e); 2907 } 2908 2909 /* 2910 * Add shared application and profile GIDs so applications can share some 2911 * resources like shared libraries and access user-wide resources 2912 */ 2913 if (permGids == null) { 2914 gids = new int[2]; 2915 } else { 2916 gids = new int[permGids.length + 2]; 2917 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2918 } 2919 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2920 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2921 } 2922 checkTime(startTime, "startProcess: building args"); 2923 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2924 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2925 && mTopComponent != null 2926 && app.processName.equals(mTopComponent.getPackageName())) { 2927 uid = 0; 2928 } 2929 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2930 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2931 uid = 0; 2932 } 2933 } 2934 int debugFlags = 0; 2935 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2936 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2937 // Also turn on CheckJNI for debuggable apps. It's quite 2938 // awkward to turn on otherwise. 2939 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2940 } 2941 // Run the app in safe mode if its manifest requests so or the 2942 // system is booted in safe mode. 2943 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2944 mSafeMode == true) { 2945 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2946 } 2947 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2948 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2949 } 2950 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2951 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2952 } 2953 if ("1".equals(SystemProperties.get("debug.assert"))) { 2954 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2955 } 2956 2957 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2958 if (requiredAbi == null) { 2959 requiredAbi = Build.SUPPORTED_ABIS[0]; 2960 } 2961 2962 String instructionSet = null; 2963 if (app.info.primaryCpuAbi != null) { 2964 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2965 } 2966 2967 // Start the process. It will either succeed and return a result containing 2968 // the PID of the new process, or else throw a RuntimeException. 2969 boolean isActivityProcess = (entryPoint == null); 2970 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2971 checkTime(startTime, "startProcess: asking zygote to start proc"); 2972 Process.ProcessStartResult startResult = Process.start(entryPoint, 2973 app.processName, uid, uid, gids, debugFlags, mountExternal, 2974 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2975 app.info.dataDir, entryPointArgs); 2976 checkTime(startTime, "startProcess: returned from zygote!"); 2977 2978 if (app.isolated) { 2979 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2980 } 2981 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2982 checkTime(startTime, "startProcess: done updating battery stats"); 2983 2984 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2985 UserHandle.getUserId(uid), startResult.pid, uid, 2986 app.processName, hostingType, 2987 hostingNameStr != null ? hostingNameStr : ""); 2988 2989 if (app.persistent) { 2990 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2991 } 2992 2993 checkTime(startTime, "startProcess: building log message"); 2994 StringBuilder buf = mStringBuilder; 2995 buf.setLength(0); 2996 buf.append("Start proc "); 2997 buf.append(app.processName); 2998 if (!isActivityProcess) { 2999 buf.append(" ["); 3000 buf.append(entryPoint); 3001 buf.append("]"); 3002 } 3003 buf.append(" for "); 3004 buf.append(hostingType); 3005 if (hostingNameStr != null) { 3006 buf.append(" "); 3007 buf.append(hostingNameStr); 3008 } 3009 buf.append(": pid="); 3010 buf.append(startResult.pid); 3011 buf.append(" uid="); 3012 buf.append(uid); 3013 buf.append(" gids={"); 3014 if (gids != null) { 3015 for (int gi=0; gi<gids.length; gi++) { 3016 if (gi != 0) buf.append(", "); 3017 buf.append(gids[gi]); 3018 3019 } 3020 } 3021 buf.append("}"); 3022 if (requiredAbi != null) { 3023 buf.append(" abi="); 3024 buf.append(requiredAbi); 3025 } 3026 Slog.i(TAG, buf.toString()); 3027 app.setPid(startResult.pid); 3028 app.usingWrapper = startResult.usingWrapper; 3029 app.removed = false; 3030 app.killed = false; 3031 app.killedByAm = false; 3032 checkTime(startTime, "startProcess: starting to update pids map"); 3033 synchronized (mPidsSelfLocked) { 3034 this.mPidsSelfLocked.put(startResult.pid, app); 3035 if (isActivityProcess) { 3036 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3037 msg.obj = app; 3038 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3039 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3040 } 3041 } 3042 checkTime(startTime, "startProcess: done updating pids map"); 3043 } catch (RuntimeException e) { 3044 // XXX do better error recovery. 3045 app.setPid(0); 3046 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3047 if (app.isolated) { 3048 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3049 } 3050 Slog.e(TAG, "Failure starting process " + app.processName, e); 3051 } 3052 } 3053 3054 void updateUsageStats(ActivityRecord component, boolean resumed) { 3055 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3056 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3057 if (resumed) { 3058 if (mUsageStatsService != null) { 3059 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3060 UsageEvents.Event.MOVE_TO_FOREGROUND); 3061 } 3062 synchronized (stats) { 3063 stats.noteActivityResumedLocked(component.app.uid); 3064 } 3065 } else { 3066 if (mUsageStatsService != null) { 3067 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3068 UsageEvents.Event.MOVE_TO_BACKGROUND); 3069 } 3070 synchronized (stats) { 3071 stats.noteActivityPausedLocked(component.app.uid); 3072 } 3073 } 3074 } 3075 3076 Intent getHomeIntent() { 3077 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3078 intent.setComponent(mTopComponent); 3079 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3080 intent.addCategory(Intent.CATEGORY_HOME); 3081 } 3082 return intent; 3083 } 3084 3085 boolean startHomeActivityLocked(int userId) { 3086 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3087 && mTopAction == null) { 3088 // We are running in factory test mode, but unable to find 3089 // the factory test app, so just sit around displaying the 3090 // error message and don't try to start anything. 3091 return false; 3092 } 3093 Intent intent = getHomeIntent(); 3094 ActivityInfo aInfo = 3095 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3096 if (aInfo != null) { 3097 intent.setComponent(new ComponentName( 3098 aInfo.applicationInfo.packageName, aInfo.name)); 3099 // Don't do this if the home app is currently being 3100 // instrumented. 3101 aInfo = new ActivityInfo(aInfo); 3102 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3103 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3104 aInfo.applicationInfo.uid, true); 3105 if (app == null || app.instrumentationClass == null) { 3106 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3107 mStackSupervisor.startHomeActivity(intent, aInfo); 3108 } 3109 } 3110 3111 return true; 3112 } 3113 3114 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3115 ActivityInfo ai = null; 3116 ComponentName comp = intent.getComponent(); 3117 try { 3118 if (comp != null) { 3119 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3120 } else { 3121 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3122 intent, 3123 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3124 flags, userId); 3125 3126 if (info != null) { 3127 ai = info.activityInfo; 3128 } 3129 } 3130 } catch (RemoteException e) { 3131 // ignore 3132 } 3133 3134 return ai; 3135 } 3136 3137 /** 3138 * Starts the "new version setup screen" if appropriate. 3139 */ 3140 void startSetupActivityLocked() { 3141 // Only do this once per boot. 3142 if (mCheckedForSetup) { 3143 return; 3144 } 3145 3146 // We will show this screen if the current one is a different 3147 // version than the last one shown, and we are not running in 3148 // low-level factory test mode. 3149 final ContentResolver resolver = mContext.getContentResolver(); 3150 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3151 Settings.Global.getInt(resolver, 3152 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3153 mCheckedForSetup = true; 3154 3155 // See if we should be showing the platform update setup UI. 3156 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3157 List<ResolveInfo> ris = mContext.getPackageManager() 3158 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3159 3160 // We don't allow third party apps to replace this. 3161 ResolveInfo ri = null; 3162 for (int i=0; ris != null && i<ris.size(); i++) { 3163 if ((ris.get(i).activityInfo.applicationInfo.flags 3164 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3165 ri = ris.get(i); 3166 break; 3167 } 3168 } 3169 3170 if (ri != null) { 3171 String vers = ri.activityInfo.metaData != null 3172 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3173 : null; 3174 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3175 vers = ri.activityInfo.applicationInfo.metaData.getString( 3176 Intent.METADATA_SETUP_VERSION); 3177 } 3178 String lastVers = Settings.Secure.getString( 3179 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3180 if (vers != null && !vers.equals(lastVers)) { 3181 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3182 intent.setComponent(new ComponentName( 3183 ri.activityInfo.packageName, ri.activityInfo.name)); 3184 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3185 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3186 null); 3187 } 3188 } 3189 } 3190 } 3191 3192 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3193 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3194 } 3195 3196 void enforceNotIsolatedCaller(String caller) { 3197 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3198 throw new SecurityException("Isolated process not allowed to call " + caller); 3199 } 3200 } 3201 3202 void enforceShellRestriction(String restriction, int userHandle) { 3203 if (Binder.getCallingUid() == Process.SHELL_UID) { 3204 if (userHandle < 0 3205 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3206 throw new SecurityException("Shell does not have permission to access user " 3207 + userHandle); 3208 } 3209 } 3210 } 3211 3212 @Override 3213 public int getFrontActivityScreenCompatMode() { 3214 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3215 synchronized (this) { 3216 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3217 } 3218 } 3219 3220 @Override 3221 public void setFrontActivityScreenCompatMode(int mode) { 3222 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3223 "setFrontActivityScreenCompatMode"); 3224 synchronized (this) { 3225 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3226 } 3227 } 3228 3229 @Override 3230 public int getPackageScreenCompatMode(String packageName) { 3231 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3232 synchronized (this) { 3233 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3234 } 3235 } 3236 3237 @Override 3238 public void setPackageScreenCompatMode(String packageName, int mode) { 3239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3240 "setPackageScreenCompatMode"); 3241 synchronized (this) { 3242 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3243 } 3244 } 3245 3246 @Override 3247 public boolean getPackageAskScreenCompat(String packageName) { 3248 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3249 synchronized (this) { 3250 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3251 } 3252 } 3253 3254 @Override 3255 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setPackageAskScreenCompat"); 3258 synchronized (this) { 3259 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3260 } 3261 } 3262 3263 private void dispatchProcessesChanged() { 3264 int N; 3265 synchronized (this) { 3266 N = mPendingProcessChanges.size(); 3267 if (mActiveProcessChanges.length < N) { 3268 mActiveProcessChanges = new ProcessChangeItem[N]; 3269 } 3270 mPendingProcessChanges.toArray(mActiveProcessChanges); 3271 mAvailProcessChanges.addAll(mPendingProcessChanges); 3272 mPendingProcessChanges.clear(); 3273 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3274 } 3275 3276 int i = mProcessObservers.beginBroadcast(); 3277 while (i > 0) { 3278 i--; 3279 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3280 if (observer != null) { 3281 try { 3282 for (int j=0; j<N; j++) { 3283 ProcessChangeItem item = mActiveProcessChanges[j]; 3284 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3286 + item.pid + " uid=" + item.uid + ": " 3287 + item.foregroundActivities); 3288 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3289 item.foregroundActivities); 3290 } 3291 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3292 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3293 + item.pid + " uid=" + item.uid + ": " + item.processState); 3294 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3295 } 3296 } 3297 } catch (RemoteException e) { 3298 } 3299 } 3300 } 3301 mProcessObservers.finishBroadcast(); 3302 } 3303 3304 private void dispatchProcessDied(int pid, int uid) { 3305 int i = mProcessObservers.beginBroadcast(); 3306 while (i > 0) { 3307 i--; 3308 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3309 if (observer != null) { 3310 try { 3311 observer.onProcessDied(pid, uid); 3312 } catch (RemoteException e) { 3313 } 3314 } 3315 } 3316 mProcessObservers.finishBroadcast(); 3317 } 3318 3319 @Override 3320 public final int startActivity(IApplicationThread caller, String callingPackage, 3321 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3322 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3323 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3324 resultWho, requestCode, startFlags, profilerInfo, options, 3325 UserHandle.getCallingUserId()); 3326 } 3327 3328 @Override 3329 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3330 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3331 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3332 enforceNotIsolatedCaller("startActivity"); 3333 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3334 false, ALLOW_FULL_ONLY, "startActivity", null); 3335 // TODO: Switch to user app stacks here. 3336 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3337 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3338 profilerInfo, null, null, options, userId, null, null); 3339 } 3340 3341 @Override 3342 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3343 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3344 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3345 3346 // This is very dangerous -- it allows you to perform a start activity (including 3347 // permission grants) as any app that may launch one of your own activities. So 3348 // we will only allow this to be done from activities that are part of the core framework, 3349 // and then only when they are running as the system. 3350 final ActivityRecord sourceRecord; 3351 final int targetUid; 3352 final String targetPackage; 3353 synchronized (this) { 3354 if (resultTo == null) { 3355 throw new SecurityException("Must be called from an activity"); 3356 } 3357 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3358 if (sourceRecord == null) { 3359 throw new SecurityException("Called with bad activity token: " + resultTo); 3360 } 3361 if (!sourceRecord.info.packageName.equals("android")) { 3362 throw new SecurityException( 3363 "Must be called from an activity that is declared in the android package"); 3364 } 3365 if (sourceRecord.app == null) { 3366 throw new SecurityException("Called without a process attached to activity"); 3367 } 3368 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3369 // This is still okay, as long as this activity is running under the 3370 // uid of the original calling activity. 3371 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3372 throw new SecurityException( 3373 "Calling activity in uid " + sourceRecord.app.uid 3374 + " must be system uid or original calling uid " 3375 + sourceRecord.launchedFromUid); 3376 } 3377 } 3378 targetUid = sourceRecord.launchedFromUid; 3379 targetPackage = sourceRecord.launchedFromPackage; 3380 } 3381 3382 if (userId == UserHandle.USER_NULL) { 3383 userId = UserHandle.getUserId(sourceRecord.app.uid); 3384 } 3385 3386 // TODO: Switch to user app stacks here. 3387 try { 3388 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3389 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3390 null, null, options, userId, null, null); 3391 return ret; 3392 } catch (SecurityException e) { 3393 // XXX need to figure out how to propagate to original app. 3394 // A SecurityException here is generally actually a fault of the original 3395 // calling activity (such as a fairly granting permissions), so propagate it 3396 // back to them. 3397 /* 3398 StringBuilder msg = new StringBuilder(); 3399 msg.append("While launching"); 3400 msg.append(intent.toString()); 3401 msg.append(": "); 3402 msg.append(e.getMessage()); 3403 */ 3404 throw e; 3405 } 3406 } 3407 3408 @Override 3409 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3410 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3411 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3412 enforceNotIsolatedCaller("startActivityAndWait"); 3413 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3414 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3415 WaitResult res = new WaitResult(); 3416 // TODO: Switch to user app stacks here. 3417 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3418 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3419 options, userId, null, null); 3420 return res; 3421 } 3422 3423 @Override 3424 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3425 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3426 int startFlags, Configuration config, Bundle options, int userId) { 3427 enforceNotIsolatedCaller("startActivityWithConfig"); 3428 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3429 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3430 // TODO: Switch to user app stacks here. 3431 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3432 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3433 null, null, config, options, userId, null, null); 3434 return ret; 3435 } 3436 3437 @Override 3438 public int startActivityIntentSender(IApplicationThread caller, 3439 IntentSender intent, Intent fillInIntent, String resolvedType, 3440 IBinder resultTo, String resultWho, int requestCode, 3441 int flagsMask, int flagsValues, Bundle options) { 3442 enforceNotIsolatedCaller("startActivityIntentSender"); 3443 // Refuse possible leaked file descriptors 3444 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3445 throw new IllegalArgumentException("File descriptors passed in Intent"); 3446 } 3447 3448 IIntentSender sender = intent.getTarget(); 3449 if (!(sender instanceof PendingIntentRecord)) { 3450 throw new IllegalArgumentException("Bad PendingIntent object"); 3451 } 3452 3453 PendingIntentRecord pir = (PendingIntentRecord)sender; 3454 3455 synchronized (this) { 3456 // If this is coming from the currently resumed activity, it is 3457 // effectively saying that app switches are allowed at this point. 3458 final ActivityStack stack = getFocusedStack(); 3459 if (stack.mResumedActivity != null && 3460 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3461 mAppSwitchesAllowedTime = 0; 3462 } 3463 } 3464 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3465 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3466 return ret; 3467 } 3468 3469 @Override 3470 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3471 Intent intent, String resolvedType, IVoiceInteractionSession session, 3472 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3473 Bundle options, int userId) { 3474 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3475 != PackageManager.PERMISSION_GRANTED) { 3476 String msg = "Permission Denial: startVoiceActivity() from pid=" 3477 + Binder.getCallingPid() 3478 + ", uid=" + Binder.getCallingUid() 3479 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3480 Slog.w(TAG, msg); 3481 throw new SecurityException(msg); 3482 } 3483 if (session == null || interactor == null) { 3484 throw new NullPointerException("null session or interactor"); 3485 } 3486 userId = handleIncomingUser(callingPid, callingUid, userId, 3487 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3488 // TODO: Switch to user app stacks here. 3489 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3490 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3491 null, options, userId, null, null); 3492 } 3493 3494 @Override 3495 public boolean startNextMatchingActivity(IBinder callingActivity, 3496 Intent intent, Bundle options) { 3497 // Refuse possible leaked file descriptors 3498 if (intent != null && intent.hasFileDescriptors() == true) { 3499 throw new IllegalArgumentException("File descriptors passed in Intent"); 3500 } 3501 3502 synchronized (this) { 3503 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3504 if (r == null) { 3505 ActivityOptions.abort(options); 3506 return false; 3507 } 3508 if (r.app == null || r.app.thread == null) { 3509 // The caller is not running... d'oh! 3510 ActivityOptions.abort(options); 3511 return false; 3512 } 3513 intent = new Intent(intent); 3514 // The caller is not allowed to change the data. 3515 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3516 // And we are resetting to find the next component... 3517 intent.setComponent(null); 3518 3519 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3520 3521 ActivityInfo aInfo = null; 3522 try { 3523 List<ResolveInfo> resolves = 3524 AppGlobals.getPackageManager().queryIntentActivities( 3525 intent, r.resolvedType, 3526 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3527 UserHandle.getCallingUserId()); 3528 3529 // Look for the original activity in the list... 3530 final int N = resolves != null ? resolves.size() : 0; 3531 for (int i=0; i<N; i++) { 3532 ResolveInfo rInfo = resolves.get(i); 3533 if (rInfo.activityInfo.packageName.equals(r.packageName) 3534 && rInfo.activityInfo.name.equals(r.info.name)) { 3535 // We found the current one... the next matching is 3536 // after it. 3537 i++; 3538 if (i<N) { 3539 aInfo = resolves.get(i).activityInfo; 3540 } 3541 if (debug) { 3542 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3543 + "/" + r.info.name); 3544 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3545 + "/" + aInfo.name); 3546 } 3547 break; 3548 } 3549 } 3550 } catch (RemoteException e) { 3551 } 3552 3553 if (aInfo == null) { 3554 // Nobody who is next! 3555 ActivityOptions.abort(options); 3556 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3557 return false; 3558 } 3559 3560 intent.setComponent(new ComponentName( 3561 aInfo.applicationInfo.packageName, aInfo.name)); 3562 intent.setFlags(intent.getFlags()&~( 3563 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3564 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3565 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3566 Intent.FLAG_ACTIVITY_NEW_TASK)); 3567 3568 // Okay now we need to start the new activity, replacing the 3569 // currently running activity. This is a little tricky because 3570 // we want to start the new one as if the current one is finished, 3571 // but not finish the current one first so that there is no flicker. 3572 // And thus... 3573 final boolean wasFinishing = r.finishing; 3574 r.finishing = true; 3575 3576 // Propagate reply information over to the new activity. 3577 final ActivityRecord resultTo = r.resultTo; 3578 final String resultWho = r.resultWho; 3579 final int requestCode = r.requestCode; 3580 r.resultTo = null; 3581 if (resultTo != null) { 3582 resultTo.removeResultsLocked(r, resultWho, requestCode); 3583 } 3584 3585 final long origId = Binder.clearCallingIdentity(); 3586 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3587 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3588 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3589 -1, r.launchedFromUid, 0, options, false, null, null, null); 3590 Binder.restoreCallingIdentity(origId); 3591 3592 r.finishing = wasFinishing; 3593 if (res != ActivityManager.START_SUCCESS) { 3594 return false; 3595 } 3596 return true; 3597 } 3598 } 3599 3600 @Override 3601 public final int startActivityFromRecents(int taskId, Bundle options) { 3602 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3603 String msg = "Permission Denial: startActivityFromRecents called without " + 3604 START_TASKS_FROM_RECENTS; 3605 Slog.w(TAG, msg); 3606 throw new SecurityException(msg); 3607 } 3608 return startActivityFromRecentsInner(taskId, options); 3609 } 3610 3611 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3612 final TaskRecord task; 3613 final int callingUid; 3614 final String callingPackage; 3615 final Intent intent; 3616 final int userId; 3617 synchronized (this) { 3618 task = recentTaskForIdLocked(taskId); 3619 if (task == null) { 3620 throw new IllegalArgumentException("Task " + taskId + " not found."); 3621 } 3622 callingUid = task.mCallingUid; 3623 callingPackage = task.mCallingPackage; 3624 intent = task.intent; 3625 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3626 userId = task.userId; 3627 } 3628 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3629 options, userId, null, task); 3630 } 3631 3632 final int startActivityInPackage(int uid, String callingPackage, 3633 Intent intent, String resolvedType, IBinder resultTo, 3634 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3635 IActivityContainer container, TaskRecord inTask) { 3636 3637 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3638 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3639 3640 // TODO: Switch to user app stacks here. 3641 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3642 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3643 null, null, null, options, userId, container, inTask); 3644 return ret; 3645 } 3646 3647 @Override 3648 public final int startActivities(IApplicationThread caller, String callingPackage, 3649 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3650 int userId) { 3651 enforceNotIsolatedCaller("startActivities"); 3652 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3653 false, ALLOW_FULL_ONLY, "startActivity", null); 3654 // TODO: Switch to user app stacks here. 3655 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3656 resolvedTypes, resultTo, options, userId); 3657 return ret; 3658 } 3659 3660 final int startActivitiesInPackage(int uid, String callingPackage, 3661 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3662 Bundle options, int userId) { 3663 3664 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3665 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3666 // TODO: Switch to user app stacks here. 3667 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3668 resultTo, options, userId); 3669 return ret; 3670 } 3671 3672 //explicitly remove thd old information in mRecentTasks when removing existing user. 3673 private void removeRecentTasksForUserLocked(int userId) { 3674 if(userId <= 0) { 3675 Slog.i(TAG, "Can't remove recent task on user " + userId); 3676 return; 3677 } 3678 3679 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3680 TaskRecord tr = mRecentTasks.get(i); 3681 if (tr.userId == userId) { 3682 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3683 + " when finishing user" + userId); 3684 mRecentTasks.remove(i); 3685 tr.removedFromRecents(); 3686 } 3687 } 3688 3689 // Remove tasks from persistent storage. 3690 notifyTaskPersisterLocked(null, true); 3691 } 3692 3693 // Sort by taskId 3694 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3695 @Override 3696 public int compare(TaskRecord lhs, TaskRecord rhs) { 3697 return rhs.taskId - lhs.taskId; 3698 } 3699 }; 3700 3701 // Extract the affiliates of the chain containing mRecentTasks[start]. 3702 private int processNextAffiliateChainLocked(int start) { 3703 final TaskRecord startTask = mRecentTasks.get(start); 3704 final int affiliateId = startTask.mAffiliatedTaskId; 3705 3706 // Quick identification of isolated tasks. I.e. those not launched behind. 3707 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3708 startTask.mNextAffiliate == null) { 3709 // There is still a slim chance that there are other tasks that point to this task 3710 // and that the chain is so messed up that this task no longer points to them but 3711 // the gain of this optimization outweighs the risk. 3712 startTask.inRecents = true; 3713 return start + 1; 3714 } 3715 3716 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3717 mTmpRecents.clear(); 3718 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3719 final TaskRecord task = mRecentTasks.get(i); 3720 if (task.mAffiliatedTaskId == affiliateId) { 3721 mRecentTasks.remove(i); 3722 mTmpRecents.add(task); 3723 } 3724 } 3725 3726 // Sort them all by taskId. That is the order they were create in and that order will 3727 // always be correct. 3728 Collections.sort(mTmpRecents, mTaskRecordComparator); 3729 3730 // Go through and fix up the linked list. 3731 // The first one is the end of the chain and has no next. 3732 final TaskRecord first = mTmpRecents.get(0); 3733 first.inRecents = true; 3734 if (first.mNextAffiliate != null) { 3735 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3736 first.setNextAffiliate(null); 3737 notifyTaskPersisterLocked(first, false); 3738 } 3739 // Everything in the middle is doubly linked from next to prev. 3740 final int tmpSize = mTmpRecents.size(); 3741 for (int i = 0; i < tmpSize - 1; ++i) { 3742 final TaskRecord next = mTmpRecents.get(i); 3743 final TaskRecord prev = mTmpRecents.get(i + 1); 3744 if (next.mPrevAffiliate != prev) { 3745 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3746 " setting prev=" + prev); 3747 next.setPrevAffiliate(prev); 3748 notifyTaskPersisterLocked(next, false); 3749 } 3750 if (prev.mNextAffiliate != next) { 3751 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3752 " setting next=" + next); 3753 prev.setNextAffiliate(next); 3754 notifyTaskPersisterLocked(prev, false); 3755 } 3756 prev.inRecents = true; 3757 } 3758 // The last one is the beginning of the list and has no prev. 3759 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3760 if (last.mPrevAffiliate != null) { 3761 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3762 last.setPrevAffiliate(null); 3763 notifyTaskPersisterLocked(last, false); 3764 } 3765 3766 // Insert the group back into mRecentTasks at start. 3767 mRecentTasks.addAll(start, mTmpRecents); 3768 3769 // Let the caller know where we left off. 3770 return start + tmpSize; 3771 } 3772 3773 /** 3774 * Update the recent tasks lists: make sure tasks should still be here (their 3775 * applications / activities still exist), update their availability, fixup ordering 3776 * of affiliations. 3777 */ 3778 void cleanupRecentTasksLocked(int userId) { 3779 if (mRecentTasks == null) { 3780 // Happens when called from the packagemanager broadcast before boot. 3781 return; 3782 } 3783 3784 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3785 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3786 final IPackageManager pm = AppGlobals.getPackageManager(); 3787 final ActivityInfo dummyAct = new ActivityInfo(); 3788 final ApplicationInfo dummyApp = new ApplicationInfo(); 3789 3790 int N = mRecentTasks.size(); 3791 3792 int[] users = userId == UserHandle.USER_ALL 3793 ? getUsersLocked() : new int[] { userId }; 3794 for (int user : users) { 3795 for (int i = 0; i < N; i++) { 3796 TaskRecord task = mRecentTasks.get(i); 3797 if (task.userId != user) { 3798 // Only look at tasks for the user ID of interest. 3799 continue; 3800 } 3801 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3802 // This situation is broken, and we should just get rid of it now. 3803 mRecentTasks.remove(i); 3804 task.removedFromRecents(); 3805 i--; 3806 N--; 3807 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3808 continue; 3809 } 3810 // Check whether this activity is currently available. 3811 if (task.realActivity != null) { 3812 ActivityInfo ai = availActCache.get(task.realActivity); 3813 if (ai == null) { 3814 try { 3815 ai = pm.getActivityInfo(task.realActivity, 3816 PackageManager.GET_UNINSTALLED_PACKAGES 3817 | PackageManager.GET_DISABLED_COMPONENTS, user); 3818 } catch (RemoteException e) { 3819 // Will never happen. 3820 continue; 3821 } 3822 if (ai == null) { 3823 ai = dummyAct; 3824 } 3825 availActCache.put(task.realActivity, ai); 3826 } 3827 if (ai == dummyAct) { 3828 // This could be either because the activity no longer exists, or the 3829 // app is temporarily gone. For the former we want to remove the recents 3830 // entry; for the latter we want to mark it as unavailable. 3831 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3832 if (app == null) { 3833 try { 3834 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3835 PackageManager.GET_UNINSTALLED_PACKAGES 3836 | PackageManager.GET_DISABLED_COMPONENTS, user); 3837 } catch (RemoteException e) { 3838 // Will never happen. 3839 continue; 3840 } 3841 if (app == null) { 3842 app = dummyApp; 3843 } 3844 availAppCache.put(task.realActivity.getPackageName(), app); 3845 } 3846 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3847 // Doesn't exist any more! Good-bye. 3848 mRecentTasks.remove(i); 3849 task.removedFromRecents(); 3850 i--; 3851 N--; 3852 Slog.w(TAG, "Removing no longer valid recent: " + task); 3853 continue; 3854 } else { 3855 // Otherwise just not available for now. 3856 if (task.isAvailable) { 3857 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3858 + task); 3859 } 3860 task.isAvailable = false; 3861 } 3862 } else { 3863 if (!ai.enabled || !ai.applicationInfo.enabled 3864 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3865 if (task.isAvailable) { 3866 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3867 + task + " (enabled=" + ai.enabled + "/" 3868 + ai.applicationInfo.enabled + " flags=" 3869 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3870 } 3871 task.isAvailable = false; 3872 } else { 3873 if (!task.isAvailable) { 3874 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3875 + task); 3876 } 3877 task.isAvailable = true; 3878 } 3879 } 3880 } 3881 } 3882 } 3883 3884 // Verify the affiliate chain for each task. 3885 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3886 } 3887 3888 mTmpRecents.clear(); 3889 // mRecentTasks is now in sorted, affiliated order. 3890 } 3891 3892 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3893 int N = mRecentTasks.size(); 3894 TaskRecord top = task; 3895 int topIndex = taskIndex; 3896 while (top.mNextAffiliate != null && topIndex > 0) { 3897 top = top.mNextAffiliate; 3898 topIndex--; 3899 } 3900 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3901 + topIndex + " from intial " + taskIndex); 3902 // Find the end of the chain, doing a sanity check along the way. 3903 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3904 int endIndex = topIndex; 3905 TaskRecord prev = top; 3906 while (endIndex < N) { 3907 TaskRecord cur = mRecentTasks.get(endIndex); 3908 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3909 + endIndex + " " + cur); 3910 if (cur == top) { 3911 // Verify start of the chain. 3912 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3913 Slog.wtf(TAG, "Bad chain @" + endIndex 3914 + ": first task has next affiliate: " + prev); 3915 sane = false; 3916 break; 3917 } 3918 } else { 3919 // Verify middle of the chain's next points back to the one before. 3920 if (cur.mNextAffiliate != prev 3921 || cur.mNextAffiliateTaskId != prev.taskId) { 3922 Slog.wtf(TAG, "Bad chain @" + endIndex 3923 + ": middle task " + cur + " @" + endIndex 3924 + " has bad next affiliate " 3925 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3926 + ", expected " + prev); 3927 sane = false; 3928 break; 3929 } 3930 } 3931 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3932 // Chain ends here. 3933 if (cur.mPrevAffiliate != null) { 3934 Slog.wtf(TAG, "Bad chain @" + endIndex 3935 + ": last task " + cur + " has previous affiliate " 3936 + cur.mPrevAffiliate); 3937 sane = false; 3938 } 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3940 break; 3941 } else { 3942 // Verify middle of the chain's prev points to a valid item. 3943 if (cur.mPrevAffiliate == null) { 3944 Slog.wtf(TAG, "Bad chain @" + endIndex 3945 + ": task " + cur + " has previous affiliate " 3946 + cur.mPrevAffiliate + " but should be id " 3947 + cur.mPrevAffiliate); 3948 sane = false; 3949 break; 3950 } 3951 } 3952 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3953 Slog.wtf(TAG, "Bad chain @" + endIndex 3954 + ": task " + cur + " has affiliated id " 3955 + cur.mAffiliatedTaskId + " but should be " 3956 + task.mAffiliatedTaskId); 3957 sane = false; 3958 break; 3959 } 3960 prev = cur; 3961 endIndex++; 3962 if (endIndex >= N) { 3963 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3964 + ": last task " + prev); 3965 sane = false; 3966 break; 3967 } 3968 } 3969 if (sane) { 3970 if (endIndex < taskIndex) { 3971 Slog.wtf(TAG, "Bad chain @" + endIndex 3972 + ": did not extend to task " + task + " @" + taskIndex); 3973 sane = false; 3974 } 3975 } 3976 if (sane) { 3977 // All looks good, we can just move all of the affiliated tasks 3978 // to the top. 3979 for (int i=topIndex; i<=endIndex; i++) { 3980 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3981 + " from " + i + " to " + (i-topIndex)); 3982 TaskRecord cur = mRecentTasks.remove(i); 3983 mRecentTasks.add(i-topIndex, cur); 3984 } 3985 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3986 + " to " + endIndex); 3987 return true; 3988 } 3989 3990 // Whoops, couldn't do it. 3991 return false; 3992 } 3993 3994 final void addRecentTaskLocked(TaskRecord task) { 3995 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3996 || task.mNextAffiliateTaskId != INVALID_TASK_ID 3997 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 3998 3999 int N = mRecentTasks.size(); 4000 // Quick case: check if the top-most recent task is the same. 4001 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4002 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4003 return; 4004 } 4005 // Another quick case: check if this is part of a set of affiliated 4006 // tasks that are at the top. 4007 if (isAffiliated && N > 0 && task.inRecents 4008 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4009 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4010 + " at top when adding " + task); 4011 return; 4012 } 4013 // Another quick case: never add voice sessions. 4014 if (task.voiceSession != null) { 4015 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4016 return; 4017 } 4018 4019 boolean needAffiliationFix = false; 4020 4021 // Slightly less quick case: the task is already in recents, so all we need 4022 // to do is move it. 4023 if (task.inRecents) { 4024 int taskIndex = mRecentTasks.indexOf(task); 4025 if (taskIndex >= 0) { 4026 if (!isAffiliated) { 4027 // Simple case: this is not an affiliated task, so we just move it to the front. 4028 mRecentTasks.remove(taskIndex); 4029 mRecentTasks.add(0, task); 4030 notifyTaskPersisterLocked(task, false); 4031 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4032 + " from " + taskIndex); 4033 return; 4034 } else { 4035 // More complicated: need to keep all affiliated tasks together. 4036 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4037 // All went well. 4038 return; 4039 } 4040 4041 // Uh oh... something bad in the affiliation chain, try to rebuild 4042 // everything and then go through our general path of adding a new task. 4043 needAffiliationFix = true; 4044 } 4045 } else { 4046 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4047 needAffiliationFix = true; 4048 } 4049 } 4050 4051 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4052 trimRecentsForTaskLocked(task, true); 4053 4054 N = mRecentTasks.size(); 4055 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4056 final TaskRecord tr = mRecentTasks.remove(N - 1); 4057 tr.removedFromRecents(); 4058 N--; 4059 } 4060 task.inRecents = true; 4061 if (!isAffiliated || needAffiliationFix) { 4062 // If this is a simple non-affiliated task, or we had some failure trying to 4063 // handle it as part of an affilated task, then just place it at the top. 4064 mRecentTasks.add(0, task); 4065 } else if (isAffiliated) { 4066 // If this is a new affiliated task, then move all of the affiliated tasks 4067 // to the front and insert this new one. 4068 TaskRecord other = task.mNextAffiliate; 4069 if (other == null) { 4070 other = task.mPrevAffiliate; 4071 } 4072 if (other != null) { 4073 int otherIndex = mRecentTasks.indexOf(other); 4074 if (otherIndex >= 0) { 4075 // Insert new task at appropriate location. 4076 int taskIndex; 4077 if (other == task.mNextAffiliate) { 4078 // We found the index of our next affiliation, which is who is 4079 // before us in the list, so add after that point. 4080 taskIndex = otherIndex+1; 4081 } else { 4082 // We found the index of our previous affiliation, which is who is 4083 // after us in the list, so add at their position. 4084 taskIndex = otherIndex; 4085 } 4086 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4087 + taskIndex + ": " + task); 4088 mRecentTasks.add(taskIndex, task); 4089 4090 // Now move everything to the front. 4091 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4092 // All went well. 4093 return; 4094 } 4095 4096 // Uh oh... something bad in the affiliation chain, try to rebuild 4097 // everything and then go through our general path of adding a new task. 4098 needAffiliationFix = true; 4099 } else { 4100 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4101 + other); 4102 needAffiliationFix = true; 4103 } 4104 } else { 4105 if (DEBUG_RECENTS) Slog.d(TAG, 4106 "addRecent: adding affiliated task without next/prev:" + task); 4107 needAffiliationFix = true; 4108 } 4109 } 4110 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4111 4112 if (needAffiliationFix) { 4113 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4114 cleanupRecentTasksLocked(task.userId); 4115 } 4116 } 4117 4118 /** 4119 * If needed, remove oldest existing entries in recents that are for the same kind 4120 * of task as the given one. 4121 */ 4122 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4123 int N = mRecentTasks.size(); 4124 final Intent intent = task.intent; 4125 final boolean document = intent != null && intent.isDocument(); 4126 4127 int maxRecents = task.maxRecents - 1; 4128 for (int i=0; i<N; i++) { 4129 final TaskRecord tr = mRecentTasks.get(i); 4130 if (task != tr) { 4131 if (task.userId != tr.userId) { 4132 continue; 4133 } 4134 if (i > MAX_RECENT_BITMAPS) { 4135 tr.freeLastThumbnail(); 4136 } 4137 final Intent trIntent = tr.intent; 4138 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4139 (intent == null || !intent.filterEquals(trIntent))) { 4140 continue; 4141 } 4142 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4143 if (document && trIsDocument) { 4144 // These are the same document activity (not necessarily the same doc). 4145 if (maxRecents > 0) { 4146 --maxRecents; 4147 continue; 4148 } 4149 // Hit the maximum number of documents for this task. Fall through 4150 // and remove this document from recents. 4151 } else if (document || trIsDocument) { 4152 // Only one of these is a document. Not the droid we're looking for. 4153 continue; 4154 } 4155 } 4156 4157 if (!doTrim) { 4158 // If the caller is not actually asking for a trim, just tell them we reached 4159 // a point where the trim would happen. 4160 return i; 4161 } 4162 4163 // Either task and tr are the same or, their affinities match or their intents match 4164 // and neither of them is a document, or they are documents using the same activity 4165 // and their maxRecents has been reached. 4166 tr.disposeThumbnail(); 4167 mRecentTasks.remove(i); 4168 if (task != tr) { 4169 tr.removedFromRecents(); 4170 } 4171 i--; 4172 N--; 4173 if (task.intent == null) { 4174 // If the new recent task we are adding is not fully 4175 // specified, then replace it with the existing recent task. 4176 task = tr; 4177 } 4178 notifyTaskPersisterLocked(tr, false); 4179 } 4180 4181 return -1; 4182 } 4183 4184 @Override 4185 public void reportActivityFullyDrawn(IBinder token) { 4186 synchronized (this) { 4187 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4188 if (r == null) { 4189 return; 4190 } 4191 r.reportFullyDrawnLocked(); 4192 } 4193 } 4194 4195 @Override 4196 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4197 synchronized (this) { 4198 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4199 if (r == null) { 4200 return; 4201 } 4202 final long origId = Binder.clearCallingIdentity(); 4203 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4204 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4205 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4206 if (config != null) { 4207 r.frozenBeforeDestroy = true; 4208 if (!updateConfigurationLocked(config, r, false, false)) { 4209 mStackSupervisor.resumeTopActivitiesLocked(); 4210 } 4211 } 4212 Binder.restoreCallingIdentity(origId); 4213 } 4214 } 4215 4216 @Override 4217 public int getRequestedOrientation(IBinder token) { 4218 synchronized (this) { 4219 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4220 if (r == null) { 4221 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4222 } 4223 return mWindowManager.getAppOrientation(r.appToken); 4224 } 4225 } 4226 4227 /** 4228 * This is the internal entry point for handling Activity.finish(). 4229 * 4230 * @param token The Binder token referencing the Activity we want to finish. 4231 * @param resultCode Result code, if any, from this Activity. 4232 * @param resultData Result data (Intent), if any, from this Activity. 4233 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4234 * the root Activity in the task. 4235 * 4236 * @return Returns true if the activity successfully finished, or false if it is still running. 4237 */ 4238 @Override 4239 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4240 boolean finishTask) { 4241 // Refuse possible leaked file descriptors 4242 if (resultData != null && resultData.hasFileDescriptors() == true) { 4243 throw new IllegalArgumentException("File descriptors passed in Intent"); 4244 } 4245 4246 synchronized(this) { 4247 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4248 if (r == null) { 4249 return true; 4250 } 4251 // Keep track of the root activity of the task before we finish it 4252 TaskRecord tr = r.task; 4253 ActivityRecord rootR = tr.getRootActivity(); 4254 if (rootR == null) { 4255 Slog.w(TAG, "Finishing task with all activities already finished"); 4256 } 4257 // Do not allow task to finish in Lock Task mode. 4258 if (tr == mStackSupervisor.mLockTaskModeTask) { 4259 if (rootR == r) { 4260 Slog.i(TAG, "Not finishing task in lock task mode"); 4261 mStackSupervisor.showLockTaskToast(); 4262 return false; 4263 } 4264 } 4265 if (mController != null) { 4266 // Find the first activity that is not finishing. 4267 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4268 if (next != null) { 4269 // ask watcher if this is allowed 4270 boolean resumeOK = true; 4271 try { 4272 resumeOK = mController.activityResuming(next.packageName); 4273 } catch (RemoteException e) { 4274 mController = null; 4275 Watchdog.getInstance().setActivityController(null); 4276 } 4277 4278 if (!resumeOK) { 4279 Slog.i(TAG, "Not finishing activity because controller resumed"); 4280 return false; 4281 } 4282 } 4283 } 4284 final long origId = Binder.clearCallingIdentity(); 4285 try { 4286 boolean res; 4287 if (finishTask && r == rootR) { 4288 // If requested, remove the task that is associated to this activity only if it 4289 // was the root activity in the task. The result code and data is ignored 4290 // because we don't support returning them across task boundaries. 4291 res = removeTaskByIdLocked(tr.taskId, false); 4292 if (!res) { 4293 Slog.i(TAG, "Removing task failed to finish activity"); 4294 } 4295 } else { 4296 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4297 resultData, "app-request", true); 4298 if (!res) { 4299 Slog.i(TAG, "Failed to finish by app-request"); 4300 } 4301 } 4302 return res; 4303 } finally { 4304 Binder.restoreCallingIdentity(origId); 4305 } 4306 } 4307 } 4308 4309 @Override 4310 public final void finishHeavyWeightApp() { 4311 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4312 != PackageManager.PERMISSION_GRANTED) { 4313 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4314 + Binder.getCallingPid() 4315 + ", uid=" + Binder.getCallingUid() 4316 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4317 Slog.w(TAG, msg); 4318 throw new SecurityException(msg); 4319 } 4320 4321 synchronized(this) { 4322 if (mHeavyWeightProcess == null) { 4323 return; 4324 } 4325 4326 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4327 mHeavyWeightProcess.activities); 4328 for (int i=0; i<activities.size(); i++) { 4329 ActivityRecord r = activities.get(i); 4330 if (!r.finishing) { 4331 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4332 null, "finish-heavy", true); 4333 } 4334 } 4335 4336 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4337 mHeavyWeightProcess.userId, 0)); 4338 mHeavyWeightProcess = null; 4339 } 4340 } 4341 4342 @Override 4343 public void crashApplication(int uid, int initialPid, String packageName, 4344 String message) { 4345 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4346 != PackageManager.PERMISSION_GRANTED) { 4347 String msg = "Permission Denial: crashApplication() from pid=" 4348 + Binder.getCallingPid() 4349 + ", uid=" + Binder.getCallingUid() 4350 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4351 Slog.w(TAG, msg); 4352 throw new SecurityException(msg); 4353 } 4354 4355 synchronized(this) { 4356 ProcessRecord proc = null; 4357 4358 // Figure out which process to kill. We don't trust that initialPid 4359 // still has any relation to current pids, so must scan through the 4360 // list. 4361 synchronized (mPidsSelfLocked) { 4362 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4363 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4364 if (p.uid != uid) { 4365 continue; 4366 } 4367 if (p.pid == initialPid) { 4368 proc = p; 4369 break; 4370 } 4371 if (p.pkgList.containsKey(packageName)) { 4372 proc = p; 4373 } 4374 } 4375 } 4376 4377 if (proc == null) { 4378 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4379 + " initialPid=" + initialPid 4380 + " packageName=" + packageName); 4381 return; 4382 } 4383 4384 if (proc.thread != null) { 4385 if (proc.pid == Process.myPid()) { 4386 Log.w(TAG, "crashApplication: trying to crash self!"); 4387 return; 4388 } 4389 long ident = Binder.clearCallingIdentity(); 4390 try { 4391 proc.thread.scheduleCrash(message); 4392 } catch (RemoteException e) { 4393 } 4394 Binder.restoreCallingIdentity(ident); 4395 } 4396 } 4397 } 4398 4399 @Override 4400 public final void finishSubActivity(IBinder token, String resultWho, 4401 int requestCode) { 4402 synchronized(this) { 4403 final long origId = Binder.clearCallingIdentity(); 4404 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4405 if (r != null) { 4406 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4407 } 4408 Binder.restoreCallingIdentity(origId); 4409 } 4410 } 4411 4412 @Override 4413 public boolean finishActivityAffinity(IBinder token) { 4414 synchronized(this) { 4415 final long origId = Binder.clearCallingIdentity(); 4416 try { 4417 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4418 4419 ActivityRecord rootR = r.task.getRootActivity(); 4420 // Do not allow task to finish in Lock Task mode. 4421 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4422 if (rootR == r) { 4423 mStackSupervisor.showLockTaskToast(); 4424 return false; 4425 } 4426 } 4427 boolean res = false; 4428 if (r != null) { 4429 res = r.task.stack.finishActivityAffinityLocked(r); 4430 } 4431 return res; 4432 } finally { 4433 Binder.restoreCallingIdentity(origId); 4434 } 4435 } 4436 } 4437 4438 @Override 4439 public void finishVoiceTask(IVoiceInteractionSession session) { 4440 synchronized(this) { 4441 final long origId = Binder.clearCallingIdentity(); 4442 try { 4443 mStackSupervisor.finishVoiceTask(session); 4444 } finally { 4445 Binder.restoreCallingIdentity(origId); 4446 } 4447 } 4448 4449 } 4450 4451 @Override 4452 public boolean releaseActivityInstance(IBinder token) { 4453 synchronized(this) { 4454 final long origId = Binder.clearCallingIdentity(); 4455 try { 4456 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4457 if (r.task == null || r.task.stack == null) { 4458 return false; 4459 } 4460 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4461 } finally { 4462 Binder.restoreCallingIdentity(origId); 4463 } 4464 } 4465 } 4466 4467 @Override 4468 public void releaseSomeActivities(IApplicationThread appInt) { 4469 synchronized(this) { 4470 final long origId = Binder.clearCallingIdentity(); 4471 try { 4472 ProcessRecord app = getRecordForAppLocked(appInt); 4473 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4474 } finally { 4475 Binder.restoreCallingIdentity(origId); 4476 } 4477 } 4478 } 4479 4480 @Override 4481 public boolean willActivityBeVisible(IBinder token) { 4482 synchronized(this) { 4483 ActivityStack stack = ActivityRecord.getStackLocked(token); 4484 if (stack != null) { 4485 return stack.willActivityBeVisibleLocked(token); 4486 } 4487 return false; 4488 } 4489 } 4490 4491 @Override 4492 public void overridePendingTransition(IBinder token, String packageName, 4493 int enterAnim, int exitAnim) { 4494 synchronized(this) { 4495 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4496 if (self == null) { 4497 return; 4498 } 4499 4500 final long origId = Binder.clearCallingIdentity(); 4501 4502 if (self.state == ActivityState.RESUMED 4503 || self.state == ActivityState.PAUSING) { 4504 mWindowManager.overridePendingAppTransition(packageName, 4505 enterAnim, exitAnim, null); 4506 } 4507 4508 Binder.restoreCallingIdentity(origId); 4509 } 4510 } 4511 4512 /** 4513 * Main function for removing an existing process from the activity manager 4514 * as a result of that process going away. Clears out all connections 4515 * to the process. 4516 */ 4517 private final void handleAppDiedLocked(ProcessRecord app, 4518 boolean restarting, boolean allowRestart) { 4519 int pid = app.pid; 4520 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4521 if (!kept && !restarting) { 4522 removeLruProcessLocked(app); 4523 if (pid > 0) { 4524 ProcessList.remove(pid); 4525 } 4526 } 4527 4528 if (mProfileProc == app) { 4529 clearProfilerLocked(); 4530 } 4531 4532 // Remove this application's activities from active lists. 4533 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4534 4535 app.activities.clear(); 4536 4537 if (app.instrumentationClass != null) { 4538 Slog.w(TAG, "Crash of app " + app.processName 4539 + " running instrumentation " + app.instrumentationClass); 4540 Bundle info = new Bundle(); 4541 info.putString("shortMsg", "Process crashed."); 4542 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4543 } 4544 4545 if (!restarting) { 4546 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4547 // If there was nothing to resume, and we are not already 4548 // restarting this process, but there is a visible activity that 4549 // is hosted by the process... then make sure all visible 4550 // activities are running, taking care of restarting this 4551 // process. 4552 if (hasVisibleActivities) { 4553 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4554 } 4555 } 4556 } 4557 } 4558 4559 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4560 IBinder threadBinder = thread.asBinder(); 4561 // Find the application record. 4562 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4563 ProcessRecord rec = mLruProcesses.get(i); 4564 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4565 return i; 4566 } 4567 } 4568 return -1; 4569 } 4570 4571 final ProcessRecord getRecordForAppLocked( 4572 IApplicationThread thread) { 4573 if (thread == null) { 4574 return null; 4575 } 4576 4577 int appIndex = getLRURecordIndexForAppLocked(thread); 4578 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4579 } 4580 4581 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4582 // If there are no longer any background processes running, 4583 // and the app that died was not running instrumentation, 4584 // then tell everyone we are now low on memory. 4585 boolean haveBg = false; 4586 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4587 ProcessRecord rec = mLruProcesses.get(i); 4588 if (rec.thread != null 4589 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4590 haveBg = true; 4591 break; 4592 } 4593 } 4594 4595 if (!haveBg) { 4596 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4597 if (doReport) { 4598 long now = SystemClock.uptimeMillis(); 4599 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4600 doReport = false; 4601 } else { 4602 mLastMemUsageReportTime = now; 4603 } 4604 } 4605 final ArrayList<ProcessMemInfo> memInfos 4606 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4607 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4608 long now = SystemClock.uptimeMillis(); 4609 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4610 ProcessRecord rec = mLruProcesses.get(i); 4611 if (rec == dyingProc || rec.thread == null) { 4612 continue; 4613 } 4614 if (doReport) { 4615 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4616 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4617 } 4618 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4619 // The low memory report is overriding any current 4620 // state for a GC request. Make sure to do 4621 // heavy/important/visible/foreground processes first. 4622 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4623 rec.lastRequestedGc = 0; 4624 } else { 4625 rec.lastRequestedGc = rec.lastLowMemory; 4626 } 4627 rec.reportLowMemory = true; 4628 rec.lastLowMemory = now; 4629 mProcessesToGc.remove(rec); 4630 addProcessToGcListLocked(rec); 4631 } 4632 } 4633 if (doReport) { 4634 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4635 mHandler.sendMessage(msg); 4636 } 4637 scheduleAppGcsLocked(); 4638 } 4639 } 4640 4641 final void appDiedLocked(ProcessRecord app) { 4642 appDiedLocked(app, app.pid, app.thread); 4643 } 4644 4645 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4646 // First check if this ProcessRecord is actually active for the pid. 4647 synchronized (mPidsSelfLocked) { 4648 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4649 if (curProc != app) { 4650 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4651 return; 4652 } 4653 } 4654 4655 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4656 synchronized (stats) { 4657 stats.noteProcessDiedLocked(app.info.uid, pid); 4658 } 4659 4660 if (!app.killed) { 4661 Process.killProcessQuiet(pid); 4662 Process.killProcessGroup(app.info.uid, pid); 4663 app.killed = true; 4664 } 4665 4666 // Clean up already done if the process has been re-started. 4667 if (app.pid == pid && app.thread != null && 4668 app.thread.asBinder() == thread.asBinder()) { 4669 boolean doLowMem = app.instrumentationClass == null; 4670 boolean doOomAdj = doLowMem; 4671 if (!app.killedByAm) { 4672 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4673 + ") has died"); 4674 mAllowLowerMemLevel = true; 4675 } else { 4676 // Note that we always want to do oom adj to update our state with the 4677 // new number of procs. 4678 mAllowLowerMemLevel = false; 4679 doLowMem = false; 4680 } 4681 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4682 if (DEBUG_CLEANUP) Slog.v( 4683 TAG, "Dying app: " + app + ", pid: " + pid 4684 + ", thread: " + thread.asBinder()); 4685 handleAppDiedLocked(app, false, true); 4686 4687 if (doOomAdj) { 4688 updateOomAdjLocked(); 4689 } 4690 if (doLowMem) { 4691 doLowMemReportIfNeededLocked(app); 4692 } 4693 } else if (app.pid != pid) { 4694 // A new process has already been started. 4695 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4696 + ") has died and restarted (pid " + app.pid + ")."); 4697 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4698 } else if (DEBUG_PROCESSES) { 4699 Slog.d(TAG, "Received spurious death notification for thread " 4700 + thread.asBinder()); 4701 } 4702 } 4703 4704 /** 4705 * If a stack trace dump file is configured, dump process stack traces. 4706 * @param clearTraces causes the dump file to be erased prior to the new 4707 * traces being written, if true; when false, the new traces will be 4708 * appended to any existing file content. 4709 * @param firstPids of dalvik VM processes to dump stack traces for first 4710 * @param lastPids of dalvik VM processes to dump stack traces for last 4711 * @param nativeProcs optional list of native process names to dump stack crawls 4712 * @return file containing stack traces, or null if no dump file is configured 4713 */ 4714 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4715 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4716 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4717 if (tracesPath == null || tracesPath.length() == 0) { 4718 return null; 4719 } 4720 4721 File tracesFile = new File(tracesPath); 4722 try { 4723 File tracesDir = tracesFile.getParentFile(); 4724 if (!tracesDir.exists()) { 4725 tracesDir.mkdirs(); 4726 if (!SELinux.restorecon(tracesDir)) { 4727 return null; 4728 } 4729 } 4730 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4731 4732 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4733 tracesFile.createNewFile(); 4734 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4735 } catch (IOException e) { 4736 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4737 return null; 4738 } 4739 4740 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4741 return tracesFile; 4742 } 4743 4744 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4745 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4746 // Use a FileObserver to detect when traces finish writing. 4747 // The order of traces is considered important to maintain for legibility. 4748 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4749 @Override 4750 public synchronized void onEvent(int event, String path) { notify(); } 4751 }; 4752 4753 try { 4754 observer.startWatching(); 4755 4756 // First collect all of the stacks of the most important pids. 4757 if (firstPids != null) { 4758 try { 4759 int num = firstPids.size(); 4760 for (int i = 0; i < num; i++) { 4761 synchronized (observer) { 4762 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4763 observer.wait(200); // Wait for write-close, give up after 200msec 4764 } 4765 } 4766 } catch (InterruptedException e) { 4767 Slog.wtf(TAG, e); 4768 } 4769 } 4770 4771 // Next collect the stacks of the native pids 4772 if (nativeProcs != null) { 4773 int[] pids = Process.getPidsForCommands(nativeProcs); 4774 if (pids != null) { 4775 for (int pid : pids) { 4776 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4777 } 4778 } 4779 } 4780 4781 // Lastly, measure CPU usage. 4782 if (processCpuTracker != null) { 4783 processCpuTracker.init(); 4784 System.gc(); 4785 processCpuTracker.update(); 4786 try { 4787 synchronized (processCpuTracker) { 4788 processCpuTracker.wait(500); // measure over 1/2 second. 4789 } 4790 } catch (InterruptedException e) { 4791 } 4792 processCpuTracker.update(); 4793 4794 // We'll take the stack crawls of just the top apps using CPU. 4795 final int N = processCpuTracker.countWorkingStats(); 4796 int numProcs = 0; 4797 for (int i=0; i<N && numProcs<5; i++) { 4798 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4799 if (lastPids.indexOfKey(stats.pid) >= 0) { 4800 numProcs++; 4801 try { 4802 synchronized (observer) { 4803 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4804 observer.wait(200); // Wait for write-close, give up after 200msec 4805 } 4806 } catch (InterruptedException e) { 4807 Slog.wtf(TAG, e); 4808 } 4809 4810 } 4811 } 4812 } 4813 } finally { 4814 observer.stopWatching(); 4815 } 4816 } 4817 4818 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4819 if (true || IS_USER_BUILD) { 4820 return; 4821 } 4822 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4823 if (tracesPath == null || tracesPath.length() == 0) { 4824 return; 4825 } 4826 4827 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4828 StrictMode.allowThreadDiskWrites(); 4829 try { 4830 final File tracesFile = new File(tracesPath); 4831 final File tracesDir = tracesFile.getParentFile(); 4832 final File tracesTmp = new File(tracesDir, "__tmp__"); 4833 try { 4834 if (!tracesDir.exists()) { 4835 tracesDir.mkdirs(); 4836 if (!SELinux.restorecon(tracesDir.getPath())) { 4837 return; 4838 } 4839 } 4840 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4841 4842 if (tracesFile.exists()) { 4843 tracesTmp.delete(); 4844 tracesFile.renameTo(tracesTmp); 4845 } 4846 StringBuilder sb = new StringBuilder(); 4847 Time tobj = new Time(); 4848 tobj.set(System.currentTimeMillis()); 4849 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4850 sb.append(": "); 4851 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4852 sb.append(" since "); 4853 sb.append(msg); 4854 FileOutputStream fos = new FileOutputStream(tracesFile); 4855 fos.write(sb.toString().getBytes()); 4856 if (app == null) { 4857 fos.write("\n*** No application process!".getBytes()); 4858 } 4859 fos.close(); 4860 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4861 } catch (IOException e) { 4862 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4863 return; 4864 } 4865 4866 if (app != null) { 4867 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4868 firstPids.add(app.pid); 4869 dumpStackTraces(tracesPath, firstPids, null, null, null); 4870 } 4871 4872 File lastTracesFile = null; 4873 File curTracesFile = null; 4874 for (int i=9; i>=0; i--) { 4875 String name = String.format(Locale.US, "slow%02d.txt", i); 4876 curTracesFile = new File(tracesDir, name); 4877 if (curTracesFile.exists()) { 4878 if (lastTracesFile != null) { 4879 curTracesFile.renameTo(lastTracesFile); 4880 } else { 4881 curTracesFile.delete(); 4882 } 4883 } 4884 lastTracesFile = curTracesFile; 4885 } 4886 tracesFile.renameTo(curTracesFile); 4887 if (tracesTmp.exists()) { 4888 tracesTmp.renameTo(tracesFile); 4889 } 4890 } finally { 4891 StrictMode.setThreadPolicy(oldPolicy); 4892 } 4893 } 4894 4895 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4896 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4897 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4898 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4899 4900 if (mController != null) { 4901 try { 4902 // 0 == continue, -1 = kill process immediately 4903 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4904 if (res < 0 && app.pid != MY_PID) { 4905 app.kill("anr", true); 4906 } 4907 } catch (RemoteException e) { 4908 mController = null; 4909 Watchdog.getInstance().setActivityController(null); 4910 } 4911 } 4912 4913 long anrTime = SystemClock.uptimeMillis(); 4914 if (MONITOR_CPU_USAGE) { 4915 updateCpuStatsNow(); 4916 } 4917 4918 synchronized (this) { 4919 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4920 if (mShuttingDown) { 4921 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4922 return; 4923 } else if (app.notResponding) { 4924 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4925 return; 4926 } else if (app.crashing) { 4927 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4928 return; 4929 } 4930 4931 // In case we come through here for the same app before completing 4932 // this one, mark as anring now so we will bail out. 4933 app.notResponding = true; 4934 4935 // Log the ANR to the event log. 4936 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4937 app.processName, app.info.flags, annotation); 4938 4939 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4940 firstPids.add(app.pid); 4941 4942 int parentPid = app.pid; 4943 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4944 if (parentPid != app.pid) firstPids.add(parentPid); 4945 4946 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4947 4948 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4949 ProcessRecord r = mLruProcesses.get(i); 4950 if (r != null && r.thread != null) { 4951 int pid = r.pid; 4952 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4953 if (r.persistent) { 4954 firstPids.add(pid); 4955 } else { 4956 lastPids.put(pid, Boolean.TRUE); 4957 } 4958 } 4959 } 4960 } 4961 } 4962 4963 // Log the ANR to the main log. 4964 StringBuilder info = new StringBuilder(); 4965 info.setLength(0); 4966 info.append("ANR in ").append(app.processName); 4967 if (activity != null && activity.shortComponentName != null) { 4968 info.append(" (").append(activity.shortComponentName).append(")"); 4969 } 4970 info.append("\n"); 4971 info.append("PID: ").append(app.pid).append("\n"); 4972 if (annotation != null) { 4973 info.append("Reason: ").append(annotation).append("\n"); 4974 } 4975 if (parent != null && parent != activity) { 4976 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4977 } 4978 4979 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4980 4981 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4982 NATIVE_STACKS_OF_INTEREST); 4983 4984 String cpuInfo = null; 4985 if (MONITOR_CPU_USAGE) { 4986 updateCpuStatsNow(); 4987 synchronized (mProcessCpuTracker) { 4988 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4989 } 4990 info.append(processCpuTracker.printCurrentLoad()); 4991 info.append(cpuInfo); 4992 } 4993 4994 info.append(processCpuTracker.printCurrentState(anrTime)); 4995 4996 Slog.e(TAG, info.toString()); 4997 if (tracesFile == null) { 4998 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4999 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5000 } 5001 5002 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5003 cpuInfo, tracesFile, null); 5004 5005 if (mController != null) { 5006 try { 5007 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5008 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5009 if (res != 0) { 5010 if (res < 0 && app.pid != MY_PID) { 5011 app.kill("anr", true); 5012 } else { 5013 synchronized (this) { 5014 mServices.scheduleServiceTimeoutLocked(app); 5015 } 5016 } 5017 return; 5018 } 5019 } catch (RemoteException e) { 5020 mController = null; 5021 Watchdog.getInstance().setActivityController(null); 5022 } 5023 } 5024 5025 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5026 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5027 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5028 5029 synchronized (this) { 5030 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5031 5032 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5033 app.kill("bg anr", true); 5034 return; 5035 } 5036 5037 // Set the app's notResponding state, and look up the errorReportReceiver 5038 makeAppNotRespondingLocked(app, 5039 activity != null ? activity.shortComponentName : null, 5040 annotation != null ? "ANR " + annotation : "ANR", 5041 info.toString()); 5042 5043 // Bring up the infamous App Not Responding dialog 5044 Message msg = Message.obtain(); 5045 HashMap<String, Object> map = new HashMap<String, Object>(); 5046 msg.what = SHOW_NOT_RESPONDING_MSG; 5047 msg.obj = map; 5048 msg.arg1 = aboveSystem ? 1 : 0; 5049 map.put("app", app); 5050 if (activity != null) { 5051 map.put("activity", activity); 5052 } 5053 5054 mHandler.sendMessage(msg); 5055 } 5056 } 5057 5058 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5059 if (!mLaunchWarningShown) { 5060 mLaunchWarningShown = true; 5061 mHandler.post(new Runnable() { 5062 @Override 5063 public void run() { 5064 synchronized (ActivityManagerService.this) { 5065 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5066 d.show(); 5067 mHandler.postDelayed(new Runnable() { 5068 @Override 5069 public void run() { 5070 synchronized (ActivityManagerService.this) { 5071 d.dismiss(); 5072 mLaunchWarningShown = false; 5073 } 5074 } 5075 }, 4000); 5076 } 5077 } 5078 }); 5079 } 5080 } 5081 5082 @Override 5083 public boolean clearApplicationUserData(final String packageName, 5084 final IPackageDataObserver observer, int userId) { 5085 enforceNotIsolatedCaller("clearApplicationUserData"); 5086 int uid = Binder.getCallingUid(); 5087 int pid = Binder.getCallingPid(); 5088 userId = handleIncomingUser(pid, uid, 5089 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5090 long callingId = Binder.clearCallingIdentity(); 5091 try { 5092 IPackageManager pm = AppGlobals.getPackageManager(); 5093 int pkgUid = -1; 5094 synchronized(this) { 5095 try { 5096 pkgUid = pm.getPackageUid(packageName, userId); 5097 } catch (RemoteException e) { 5098 } 5099 if (pkgUid == -1) { 5100 Slog.w(TAG, "Invalid packageName: " + packageName); 5101 if (observer != null) { 5102 try { 5103 observer.onRemoveCompleted(packageName, false); 5104 } catch (RemoteException e) { 5105 Slog.i(TAG, "Observer no longer exists."); 5106 } 5107 } 5108 return false; 5109 } 5110 if (uid == pkgUid || checkComponentPermission( 5111 android.Manifest.permission.CLEAR_APP_USER_DATA, 5112 pid, uid, -1, true) 5113 == PackageManager.PERMISSION_GRANTED) { 5114 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5115 } else { 5116 throw new SecurityException("PID " + pid + " does not have permission " 5117 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5118 + " of package " + packageName); 5119 } 5120 5121 // Remove all tasks match the cleared application package and user 5122 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5123 final TaskRecord tr = mRecentTasks.get(i); 5124 final String taskPackageName = 5125 tr.getBaseIntent().getComponent().getPackageName(); 5126 if (tr.userId != userId) continue; 5127 if (!taskPackageName.equals(packageName)) continue; 5128 removeTaskByIdLocked(tr.taskId, false); 5129 } 5130 } 5131 5132 try { 5133 // Clear application user data 5134 pm.clearApplicationUserData(packageName, observer, userId); 5135 5136 synchronized(this) { 5137 // Remove all permissions granted from/to this package 5138 removeUriPermissionsForPackageLocked(packageName, userId, true); 5139 } 5140 5141 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5142 Uri.fromParts("package", packageName, null)); 5143 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5144 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5145 null, null, 0, null, null, null, false, false, userId); 5146 } catch (RemoteException e) { 5147 } 5148 } finally { 5149 Binder.restoreCallingIdentity(callingId); 5150 } 5151 return true; 5152 } 5153 5154 @Override 5155 public void killBackgroundProcesses(final String packageName, int userId) { 5156 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5157 != PackageManager.PERMISSION_GRANTED && 5158 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5159 != PackageManager.PERMISSION_GRANTED) { 5160 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5161 + Binder.getCallingPid() 5162 + ", uid=" + Binder.getCallingUid() 5163 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5164 Slog.w(TAG, msg); 5165 throw new SecurityException(msg); 5166 } 5167 5168 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5169 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5170 long callingId = Binder.clearCallingIdentity(); 5171 try { 5172 IPackageManager pm = AppGlobals.getPackageManager(); 5173 synchronized(this) { 5174 int appId = -1; 5175 try { 5176 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5177 } catch (RemoteException e) { 5178 } 5179 if (appId == -1) { 5180 Slog.w(TAG, "Invalid packageName: " + packageName); 5181 return; 5182 } 5183 killPackageProcessesLocked(packageName, appId, userId, 5184 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5185 } 5186 } finally { 5187 Binder.restoreCallingIdentity(callingId); 5188 } 5189 } 5190 5191 @Override 5192 public void killAllBackgroundProcesses() { 5193 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5194 != PackageManager.PERMISSION_GRANTED) { 5195 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5196 + Binder.getCallingPid() 5197 + ", uid=" + Binder.getCallingUid() 5198 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5199 Slog.w(TAG, msg); 5200 throw new SecurityException(msg); 5201 } 5202 5203 long callingId = Binder.clearCallingIdentity(); 5204 try { 5205 synchronized(this) { 5206 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5207 final int NP = mProcessNames.getMap().size(); 5208 for (int ip=0; ip<NP; ip++) { 5209 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5210 final int NA = apps.size(); 5211 for (int ia=0; ia<NA; ia++) { 5212 ProcessRecord app = apps.valueAt(ia); 5213 if (app.persistent) { 5214 // we don't kill persistent processes 5215 continue; 5216 } 5217 if (app.removed) { 5218 procs.add(app); 5219 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5220 app.removed = true; 5221 procs.add(app); 5222 } 5223 } 5224 } 5225 5226 int N = procs.size(); 5227 for (int i=0; i<N; i++) { 5228 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5229 } 5230 mAllowLowerMemLevel = true; 5231 updateOomAdjLocked(); 5232 doLowMemReportIfNeededLocked(null); 5233 } 5234 } finally { 5235 Binder.restoreCallingIdentity(callingId); 5236 } 5237 } 5238 5239 @Override 5240 public void forceStopPackage(final String packageName, int userId) { 5241 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5242 != PackageManager.PERMISSION_GRANTED) { 5243 String msg = "Permission Denial: forceStopPackage() from pid=" 5244 + Binder.getCallingPid() 5245 + ", uid=" + Binder.getCallingUid() 5246 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5247 Slog.w(TAG, msg); 5248 throw new SecurityException(msg); 5249 } 5250 final int callingPid = Binder.getCallingPid(); 5251 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5252 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5253 long callingId = Binder.clearCallingIdentity(); 5254 try { 5255 IPackageManager pm = AppGlobals.getPackageManager(); 5256 synchronized(this) { 5257 int[] users = userId == UserHandle.USER_ALL 5258 ? getUsersLocked() : new int[] { userId }; 5259 for (int user : users) { 5260 int pkgUid = -1; 5261 try { 5262 pkgUid = pm.getPackageUid(packageName, user); 5263 } catch (RemoteException e) { 5264 } 5265 if (pkgUid == -1) { 5266 Slog.w(TAG, "Invalid packageName: " + packageName); 5267 continue; 5268 } 5269 try { 5270 pm.setPackageStoppedState(packageName, true, user); 5271 } catch (RemoteException e) { 5272 } catch (IllegalArgumentException e) { 5273 Slog.w(TAG, "Failed trying to unstop package " 5274 + packageName + ": " + e); 5275 } 5276 if (isUserRunningLocked(user, false)) { 5277 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5278 } 5279 } 5280 } 5281 } finally { 5282 Binder.restoreCallingIdentity(callingId); 5283 } 5284 } 5285 5286 @Override 5287 public void addPackageDependency(String packageName) { 5288 synchronized (this) { 5289 int callingPid = Binder.getCallingPid(); 5290 if (callingPid == Process.myPid()) { 5291 // Yeah, um, no. 5292 Slog.w(TAG, "Can't addPackageDependency on system process"); 5293 return; 5294 } 5295 ProcessRecord proc; 5296 synchronized (mPidsSelfLocked) { 5297 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5298 } 5299 if (proc != null) { 5300 if (proc.pkgDeps == null) { 5301 proc.pkgDeps = new ArraySet<String>(1); 5302 } 5303 proc.pkgDeps.add(packageName); 5304 } 5305 } 5306 } 5307 5308 /* 5309 * The pkg name and app id have to be specified. 5310 */ 5311 @Override 5312 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5313 if (pkg == null) { 5314 return; 5315 } 5316 // Make sure the uid is valid. 5317 if (appid < 0) { 5318 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5319 return; 5320 } 5321 int callerUid = Binder.getCallingUid(); 5322 // Only the system server can kill an application 5323 if (callerUid == Process.SYSTEM_UID) { 5324 // Post an aysnc message to kill the application 5325 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5326 msg.arg1 = appid; 5327 msg.arg2 = 0; 5328 Bundle bundle = new Bundle(); 5329 bundle.putString("pkg", pkg); 5330 bundle.putString("reason", reason); 5331 msg.obj = bundle; 5332 mHandler.sendMessage(msg); 5333 } else { 5334 throw new SecurityException(callerUid + " cannot kill pkg: " + 5335 pkg); 5336 } 5337 } 5338 5339 @Override 5340 public void closeSystemDialogs(String reason) { 5341 enforceNotIsolatedCaller("closeSystemDialogs"); 5342 5343 final int pid = Binder.getCallingPid(); 5344 final int uid = Binder.getCallingUid(); 5345 final long origId = Binder.clearCallingIdentity(); 5346 try { 5347 synchronized (this) { 5348 // Only allow this from foreground processes, so that background 5349 // applications can't abuse it to prevent system UI from being shown. 5350 if (uid >= Process.FIRST_APPLICATION_UID) { 5351 ProcessRecord proc; 5352 synchronized (mPidsSelfLocked) { 5353 proc = mPidsSelfLocked.get(pid); 5354 } 5355 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5356 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5357 + " from background process " + proc); 5358 return; 5359 } 5360 } 5361 closeSystemDialogsLocked(reason); 5362 } 5363 } finally { 5364 Binder.restoreCallingIdentity(origId); 5365 } 5366 } 5367 5368 void closeSystemDialogsLocked(String reason) { 5369 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5370 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5371 | Intent.FLAG_RECEIVER_FOREGROUND); 5372 if (reason != null) { 5373 intent.putExtra("reason", reason); 5374 } 5375 mWindowManager.closeSystemDialogs(reason); 5376 5377 mStackSupervisor.closeSystemDialogsLocked(); 5378 5379 broadcastIntentLocked(null, null, intent, null, 5380 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5381 Process.SYSTEM_UID, UserHandle.USER_ALL); 5382 } 5383 5384 @Override 5385 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5386 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5387 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5388 for (int i=pids.length-1; i>=0; i--) { 5389 ProcessRecord proc; 5390 int oomAdj; 5391 synchronized (this) { 5392 synchronized (mPidsSelfLocked) { 5393 proc = mPidsSelfLocked.get(pids[i]); 5394 oomAdj = proc != null ? proc.setAdj : 0; 5395 } 5396 } 5397 infos[i] = new Debug.MemoryInfo(); 5398 Debug.getMemoryInfo(pids[i], infos[i]); 5399 if (proc != null) { 5400 synchronized (this) { 5401 if (proc.thread != null && proc.setAdj == oomAdj) { 5402 // Record this for posterity if the process has been stable. 5403 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5404 infos[i].getTotalUss(), false, proc.pkgList); 5405 } 5406 } 5407 } 5408 } 5409 return infos; 5410 } 5411 5412 @Override 5413 public long[] getProcessPss(int[] pids) { 5414 enforceNotIsolatedCaller("getProcessPss"); 5415 long[] pss = new long[pids.length]; 5416 for (int i=pids.length-1; i>=0; i--) { 5417 ProcessRecord proc; 5418 int oomAdj; 5419 synchronized (this) { 5420 synchronized (mPidsSelfLocked) { 5421 proc = mPidsSelfLocked.get(pids[i]); 5422 oomAdj = proc != null ? proc.setAdj : 0; 5423 } 5424 } 5425 long[] tmpUss = new long[1]; 5426 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5427 if (proc != null) { 5428 synchronized (this) { 5429 if (proc.thread != null && proc.setAdj == oomAdj) { 5430 // Record this for posterity if the process has been stable. 5431 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5432 } 5433 } 5434 } 5435 } 5436 return pss; 5437 } 5438 5439 @Override 5440 public void killApplicationProcess(String processName, int uid) { 5441 if (processName == null) { 5442 return; 5443 } 5444 5445 int callerUid = Binder.getCallingUid(); 5446 // Only the system server can kill an application 5447 if (callerUid == Process.SYSTEM_UID) { 5448 synchronized (this) { 5449 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5450 if (app != null && app.thread != null) { 5451 try { 5452 app.thread.scheduleSuicide(); 5453 } catch (RemoteException e) { 5454 // If the other end already died, then our work here is done. 5455 } 5456 } else { 5457 Slog.w(TAG, "Process/uid not found attempting kill of " 5458 + processName + " / " + uid); 5459 } 5460 } 5461 } else { 5462 throw new SecurityException(callerUid + " cannot kill app process: " + 5463 processName); 5464 } 5465 } 5466 5467 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5468 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5469 false, true, false, false, UserHandle.getUserId(uid), reason); 5470 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5471 Uri.fromParts("package", packageName, null)); 5472 if (!mProcessesReady) { 5473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5474 | Intent.FLAG_RECEIVER_FOREGROUND); 5475 } 5476 intent.putExtra(Intent.EXTRA_UID, uid); 5477 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5478 broadcastIntentLocked(null, null, intent, 5479 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5480 false, false, 5481 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5482 } 5483 5484 private void forceStopUserLocked(int userId, String reason) { 5485 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5486 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5487 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5488 | Intent.FLAG_RECEIVER_FOREGROUND); 5489 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5490 broadcastIntentLocked(null, null, intent, 5491 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5492 false, false, 5493 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5494 } 5495 5496 private final boolean killPackageProcessesLocked(String packageName, int appId, 5497 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5498 boolean doit, boolean evenPersistent, String reason) { 5499 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5500 5501 // Remove all processes this package may have touched: all with the 5502 // same UID (except for the system or root user), and all whose name 5503 // matches the package name. 5504 final int NP = mProcessNames.getMap().size(); 5505 for (int ip=0; ip<NP; ip++) { 5506 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5507 final int NA = apps.size(); 5508 for (int ia=0; ia<NA; ia++) { 5509 ProcessRecord app = apps.valueAt(ia); 5510 if (app.persistent && !evenPersistent) { 5511 // we don't kill persistent processes 5512 continue; 5513 } 5514 if (app.removed) { 5515 if (doit) { 5516 procs.add(app); 5517 } 5518 continue; 5519 } 5520 5521 // Skip process if it doesn't meet our oom adj requirement. 5522 if (app.setAdj < minOomAdj) { 5523 continue; 5524 } 5525 5526 // If no package is specified, we call all processes under the 5527 // give user id. 5528 if (packageName == null) { 5529 if (app.userId != userId) { 5530 continue; 5531 } 5532 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5533 continue; 5534 } 5535 // Package has been specified, we want to hit all processes 5536 // that match it. We need to qualify this by the processes 5537 // that are running under the specified app and user ID. 5538 } else { 5539 final boolean isDep = app.pkgDeps != null 5540 && app.pkgDeps.contains(packageName); 5541 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5542 continue; 5543 } 5544 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5545 continue; 5546 } 5547 if (!app.pkgList.containsKey(packageName) && !isDep) { 5548 continue; 5549 } 5550 } 5551 5552 // Process has passed all conditions, kill it! 5553 if (!doit) { 5554 return true; 5555 } 5556 app.removed = true; 5557 procs.add(app); 5558 } 5559 } 5560 5561 int N = procs.size(); 5562 for (int i=0; i<N; i++) { 5563 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5564 } 5565 updateOomAdjLocked(); 5566 return N > 0; 5567 } 5568 5569 private final boolean forceStopPackageLocked(String name, int appId, 5570 boolean callerWillRestart, boolean purgeCache, boolean doit, 5571 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5572 int i; 5573 int N; 5574 5575 if (userId == UserHandle.USER_ALL && name == null) { 5576 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5577 } 5578 5579 if (appId < 0 && name != null) { 5580 try { 5581 appId = UserHandle.getAppId( 5582 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5583 } catch (RemoteException e) { 5584 } 5585 } 5586 5587 if (doit) { 5588 if (name != null) { 5589 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5590 + " user=" + userId + ": " + reason); 5591 } else { 5592 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5593 } 5594 5595 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5596 for (int ip=pmap.size()-1; ip>=0; ip--) { 5597 SparseArray<Long> ba = pmap.valueAt(ip); 5598 for (i=ba.size()-1; i>=0; i--) { 5599 boolean remove = false; 5600 final int entUid = ba.keyAt(i); 5601 if (name != null) { 5602 if (userId == UserHandle.USER_ALL) { 5603 if (UserHandle.getAppId(entUid) == appId) { 5604 remove = true; 5605 } 5606 } else { 5607 if (entUid == UserHandle.getUid(userId, appId)) { 5608 remove = true; 5609 } 5610 } 5611 } else if (UserHandle.getUserId(entUid) == userId) { 5612 remove = true; 5613 } 5614 if (remove) { 5615 ba.removeAt(i); 5616 } 5617 } 5618 if (ba.size() == 0) { 5619 pmap.removeAt(ip); 5620 } 5621 } 5622 } 5623 5624 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5625 -100, callerWillRestart, true, doit, evenPersistent, 5626 name == null ? ("stop user " + userId) : ("stop " + name)); 5627 5628 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5629 if (!doit) { 5630 return true; 5631 } 5632 didSomething = true; 5633 } 5634 5635 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5636 if (!doit) { 5637 return true; 5638 } 5639 didSomething = true; 5640 } 5641 5642 if (name == null) { 5643 // Remove all sticky broadcasts from this user. 5644 mStickyBroadcasts.remove(userId); 5645 } 5646 5647 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5648 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5649 userId, providers)) { 5650 if (!doit) { 5651 return true; 5652 } 5653 didSomething = true; 5654 } 5655 N = providers.size(); 5656 for (i=0; i<N; i++) { 5657 removeDyingProviderLocked(null, providers.get(i), true); 5658 } 5659 5660 // Remove transient permissions granted from/to this package/user 5661 removeUriPermissionsForPackageLocked(name, userId, false); 5662 5663 if (name == null || uninstalling) { 5664 // Remove pending intents. For now we only do this when force 5665 // stopping users, because we have some problems when doing this 5666 // for packages -- app widgets are not currently cleaned up for 5667 // such packages, so they can be left with bad pending intents. 5668 if (mIntentSenderRecords.size() > 0) { 5669 Iterator<WeakReference<PendingIntentRecord>> it 5670 = mIntentSenderRecords.values().iterator(); 5671 while (it.hasNext()) { 5672 WeakReference<PendingIntentRecord> wpir = it.next(); 5673 if (wpir == null) { 5674 it.remove(); 5675 continue; 5676 } 5677 PendingIntentRecord pir = wpir.get(); 5678 if (pir == null) { 5679 it.remove(); 5680 continue; 5681 } 5682 if (name == null) { 5683 // Stopping user, remove all objects for the user. 5684 if (pir.key.userId != userId) { 5685 // Not the same user, skip it. 5686 continue; 5687 } 5688 } else { 5689 if (UserHandle.getAppId(pir.uid) != appId) { 5690 // Different app id, skip it. 5691 continue; 5692 } 5693 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5694 // Different user, skip it. 5695 continue; 5696 } 5697 if (!pir.key.packageName.equals(name)) { 5698 // Different package, skip it. 5699 continue; 5700 } 5701 } 5702 if (!doit) { 5703 return true; 5704 } 5705 didSomething = true; 5706 it.remove(); 5707 pir.canceled = true; 5708 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5709 pir.key.activity.pendingResults.remove(pir.ref); 5710 } 5711 } 5712 } 5713 } 5714 5715 if (doit) { 5716 if (purgeCache && name != null) { 5717 AttributeCache ac = AttributeCache.instance(); 5718 if (ac != null) { 5719 ac.removePackage(name); 5720 } 5721 } 5722 if (mBooted) { 5723 mStackSupervisor.resumeTopActivitiesLocked(); 5724 mStackSupervisor.scheduleIdleLocked(); 5725 } 5726 } 5727 5728 return didSomething; 5729 } 5730 5731 private final boolean removeProcessLocked(ProcessRecord app, 5732 boolean callerWillRestart, boolean allowRestart, String reason) { 5733 final String name = app.processName; 5734 final int uid = app.uid; 5735 if (DEBUG_PROCESSES) Slog.d( 5736 TAG, "Force removing proc " + app.toShortString() + " (" + name 5737 + "/" + uid + ")"); 5738 5739 mProcessNames.remove(name, uid); 5740 mIsolatedProcesses.remove(app.uid); 5741 if (mHeavyWeightProcess == app) { 5742 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5743 mHeavyWeightProcess.userId, 0)); 5744 mHeavyWeightProcess = null; 5745 } 5746 boolean needRestart = false; 5747 if (app.pid > 0 && app.pid != MY_PID) { 5748 int pid = app.pid; 5749 synchronized (mPidsSelfLocked) { 5750 mPidsSelfLocked.remove(pid); 5751 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5752 } 5753 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5754 if (app.isolated) { 5755 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5756 } 5757 app.kill(reason, true); 5758 handleAppDiedLocked(app, true, allowRestart); 5759 removeLruProcessLocked(app); 5760 5761 if (app.persistent && !app.isolated) { 5762 if (!callerWillRestart) { 5763 addAppLocked(app.info, false, null /* ABI override */); 5764 } else { 5765 needRestart = true; 5766 } 5767 } 5768 } else { 5769 mRemovedProcesses.add(app); 5770 } 5771 5772 return needRestart; 5773 } 5774 5775 private final void processStartTimedOutLocked(ProcessRecord app) { 5776 final int pid = app.pid; 5777 boolean gone = false; 5778 synchronized (mPidsSelfLocked) { 5779 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5780 if (knownApp != null && knownApp.thread == null) { 5781 mPidsSelfLocked.remove(pid); 5782 gone = true; 5783 } 5784 } 5785 5786 if (gone) { 5787 Slog.w(TAG, "Process " + app + " failed to attach"); 5788 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5789 pid, app.uid, app.processName); 5790 mProcessNames.remove(app.processName, app.uid); 5791 mIsolatedProcesses.remove(app.uid); 5792 if (mHeavyWeightProcess == app) { 5793 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5794 mHeavyWeightProcess.userId, 0)); 5795 mHeavyWeightProcess = null; 5796 } 5797 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5798 if (app.isolated) { 5799 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5800 } 5801 // Take care of any launching providers waiting for this process. 5802 checkAppInLaunchingProvidersLocked(app, true); 5803 // Take care of any services that are waiting for the process. 5804 mServices.processStartTimedOutLocked(app); 5805 app.kill("start timeout", true); 5806 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5807 Slog.w(TAG, "Unattached app died before backup, skipping"); 5808 try { 5809 IBackupManager bm = IBackupManager.Stub.asInterface( 5810 ServiceManager.getService(Context.BACKUP_SERVICE)); 5811 bm.agentDisconnected(app.info.packageName); 5812 } catch (RemoteException e) { 5813 // Can't happen; the backup manager is local 5814 } 5815 } 5816 if (isPendingBroadcastProcessLocked(pid)) { 5817 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5818 skipPendingBroadcastLocked(pid); 5819 } 5820 } else { 5821 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5822 } 5823 } 5824 5825 private final boolean attachApplicationLocked(IApplicationThread thread, 5826 int pid) { 5827 5828 // Find the application record that is being attached... either via 5829 // the pid if we are running in multiple processes, or just pull the 5830 // next app record if we are emulating process with anonymous threads. 5831 ProcessRecord app; 5832 if (pid != MY_PID && pid >= 0) { 5833 synchronized (mPidsSelfLocked) { 5834 app = mPidsSelfLocked.get(pid); 5835 } 5836 } else { 5837 app = null; 5838 } 5839 5840 if (app == null) { 5841 Slog.w(TAG, "No pending application record for pid " + pid 5842 + " (IApplicationThread " + thread + "); dropping process"); 5843 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5844 if (pid > 0 && pid != MY_PID) { 5845 Process.killProcessQuiet(pid); 5846 //TODO: Process.killProcessGroup(app.info.uid, pid); 5847 } else { 5848 try { 5849 thread.scheduleExit(); 5850 } catch (Exception e) { 5851 // Ignore exceptions. 5852 } 5853 } 5854 return false; 5855 } 5856 5857 // If this application record is still attached to a previous 5858 // process, clean it up now. 5859 if (app.thread != null) { 5860 handleAppDiedLocked(app, true, true); 5861 } 5862 5863 // Tell the process all about itself. 5864 5865 if (localLOGV) Slog.v( 5866 TAG, "Binding process pid " + pid + " to record " + app); 5867 5868 final String processName = app.processName; 5869 try { 5870 AppDeathRecipient adr = new AppDeathRecipient( 5871 app, pid, thread); 5872 thread.asBinder().linkToDeath(adr, 0); 5873 app.deathRecipient = adr; 5874 } catch (RemoteException e) { 5875 app.resetPackageList(mProcessStats); 5876 startProcessLocked(app, "link fail", processName); 5877 return false; 5878 } 5879 5880 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5881 5882 app.makeActive(thread, mProcessStats); 5883 app.curAdj = app.setAdj = -100; 5884 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5885 app.forcingToForeground = null; 5886 updateProcessForegroundLocked(app, false, false); 5887 app.hasShownUi = false; 5888 app.debugging = false; 5889 app.cached = false; 5890 app.killedByAm = false; 5891 5892 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5893 5894 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5895 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5896 5897 if (!normalMode) { 5898 Slog.i(TAG, "Launching preboot mode app: " + app); 5899 } 5900 5901 if (localLOGV) Slog.v( 5902 TAG, "New app record " + app 5903 + " thread=" + thread.asBinder() + " pid=" + pid); 5904 try { 5905 int testMode = IApplicationThread.DEBUG_OFF; 5906 if (mDebugApp != null && mDebugApp.equals(processName)) { 5907 testMode = mWaitForDebugger 5908 ? IApplicationThread.DEBUG_WAIT 5909 : IApplicationThread.DEBUG_ON; 5910 app.debugging = true; 5911 if (mDebugTransient) { 5912 mDebugApp = mOrigDebugApp; 5913 mWaitForDebugger = mOrigWaitForDebugger; 5914 } 5915 } 5916 String profileFile = app.instrumentationProfileFile; 5917 ParcelFileDescriptor profileFd = null; 5918 int samplingInterval = 0; 5919 boolean profileAutoStop = false; 5920 if (mProfileApp != null && mProfileApp.equals(processName)) { 5921 mProfileProc = app; 5922 profileFile = mProfileFile; 5923 profileFd = mProfileFd; 5924 samplingInterval = mSamplingInterval; 5925 profileAutoStop = mAutoStopProfiler; 5926 } 5927 boolean enableOpenGlTrace = false; 5928 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5929 enableOpenGlTrace = true; 5930 mOpenGlTraceApp = null; 5931 } 5932 5933 // If the app is being launched for restore or full backup, set it up specially 5934 boolean isRestrictedBackupMode = false; 5935 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5936 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5937 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5938 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5939 } 5940 5941 ensurePackageDexOpt(app.instrumentationInfo != null 5942 ? app.instrumentationInfo.packageName 5943 : app.info.packageName); 5944 if (app.instrumentationClass != null) { 5945 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5946 } 5947 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5948 + processName + " with config " + mConfiguration); 5949 ApplicationInfo appInfo = app.instrumentationInfo != null 5950 ? app.instrumentationInfo : app.info; 5951 app.compat = compatibilityInfoForPackageLocked(appInfo); 5952 if (profileFd != null) { 5953 profileFd = profileFd.dup(); 5954 } 5955 ProfilerInfo profilerInfo = profileFile == null ? null 5956 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5957 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5958 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5959 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5960 isRestrictedBackupMode || !normalMode, app.persistent, 5961 new Configuration(mConfiguration), app.compat, 5962 getCommonServicesLocked(app.isolated), 5963 mCoreSettingsObserver.getCoreSettingsLocked()); 5964 updateLruProcessLocked(app, false, null); 5965 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5966 } catch (Exception e) { 5967 // todo: Yikes! What should we do? For now we will try to 5968 // start another process, but that could easily get us in 5969 // an infinite loop of restarting processes... 5970 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5971 5972 app.resetPackageList(mProcessStats); 5973 app.unlinkDeathRecipient(); 5974 startProcessLocked(app, "bind fail", processName); 5975 return false; 5976 } 5977 5978 // Remove this record from the list of starting applications. 5979 mPersistentStartingProcesses.remove(app); 5980 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5981 "Attach application locked removing on hold: " + app); 5982 mProcessesOnHold.remove(app); 5983 5984 boolean badApp = false; 5985 boolean didSomething = false; 5986 5987 // See if the top visible activity is waiting to run in this process... 5988 if (normalMode) { 5989 try { 5990 if (mStackSupervisor.attachApplicationLocked(app)) { 5991 didSomething = true; 5992 } 5993 } catch (Exception e) { 5994 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5995 badApp = true; 5996 } 5997 } 5998 5999 // Find any services that should be running in this process... 6000 if (!badApp) { 6001 try { 6002 didSomething |= mServices.attachApplicationLocked(app, processName); 6003 } catch (Exception e) { 6004 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6005 badApp = true; 6006 } 6007 } 6008 6009 // Check if a next-broadcast receiver is in this process... 6010 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6011 try { 6012 didSomething |= sendPendingBroadcastsLocked(app); 6013 } catch (Exception e) { 6014 // If the app died trying to launch the receiver we declare it 'bad' 6015 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6016 badApp = true; 6017 } 6018 } 6019 6020 // Check whether the next backup agent is in this process... 6021 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6022 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6023 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6024 try { 6025 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6026 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6027 mBackupTarget.backupMode); 6028 } catch (Exception e) { 6029 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6030 badApp = true; 6031 } 6032 } 6033 6034 if (badApp) { 6035 app.kill("error during init", true); 6036 handleAppDiedLocked(app, false, true); 6037 return false; 6038 } 6039 6040 if (!didSomething) { 6041 updateOomAdjLocked(); 6042 } 6043 6044 return true; 6045 } 6046 6047 @Override 6048 public final void attachApplication(IApplicationThread thread) { 6049 synchronized (this) { 6050 int callingPid = Binder.getCallingPid(); 6051 final long origId = Binder.clearCallingIdentity(); 6052 attachApplicationLocked(thread, callingPid); 6053 Binder.restoreCallingIdentity(origId); 6054 } 6055 } 6056 6057 @Override 6058 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6059 final long origId = Binder.clearCallingIdentity(); 6060 synchronized (this) { 6061 ActivityStack stack = ActivityRecord.getStackLocked(token); 6062 if (stack != null) { 6063 ActivityRecord r = 6064 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6065 if (stopProfiling) { 6066 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6067 try { 6068 mProfileFd.close(); 6069 } catch (IOException e) { 6070 } 6071 clearProfilerLocked(); 6072 } 6073 } 6074 } 6075 } 6076 Binder.restoreCallingIdentity(origId); 6077 } 6078 6079 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6080 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6081 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6082 } 6083 6084 void enableScreenAfterBoot() { 6085 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6086 SystemClock.uptimeMillis()); 6087 mWindowManager.enableScreenAfterBoot(); 6088 6089 synchronized (this) { 6090 updateEventDispatchingLocked(); 6091 } 6092 } 6093 6094 @Override 6095 public void showBootMessage(final CharSequence msg, final boolean always) { 6096 enforceNotIsolatedCaller("showBootMessage"); 6097 mWindowManager.showBootMessage(msg, always); 6098 } 6099 6100 @Override 6101 public void keyguardWaitingForActivityDrawn() { 6102 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6103 final long token = Binder.clearCallingIdentity(); 6104 try { 6105 synchronized (this) { 6106 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6107 mWindowManager.keyguardWaitingForActivityDrawn(); 6108 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6109 mLockScreenShown = LOCK_SCREEN_LEAVING; 6110 updateSleepIfNeededLocked(); 6111 } 6112 } 6113 } finally { 6114 Binder.restoreCallingIdentity(token); 6115 } 6116 } 6117 6118 final void finishBooting() { 6119 synchronized (this) { 6120 if (!mBootAnimationComplete) { 6121 mCallFinishBooting = true; 6122 return; 6123 } 6124 mCallFinishBooting = false; 6125 } 6126 6127 ArraySet<String> completedIsas = new ArraySet<String>(); 6128 for (String abi : Build.SUPPORTED_ABIS) { 6129 Process.establishZygoteConnectionForAbi(abi); 6130 final String instructionSet = VMRuntime.getInstructionSet(abi); 6131 if (!completedIsas.contains(instructionSet)) { 6132 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6133 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6134 } 6135 completedIsas.add(instructionSet); 6136 } 6137 } 6138 6139 IntentFilter pkgFilter = new IntentFilter(); 6140 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6141 pkgFilter.addDataScheme("package"); 6142 mContext.registerReceiver(new BroadcastReceiver() { 6143 @Override 6144 public void onReceive(Context context, Intent intent) { 6145 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6146 if (pkgs != null) { 6147 for (String pkg : pkgs) { 6148 synchronized (ActivityManagerService.this) { 6149 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6150 0, "finished booting")) { 6151 setResultCode(Activity.RESULT_OK); 6152 return; 6153 } 6154 } 6155 } 6156 } 6157 } 6158 }, pkgFilter); 6159 6160 // Let system services know. 6161 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6162 6163 synchronized (this) { 6164 // Ensure that any processes we had put on hold are now started 6165 // up. 6166 final int NP = mProcessesOnHold.size(); 6167 if (NP > 0) { 6168 ArrayList<ProcessRecord> procs = 6169 new ArrayList<ProcessRecord>(mProcessesOnHold); 6170 for (int ip=0; ip<NP; ip++) { 6171 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6172 + procs.get(ip)); 6173 startProcessLocked(procs.get(ip), "on-hold", null); 6174 } 6175 } 6176 6177 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6178 // Start looking for apps that are abusing wake locks. 6179 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6180 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6181 // Tell anyone interested that we are done booting! 6182 SystemProperties.set("sys.boot_completed", "1"); 6183 6184 // And trigger dev.bootcomplete if we are not showing encryption progress 6185 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6186 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6187 SystemProperties.set("dev.bootcomplete", "1"); 6188 } 6189 for (int i=0; i<mStartedUsers.size(); i++) { 6190 UserStartedState uss = mStartedUsers.valueAt(i); 6191 if (uss.mState == UserStartedState.STATE_BOOTING) { 6192 uss.mState = UserStartedState.STATE_RUNNING; 6193 final int userId = mStartedUsers.keyAt(i); 6194 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6195 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6196 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6197 broadcastIntentLocked(null, null, intent, null, 6198 new IIntentReceiver.Stub() { 6199 @Override 6200 public void performReceive(Intent intent, int resultCode, 6201 String data, Bundle extras, boolean ordered, 6202 boolean sticky, int sendingUser) { 6203 synchronized (ActivityManagerService.this) { 6204 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6205 true, false); 6206 } 6207 } 6208 }, 6209 0, null, null, 6210 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6211 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6212 userId); 6213 } 6214 } 6215 scheduleStartProfilesLocked(); 6216 } 6217 } 6218 } 6219 6220 @Override 6221 public void bootAnimationComplete() { 6222 final boolean callFinishBooting; 6223 synchronized (this) { 6224 callFinishBooting = mCallFinishBooting; 6225 mBootAnimationComplete = true; 6226 } 6227 if (callFinishBooting) { 6228 finishBooting(); 6229 } 6230 } 6231 6232 @Override 6233 public void systemBackupRestored() { 6234 synchronized (this) { 6235 if (mSystemReady) { 6236 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6237 } else { 6238 Slog.w(TAG, "System backup restored before system is ready"); 6239 } 6240 } 6241 } 6242 6243 final void ensureBootCompleted() { 6244 boolean booting; 6245 boolean enableScreen; 6246 synchronized (this) { 6247 booting = mBooting; 6248 mBooting = false; 6249 enableScreen = !mBooted; 6250 mBooted = true; 6251 } 6252 6253 if (booting) { 6254 finishBooting(); 6255 } 6256 6257 if (enableScreen) { 6258 enableScreenAfterBoot(); 6259 } 6260 } 6261 6262 @Override 6263 public final void activityResumed(IBinder token) { 6264 final long origId = Binder.clearCallingIdentity(); 6265 synchronized(this) { 6266 ActivityStack stack = ActivityRecord.getStackLocked(token); 6267 if (stack != null) { 6268 ActivityRecord.activityResumedLocked(token); 6269 } 6270 } 6271 Binder.restoreCallingIdentity(origId); 6272 } 6273 6274 @Override 6275 public final void activityPaused(IBinder token) { 6276 final long origId = Binder.clearCallingIdentity(); 6277 synchronized(this) { 6278 ActivityStack stack = ActivityRecord.getStackLocked(token); 6279 if (stack != null) { 6280 stack.activityPausedLocked(token, false); 6281 } 6282 } 6283 Binder.restoreCallingIdentity(origId); 6284 } 6285 6286 @Override 6287 public final void activityStopped(IBinder token, Bundle icicle, 6288 PersistableBundle persistentState, CharSequence description) { 6289 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6290 6291 // Refuse possible leaked file descriptors 6292 if (icicle != null && icicle.hasFileDescriptors()) { 6293 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6294 } 6295 6296 final long origId = Binder.clearCallingIdentity(); 6297 6298 synchronized (this) { 6299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6300 if (r != null) { 6301 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6302 } 6303 } 6304 6305 trimApplications(); 6306 6307 Binder.restoreCallingIdentity(origId); 6308 } 6309 6310 @Override 6311 public final void activityDestroyed(IBinder token) { 6312 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6313 synchronized (this) { 6314 ActivityStack stack = ActivityRecord.getStackLocked(token); 6315 if (stack != null) { 6316 stack.activityDestroyedLocked(token); 6317 } 6318 } 6319 } 6320 6321 @Override 6322 public final void backgroundResourcesReleased(IBinder token) { 6323 final long origId = Binder.clearCallingIdentity(); 6324 try { 6325 synchronized (this) { 6326 ActivityStack stack = ActivityRecord.getStackLocked(token); 6327 if (stack != null) { 6328 stack.backgroundResourcesReleased(); 6329 } 6330 } 6331 } finally { 6332 Binder.restoreCallingIdentity(origId); 6333 } 6334 } 6335 6336 @Override 6337 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6338 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6339 } 6340 6341 @Override 6342 public final void notifyEnterAnimationComplete(IBinder token) { 6343 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6344 } 6345 6346 @Override 6347 public String getCallingPackage(IBinder token) { 6348 synchronized (this) { 6349 ActivityRecord r = getCallingRecordLocked(token); 6350 return r != null ? r.info.packageName : null; 6351 } 6352 } 6353 6354 @Override 6355 public ComponentName getCallingActivity(IBinder token) { 6356 synchronized (this) { 6357 ActivityRecord r = getCallingRecordLocked(token); 6358 return r != null ? r.intent.getComponent() : null; 6359 } 6360 } 6361 6362 private ActivityRecord getCallingRecordLocked(IBinder token) { 6363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6364 if (r == null) { 6365 return null; 6366 } 6367 return r.resultTo; 6368 } 6369 6370 @Override 6371 public ComponentName getActivityClassForToken(IBinder token) { 6372 synchronized(this) { 6373 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6374 if (r == null) { 6375 return null; 6376 } 6377 return r.intent.getComponent(); 6378 } 6379 } 6380 6381 @Override 6382 public String getPackageForToken(IBinder token) { 6383 synchronized(this) { 6384 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6385 if (r == null) { 6386 return null; 6387 } 6388 return r.packageName; 6389 } 6390 } 6391 6392 @Override 6393 public IIntentSender getIntentSender(int type, 6394 String packageName, IBinder token, String resultWho, 6395 int requestCode, Intent[] intents, String[] resolvedTypes, 6396 int flags, Bundle options, int userId) { 6397 enforceNotIsolatedCaller("getIntentSender"); 6398 // Refuse possible leaked file descriptors 6399 if (intents != null) { 6400 if (intents.length < 1) { 6401 throw new IllegalArgumentException("Intents array length must be >= 1"); 6402 } 6403 for (int i=0; i<intents.length; i++) { 6404 Intent intent = intents[i]; 6405 if (intent != null) { 6406 if (intent.hasFileDescriptors()) { 6407 throw new IllegalArgumentException("File descriptors passed in Intent"); 6408 } 6409 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6410 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6411 throw new IllegalArgumentException( 6412 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6413 } 6414 intents[i] = new Intent(intent); 6415 } 6416 } 6417 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6418 throw new IllegalArgumentException( 6419 "Intent array length does not match resolvedTypes length"); 6420 } 6421 } 6422 if (options != null) { 6423 if (options.hasFileDescriptors()) { 6424 throw new IllegalArgumentException("File descriptors passed in options"); 6425 } 6426 } 6427 6428 synchronized(this) { 6429 int callingUid = Binder.getCallingUid(); 6430 int origUserId = userId; 6431 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6432 type == ActivityManager.INTENT_SENDER_BROADCAST, 6433 ALLOW_NON_FULL, "getIntentSender", null); 6434 if (origUserId == UserHandle.USER_CURRENT) { 6435 // We don't want to evaluate this until the pending intent is 6436 // actually executed. However, we do want to always do the 6437 // security checking for it above. 6438 userId = UserHandle.USER_CURRENT; 6439 } 6440 try { 6441 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6442 int uid = AppGlobals.getPackageManager() 6443 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6444 if (!UserHandle.isSameApp(callingUid, uid)) { 6445 String msg = "Permission Denial: getIntentSender() from pid=" 6446 + Binder.getCallingPid() 6447 + ", uid=" + Binder.getCallingUid() 6448 + ", (need uid=" + uid + ")" 6449 + " is not allowed to send as package " + packageName; 6450 Slog.w(TAG, msg); 6451 throw new SecurityException(msg); 6452 } 6453 } 6454 6455 return getIntentSenderLocked(type, packageName, callingUid, userId, 6456 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6457 6458 } catch (RemoteException e) { 6459 throw new SecurityException(e); 6460 } 6461 } 6462 } 6463 6464 IIntentSender getIntentSenderLocked(int type, String packageName, 6465 int callingUid, int userId, IBinder token, String resultWho, 6466 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6467 Bundle options) { 6468 if (DEBUG_MU) 6469 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6470 ActivityRecord activity = null; 6471 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6472 activity = ActivityRecord.isInStackLocked(token); 6473 if (activity == null) { 6474 return null; 6475 } 6476 if (activity.finishing) { 6477 return null; 6478 } 6479 } 6480 6481 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6482 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6483 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6484 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6485 |PendingIntent.FLAG_UPDATE_CURRENT); 6486 6487 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6488 type, packageName, activity, resultWho, 6489 requestCode, intents, resolvedTypes, flags, options, userId); 6490 WeakReference<PendingIntentRecord> ref; 6491 ref = mIntentSenderRecords.get(key); 6492 PendingIntentRecord rec = ref != null ? ref.get() : null; 6493 if (rec != null) { 6494 if (!cancelCurrent) { 6495 if (updateCurrent) { 6496 if (rec.key.requestIntent != null) { 6497 rec.key.requestIntent.replaceExtras(intents != null ? 6498 intents[intents.length - 1] : null); 6499 } 6500 if (intents != null) { 6501 intents[intents.length-1] = rec.key.requestIntent; 6502 rec.key.allIntents = intents; 6503 rec.key.allResolvedTypes = resolvedTypes; 6504 } else { 6505 rec.key.allIntents = null; 6506 rec.key.allResolvedTypes = null; 6507 } 6508 } 6509 return rec; 6510 } 6511 rec.canceled = true; 6512 mIntentSenderRecords.remove(key); 6513 } 6514 if (noCreate) { 6515 return rec; 6516 } 6517 rec = new PendingIntentRecord(this, key, callingUid); 6518 mIntentSenderRecords.put(key, rec.ref); 6519 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6520 if (activity.pendingResults == null) { 6521 activity.pendingResults 6522 = new HashSet<WeakReference<PendingIntentRecord>>(); 6523 } 6524 activity.pendingResults.add(rec.ref); 6525 } 6526 return rec; 6527 } 6528 6529 @Override 6530 public void cancelIntentSender(IIntentSender sender) { 6531 if (!(sender instanceof PendingIntentRecord)) { 6532 return; 6533 } 6534 synchronized(this) { 6535 PendingIntentRecord rec = (PendingIntentRecord)sender; 6536 try { 6537 int uid = AppGlobals.getPackageManager() 6538 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6539 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6540 String msg = "Permission Denial: cancelIntentSender() from pid=" 6541 + Binder.getCallingPid() 6542 + ", uid=" + Binder.getCallingUid() 6543 + " is not allowed to cancel packges " 6544 + rec.key.packageName; 6545 Slog.w(TAG, msg); 6546 throw new SecurityException(msg); 6547 } 6548 } catch (RemoteException e) { 6549 throw new SecurityException(e); 6550 } 6551 cancelIntentSenderLocked(rec, true); 6552 } 6553 } 6554 6555 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6556 rec.canceled = true; 6557 mIntentSenderRecords.remove(rec.key); 6558 if (cleanActivity && rec.key.activity != null) { 6559 rec.key.activity.pendingResults.remove(rec.ref); 6560 } 6561 } 6562 6563 @Override 6564 public String getPackageForIntentSender(IIntentSender pendingResult) { 6565 if (!(pendingResult instanceof PendingIntentRecord)) { 6566 return null; 6567 } 6568 try { 6569 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6570 return res.key.packageName; 6571 } catch (ClassCastException e) { 6572 } 6573 return null; 6574 } 6575 6576 @Override 6577 public int getUidForIntentSender(IIntentSender sender) { 6578 if (sender instanceof PendingIntentRecord) { 6579 try { 6580 PendingIntentRecord res = (PendingIntentRecord)sender; 6581 return res.uid; 6582 } catch (ClassCastException e) { 6583 } 6584 } 6585 return -1; 6586 } 6587 6588 @Override 6589 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6590 if (!(pendingResult instanceof PendingIntentRecord)) { 6591 return false; 6592 } 6593 try { 6594 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6595 if (res.key.allIntents == null) { 6596 return false; 6597 } 6598 for (int i=0; i<res.key.allIntents.length; i++) { 6599 Intent intent = res.key.allIntents[i]; 6600 if (intent.getPackage() != null && intent.getComponent() != null) { 6601 return false; 6602 } 6603 } 6604 return true; 6605 } catch (ClassCastException e) { 6606 } 6607 return false; 6608 } 6609 6610 @Override 6611 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6612 if (!(pendingResult instanceof PendingIntentRecord)) { 6613 return false; 6614 } 6615 try { 6616 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6617 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6618 return true; 6619 } 6620 return false; 6621 } catch (ClassCastException e) { 6622 } 6623 return false; 6624 } 6625 6626 @Override 6627 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6628 if (!(pendingResult instanceof PendingIntentRecord)) { 6629 return null; 6630 } 6631 try { 6632 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6633 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6634 } catch (ClassCastException e) { 6635 } 6636 return null; 6637 } 6638 6639 @Override 6640 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6641 if (!(pendingResult instanceof PendingIntentRecord)) { 6642 return null; 6643 } 6644 try { 6645 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6646 Intent intent = res.key.requestIntent; 6647 if (intent != null) { 6648 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6649 || res.lastTagPrefix.equals(prefix))) { 6650 return res.lastTag; 6651 } 6652 res.lastTagPrefix = prefix; 6653 StringBuilder sb = new StringBuilder(128); 6654 if (prefix != null) { 6655 sb.append(prefix); 6656 } 6657 if (intent.getAction() != null) { 6658 sb.append(intent.getAction()); 6659 } else if (intent.getComponent() != null) { 6660 intent.getComponent().appendShortString(sb); 6661 } else { 6662 sb.append("?"); 6663 } 6664 return res.lastTag = sb.toString(); 6665 } 6666 } catch (ClassCastException e) { 6667 } 6668 return null; 6669 } 6670 6671 @Override 6672 public void setProcessLimit(int max) { 6673 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6674 "setProcessLimit()"); 6675 synchronized (this) { 6676 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6677 mProcessLimitOverride = max; 6678 } 6679 trimApplications(); 6680 } 6681 6682 @Override 6683 public int getProcessLimit() { 6684 synchronized (this) { 6685 return mProcessLimitOverride; 6686 } 6687 } 6688 6689 void foregroundTokenDied(ForegroundToken token) { 6690 synchronized (ActivityManagerService.this) { 6691 synchronized (mPidsSelfLocked) { 6692 ForegroundToken cur 6693 = mForegroundProcesses.get(token.pid); 6694 if (cur != token) { 6695 return; 6696 } 6697 mForegroundProcesses.remove(token.pid); 6698 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6699 if (pr == null) { 6700 return; 6701 } 6702 pr.forcingToForeground = null; 6703 updateProcessForegroundLocked(pr, false, false); 6704 } 6705 updateOomAdjLocked(); 6706 } 6707 } 6708 6709 @Override 6710 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6711 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6712 "setProcessForeground()"); 6713 synchronized(this) { 6714 boolean changed = false; 6715 6716 synchronized (mPidsSelfLocked) { 6717 ProcessRecord pr = mPidsSelfLocked.get(pid); 6718 if (pr == null && isForeground) { 6719 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6720 return; 6721 } 6722 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6723 if (oldToken != null) { 6724 oldToken.token.unlinkToDeath(oldToken, 0); 6725 mForegroundProcesses.remove(pid); 6726 if (pr != null) { 6727 pr.forcingToForeground = null; 6728 } 6729 changed = true; 6730 } 6731 if (isForeground && token != null) { 6732 ForegroundToken newToken = new ForegroundToken() { 6733 @Override 6734 public void binderDied() { 6735 foregroundTokenDied(this); 6736 } 6737 }; 6738 newToken.pid = pid; 6739 newToken.token = token; 6740 try { 6741 token.linkToDeath(newToken, 0); 6742 mForegroundProcesses.put(pid, newToken); 6743 pr.forcingToForeground = token; 6744 changed = true; 6745 } catch (RemoteException e) { 6746 // If the process died while doing this, we will later 6747 // do the cleanup with the process death link. 6748 } 6749 } 6750 } 6751 6752 if (changed) { 6753 updateOomAdjLocked(); 6754 } 6755 } 6756 } 6757 6758 // ========================================================= 6759 // PERMISSIONS 6760 // ========================================================= 6761 6762 static class PermissionController extends IPermissionController.Stub { 6763 ActivityManagerService mActivityManagerService; 6764 PermissionController(ActivityManagerService activityManagerService) { 6765 mActivityManagerService = activityManagerService; 6766 } 6767 6768 @Override 6769 public boolean checkPermission(String permission, int pid, int uid) { 6770 return mActivityManagerService.checkPermission(permission, pid, 6771 uid) == PackageManager.PERMISSION_GRANTED; 6772 } 6773 } 6774 6775 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6776 @Override 6777 public int checkComponentPermission(String permission, int pid, int uid, 6778 int owningUid, boolean exported) { 6779 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6780 owningUid, exported); 6781 } 6782 6783 @Override 6784 public Object getAMSLock() { 6785 return ActivityManagerService.this; 6786 } 6787 } 6788 6789 /** 6790 * This can be called with or without the global lock held. 6791 */ 6792 int checkComponentPermission(String permission, int pid, int uid, 6793 int owningUid, boolean exported) { 6794 if (pid == MY_PID) { 6795 return PackageManager.PERMISSION_GRANTED; 6796 } 6797 return ActivityManager.checkComponentPermission(permission, uid, 6798 owningUid, exported); 6799 } 6800 6801 /** 6802 * As the only public entry point for permissions checking, this method 6803 * can enforce the semantic that requesting a check on a null global 6804 * permission is automatically denied. (Internally a null permission 6805 * string is used when calling {@link #checkComponentPermission} in cases 6806 * when only uid-based security is needed.) 6807 * 6808 * This can be called with or without the global lock held. 6809 */ 6810 @Override 6811 public int checkPermission(String permission, int pid, int uid) { 6812 if (permission == null) { 6813 return PackageManager.PERMISSION_DENIED; 6814 } 6815 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6816 } 6817 6818 @Override 6819 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6820 if (permission == null) { 6821 return PackageManager.PERMISSION_DENIED; 6822 } 6823 6824 // We might be performing an operation on behalf of an indirect binder 6825 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6826 // client identity accordingly before proceeding. 6827 Identity tlsIdentity = sCallerIdentity.get(); 6828 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6829 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6830 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6831 uid = tlsIdentity.uid; 6832 pid = tlsIdentity.pid; 6833 } 6834 6835 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6836 } 6837 6838 /** 6839 * Binder IPC calls go through the public entry point. 6840 * This can be called with or without the global lock held. 6841 */ 6842 int checkCallingPermission(String permission) { 6843 return checkPermission(permission, 6844 Binder.getCallingPid(), 6845 UserHandle.getAppId(Binder.getCallingUid())); 6846 } 6847 6848 /** 6849 * This can be called with or without the global lock held. 6850 */ 6851 void enforceCallingPermission(String permission, String func) { 6852 if (checkCallingPermission(permission) 6853 == PackageManager.PERMISSION_GRANTED) { 6854 return; 6855 } 6856 6857 String msg = "Permission Denial: " + func + " from pid=" 6858 + Binder.getCallingPid() 6859 + ", uid=" + Binder.getCallingUid() 6860 + " requires " + permission; 6861 Slog.w(TAG, msg); 6862 throw new SecurityException(msg); 6863 } 6864 6865 /** 6866 * Determine if UID is holding permissions required to access {@link Uri} in 6867 * the given {@link ProviderInfo}. Final permission checking is always done 6868 * in {@link ContentProvider}. 6869 */ 6870 private final boolean checkHoldingPermissionsLocked( 6871 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6872 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6873 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6874 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6875 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6876 != PERMISSION_GRANTED) { 6877 return false; 6878 } 6879 } 6880 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6881 } 6882 6883 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6884 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6885 if (pi.applicationInfo.uid == uid) { 6886 return true; 6887 } else if (!pi.exported) { 6888 return false; 6889 } 6890 6891 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6892 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6893 try { 6894 // check if target holds top-level <provider> permissions 6895 if (!readMet && pi.readPermission != null && considerUidPermissions 6896 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6897 readMet = true; 6898 } 6899 if (!writeMet && pi.writePermission != null && considerUidPermissions 6900 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6901 writeMet = true; 6902 } 6903 6904 // track if unprotected read/write is allowed; any denied 6905 // <path-permission> below removes this ability 6906 boolean allowDefaultRead = pi.readPermission == null; 6907 boolean allowDefaultWrite = pi.writePermission == null; 6908 6909 // check if target holds any <path-permission> that match uri 6910 final PathPermission[] pps = pi.pathPermissions; 6911 if (pps != null) { 6912 final String path = grantUri.uri.getPath(); 6913 int i = pps.length; 6914 while (i > 0 && (!readMet || !writeMet)) { 6915 i--; 6916 PathPermission pp = pps[i]; 6917 if (pp.match(path)) { 6918 if (!readMet) { 6919 final String pprperm = pp.getReadPermission(); 6920 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6921 + pprperm + " for " + pp.getPath() 6922 + ": match=" + pp.match(path) 6923 + " check=" + pm.checkUidPermission(pprperm, uid)); 6924 if (pprperm != null) { 6925 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6926 == PERMISSION_GRANTED) { 6927 readMet = true; 6928 } else { 6929 allowDefaultRead = false; 6930 } 6931 } 6932 } 6933 if (!writeMet) { 6934 final String ppwperm = pp.getWritePermission(); 6935 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6936 + ppwperm + " for " + pp.getPath() 6937 + ": match=" + pp.match(path) 6938 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6939 if (ppwperm != null) { 6940 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6941 == PERMISSION_GRANTED) { 6942 writeMet = true; 6943 } else { 6944 allowDefaultWrite = false; 6945 } 6946 } 6947 } 6948 } 6949 } 6950 } 6951 6952 // grant unprotected <provider> read/write, if not blocked by 6953 // <path-permission> above 6954 if (allowDefaultRead) readMet = true; 6955 if (allowDefaultWrite) writeMet = true; 6956 6957 } catch (RemoteException e) { 6958 return false; 6959 } 6960 6961 return readMet && writeMet; 6962 } 6963 6964 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6965 ProviderInfo pi = null; 6966 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6967 if (cpr != null) { 6968 pi = cpr.info; 6969 } else { 6970 try { 6971 pi = AppGlobals.getPackageManager().resolveContentProvider( 6972 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6973 } catch (RemoteException ex) { 6974 } 6975 } 6976 return pi; 6977 } 6978 6979 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6980 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6981 if (targetUris != null) { 6982 return targetUris.get(grantUri); 6983 } 6984 return null; 6985 } 6986 6987 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6988 String targetPkg, int targetUid, GrantUri grantUri) { 6989 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6990 if (targetUris == null) { 6991 targetUris = Maps.newArrayMap(); 6992 mGrantedUriPermissions.put(targetUid, targetUris); 6993 } 6994 6995 UriPermission perm = targetUris.get(grantUri); 6996 if (perm == null) { 6997 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6998 targetUris.put(grantUri, perm); 6999 } 7000 7001 return perm; 7002 } 7003 7004 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7005 final int modeFlags) { 7006 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7007 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7008 : UriPermission.STRENGTH_OWNED; 7009 7010 // Root gets to do everything. 7011 if (uid == 0) { 7012 return true; 7013 } 7014 7015 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7016 if (perms == null) return false; 7017 7018 // First look for exact match 7019 final UriPermission exactPerm = perms.get(grantUri); 7020 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7021 return true; 7022 } 7023 7024 // No exact match, look for prefixes 7025 final int N = perms.size(); 7026 for (int i = 0; i < N; i++) { 7027 final UriPermission perm = perms.valueAt(i); 7028 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7029 && perm.getStrength(modeFlags) >= minStrength) { 7030 return true; 7031 } 7032 } 7033 7034 return false; 7035 } 7036 7037 /** 7038 * @param uri This uri must NOT contain an embedded userId. 7039 * @param userId The userId in which the uri is to be resolved. 7040 */ 7041 @Override 7042 public int checkUriPermission(Uri uri, int pid, int uid, 7043 final int modeFlags, int userId, IBinder callerToken) { 7044 enforceNotIsolatedCaller("checkUriPermission"); 7045 7046 // Another redirected-binder-call permissions check as in 7047 // {@link checkPermissionWithToken}. 7048 Identity tlsIdentity = sCallerIdentity.get(); 7049 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7050 uid = tlsIdentity.uid; 7051 pid = tlsIdentity.pid; 7052 } 7053 7054 // Our own process gets to do everything. 7055 if (pid == MY_PID) { 7056 return PackageManager.PERMISSION_GRANTED; 7057 } 7058 synchronized (this) { 7059 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7060 ? PackageManager.PERMISSION_GRANTED 7061 : PackageManager.PERMISSION_DENIED; 7062 } 7063 } 7064 7065 /** 7066 * Check if the targetPkg can be granted permission to access uri by 7067 * the callingUid using the given modeFlags. Throws a security exception 7068 * if callingUid is not allowed to do this. Returns the uid of the target 7069 * if the URI permission grant should be performed; returns -1 if it is not 7070 * needed (for example targetPkg already has permission to access the URI). 7071 * If you already know the uid of the target, you can supply it in 7072 * lastTargetUid else set that to -1. 7073 */ 7074 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7075 final int modeFlags, int lastTargetUid) { 7076 if (!Intent.isAccessUriMode(modeFlags)) { 7077 return -1; 7078 } 7079 7080 if (targetPkg != null) { 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Checking grant " + targetPkg + " permission to " + grantUri); 7083 } 7084 7085 final IPackageManager pm = AppGlobals.getPackageManager(); 7086 7087 // If this is not a content: uri, we can't do anything with it. 7088 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7090 "Can't grant URI permission for non-content URI: " + grantUri); 7091 return -1; 7092 } 7093 7094 final String authority = grantUri.uri.getAuthority(); 7095 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7096 if (pi == null) { 7097 Slog.w(TAG, "No content provider found for permission check: " + 7098 grantUri.uri.toSafeString()); 7099 return -1; 7100 } 7101 7102 int targetUid = lastTargetUid; 7103 if (targetUid < 0 && targetPkg != null) { 7104 try { 7105 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7106 if (targetUid < 0) { 7107 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7108 "Can't grant URI permission no uid for: " + targetPkg); 7109 return -1; 7110 } 7111 } catch (RemoteException ex) { 7112 return -1; 7113 } 7114 } 7115 7116 if (targetUid >= 0) { 7117 // First... does the target actually need this permission? 7118 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7119 // No need to grant the target this permission. 7120 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7121 "Target " + targetPkg + " already has full permission to " + grantUri); 7122 return -1; 7123 } 7124 } else { 7125 // First... there is no target package, so can anyone access it? 7126 boolean allowed = pi.exported; 7127 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7128 if (pi.readPermission != null) { 7129 allowed = false; 7130 } 7131 } 7132 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7133 if (pi.writePermission != null) { 7134 allowed = false; 7135 } 7136 } 7137 if (allowed) { 7138 return -1; 7139 } 7140 } 7141 7142 /* There is a special cross user grant if: 7143 * - The target is on another user. 7144 * - Apps on the current user can access the uri without any uid permissions. 7145 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7146 * grant uri permissions. 7147 */ 7148 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7149 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7150 modeFlags, false /*without considering the uid permissions*/); 7151 7152 // Second... is the provider allowing granting of URI permissions? 7153 if (!specialCrossUserGrant) { 7154 if (!pi.grantUriPermissions) { 7155 throw new SecurityException("Provider " + pi.packageName 7156 + "/" + pi.name 7157 + " does not allow granting of Uri permissions (uri " 7158 + grantUri + ")"); 7159 } 7160 if (pi.uriPermissionPatterns != null) { 7161 final int N = pi.uriPermissionPatterns.length; 7162 boolean allowed = false; 7163 for (int i=0; i<N; i++) { 7164 if (pi.uriPermissionPatterns[i] != null 7165 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7166 allowed = true; 7167 break; 7168 } 7169 } 7170 if (!allowed) { 7171 throw new SecurityException("Provider " + pi.packageName 7172 + "/" + pi.name 7173 + " does not allow granting of permission to path of Uri " 7174 + grantUri); 7175 } 7176 } 7177 } 7178 7179 // Third... does the caller itself have permission to access 7180 // this uri? 7181 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7182 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7183 // Require they hold a strong enough Uri permission 7184 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7185 throw new SecurityException("Uid " + callingUid 7186 + " does not have permission to uri " + grantUri); 7187 } 7188 } 7189 } 7190 return targetUid; 7191 } 7192 7193 /** 7194 * @param uri This uri must NOT contain an embedded userId. 7195 * @param userId The userId in which the uri is to be resolved. 7196 */ 7197 @Override 7198 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7199 final int modeFlags, int userId) { 7200 enforceNotIsolatedCaller("checkGrantUriPermission"); 7201 synchronized(this) { 7202 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7203 new GrantUri(userId, uri, false), modeFlags, -1); 7204 } 7205 } 7206 7207 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7208 final int modeFlags, UriPermissionOwner owner) { 7209 if (!Intent.isAccessUriMode(modeFlags)) { 7210 return; 7211 } 7212 7213 // So here we are: the caller has the assumed permission 7214 // to the uri, and the target doesn't. Let's now give this to 7215 // the target. 7216 7217 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7218 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7219 7220 final String authority = grantUri.uri.getAuthority(); 7221 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7222 if (pi == null) { 7223 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7224 return; 7225 } 7226 7227 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7228 grantUri.prefix = true; 7229 } 7230 final UriPermission perm = findOrCreateUriPermissionLocked( 7231 pi.packageName, targetPkg, targetUid, grantUri); 7232 perm.grantModes(modeFlags, owner); 7233 } 7234 7235 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7236 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7237 if (targetPkg == null) { 7238 throw new NullPointerException("targetPkg"); 7239 } 7240 int targetUid; 7241 final IPackageManager pm = AppGlobals.getPackageManager(); 7242 try { 7243 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7244 } catch (RemoteException ex) { 7245 return; 7246 } 7247 7248 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7249 targetUid); 7250 if (targetUid < 0) { 7251 return; 7252 } 7253 7254 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7255 owner); 7256 } 7257 7258 static class NeededUriGrants extends ArrayList<GrantUri> { 7259 final String targetPkg; 7260 final int targetUid; 7261 final int flags; 7262 7263 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7264 this.targetPkg = targetPkg; 7265 this.targetUid = targetUid; 7266 this.flags = flags; 7267 } 7268 } 7269 7270 /** 7271 * Like checkGrantUriPermissionLocked, but takes an Intent. 7272 */ 7273 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7274 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7276 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7277 + " clip=" + (intent != null ? intent.getClipData() : null) 7278 + " from " + intent + "; flags=0x" 7279 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7280 7281 if (targetPkg == null) { 7282 throw new NullPointerException("targetPkg"); 7283 } 7284 7285 if (intent == null) { 7286 return null; 7287 } 7288 Uri data = intent.getData(); 7289 ClipData clip = intent.getClipData(); 7290 if (data == null && clip == null) { 7291 return null; 7292 } 7293 // Default userId for uris in the intent (if they don't specify it themselves) 7294 int contentUserHint = intent.getContentUserHint(); 7295 if (contentUserHint == UserHandle.USER_CURRENT) { 7296 contentUserHint = UserHandle.getUserId(callingUid); 7297 } 7298 final IPackageManager pm = AppGlobals.getPackageManager(); 7299 int targetUid; 7300 if (needed != null) { 7301 targetUid = needed.targetUid; 7302 } else { 7303 try { 7304 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7305 } catch (RemoteException ex) { 7306 return null; 7307 } 7308 if (targetUid < 0) { 7309 if (DEBUG_URI_PERMISSION) { 7310 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7311 + " on user " + targetUserId); 7312 } 7313 return null; 7314 } 7315 } 7316 if (data != null) { 7317 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7318 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7319 targetUid); 7320 if (targetUid > 0) { 7321 if (needed == null) { 7322 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7323 } 7324 needed.add(grantUri); 7325 } 7326 } 7327 if (clip != null) { 7328 for (int i=0; i<clip.getItemCount(); i++) { 7329 Uri uri = clip.getItemAt(i).getUri(); 7330 if (uri != null) { 7331 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7332 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7333 targetUid); 7334 if (targetUid > 0) { 7335 if (needed == null) { 7336 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7337 } 7338 needed.add(grantUri); 7339 } 7340 } else { 7341 Intent clipIntent = clip.getItemAt(i).getIntent(); 7342 if (clipIntent != null) { 7343 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7344 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7345 if (newNeeded != null) { 7346 needed = newNeeded; 7347 } 7348 } 7349 } 7350 } 7351 } 7352 7353 return needed; 7354 } 7355 7356 /** 7357 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7358 */ 7359 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7360 UriPermissionOwner owner) { 7361 if (needed != null) { 7362 for (int i=0; i<needed.size(); i++) { 7363 GrantUri grantUri = needed.get(i); 7364 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7365 grantUri, needed.flags, owner); 7366 } 7367 } 7368 } 7369 7370 void grantUriPermissionFromIntentLocked(int callingUid, 7371 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7372 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7373 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7374 if (needed == null) { 7375 return; 7376 } 7377 7378 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7379 } 7380 7381 /** 7382 * @param uri This uri must NOT contain an embedded userId. 7383 * @param userId The userId in which the uri is to be resolved. 7384 */ 7385 @Override 7386 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7387 final int modeFlags, int userId) { 7388 enforceNotIsolatedCaller("grantUriPermission"); 7389 GrantUri grantUri = new GrantUri(userId, uri, false); 7390 synchronized(this) { 7391 final ProcessRecord r = getRecordForAppLocked(caller); 7392 if (r == null) { 7393 throw new SecurityException("Unable to find app for caller " 7394 + caller 7395 + " when granting permission to uri " + grantUri); 7396 } 7397 if (targetPkg == null) { 7398 throw new IllegalArgumentException("null target"); 7399 } 7400 if (grantUri == null) { 7401 throw new IllegalArgumentException("null uri"); 7402 } 7403 7404 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7405 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7406 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7407 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7408 7409 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7410 UserHandle.getUserId(r.uid)); 7411 } 7412 } 7413 7414 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7415 if (perm.modeFlags == 0) { 7416 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7417 perm.targetUid); 7418 if (perms != null) { 7419 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7420 "Removing " + perm.targetUid + " permission to " + perm.uri); 7421 7422 perms.remove(perm.uri); 7423 if (perms.isEmpty()) { 7424 mGrantedUriPermissions.remove(perm.targetUid); 7425 } 7426 } 7427 } 7428 } 7429 7430 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7431 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7432 7433 final IPackageManager pm = AppGlobals.getPackageManager(); 7434 final String authority = grantUri.uri.getAuthority(); 7435 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7436 if (pi == null) { 7437 Slog.w(TAG, "No content provider found for permission revoke: " 7438 + grantUri.toSafeString()); 7439 return; 7440 } 7441 7442 // Does the caller have this permission on the URI? 7443 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7444 // If they don't have direct access to the URI, then revoke any 7445 // ownerless URI permissions that have been granted to them. 7446 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7447 if (perms != null) { 7448 boolean persistChanged = false; 7449 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7450 final UriPermission perm = it.next(); 7451 if (perm.uri.sourceUserId == grantUri.sourceUserId 7452 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7453 if (DEBUG_URI_PERMISSION) 7454 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7455 " permission to " + perm.uri); 7456 persistChanged |= perm.revokeModes( 7457 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7458 if (perm.modeFlags == 0) { 7459 it.remove(); 7460 } 7461 } 7462 } 7463 if (perms.isEmpty()) { 7464 mGrantedUriPermissions.remove(callingUid); 7465 } 7466 if (persistChanged) { 7467 schedulePersistUriGrants(); 7468 } 7469 } 7470 return; 7471 } 7472 7473 boolean persistChanged = false; 7474 7475 // Go through all of the permissions and remove any that match. 7476 int N = mGrantedUriPermissions.size(); 7477 for (int i = 0; i < N; i++) { 7478 final int targetUid = mGrantedUriPermissions.keyAt(i); 7479 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7480 7481 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7482 final UriPermission perm = it.next(); 7483 if (perm.uri.sourceUserId == grantUri.sourceUserId 7484 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7485 if (DEBUG_URI_PERMISSION) 7486 Slog.v(TAG, 7487 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7488 persistChanged |= perm.revokeModes( 7489 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7490 if (perm.modeFlags == 0) { 7491 it.remove(); 7492 } 7493 } 7494 } 7495 7496 if (perms.isEmpty()) { 7497 mGrantedUriPermissions.remove(targetUid); 7498 N--; 7499 i--; 7500 } 7501 } 7502 7503 if (persistChanged) { 7504 schedulePersistUriGrants(); 7505 } 7506 } 7507 7508 /** 7509 * @param uri This uri must NOT contain an embedded userId. 7510 * @param userId The userId in which the uri is to be resolved. 7511 */ 7512 @Override 7513 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7514 int userId) { 7515 enforceNotIsolatedCaller("revokeUriPermission"); 7516 synchronized(this) { 7517 final ProcessRecord r = getRecordForAppLocked(caller); 7518 if (r == null) { 7519 throw new SecurityException("Unable to find app for caller " 7520 + caller 7521 + " when revoking permission to uri " + uri); 7522 } 7523 if (uri == null) { 7524 Slog.w(TAG, "revokeUriPermission: null uri"); 7525 return; 7526 } 7527 7528 if (!Intent.isAccessUriMode(modeFlags)) { 7529 return; 7530 } 7531 7532 final IPackageManager pm = AppGlobals.getPackageManager(); 7533 final String authority = uri.getAuthority(); 7534 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7535 if (pi == null) { 7536 Slog.w(TAG, "No content provider found for permission revoke: " 7537 + uri.toSafeString()); 7538 return; 7539 } 7540 7541 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7542 } 7543 } 7544 7545 /** 7546 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7547 * given package. 7548 * 7549 * @param packageName Package name to match, or {@code null} to apply to all 7550 * packages. 7551 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7552 * to all users. 7553 * @param persistable If persistable grants should be removed. 7554 */ 7555 private void removeUriPermissionsForPackageLocked( 7556 String packageName, int userHandle, boolean persistable) { 7557 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7558 throw new IllegalArgumentException("Must narrow by either package or user"); 7559 } 7560 7561 boolean persistChanged = false; 7562 7563 int N = mGrantedUriPermissions.size(); 7564 for (int i = 0; i < N; i++) { 7565 final int targetUid = mGrantedUriPermissions.keyAt(i); 7566 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7567 7568 // Only inspect grants matching user 7569 if (userHandle == UserHandle.USER_ALL 7570 || userHandle == UserHandle.getUserId(targetUid)) { 7571 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7572 final UriPermission perm = it.next(); 7573 7574 // Only inspect grants matching package 7575 if (packageName == null || perm.sourcePkg.equals(packageName) 7576 || perm.targetPkg.equals(packageName)) { 7577 persistChanged |= perm.revokeModes(persistable 7578 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7579 7580 // Only remove when no modes remain; any persisted grants 7581 // will keep this alive. 7582 if (perm.modeFlags == 0) { 7583 it.remove(); 7584 } 7585 } 7586 } 7587 7588 if (perms.isEmpty()) { 7589 mGrantedUriPermissions.remove(targetUid); 7590 N--; 7591 i--; 7592 } 7593 } 7594 } 7595 7596 if (persistChanged) { 7597 schedulePersistUriGrants(); 7598 } 7599 } 7600 7601 @Override 7602 public IBinder newUriPermissionOwner(String name) { 7603 enforceNotIsolatedCaller("newUriPermissionOwner"); 7604 synchronized(this) { 7605 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7606 return owner.getExternalTokenLocked(); 7607 } 7608 } 7609 7610 /** 7611 * @param uri This uri must NOT contain an embedded userId. 7612 * @param sourceUserId The userId in which the uri is to be resolved. 7613 * @param targetUserId The userId of the app that receives the grant. 7614 */ 7615 @Override 7616 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7617 final int modeFlags, int sourceUserId, int targetUserId) { 7618 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7619 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7620 synchronized(this) { 7621 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7622 if (owner == null) { 7623 throw new IllegalArgumentException("Unknown owner: " + token); 7624 } 7625 if (fromUid != Binder.getCallingUid()) { 7626 if (Binder.getCallingUid() != Process.myUid()) { 7627 // Only system code can grant URI permissions on behalf 7628 // of other users. 7629 throw new SecurityException("nice try"); 7630 } 7631 } 7632 if (targetPkg == null) { 7633 throw new IllegalArgumentException("null target"); 7634 } 7635 if (uri == null) { 7636 throw new IllegalArgumentException("null uri"); 7637 } 7638 7639 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7640 modeFlags, owner, targetUserId); 7641 } 7642 } 7643 7644 /** 7645 * @param uri This uri must NOT contain an embedded userId. 7646 * @param userId The userId in which the uri is to be resolved. 7647 */ 7648 @Override 7649 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7650 synchronized(this) { 7651 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7652 if (owner == null) { 7653 throw new IllegalArgumentException("Unknown owner: " + token); 7654 } 7655 7656 if (uri == null) { 7657 owner.removeUriPermissionsLocked(mode); 7658 } else { 7659 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7660 } 7661 } 7662 } 7663 7664 private void schedulePersistUriGrants() { 7665 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7666 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7667 10 * DateUtils.SECOND_IN_MILLIS); 7668 } 7669 } 7670 7671 private void writeGrantedUriPermissions() { 7672 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7673 7674 // Snapshot permissions so we can persist without lock 7675 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7676 synchronized (this) { 7677 final int size = mGrantedUriPermissions.size(); 7678 for (int i = 0; i < size; i++) { 7679 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7680 for (UriPermission perm : perms.values()) { 7681 if (perm.persistedModeFlags != 0) { 7682 persist.add(perm.snapshot()); 7683 } 7684 } 7685 } 7686 } 7687 7688 FileOutputStream fos = null; 7689 try { 7690 fos = mGrantFile.startWrite(); 7691 7692 XmlSerializer out = new FastXmlSerializer(); 7693 out.setOutput(fos, "utf-8"); 7694 out.startDocument(null, true); 7695 out.startTag(null, TAG_URI_GRANTS); 7696 for (UriPermission.Snapshot perm : persist) { 7697 out.startTag(null, TAG_URI_GRANT); 7698 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7699 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7700 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7701 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7702 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7703 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7704 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7705 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7706 out.endTag(null, TAG_URI_GRANT); 7707 } 7708 out.endTag(null, TAG_URI_GRANTS); 7709 out.endDocument(); 7710 7711 mGrantFile.finishWrite(fos); 7712 } catch (IOException e) { 7713 if (fos != null) { 7714 mGrantFile.failWrite(fos); 7715 } 7716 } 7717 } 7718 7719 private void readGrantedUriPermissionsLocked() { 7720 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7721 7722 final long now = System.currentTimeMillis(); 7723 7724 FileInputStream fis = null; 7725 try { 7726 fis = mGrantFile.openRead(); 7727 final XmlPullParser in = Xml.newPullParser(); 7728 in.setInput(fis, null); 7729 7730 int type; 7731 while ((type = in.next()) != END_DOCUMENT) { 7732 final String tag = in.getName(); 7733 if (type == START_TAG) { 7734 if (TAG_URI_GRANT.equals(tag)) { 7735 final int sourceUserId; 7736 final int targetUserId; 7737 final int userHandle = readIntAttribute(in, 7738 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7739 if (userHandle != UserHandle.USER_NULL) { 7740 // For backwards compatibility. 7741 sourceUserId = userHandle; 7742 targetUserId = userHandle; 7743 } else { 7744 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7745 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7746 } 7747 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7748 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7749 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7750 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7751 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7752 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7753 7754 // Sanity check that provider still belongs to source package 7755 final ProviderInfo pi = getProviderInfoLocked( 7756 uri.getAuthority(), sourceUserId); 7757 if (pi != null && sourcePkg.equals(pi.packageName)) { 7758 int targetUid = -1; 7759 try { 7760 targetUid = AppGlobals.getPackageManager() 7761 .getPackageUid(targetPkg, targetUserId); 7762 } catch (RemoteException e) { 7763 } 7764 if (targetUid != -1) { 7765 final UriPermission perm = findOrCreateUriPermissionLocked( 7766 sourcePkg, targetPkg, targetUid, 7767 new GrantUri(sourceUserId, uri, prefix)); 7768 perm.initPersistedModes(modeFlags, createdTime); 7769 } 7770 } else { 7771 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7772 + " but instead found " + pi); 7773 } 7774 } 7775 } 7776 } 7777 } catch (FileNotFoundException e) { 7778 // Missing grants is okay 7779 } catch (IOException e) { 7780 Slog.wtf(TAG, "Failed reading Uri grants", e); 7781 } catch (XmlPullParserException e) { 7782 Slog.wtf(TAG, "Failed reading Uri grants", e); 7783 } finally { 7784 IoUtils.closeQuietly(fis); 7785 } 7786 } 7787 7788 /** 7789 * @param uri This uri must NOT contain an embedded userId. 7790 * @param userId The userId in which the uri is to be resolved. 7791 */ 7792 @Override 7793 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7794 enforceNotIsolatedCaller("takePersistableUriPermission"); 7795 7796 Preconditions.checkFlagsArgument(modeFlags, 7797 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7798 7799 synchronized (this) { 7800 final int callingUid = Binder.getCallingUid(); 7801 boolean persistChanged = false; 7802 GrantUri grantUri = new GrantUri(userId, uri, false); 7803 7804 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7805 new GrantUri(userId, uri, false)); 7806 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7807 new GrantUri(userId, uri, true)); 7808 7809 final boolean exactValid = (exactPerm != null) 7810 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7811 final boolean prefixValid = (prefixPerm != null) 7812 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7813 7814 if (!(exactValid || prefixValid)) { 7815 throw new SecurityException("No persistable permission grants found for UID " 7816 + callingUid + " and Uri " + grantUri.toSafeString()); 7817 } 7818 7819 if (exactValid) { 7820 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7821 } 7822 if (prefixValid) { 7823 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7824 } 7825 7826 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7827 7828 if (persistChanged) { 7829 schedulePersistUriGrants(); 7830 } 7831 } 7832 } 7833 7834 /** 7835 * @param uri This uri must NOT contain an embedded userId. 7836 * @param userId The userId in which the uri is to be resolved. 7837 */ 7838 @Override 7839 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7840 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7841 7842 Preconditions.checkFlagsArgument(modeFlags, 7843 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7844 7845 synchronized (this) { 7846 final int callingUid = Binder.getCallingUid(); 7847 boolean persistChanged = false; 7848 7849 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7850 new GrantUri(userId, uri, false)); 7851 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7852 new GrantUri(userId, uri, true)); 7853 if (exactPerm == null && prefixPerm == null) { 7854 throw new SecurityException("No permission grants found for UID " + callingUid 7855 + " and Uri " + uri.toSafeString()); 7856 } 7857 7858 if (exactPerm != null) { 7859 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7860 removeUriPermissionIfNeededLocked(exactPerm); 7861 } 7862 if (prefixPerm != null) { 7863 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7864 removeUriPermissionIfNeededLocked(prefixPerm); 7865 } 7866 7867 if (persistChanged) { 7868 schedulePersistUriGrants(); 7869 } 7870 } 7871 } 7872 7873 /** 7874 * Prune any older {@link UriPermission} for the given UID until outstanding 7875 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7876 * 7877 * @return if any mutations occured that require persisting. 7878 */ 7879 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7880 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7881 if (perms == null) return false; 7882 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7883 7884 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7885 for (UriPermission perm : perms.values()) { 7886 if (perm.persistedModeFlags != 0) { 7887 persisted.add(perm); 7888 } 7889 } 7890 7891 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7892 if (trimCount <= 0) return false; 7893 7894 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7895 for (int i = 0; i < trimCount; i++) { 7896 final UriPermission perm = persisted.get(i); 7897 7898 if (DEBUG_URI_PERMISSION) { 7899 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7900 } 7901 7902 perm.releasePersistableModes(~0); 7903 removeUriPermissionIfNeededLocked(perm); 7904 } 7905 7906 return true; 7907 } 7908 7909 @Override 7910 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7911 String packageName, boolean incoming) { 7912 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7913 Preconditions.checkNotNull(packageName, "packageName"); 7914 7915 final int callingUid = Binder.getCallingUid(); 7916 final IPackageManager pm = AppGlobals.getPackageManager(); 7917 try { 7918 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7919 if (packageUid != callingUid) { 7920 throw new SecurityException( 7921 "Package " + packageName + " does not belong to calling UID " + callingUid); 7922 } 7923 } catch (RemoteException e) { 7924 throw new SecurityException("Failed to verify package name ownership"); 7925 } 7926 7927 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7928 synchronized (this) { 7929 if (incoming) { 7930 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7931 callingUid); 7932 if (perms == null) { 7933 Slog.w(TAG, "No permission grants found for " + packageName); 7934 } else { 7935 for (UriPermission perm : perms.values()) { 7936 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7937 result.add(perm.buildPersistedPublicApiObject()); 7938 } 7939 } 7940 } 7941 } else { 7942 final int size = mGrantedUriPermissions.size(); 7943 for (int i = 0; i < size; i++) { 7944 final ArrayMap<GrantUri, UriPermission> perms = 7945 mGrantedUriPermissions.valueAt(i); 7946 for (UriPermission perm : perms.values()) { 7947 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7948 result.add(perm.buildPersistedPublicApiObject()); 7949 } 7950 } 7951 } 7952 } 7953 } 7954 return new ParceledListSlice<android.content.UriPermission>(result); 7955 } 7956 7957 @Override 7958 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7959 synchronized (this) { 7960 ProcessRecord app = 7961 who != null ? getRecordForAppLocked(who) : null; 7962 if (app == null) return; 7963 7964 Message msg = Message.obtain(); 7965 msg.what = WAIT_FOR_DEBUGGER_MSG; 7966 msg.obj = app; 7967 msg.arg1 = waiting ? 1 : 0; 7968 mHandler.sendMessage(msg); 7969 } 7970 } 7971 7972 @Override 7973 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7974 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7975 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7976 outInfo.availMem = Process.getFreeMemory(); 7977 outInfo.totalMem = Process.getTotalMemory(); 7978 outInfo.threshold = homeAppMem; 7979 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7980 outInfo.hiddenAppThreshold = cachedAppMem; 7981 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7982 ProcessList.SERVICE_ADJ); 7983 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7984 ProcessList.VISIBLE_APP_ADJ); 7985 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7986 ProcessList.FOREGROUND_APP_ADJ); 7987 } 7988 7989 // ========================================================= 7990 // TASK MANAGEMENT 7991 // ========================================================= 7992 7993 @Override 7994 public List<IAppTask> getAppTasks(String callingPackage) { 7995 int callingUid = Binder.getCallingUid(); 7996 long ident = Binder.clearCallingIdentity(); 7997 7998 synchronized(this) { 7999 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8000 try { 8001 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8002 8003 final int N = mRecentTasks.size(); 8004 for (int i = 0; i < N; i++) { 8005 TaskRecord tr = mRecentTasks.get(i); 8006 // Skip tasks that do not match the caller. We don't need to verify 8007 // callingPackage, because we are also limiting to callingUid and know 8008 // that will limit to the correct security sandbox. 8009 if (tr.effectiveUid != callingUid) { 8010 continue; 8011 } 8012 Intent intent = tr.getBaseIntent(); 8013 if (intent == null || 8014 !callingPackage.equals(intent.getComponent().getPackageName())) { 8015 continue; 8016 } 8017 ActivityManager.RecentTaskInfo taskInfo = 8018 createRecentTaskInfoFromTaskRecord(tr); 8019 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8020 list.add(taskImpl); 8021 } 8022 } finally { 8023 Binder.restoreCallingIdentity(ident); 8024 } 8025 return list; 8026 } 8027 } 8028 8029 @Override 8030 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8031 final int callingUid = Binder.getCallingUid(); 8032 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8033 8034 synchronized(this) { 8035 if (localLOGV) Slog.v( 8036 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8037 8038 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8039 callingUid); 8040 8041 // TODO: Improve with MRU list from all ActivityStacks. 8042 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8043 } 8044 8045 return list; 8046 } 8047 8048 /** 8049 * Creates a new RecentTaskInfo from a TaskRecord. 8050 */ 8051 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8052 // Update the task description to reflect any changes in the task stack 8053 tr.updateTaskDescription(); 8054 8055 // Compose the recent task info 8056 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8057 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8058 rti.persistentId = tr.taskId; 8059 rti.baseIntent = new Intent(tr.getBaseIntent()); 8060 rti.origActivity = tr.origActivity; 8061 rti.description = tr.lastDescription; 8062 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8063 rti.userId = tr.userId; 8064 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8065 rti.firstActiveTime = tr.firstActiveTime; 8066 rti.lastActiveTime = tr.lastActiveTime; 8067 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8068 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8069 return rti; 8070 } 8071 8072 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8073 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8074 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8075 if (!allowed) { 8076 if (checkPermission(android.Manifest.permission.GET_TASKS, 8077 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8078 // Temporary compatibility: some existing apps on the system image may 8079 // still be requesting the old permission and not switched to the new 8080 // one; if so, we'll still allow them full access. This means we need 8081 // to see if they are holding the old permission and are a system app. 8082 try { 8083 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8084 allowed = true; 8085 Slog.w(TAG, caller + ": caller " + callingUid 8086 + " is using old GET_TASKS but privileged; allowing"); 8087 } 8088 } catch (RemoteException e) { 8089 } 8090 } 8091 } 8092 if (!allowed) { 8093 Slog.w(TAG, caller + ": caller " + callingUid 8094 + " does not hold GET_TASKS; limiting output"); 8095 } 8096 return allowed; 8097 } 8098 8099 @Override 8100 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8101 final int callingUid = Binder.getCallingUid(); 8102 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8103 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8104 8105 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8106 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8107 synchronized (this) { 8108 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8109 callingUid); 8110 final boolean detailed = checkCallingPermission( 8111 android.Manifest.permission.GET_DETAILED_TASKS) 8112 == PackageManager.PERMISSION_GRANTED; 8113 8114 final int N = mRecentTasks.size(); 8115 ArrayList<ActivityManager.RecentTaskInfo> res 8116 = new ArrayList<ActivityManager.RecentTaskInfo>( 8117 maxNum < N ? maxNum : N); 8118 8119 final Set<Integer> includedUsers; 8120 if (includeProfiles) { 8121 includedUsers = getProfileIdsLocked(userId); 8122 } else { 8123 includedUsers = new HashSet<Integer>(); 8124 } 8125 includedUsers.add(Integer.valueOf(userId)); 8126 8127 for (int i=0; i<N && maxNum > 0; i++) { 8128 TaskRecord tr = mRecentTasks.get(i); 8129 // Only add calling user or related users recent tasks 8130 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8131 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8132 continue; 8133 } 8134 8135 // Return the entry if desired by the caller. We always return 8136 // the first entry, because callers always expect this to be the 8137 // foreground app. We may filter others if the caller has 8138 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8139 // we should exclude the entry. 8140 8141 if (i == 0 8142 || withExcluded 8143 || (tr.intent == null) 8144 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8145 == 0)) { 8146 if (!allowed) { 8147 // If the caller doesn't have the GET_TASKS permission, then only 8148 // allow them to see a small subset of tasks -- their own and home. 8149 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8150 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8151 continue; 8152 } 8153 } 8154 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8155 if (tr.stack != null && tr.stack.isHomeStack()) { 8156 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8157 continue; 8158 } 8159 } 8160 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8161 // Don't include auto remove tasks that are finished or finishing. 8162 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8163 + tr); 8164 continue; 8165 } 8166 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8167 && !tr.isAvailable) { 8168 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8169 continue; 8170 } 8171 8172 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8173 if (!detailed) { 8174 rti.baseIntent.replaceExtras((Bundle)null); 8175 } 8176 8177 res.add(rti); 8178 maxNum--; 8179 } 8180 } 8181 return res; 8182 } 8183 } 8184 8185 TaskRecord recentTaskForIdLocked(int id) { 8186 final int N = mRecentTasks.size(); 8187 for (int i=0; i<N; i++) { 8188 TaskRecord tr = mRecentTasks.get(i); 8189 if (tr.taskId == id) { 8190 return tr; 8191 } 8192 } 8193 return null; 8194 } 8195 8196 @Override 8197 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8198 synchronized (this) { 8199 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8200 "getTaskThumbnail()"); 8201 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8202 if (tr != null) { 8203 return tr.getTaskThumbnailLocked(); 8204 } 8205 } 8206 return null; 8207 } 8208 8209 @Override 8210 public int addAppTask(IBinder activityToken, Intent intent, 8211 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8212 final int callingUid = Binder.getCallingUid(); 8213 final long callingIdent = Binder.clearCallingIdentity(); 8214 8215 try { 8216 synchronized (this) { 8217 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8218 if (r == null) { 8219 throw new IllegalArgumentException("Activity does not exist; token=" 8220 + activityToken); 8221 } 8222 ComponentName comp = intent.getComponent(); 8223 if (comp == null) { 8224 throw new IllegalArgumentException("Intent " + intent 8225 + " must specify explicit component"); 8226 } 8227 if (thumbnail.getWidth() != mThumbnailWidth 8228 || thumbnail.getHeight() != mThumbnailHeight) { 8229 throw new IllegalArgumentException("Bad thumbnail size: got " 8230 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8231 + mThumbnailWidth + "x" + mThumbnailHeight); 8232 } 8233 if (intent.getSelector() != null) { 8234 intent.setSelector(null); 8235 } 8236 if (intent.getSourceBounds() != null) { 8237 intent.setSourceBounds(null); 8238 } 8239 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8240 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8241 // The caller has added this as an auto-remove task... that makes no 8242 // sense, so turn off auto-remove. 8243 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8244 } 8245 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8246 // Must be a new task. 8247 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8248 } 8249 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8250 mLastAddedTaskActivity = null; 8251 } 8252 ActivityInfo ainfo = mLastAddedTaskActivity; 8253 if (ainfo == null) { 8254 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8255 comp, 0, UserHandle.getUserId(callingUid)); 8256 if (ainfo.applicationInfo.uid != callingUid) { 8257 throw new SecurityException( 8258 "Can't add task for another application: target uid=" 8259 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8260 } 8261 } 8262 8263 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8264 intent, description); 8265 8266 int trimIdx = trimRecentsForTaskLocked(task, false); 8267 if (trimIdx >= 0) { 8268 // If this would have caused a trim, then we'll abort because that 8269 // means it would be added at the end of the list but then just removed. 8270 return INVALID_TASK_ID; 8271 } 8272 8273 final int N = mRecentTasks.size(); 8274 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8275 final TaskRecord tr = mRecentTasks.remove(N - 1); 8276 tr.removedFromRecents(); 8277 } 8278 8279 task.inRecents = true; 8280 mRecentTasks.add(task); 8281 r.task.stack.addTask(task, false, false); 8282 8283 task.setLastThumbnail(thumbnail); 8284 task.freeLastThumbnail(); 8285 8286 return task.taskId; 8287 } 8288 } finally { 8289 Binder.restoreCallingIdentity(callingIdent); 8290 } 8291 } 8292 8293 @Override 8294 public Point getAppTaskThumbnailSize() { 8295 synchronized (this) { 8296 return new Point(mThumbnailWidth, mThumbnailHeight); 8297 } 8298 } 8299 8300 @Override 8301 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8302 synchronized (this) { 8303 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8304 if (r != null) { 8305 r.setTaskDescription(td); 8306 r.task.updateTaskDescription(); 8307 } 8308 } 8309 } 8310 8311 @Override 8312 public Bitmap getTaskDescriptionIcon(String filename) { 8313 if (!FileUtils.isValidExtFilename(filename) 8314 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8315 throw new IllegalArgumentException("Bad filename: " + filename); 8316 } 8317 return mTaskPersister.getTaskDescriptionIcon(filename); 8318 } 8319 8320 @Override 8321 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8322 throws RemoteException { 8323 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8324 opts.getCustomInPlaceResId() == 0) { 8325 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8326 "with valid animation"); 8327 } 8328 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8329 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8330 opts.getCustomInPlaceResId()); 8331 mWindowManager.executeAppTransition(); 8332 } 8333 8334 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8335 mRecentTasks.remove(tr); 8336 tr.removedFromRecents(); 8337 ComponentName component = tr.getBaseIntent().getComponent(); 8338 if (component == null) { 8339 Slog.w(TAG, "No component for base intent of task: " + tr); 8340 return; 8341 } 8342 8343 if (!killProcess) { 8344 return; 8345 } 8346 8347 // Determine if the process(es) for this task should be killed. 8348 final String pkg = component.getPackageName(); 8349 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8350 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8351 for (int i = 0; i < pmap.size(); i++) { 8352 8353 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8354 for (int j = 0; j < uids.size(); j++) { 8355 ProcessRecord proc = uids.valueAt(j); 8356 if (proc.userId != tr.userId) { 8357 // Don't kill process for a different user. 8358 continue; 8359 } 8360 if (proc == mHomeProcess) { 8361 // Don't kill the home process along with tasks from the same package. 8362 continue; 8363 } 8364 if (!proc.pkgList.containsKey(pkg)) { 8365 // Don't kill process that is not associated with this task. 8366 continue; 8367 } 8368 8369 for (int k = 0; k < proc.activities.size(); k++) { 8370 TaskRecord otherTask = proc.activities.get(k).task; 8371 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8372 // Don't kill process(es) that has an activity in a different task that is 8373 // also in recents. 8374 return; 8375 } 8376 } 8377 8378 // Add process to kill list. 8379 procsToKill.add(proc); 8380 } 8381 } 8382 8383 // Find any running services associated with this app and stop if needed. 8384 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8385 8386 // Kill the running processes. 8387 for (int i = 0; i < procsToKill.size(); i++) { 8388 ProcessRecord pr = procsToKill.get(i); 8389 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8390 pr.kill("remove task", true); 8391 } else { 8392 pr.waitingToKill = "remove task"; 8393 } 8394 } 8395 } 8396 8397 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8398 // Remove all tasks with activities in the specified package from the list of recent tasks 8399 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8400 TaskRecord tr = mRecentTasks.get(i); 8401 if (tr.userId != userId) continue; 8402 8403 ComponentName cn = tr.intent.getComponent(); 8404 if (cn != null && cn.getPackageName().equals(packageName)) { 8405 // If the package name matches, remove the task. 8406 removeTaskByIdLocked(tr.taskId, true); 8407 } 8408 } 8409 } 8410 8411 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8412 final IPackageManager pm = AppGlobals.getPackageManager(); 8413 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8414 8415 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8416 TaskRecord tr = mRecentTasks.get(i); 8417 if (tr.userId != userId) continue; 8418 8419 ComponentName cn = tr.intent.getComponent(); 8420 if (cn != null && cn.getPackageName().equals(packageName)) { 8421 // Skip if component still exists in the package. 8422 if (componentsKnownToExist.contains(cn)) continue; 8423 8424 try { 8425 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8426 if (info != null) { 8427 componentsKnownToExist.add(cn); 8428 } else { 8429 removeTaskByIdLocked(tr.taskId, false); 8430 } 8431 } catch (RemoteException e) { 8432 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8433 } 8434 } 8435 } 8436 } 8437 8438 /** 8439 * Removes the task with the specified task id. 8440 * 8441 * @param taskId Identifier of the task to be removed. 8442 * @param killProcess Kill any process associated with the task if possible. 8443 * @return Returns true if the given task was found and removed. 8444 */ 8445 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8446 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8447 if (tr != null) { 8448 tr.removeTaskActivitiesLocked(); 8449 cleanUpRemovedTaskLocked(tr, killProcess); 8450 if (tr.isPersistable) { 8451 notifyTaskPersisterLocked(null, true); 8452 } 8453 return true; 8454 } 8455 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8456 return false; 8457 } 8458 8459 @Override 8460 public boolean removeTask(int taskId) { 8461 synchronized (this) { 8462 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8463 "removeTask()"); 8464 long ident = Binder.clearCallingIdentity(); 8465 try { 8466 return removeTaskByIdLocked(taskId, true); 8467 } finally { 8468 Binder.restoreCallingIdentity(ident); 8469 } 8470 } 8471 } 8472 8473 /** 8474 * TODO: Add mController hook 8475 */ 8476 @Override 8477 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8478 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8479 "moveTaskToFront()"); 8480 8481 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8482 synchronized(this) { 8483 moveTaskToFrontLocked(taskId, flags, options); 8484 } 8485 } 8486 8487 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8488 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8489 Binder.getCallingUid(), -1, -1, "Task to front")) { 8490 ActivityOptions.abort(options); 8491 return; 8492 } 8493 final long origId = Binder.clearCallingIdentity(); 8494 try { 8495 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8496 if (task == null) { 8497 Slog.d(TAG, "Could not find task for id: "+ taskId); 8498 return; 8499 } 8500 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8501 mStackSupervisor.showLockTaskToast(); 8502 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8503 return; 8504 } 8505 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8506 if (prev != null && prev.isRecentsActivity()) { 8507 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8508 } 8509 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8510 } finally { 8511 Binder.restoreCallingIdentity(origId); 8512 } 8513 ActivityOptions.abort(options); 8514 } 8515 8516 @Override 8517 public void moveTaskToBack(int taskId) { 8518 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8519 "moveTaskToBack()"); 8520 8521 synchronized(this) { 8522 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8523 if (tr != null) { 8524 if (tr == mStackSupervisor.mLockTaskModeTask) { 8525 mStackSupervisor.showLockTaskToast(); 8526 return; 8527 } 8528 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8529 ActivityStack stack = tr.stack; 8530 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8531 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8532 Binder.getCallingUid(), -1, -1, "Task to back")) { 8533 return; 8534 } 8535 } 8536 final long origId = Binder.clearCallingIdentity(); 8537 try { 8538 stack.moveTaskToBackLocked(taskId, null); 8539 } finally { 8540 Binder.restoreCallingIdentity(origId); 8541 } 8542 } 8543 } 8544 } 8545 8546 /** 8547 * Moves an activity, and all of the other activities within the same task, to the bottom 8548 * of the history stack. The activity's order within the task is unchanged. 8549 * 8550 * @param token A reference to the activity we wish to move 8551 * @param nonRoot If false then this only works if the activity is the root 8552 * of a task; if true it will work for any activity in a task. 8553 * @return Returns true if the move completed, false if not. 8554 */ 8555 @Override 8556 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8557 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8558 synchronized(this) { 8559 final long origId = Binder.clearCallingIdentity(); 8560 try { 8561 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8562 if (taskId >= 0) { 8563 if ((mStackSupervisor.mLockTaskModeTask != null) 8564 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8565 mStackSupervisor.showLockTaskToast(); 8566 return false; 8567 } 8568 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8569 } 8570 } finally { 8571 Binder.restoreCallingIdentity(origId); 8572 } 8573 } 8574 return false; 8575 } 8576 8577 @Override 8578 public void moveTaskBackwards(int task) { 8579 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8580 "moveTaskBackwards()"); 8581 8582 synchronized(this) { 8583 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8584 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8585 return; 8586 } 8587 final long origId = Binder.clearCallingIdentity(); 8588 moveTaskBackwardsLocked(task); 8589 Binder.restoreCallingIdentity(origId); 8590 } 8591 } 8592 8593 private final void moveTaskBackwardsLocked(int task) { 8594 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8595 } 8596 8597 @Override 8598 public IBinder getHomeActivityToken() throws RemoteException { 8599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8600 "getHomeActivityToken()"); 8601 synchronized (this) { 8602 return mStackSupervisor.getHomeActivityToken(); 8603 } 8604 } 8605 8606 @Override 8607 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8608 IActivityContainerCallback callback) throws RemoteException { 8609 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8610 "createActivityContainer()"); 8611 synchronized (this) { 8612 if (parentActivityToken == null) { 8613 throw new IllegalArgumentException("parent token must not be null"); 8614 } 8615 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8616 if (r == null) { 8617 return null; 8618 } 8619 if (callback == null) { 8620 throw new IllegalArgumentException("callback must not be null"); 8621 } 8622 return mStackSupervisor.createActivityContainer(r, callback); 8623 } 8624 } 8625 8626 @Override 8627 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8628 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8629 "deleteActivityContainer()"); 8630 synchronized (this) { 8631 mStackSupervisor.deleteActivityContainer(container); 8632 } 8633 } 8634 8635 @Override 8636 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8637 throws RemoteException { 8638 synchronized (this) { 8639 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8640 if (stack != null) { 8641 return stack.mActivityContainer; 8642 } 8643 return null; 8644 } 8645 } 8646 8647 @Override 8648 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8649 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8650 "moveTaskToStack()"); 8651 if (stackId == HOME_STACK_ID) { 8652 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8653 new RuntimeException("here").fillInStackTrace()); 8654 } 8655 synchronized (this) { 8656 long ident = Binder.clearCallingIdentity(); 8657 try { 8658 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8659 + stackId + " toTop=" + toTop); 8660 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8661 } finally { 8662 Binder.restoreCallingIdentity(ident); 8663 } 8664 } 8665 } 8666 8667 @Override 8668 public void resizeStack(int stackBoxId, Rect bounds) { 8669 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8670 "resizeStackBox()"); 8671 long ident = Binder.clearCallingIdentity(); 8672 try { 8673 mWindowManager.resizeStack(stackBoxId, bounds); 8674 } finally { 8675 Binder.restoreCallingIdentity(ident); 8676 } 8677 } 8678 8679 @Override 8680 public List<StackInfo> getAllStackInfos() { 8681 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8682 "getAllStackInfos()"); 8683 long ident = Binder.clearCallingIdentity(); 8684 try { 8685 synchronized (this) { 8686 return mStackSupervisor.getAllStackInfosLocked(); 8687 } 8688 } finally { 8689 Binder.restoreCallingIdentity(ident); 8690 } 8691 } 8692 8693 @Override 8694 public StackInfo getStackInfo(int stackId) { 8695 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8696 "getStackInfo()"); 8697 long ident = Binder.clearCallingIdentity(); 8698 try { 8699 synchronized (this) { 8700 return mStackSupervisor.getStackInfoLocked(stackId); 8701 } 8702 } finally { 8703 Binder.restoreCallingIdentity(ident); 8704 } 8705 } 8706 8707 @Override 8708 public boolean isInHomeStack(int taskId) { 8709 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8710 "getStackInfo()"); 8711 long ident = Binder.clearCallingIdentity(); 8712 try { 8713 synchronized (this) { 8714 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8715 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8716 } 8717 } finally { 8718 Binder.restoreCallingIdentity(ident); 8719 } 8720 } 8721 8722 @Override 8723 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8724 synchronized(this) { 8725 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8726 } 8727 } 8728 8729 private boolean isLockTaskAuthorized(String pkg) { 8730 final DevicePolicyManager dpm = (DevicePolicyManager) 8731 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8732 try { 8733 int uid = mContext.getPackageManager().getPackageUid(pkg, 8734 Binder.getCallingUserHandle().getIdentifier()); 8735 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8736 } catch (NameNotFoundException e) { 8737 return false; 8738 } 8739 } 8740 8741 void startLockTaskMode(TaskRecord task) { 8742 final String pkg; 8743 synchronized (this) { 8744 pkg = task.intent.getComponent().getPackageName(); 8745 } 8746 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8747 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8748 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8749 StatusBarManagerInternal.class); 8750 if (statusBarManager != null) { 8751 statusBarManager.showScreenPinningRequest(); 8752 } 8753 return; 8754 } 8755 long ident = Binder.clearCallingIdentity(); 8756 try { 8757 synchronized (this) { 8758 // Since we lost lock on task, make sure it is still there. 8759 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8760 if (task != null) { 8761 if (!isSystemInitiated 8762 && ((mStackSupervisor.getFocusedStack() == null) 8763 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8764 throw new IllegalArgumentException("Invalid task, not in foreground"); 8765 } 8766 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8767 } 8768 } 8769 } finally { 8770 Binder.restoreCallingIdentity(ident); 8771 } 8772 } 8773 8774 @Override 8775 public void startLockTaskMode(int taskId) { 8776 final TaskRecord task; 8777 long ident = Binder.clearCallingIdentity(); 8778 try { 8779 synchronized (this) { 8780 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8781 } 8782 } finally { 8783 Binder.restoreCallingIdentity(ident); 8784 } 8785 if (task != null) { 8786 startLockTaskMode(task); 8787 } 8788 } 8789 8790 @Override 8791 public void startLockTaskMode(IBinder token) { 8792 final TaskRecord task; 8793 long ident = Binder.clearCallingIdentity(); 8794 try { 8795 synchronized (this) { 8796 final ActivityRecord r = ActivityRecord.forToken(token); 8797 if (r == null) { 8798 return; 8799 } 8800 task = r.task; 8801 } 8802 } finally { 8803 Binder.restoreCallingIdentity(ident); 8804 } 8805 if (task != null) { 8806 startLockTaskMode(task); 8807 } 8808 } 8809 8810 @Override 8811 public void startLockTaskModeOnCurrent() throws RemoteException { 8812 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8813 "startLockTaskModeOnCurrent"); 8814 long ident = Binder.clearCallingIdentity(); 8815 try { 8816 ActivityRecord r = null; 8817 synchronized (this) { 8818 r = mStackSupervisor.topRunningActivityLocked(); 8819 } 8820 startLockTaskMode(r.task); 8821 } finally { 8822 Binder.restoreCallingIdentity(ident); 8823 } 8824 } 8825 8826 @Override 8827 public void stopLockTaskMode() { 8828 // Verify that the user matches the package of the intent for the TaskRecord 8829 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8830 // and stopLockTaskMode. 8831 final int callingUid = Binder.getCallingUid(); 8832 if (callingUid != Process.SYSTEM_UID) { 8833 try { 8834 String pkg = 8835 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8836 int uid = mContext.getPackageManager().getPackageUid(pkg, 8837 Binder.getCallingUserHandle().getIdentifier()); 8838 if (uid != callingUid) { 8839 throw new SecurityException("Invalid uid, expected " + uid); 8840 } 8841 } catch (NameNotFoundException e) { 8842 Log.d(TAG, "stopLockTaskMode " + e); 8843 return; 8844 } 8845 } 8846 long ident = Binder.clearCallingIdentity(); 8847 try { 8848 Log.d(TAG, "stopLockTaskMode"); 8849 // Stop lock task 8850 synchronized (this) { 8851 mStackSupervisor.setLockTaskModeLocked(null, false); 8852 } 8853 } finally { 8854 Binder.restoreCallingIdentity(ident); 8855 } 8856 } 8857 8858 @Override 8859 public void stopLockTaskModeOnCurrent() throws RemoteException { 8860 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8861 "stopLockTaskModeOnCurrent"); 8862 long ident = Binder.clearCallingIdentity(); 8863 try { 8864 stopLockTaskMode(); 8865 } finally { 8866 Binder.restoreCallingIdentity(ident); 8867 } 8868 } 8869 8870 @Override 8871 public boolean isInLockTaskMode() { 8872 synchronized (this) { 8873 return mStackSupervisor.isInLockTaskMode(); 8874 } 8875 } 8876 8877 // ========================================================= 8878 // CONTENT PROVIDERS 8879 // ========================================================= 8880 8881 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8882 List<ProviderInfo> providers = null; 8883 try { 8884 providers = AppGlobals.getPackageManager(). 8885 queryContentProviders(app.processName, app.uid, 8886 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8887 } catch (RemoteException ex) { 8888 } 8889 if (DEBUG_MU) 8890 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8891 int userId = app.userId; 8892 if (providers != null) { 8893 int N = providers.size(); 8894 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8895 for (int i=0; i<N; i++) { 8896 ProviderInfo cpi = 8897 (ProviderInfo)providers.get(i); 8898 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8899 cpi.name, cpi.flags); 8900 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8901 // This is a singleton provider, but a user besides the 8902 // default user is asking to initialize a process it runs 8903 // in... well, no, it doesn't actually run in this process, 8904 // it runs in the process of the default user. Get rid of it. 8905 providers.remove(i); 8906 N--; 8907 i--; 8908 continue; 8909 } 8910 8911 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8912 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8913 if (cpr == null) { 8914 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8915 mProviderMap.putProviderByClass(comp, cpr); 8916 } 8917 if (DEBUG_MU) 8918 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8919 app.pubProviders.put(cpi.name, cpr); 8920 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8921 // Don't add this if it is a platform component that is marked 8922 // to run in multiple processes, because this is actually 8923 // part of the framework so doesn't make sense to track as a 8924 // separate apk in the process. 8925 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8926 mProcessStats); 8927 } 8928 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8929 } 8930 } 8931 return providers; 8932 } 8933 8934 /** 8935 * Check if {@link ProcessRecord} has a possible chance at accessing the 8936 * given {@link ProviderInfo}. Final permission checking is always done 8937 * in {@link ContentProvider}. 8938 */ 8939 private final String checkContentProviderPermissionLocked( 8940 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8941 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8942 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8943 boolean checkedGrants = false; 8944 if (checkUser) { 8945 // Looking for cross-user grants before enforcing the typical cross-users permissions 8946 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8947 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8948 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8949 return null; 8950 } 8951 checkedGrants = true; 8952 } 8953 userId = handleIncomingUser(callingPid, callingUid, userId, 8954 false, ALLOW_NON_FULL, 8955 "checkContentProviderPermissionLocked " + cpi.authority, null); 8956 if (userId != tmpTargetUserId) { 8957 // When we actually went to determine the final targer user ID, this ended 8958 // up different than our initial check for the authority. This is because 8959 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8960 // SELF. So we need to re-check the grants again. 8961 checkedGrants = false; 8962 } 8963 } 8964 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8965 cpi.applicationInfo.uid, cpi.exported) 8966 == PackageManager.PERMISSION_GRANTED) { 8967 return null; 8968 } 8969 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8970 cpi.applicationInfo.uid, cpi.exported) 8971 == PackageManager.PERMISSION_GRANTED) { 8972 return null; 8973 } 8974 8975 PathPermission[] pps = cpi.pathPermissions; 8976 if (pps != null) { 8977 int i = pps.length; 8978 while (i > 0) { 8979 i--; 8980 PathPermission pp = pps[i]; 8981 String pprperm = pp.getReadPermission(); 8982 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8983 cpi.applicationInfo.uid, cpi.exported) 8984 == PackageManager.PERMISSION_GRANTED) { 8985 return null; 8986 } 8987 String ppwperm = pp.getWritePermission(); 8988 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8989 cpi.applicationInfo.uid, cpi.exported) 8990 == PackageManager.PERMISSION_GRANTED) { 8991 return null; 8992 } 8993 } 8994 } 8995 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8996 return null; 8997 } 8998 8999 String msg; 9000 if (!cpi.exported) { 9001 msg = "Permission Denial: opening provider " + cpi.name 9002 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9003 + ", uid=" + callingUid + ") that is not exported from uid " 9004 + cpi.applicationInfo.uid; 9005 } else { 9006 msg = "Permission Denial: opening provider " + cpi.name 9007 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9008 + ", uid=" + callingUid + ") requires " 9009 + cpi.readPermission + " or " + cpi.writePermission; 9010 } 9011 Slog.w(TAG, msg); 9012 return msg; 9013 } 9014 9015 /** 9016 * Returns if the ContentProvider has granted a uri to callingUid 9017 */ 9018 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9019 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9020 if (perms != null) { 9021 for (int i=perms.size()-1; i>=0; i--) { 9022 GrantUri grantUri = perms.keyAt(i); 9023 if (grantUri.sourceUserId == userId || !checkUser) { 9024 if (matchesProvider(grantUri.uri, cpi)) { 9025 return true; 9026 } 9027 } 9028 } 9029 } 9030 return false; 9031 } 9032 9033 /** 9034 * Returns true if the uri authority is one of the authorities specified in the provider. 9035 */ 9036 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9037 String uriAuth = uri.getAuthority(); 9038 String cpiAuth = cpi.authority; 9039 if (cpiAuth.indexOf(';') == -1) { 9040 return cpiAuth.equals(uriAuth); 9041 } 9042 String[] cpiAuths = cpiAuth.split(";"); 9043 int length = cpiAuths.length; 9044 for (int i = 0; i < length; i++) { 9045 if (cpiAuths[i].equals(uriAuth)) return true; 9046 } 9047 return false; 9048 } 9049 9050 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9051 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9052 if (r != null) { 9053 for (int i=0; i<r.conProviders.size(); i++) { 9054 ContentProviderConnection conn = r.conProviders.get(i); 9055 if (conn.provider == cpr) { 9056 if (DEBUG_PROVIDER) Slog.v(TAG, 9057 "Adding provider requested by " 9058 + r.processName + " from process " 9059 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9060 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9061 if (stable) { 9062 conn.stableCount++; 9063 conn.numStableIncs++; 9064 } else { 9065 conn.unstableCount++; 9066 conn.numUnstableIncs++; 9067 } 9068 return conn; 9069 } 9070 } 9071 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9072 if (stable) { 9073 conn.stableCount = 1; 9074 conn.numStableIncs = 1; 9075 } else { 9076 conn.unstableCount = 1; 9077 conn.numUnstableIncs = 1; 9078 } 9079 cpr.connections.add(conn); 9080 r.conProviders.add(conn); 9081 return conn; 9082 } 9083 cpr.addExternalProcessHandleLocked(externalProcessToken); 9084 return null; 9085 } 9086 9087 boolean decProviderCountLocked(ContentProviderConnection conn, 9088 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9089 if (conn != null) { 9090 cpr = conn.provider; 9091 if (DEBUG_PROVIDER) Slog.v(TAG, 9092 "Removing provider requested by " 9093 + conn.client.processName + " from process " 9094 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9095 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9096 if (stable) { 9097 conn.stableCount--; 9098 } else { 9099 conn.unstableCount--; 9100 } 9101 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9102 cpr.connections.remove(conn); 9103 conn.client.conProviders.remove(conn); 9104 return true; 9105 } 9106 return false; 9107 } 9108 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9109 return false; 9110 } 9111 9112 private void checkTime(long startTime, String where) { 9113 long now = SystemClock.elapsedRealtime(); 9114 if ((now-startTime) > 1000) { 9115 // If we are taking more than a second, log about it. 9116 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9117 } 9118 } 9119 9120 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9121 String name, IBinder token, boolean stable, int userId) { 9122 ContentProviderRecord cpr; 9123 ContentProviderConnection conn = null; 9124 ProviderInfo cpi = null; 9125 9126 synchronized(this) { 9127 long startTime = SystemClock.elapsedRealtime(); 9128 9129 ProcessRecord r = null; 9130 if (caller != null) { 9131 r = getRecordForAppLocked(caller); 9132 if (r == null) { 9133 throw new SecurityException( 9134 "Unable to find app for caller " + caller 9135 + " (pid=" + Binder.getCallingPid() 9136 + ") when getting content provider " + name); 9137 } 9138 } 9139 9140 boolean checkCrossUser = true; 9141 9142 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9143 9144 // First check if this content provider has been published... 9145 cpr = mProviderMap.getProviderByName(name, userId); 9146 // If that didn't work, check if it exists for user 0 and then 9147 // verify that it's a singleton provider before using it. 9148 if (cpr == null && userId != UserHandle.USER_OWNER) { 9149 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9150 if (cpr != null) { 9151 cpi = cpr.info; 9152 if (isSingleton(cpi.processName, cpi.applicationInfo, 9153 cpi.name, cpi.flags) 9154 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9155 userId = UserHandle.USER_OWNER; 9156 checkCrossUser = false; 9157 } else { 9158 cpr = null; 9159 cpi = null; 9160 } 9161 } 9162 } 9163 9164 boolean providerRunning = cpr != null; 9165 if (providerRunning) { 9166 cpi = cpr.info; 9167 String msg; 9168 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9169 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9170 != null) { 9171 throw new SecurityException(msg); 9172 } 9173 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9174 9175 if (r != null && cpr.canRunHere(r)) { 9176 // This provider has been published or is in the process 9177 // of being published... but it is also allowed to run 9178 // in the caller's process, so don't make a connection 9179 // and just let the caller instantiate its own instance. 9180 ContentProviderHolder holder = cpr.newHolder(null); 9181 // don't give caller the provider object, it needs 9182 // to make its own. 9183 holder.provider = null; 9184 return holder; 9185 } 9186 9187 final long origId = Binder.clearCallingIdentity(); 9188 9189 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9190 9191 // In this case the provider instance already exists, so we can 9192 // return it right away. 9193 conn = incProviderCountLocked(r, cpr, token, stable); 9194 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9195 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9196 // If this is a perceptible app accessing the provider, 9197 // make sure to count it as being accessed and thus 9198 // back up on the LRU list. This is good because 9199 // content providers are often expensive to start. 9200 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9201 updateLruProcessLocked(cpr.proc, false, null); 9202 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9203 } 9204 } 9205 9206 if (cpr.proc != null) { 9207 if (false) { 9208 if (cpr.name.flattenToShortString().equals( 9209 "com.android.providers.calendar/.CalendarProvider2")) { 9210 Slog.v(TAG, "****************** KILLING " 9211 + cpr.name.flattenToShortString()); 9212 Process.killProcess(cpr.proc.pid); 9213 } 9214 } 9215 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9216 boolean success = updateOomAdjLocked(cpr.proc); 9217 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9218 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9219 // NOTE: there is still a race here where a signal could be 9220 // pending on the process even though we managed to update its 9221 // adj level. Not sure what to do about this, but at least 9222 // the race is now smaller. 9223 if (!success) { 9224 // Uh oh... it looks like the provider's process 9225 // has been killed on us. We need to wait for a new 9226 // process to be started, and make sure its death 9227 // doesn't kill our process. 9228 Slog.i(TAG, 9229 "Existing provider " + cpr.name.flattenToShortString() 9230 + " is crashing; detaching " + r); 9231 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9232 checkTime(startTime, "getContentProviderImpl: before appDied"); 9233 appDiedLocked(cpr.proc); 9234 checkTime(startTime, "getContentProviderImpl: after appDied"); 9235 if (!lastRef) { 9236 // This wasn't the last ref our process had on 9237 // the provider... we have now been killed, bail. 9238 return null; 9239 } 9240 providerRunning = false; 9241 conn = null; 9242 } 9243 } 9244 9245 Binder.restoreCallingIdentity(origId); 9246 } 9247 9248 boolean singleton; 9249 if (!providerRunning) { 9250 try { 9251 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9252 cpi = AppGlobals.getPackageManager(). 9253 resolveContentProvider(name, 9254 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9255 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9256 } catch (RemoteException ex) { 9257 } 9258 if (cpi == null) { 9259 return null; 9260 } 9261 // If the provider is a singleton AND 9262 // (it's a call within the same user || the provider is a 9263 // privileged app) 9264 // Then allow connecting to the singleton provider 9265 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9266 cpi.name, cpi.flags) 9267 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9268 if (singleton) { 9269 userId = UserHandle.USER_OWNER; 9270 } 9271 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9272 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9273 9274 String msg; 9275 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9276 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9277 != null) { 9278 throw new SecurityException(msg); 9279 } 9280 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9281 9282 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9283 && !cpi.processName.equals("system")) { 9284 // If this content provider does not run in the system 9285 // process, and the system is not yet ready to run other 9286 // processes, then fail fast instead of hanging. 9287 throw new IllegalArgumentException( 9288 "Attempt to launch content provider before system ready"); 9289 } 9290 9291 // Make sure that the user who owns this provider is running. If not, 9292 // we don't want to allow it to run. 9293 if (!isUserRunningLocked(userId, false)) { 9294 Slog.w(TAG, "Unable to launch app " 9295 + cpi.applicationInfo.packageName + "/" 9296 + cpi.applicationInfo.uid + " for provider " 9297 + name + ": user " + userId + " is stopped"); 9298 return null; 9299 } 9300 9301 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9302 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9303 cpr = mProviderMap.getProviderByClass(comp, userId); 9304 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9305 final boolean firstClass = cpr == null; 9306 if (firstClass) { 9307 final long ident = Binder.clearCallingIdentity(); 9308 try { 9309 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9310 ApplicationInfo ai = 9311 AppGlobals.getPackageManager(). 9312 getApplicationInfo( 9313 cpi.applicationInfo.packageName, 9314 STOCK_PM_FLAGS, userId); 9315 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9316 if (ai == null) { 9317 Slog.w(TAG, "No package info for content provider " 9318 + cpi.name); 9319 return null; 9320 } 9321 ai = getAppInfoForUser(ai, userId); 9322 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9323 } catch (RemoteException ex) { 9324 // pm is in same process, this will never happen. 9325 } finally { 9326 Binder.restoreCallingIdentity(ident); 9327 } 9328 } 9329 9330 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9331 9332 if (r != null && cpr.canRunHere(r)) { 9333 // If this is a multiprocess provider, then just return its 9334 // info and allow the caller to instantiate it. Only do 9335 // this if the provider is the same user as the caller's 9336 // process, or can run as root (so can be in any process). 9337 return cpr.newHolder(null); 9338 } 9339 9340 if (DEBUG_PROVIDER) { 9341 RuntimeException e = new RuntimeException("here"); 9342 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9343 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9344 } 9345 9346 // This is single process, and our app is now connecting to it. 9347 // See if we are already in the process of launching this 9348 // provider. 9349 final int N = mLaunchingProviders.size(); 9350 int i; 9351 for (i=0; i<N; i++) { 9352 if (mLaunchingProviders.get(i) == cpr) { 9353 break; 9354 } 9355 } 9356 9357 // If the provider is not already being launched, then get it 9358 // started. 9359 if (i >= N) { 9360 final long origId = Binder.clearCallingIdentity(); 9361 9362 try { 9363 // Content provider is now in use, its package can't be stopped. 9364 try { 9365 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9366 AppGlobals.getPackageManager().setPackageStoppedState( 9367 cpr.appInfo.packageName, false, userId); 9368 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9369 } catch (RemoteException e) { 9370 } catch (IllegalArgumentException e) { 9371 Slog.w(TAG, "Failed trying to unstop package " 9372 + cpr.appInfo.packageName + ": " + e); 9373 } 9374 9375 // Use existing process if already started 9376 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9377 ProcessRecord proc = getProcessRecordLocked( 9378 cpi.processName, cpr.appInfo.uid, false); 9379 if (proc != null && proc.thread != null) { 9380 if (DEBUG_PROVIDER) { 9381 Slog.d(TAG, "Installing in existing process " + proc); 9382 } 9383 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9384 proc.pubProviders.put(cpi.name, cpr); 9385 try { 9386 proc.thread.scheduleInstallProvider(cpi); 9387 } catch (RemoteException e) { 9388 } 9389 } else { 9390 checkTime(startTime, "getContentProviderImpl: before start process"); 9391 proc = startProcessLocked(cpi.processName, 9392 cpr.appInfo, false, 0, "content provider", 9393 new ComponentName(cpi.applicationInfo.packageName, 9394 cpi.name), false, false, false); 9395 checkTime(startTime, "getContentProviderImpl: after start process"); 9396 if (proc == null) { 9397 Slog.w(TAG, "Unable to launch app " 9398 + cpi.applicationInfo.packageName + "/" 9399 + cpi.applicationInfo.uid + " for provider " 9400 + name + ": process is bad"); 9401 return null; 9402 } 9403 } 9404 cpr.launchingApp = proc; 9405 mLaunchingProviders.add(cpr); 9406 } finally { 9407 Binder.restoreCallingIdentity(origId); 9408 } 9409 } 9410 9411 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9412 9413 // Make sure the provider is published (the same provider class 9414 // may be published under multiple names). 9415 if (firstClass) { 9416 mProviderMap.putProviderByClass(comp, cpr); 9417 } 9418 9419 mProviderMap.putProviderByName(name, cpr); 9420 conn = incProviderCountLocked(r, cpr, token, stable); 9421 if (conn != null) { 9422 conn.waiting = true; 9423 } 9424 } 9425 checkTime(startTime, "getContentProviderImpl: done!"); 9426 } 9427 9428 // Wait for the provider to be published... 9429 synchronized (cpr) { 9430 while (cpr.provider == null) { 9431 if (cpr.launchingApp == null) { 9432 Slog.w(TAG, "Unable to launch app " 9433 + cpi.applicationInfo.packageName + "/" 9434 + cpi.applicationInfo.uid + " for provider " 9435 + name + ": launching app became null"); 9436 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9437 UserHandle.getUserId(cpi.applicationInfo.uid), 9438 cpi.applicationInfo.packageName, 9439 cpi.applicationInfo.uid, name); 9440 return null; 9441 } 9442 try { 9443 if (DEBUG_MU) { 9444 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9445 + cpr.launchingApp); 9446 } 9447 if (conn != null) { 9448 conn.waiting = true; 9449 } 9450 cpr.wait(); 9451 } catch (InterruptedException ex) { 9452 } finally { 9453 if (conn != null) { 9454 conn.waiting = false; 9455 } 9456 } 9457 } 9458 } 9459 return cpr != null ? cpr.newHolder(conn) : null; 9460 } 9461 9462 @Override 9463 public final ContentProviderHolder getContentProvider( 9464 IApplicationThread caller, String name, int userId, boolean stable) { 9465 enforceNotIsolatedCaller("getContentProvider"); 9466 if (caller == null) { 9467 String msg = "null IApplicationThread when getting content provider " 9468 + name; 9469 Slog.w(TAG, msg); 9470 throw new SecurityException(msg); 9471 } 9472 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9473 // with cross-user grant. 9474 return getContentProviderImpl(caller, name, null, stable, userId); 9475 } 9476 9477 public ContentProviderHolder getContentProviderExternal( 9478 String name, int userId, IBinder token) { 9479 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9480 "Do not have permission in call getContentProviderExternal()"); 9481 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9482 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9483 return getContentProviderExternalUnchecked(name, token, userId); 9484 } 9485 9486 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9487 IBinder token, int userId) { 9488 return getContentProviderImpl(null, name, token, true, userId); 9489 } 9490 9491 /** 9492 * Drop a content provider from a ProcessRecord's bookkeeping 9493 */ 9494 public void removeContentProvider(IBinder connection, boolean stable) { 9495 enforceNotIsolatedCaller("removeContentProvider"); 9496 long ident = Binder.clearCallingIdentity(); 9497 try { 9498 synchronized (this) { 9499 ContentProviderConnection conn; 9500 try { 9501 conn = (ContentProviderConnection)connection; 9502 } catch (ClassCastException e) { 9503 String msg ="removeContentProvider: " + connection 9504 + " not a ContentProviderConnection"; 9505 Slog.w(TAG, msg); 9506 throw new IllegalArgumentException(msg); 9507 } 9508 if (conn == null) { 9509 throw new NullPointerException("connection is null"); 9510 } 9511 if (decProviderCountLocked(conn, null, null, stable)) { 9512 updateOomAdjLocked(); 9513 } 9514 } 9515 } finally { 9516 Binder.restoreCallingIdentity(ident); 9517 } 9518 } 9519 9520 public void removeContentProviderExternal(String name, IBinder token) { 9521 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9522 "Do not have permission in call removeContentProviderExternal()"); 9523 int userId = UserHandle.getCallingUserId(); 9524 long ident = Binder.clearCallingIdentity(); 9525 try { 9526 removeContentProviderExternalUnchecked(name, token, userId); 9527 } finally { 9528 Binder.restoreCallingIdentity(ident); 9529 } 9530 } 9531 9532 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9533 synchronized (this) { 9534 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9535 if(cpr == null) { 9536 //remove from mProvidersByClass 9537 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9538 return; 9539 } 9540 9541 //update content provider record entry info 9542 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9543 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9544 if (localCpr.hasExternalProcessHandles()) { 9545 if (localCpr.removeExternalProcessHandleLocked(token)) { 9546 updateOomAdjLocked(); 9547 } else { 9548 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9549 + " with no external reference for token: " 9550 + token + "."); 9551 } 9552 } else { 9553 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9554 + " with no external references."); 9555 } 9556 } 9557 } 9558 9559 public final void publishContentProviders(IApplicationThread caller, 9560 List<ContentProviderHolder> providers) { 9561 if (providers == null) { 9562 return; 9563 } 9564 9565 enforceNotIsolatedCaller("publishContentProviders"); 9566 synchronized (this) { 9567 final ProcessRecord r = getRecordForAppLocked(caller); 9568 if (DEBUG_MU) 9569 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9570 if (r == null) { 9571 throw new SecurityException( 9572 "Unable to find app for caller " + caller 9573 + " (pid=" + Binder.getCallingPid() 9574 + ") when publishing content providers"); 9575 } 9576 9577 final long origId = Binder.clearCallingIdentity(); 9578 9579 final int N = providers.size(); 9580 for (int i=0; i<N; i++) { 9581 ContentProviderHolder src = providers.get(i); 9582 if (src == null || src.info == null || src.provider == null) { 9583 continue; 9584 } 9585 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9586 if (DEBUG_MU) 9587 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9588 if (dst != null) { 9589 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9590 mProviderMap.putProviderByClass(comp, dst); 9591 String names[] = dst.info.authority.split(";"); 9592 for (int j = 0; j < names.length; j++) { 9593 mProviderMap.putProviderByName(names[j], dst); 9594 } 9595 9596 int NL = mLaunchingProviders.size(); 9597 int j; 9598 for (j=0; j<NL; j++) { 9599 if (mLaunchingProviders.get(j) == dst) { 9600 mLaunchingProviders.remove(j); 9601 j--; 9602 NL--; 9603 } 9604 } 9605 synchronized (dst) { 9606 dst.provider = src.provider; 9607 dst.proc = r; 9608 dst.notifyAll(); 9609 } 9610 updateOomAdjLocked(r); 9611 } 9612 } 9613 9614 Binder.restoreCallingIdentity(origId); 9615 } 9616 } 9617 9618 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9619 ContentProviderConnection conn; 9620 try { 9621 conn = (ContentProviderConnection)connection; 9622 } catch (ClassCastException e) { 9623 String msg ="refContentProvider: " + connection 9624 + " not a ContentProviderConnection"; 9625 Slog.w(TAG, msg); 9626 throw new IllegalArgumentException(msg); 9627 } 9628 if (conn == null) { 9629 throw new NullPointerException("connection is null"); 9630 } 9631 9632 synchronized (this) { 9633 if (stable > 0) { 9634 conn.numStableIncs += stable; 9635 } 9636 stable = conn.stableCount + stable; 9637 if (stable < 0) { 9638 throw new IllegalStateException("stableCount < 0: " + stable); 9639 } 9640 9641 if (unstable > 0) { 9642 conn.numUnstableIncs += unstable; 9643 } 9644 unstable = conn.unstableCount + unstable; 9645 if (unstable < 0) { 9646 throw new IllegalStateException("unstableCount < 0: " + unstable); 9647 } 9648 9649 if ((stable+unstable) <= 0) { 9650 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9651 + stable + " unstable=" + unstable); 9652 } 9653 conn.stableCount = stable; 9654 conn.unstableCount = unstable; 9655 return !conn.dead; 9656 } 9657 } 9658 9659 public void unstableProviderDied(IBinder connection) { 9660 ContentProviderConnection conn; 9661 try { 9662 conn = (ContentProviderConnection)connection; 9663 } catch (ClassCastException e) { 9664 String msg ="refContentProvider: " + connection 9665 + " not a ContentProviderConnection"; 9666 Slog.w(TAG, msg); 9667 throw new IllegalArgumentException(msg); 9668 } 9669 if (conn == null) { 9670 throw new NullPointerException("connection is null"); 9671 } 9672 9673 // Safely retrieve the content provider associated with the connection. 9674 IContentProvider provider; 9675 synchronized (this) { 9676 provider = conn.provider.provider; 9677 } 9678 9679 if (provider == null) { 9680 // Um, yeah, we're way ahead of you. 9681 return; 9682 } 9683 9684 // Make sure the caller is being honest with us. 9685 if (provider.asBinder().pingBinder()) { 9686 // Er, no, still looks good to us. 9687 synchronized (this) { 9688 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9689 + " says " + conn + " died, but we don't agree"); 9690 return; 9691 } 9692 } 9693 9694 // Well look at that! It's dead! 9695 synchronized (this) { 9696 if (conn.provider.provider != provider) { 9697 // But something changed... good enough. 9698 return; 9699 } 9700 9701 ProcessRecord proc = conn.provider.proc; 9702 if (proc == null || proc.thread == null) { 9703 // Seems like the process is already cleaned up. 9704 return; 9705 } 9706 9707 // As far as we're concerned, this is just like receiving a 9708 // death notification... just a bit prematurely. 9709 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9710 + ") early provider death"); 9711 final long ident = Binder.clearCallingIdentity(); 9712 try { 9713 appDiedLocked(proc); 9714 } finally { 9715 Binder.restoreCallingIdentity(ident); 9716 } 9717 } 9718 } 9719 9720 @Override 9721 public void appNotRespondingViaProvider(IBinder connection) { 9722 enforceCallingPermission( 9723 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9724 9725 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9726 if (conn == null) { 9727 Slog.w(TAG, "ContentProviderConnection is null"); 9728 return; 9729 } 9730 9731 final ProcessRecord host = conn.provider.proc; 9732 if (host == null) { 9733 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9734 return; 9735 } 9736 9737 final long token = Binder.clearCallingIdentity(); 9738 try { 9739 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9740 } finally { 9741 Binder.restoreCallingIdentity(token); 9742 } 9743 } 9744 9745 public final void installSystemProviders() { 9746 List<ProviderInfo> providers; 9747 synchronized (this) { 9748 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9749 providers = generateApplicationProvidersLocked(app); 9750 if (providers != null) { 9751 for (int i=providers.size()-1; i>=0; i--) { 9752 ProviderInfo pi = (ProviderInfo)providers.get(i); 9753 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9754 Slog.w(TAG, "Not installing system proc provider " + pi.name 9755 + ": not system .apk"); 9756 providers.remove(i); 9757 } 9758 } 9759 } 9760 } 9761 if (providers != null) { 9762 mSystemThread.installSystemProviders(providers); 9763 } 9764 9765 mCoreSettingsObserver = new CoreSettingsObserver(this); 9766 9767 //mUsageStatsService.monitorPackages(); 9768 } 9769 9770 /** 9771 * Allows apps to retrieve the MIME type of a URI. 9772 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9773 * users, then it does not need permission to access the ContentProvider. 9774 * Either, it needs cross-user uri grants. 9775 * 9776 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9777 * 9778 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9779 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9780 */ 9781 public String getProviderMimeType(Uri uri, int userId) { 9782 enforceNotIsolatedCaller("getProviderMimeType"); 9783 final String name = uri.getAuthority(); 9784 int callingUid = Binder.getCallingUid(); 9785 int callingPid = Binder.getCallingPid(); 9786 long ident = 0; 9787 boolean clearedIdentity = false; 9788 userId = unsafeConvertIncomingUser(userId); 9789 if (canClearIdentity(callingPid, callingUid, userId)) { 9790 clearedIdentity = true; 9791 ident = Binder.clearCallingIdentity(); 9792 } 9793 ContentProviderHolder holder = null; 9794 try { 9795 holder = getContentProviderExternalUnchecked(name, null, userId); 9796 if (holder != null) { 9797 return holder.provider.getType(uri); 9798 } 9799 } catch (RemoteException e) { 9800 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9801 return null; 9802 } finally { 9803 // We need to clear the identity to call removeContentProviderExternalUnchecked 9804 if (!clearedIdentity) { 9805 ident = Binder.clearCallingIdentity(); 9806 } 9807 try { 9808 if (holder != null) { 9809 removeContentProviderExternalUnchecked(name, null, userId); 9810 } 9811 } finally { 9812 Binder.restoreCallingIdentity(ident); 9813 } 9814 } 9815 9816 return null; 9817 } 9818 9819 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9820 if (UserHandle.getUserId(callingUid) == userId) { 9821 return true; 9822 } 9823 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9824 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9825 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9826 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9827 return true; 9828 } 9829 return false; 9830 } 9831 9832 // ========================================================= 9833 // GLOBAL MANAGEMENT 9834 // ========================================================= 9835 9836 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9837 boolean isolated, int isolatedUid) { 9838 String proc = customProcess != null ? customProcess : info.processName; 9839 BatteryStatsImpl.Uid.Proc ps = null; 9840 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9841 int uid = info.uid; 9842 if (isolated) { 9843 if (isolatedUid == 0) { 9844 int userId = UserHandle.getUserId(uid); 9845 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9846 while (true) { 9847 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9848 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9849 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9850 } 9851 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9852 mNextIsolatedProcessUid++; 9853 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9854 // No process for this uid, use it. 9855 break; 9856 } 9857 stepsLeft--; 9858 if (stepsLeft <= 0) { 9859 return null; 9860 } 9861 } 9862 } else { 9863 // Special case for startIsolatedProcess (internal only), where 9864 // the uid of the isolated process is specified by the caller. 9865 uid = isolatedUid; 9866 } 9867 } 9868 return new ProcessRecord(stats, info, proc, uid); 9869 } 9870 9871 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9872 String abiOverride) { 9873 ProcessRecord app; 9874 if (!isolated) { 9875 app = getProcessRecordLocked(info.processName, info.uid, true); 9876 } else { 9877 app = null; 9878 } 9879 9880 if (app == null) { 9881 app = newProcessRecordLocked(info, null, isolated, 0); 9882 mProcessNames.put(info.processName, app.uid, app); 9883 if (isolated) { 9884 mIsolatedProcesses.put(app.uid, app); 9885 } 9886 updateLruProcessLocked(app, false, null); 9887 updateOomAdjLocked(); 9888 } 9889 9890 // This package really, really can not be stopped. 9891 try { 9892 AppGlobals.getPackageManager().setPackageStoppedState( 9893 info.packageName, false, UserHandle.getUserId(app.uid)); 9894 } catch (RemoteException e) { 9895 } catch (IllegalArgumentException e) { 9896 Slog.w(TAG, "Failed trying to unstop package " 9897 + info.packageName + ": " + e); 9898 } 9899 9900 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9901 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9902 app.persistent = true; 9903 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9904 } 9905 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9906 mPersistentStartingProcesses.add(app); 9907 startProcessLocked(app, "added application", app.processName, abiOverride, 9908 null /* entryPoint */, null /* entryPointArgs */); 9909 } 9910 9911 return app; 9912 } 9913 9914 public void unhandledBack() { 9915 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9916 "unhandledBack()"); 9917 9918 synchronized(this) { 9919 final long origId = Binder.clearCallingIdentity(); 9920 try { 9921 getFocusedStack().unhandledBackLocked(); 9922 } finally { 9923 Binder.restoreCallingIdentity(origId); 9924 } 9925 } 9926 } 9927 9928 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9929 enforceNotIsolatedCaller("openContentUri"); 9930 final int userId = UserHandle.getCallingUserId(); 9931 String name = uri.getAuthority(); 9932 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9933 ParcelFileDescriptor pfd = null; 9934 if (cph != null) { 9935 // We record the binder invoker's uid in thread-local storage before 9936 // going to the content provider to open the file. Later, in the code 9937 // that handles all permissions checks, we look for this uid and use 9938 // that rather than the Activity Manager's own uid. The effect is that 9939 // we do the check against the caller's permissions even though it looks 9940 // to the content provider like the Activity Manager itself is making 9941 // the request. 9942 Binder token = new Binder(); 9943 sCallerIdentity.set(new Identity( 9944 token, Binder.getCallingPid(), Binder.getCallingUid())); 9945 try { 9946 pfd = cph.provider.openFile(null, uri, "r", null, token); 9947 } catch (FileNotFoundException e) { 9948 // do nothing; pfd will be returned null 9949 } finally { 9950 // Ensure that whatever happens, we clean up the identity state 9951 sCallerIdentity.remove(); 9952 } 9953 9954 // We've got the fd now, so we're done with the provider. 9955 removeContentProviderExternalUnchecked(name, null, userId); 9956 } else { 9957 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9958 } 9959 return pfd; 9960 } 9961 9962 // Actually is sleeping or shutting down or whatever else in the future 9963 // is an inactive state. 9964 public boolean isSleepingOrShuttingDown() { 9965 return isSleeping() || mShuttingDown; 9966 } 9967 9968 public boolean isSleeping() { 9969 return mSleeping; 9970 } 9971 9972 void onWakefulnessChanged(int wakefulness) { 9973 synchronized(this) { 9974 mWakefulness = wakefulness; 9975 updateSleepIfNeededLocked(); 9976 } 9977 } 9978 9979 void finishRunningVoiceLocked() { 9980 if (mRunningVoice) { 9981 mRunningVoice = false; 9982 updateSleepIfNeededLocked(); 9983 } 9984 } 9985 9986 void updateSleepIfNeededLocked() { 9987 if (mSleeping && !shouldSleepLocked()) { 9988 mSleeping = false; 9989 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9990 } else if (!mSleeping && shouldSleepLocked()) { 9991 mSleeping = true; 9992 mStackSupervisor.goingToSleepLocked(); 9993 9994 // Initialize the wake times of all processes. 9995 checkExcessivePowerUsageLocked(false); 9996 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9997 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9998 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9999 } 10000 } 10001 10002 private boolean shouldSleepLocked() { 10003 // Resume applications while running a voice interactor. 10004 if (mRunningVoice) { 10005 return false; 10006 } 10007 10008 switch (mWakefulness) { 10009 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10010 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10011 // If we're interactive but applications are already paused then defer 10012 // resuming them until the lock screen is hidden. 10013 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10014 case PowerManagerInternal.WAKEFULNESS_DOZING: 10015 // If we're dozing then pause applications whenever the lock screen is shown. 10016 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10017 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10018 default: 10019 // If we're asleep then pause applications unconditionally. 10020 return true; 10021 } 10022 } 10023 10024 /** Pokes the task persister. */ 10025 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10026 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10027 // Never persist the home stack. 10028 return; 10029 } 10030 mTaskPersister.wakeup(task, flush); 10031 } 10032 10033 /** Notifies all listeners when the task stack has changed. */ 10034 void notifyTaskStackChangedLocked() { 10035 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10036 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10037 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10038 } 10039 10040 @Override 10041 public boolean shutdown(int timeout) { 10042 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10043 != PackageManager.PERMISSION_GRANTED) { 10044 throw new SecurityException("Requires permission " 10045 + android.Manifest.permission.SHUTDOWN); 10046 } 10047 10048 boolean timedout = false; 10049 10050 synchronized(this) { 10051 mShuttingDown = true; 10052 updateEventDispatchingLocked(); 10053 timedout = mStackSupervisor.shutdownLocked(timeout); 10054 } 10055 10056 mAppOpsService.shutdown(); 10057 if (mUsageStatsService != null) { 10058 mUsageStatsService.prepareShutdown(); 10059 } 10060 mBatteryStatsService.shutdown(); 10061 synchronized (this) { 10062 mProcessStats.shutdownLocked(); 10063 notifyTaskPersisterLocked(null, true); 10064 } 10065 10066 return timedout; 10067 } 10068 10069 public final void activitySlept(IBinder token) { 10070 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10071 10072 final long origId = Binder.clearCallingIdentity(); 10073 10074 synchronized (this) { 10075 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10076 if (r != null) { 10077 mStackSupervisor.activitySleptLocked(r); 10078 } 10079 } 10080 10081 Binder.restoreCallingIdentity(origId); 10082 } 10083 10084 private String lockScreenShownToString() { 10085 switch (mLockScreenShown) { 10086 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10087 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10088 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10089 default: return "Unknown=" + mLockScreenShown; 10090 } 10091 } 10092 10093 void logLockScreen(String msg) { 10094 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10095 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10096 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10097 + " mSleeping=" + mSleeping); 10098 } 10099 10100 void startRunningVoiceLocked() { 10101 if (!mRunningVoice) { 10102 mRunningVoice = true; 10103 updateSleepIfNeededLocked(); 10104 } 10105 } 10106 10107 private void updateEventDispatchingLocked() { 10108 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10109 } 10110 10111 public void setLockScreenShown(boolean shown) { 10112 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10113 != PackageManager.PERMISSION_GRANTED) { 10114 throw new SecurityException("Requires permission " 10115 + android.Manifest.permission.DEVICE_POWER); 10116 } 10117 10118 synchronized(this) { 10119 long ident = Binder.clearCallingIdentity(); 10120 try { 10121 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10122 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10123 updateSleepIfNeededLocked(); 10124 } finally { 10125 Binder.restoreCallingIdentity(ident); 10126 } 10127 } 10128 } 10129 10130 @Override 10131 public void stopAppSwitches() { 10132 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10133 != PackageManager.PERMISSION_GRANTED) { 10134 throw new SecurityException("Requires permission " 10135 + android.Manifest.permission.STOP_APP_SWITCHES); 10136 } 10137 10138 synchronized(this) { 10139 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10140 + APP_SWITCH_DELAY_TIME; 10141 mDidAppSwitch = false; 10142 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10143 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10144 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10145 } 10146 } 10147 10148 public void resumeAppSwitches() { 10149 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10150 != PackageManager.PERMISSION_GRANTED) { 10151 throw new SecurityException("Requires permission " 10152 + android.Manifest.permission.STOP_APP_SWITCHES); 10153 } 10154 10155 synchronized(this) { 10156 // Note that we don't execute any pending app switches... we will 10157 // let those wait until either the timeout, or the next start 10158 // activity request. 10159 mAppSwitchesAllowedTime = 0; 10160 } 10161 } 10162 10163 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10164 int callingPid, int callingUid, String name) { 10165 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10166 return true; 10167 } 10168 10169 int perm = checkComponentPermission( 10170 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10171 sourceUid, -1, true); 10172 if (perm == PackageManager.PERMISSION_GRANTED) { 10173 return true; 10174 } 10175 10176 // If the actual IPC caller is different from the logical source, then 10177 // also see if they are allowed to control app switches. 10178 if (callingUid != -1 && callingUid != sourceUid) { 10179 perm = checkComponentPermission( 10180 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10181 callingUid, -1, true); 10182 if (perm == PackageManager.PERMISSION_GRANTED) { 10183 return true; 10184 } 10185 } 10186 10187 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10188 return false; 10189 } 10190 10191 public void setDebugApp(String packageName, boolean waitForDebugger, 10192 boolean persistent) { 10193 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10194 "setDebugApp()"); 10195 10196 long ident = Binder.clearCallingIdentity(); 10197 try { 10198 // Note that this is not really thread safe if there are multiple 10199 // callers into it at the same time, but that's not a situation we 10200 // care about. 10201 if (persistent) { 10202 final ContentResolver resolver = mContext.getContentResolver(); 10203 Settings.Global.putString( 10204 resolver, Settings.Global.DEBUG_APP, 10205 packageName); 10206 Settings.Global.putInt( 10207 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10208 waitForDebugger ? 1 : 0); 10209 } 10210 10211 synchronized (this) { 10212 if (!persistent) { 10213 mOrigDebugApp = mDebugApp; 10214 mOrigWaitForDebugger = mWaitForDebugger; 10215 } 10216 mDebugApp = packageName; 10217 mWaitForDebugger = waitForDebugger; 10218 mDebugTransient = !persistent; 10219 if (packageName != null) { 10220 forceStopPackageLocked(packageName, -1, false, false, true, true, 10221 false, UserHandle.USER_ALL, "set debug app"); 10222 } 10223 } 10224 } finally { 10225 Binder.restoreCallingIdentity(ident); 10226 } 10227 } 10228 10229 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10230 synchronized (this) { 10231 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10232 if (!isDebuggable) { 10233 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10234 throw new SecurityException("Process not debuggable: " + app.packageName); 10235 } 10236 } 10237 10238 mOpenGlTraceApp = processName; 10239 } 10240 } 10241 10242 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10243 synchronized (this) { 10244 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10245 if (!isDebuggable) { 10246 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10247 throw new SecurityException("Process not debuggable: " + app.packageName); 10248 } 10249 } 10250 mProfileApp = processName; 10251 mProfileFile = profilerInfo.profileFile; 10252 if (mProfileFd != null) { 10253 try { 10254 mProfileFd.close(); 10255 } catch (IOException e) { 10256 } 10257 mProfileFd = null; 10258 } 10259 mProfileFd = profilerInfo.profileFd; 10260 mSamplingInterval = profilerInfo.samplingInterval; 10261 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10262 mProfileType = 0; 10263 } 10264 } 10265 10266 @Override 10267 public void setAlwaysFinish(boolean enabled) { 10268 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10269 "setAlwaysFinish()"); 10270 10271 Settings.Global.putInt( 10272 mContext.getContentResolver(), 10273 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10274 10275 synchronized (this) { 10276 mAlwaysFinishActivities = enabled; 10277 } 10278 } 10279 10280 @Override 10281 public void setActivityController(IActivityController controller) { 10282 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10283 "setActivityController()"); 10284 synchronized (this) { 10285 mController = controller; 10286 Watchdog.getInstance().setActivityController(controller); 10287 } 10288 } 10289 10290 @Override 10291 public void setUserIsMonkey(boolean userIsMonkey) { 10292 synchronized (this) { 10293 synchronized (mPidsSelfLocked) { 10294 final int callingPid = Binder.getCallingPid(); 10295 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10296 if (precessRecord == null) { 10297 throw new SecurityException("Unknown process: " + callingPid); 10298 } 10299 if (precessRecord.instrumentationUiAutomationConnection == null) { 10300 throw new SecurityException("Only an instrumentation process " 10301 + "with a UiAutomation can call setUserIsMonkey"); 10302 } 10303 } 10304 mUserIsMonkey = userIsMonkey; 10305 } 10306 } 10307 10308 @Override 10309 public boolean isUserAMonkey() { 10310 synchronized (this) { 10311 // If there is a controller also implies the user is a monkey. 10312 return (mUserIsMonkey || mController != null); 10313 } 10314 } 10315 10316 public void requestBugReport() { 10317 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10318 SystemProperties.set("ctl.start", "bugreport"); 10319 } 10320 10321 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10322 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10323 } 10324 10325 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10326 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10327 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10328 } 10329 return KEY_DISPATCHING_TIMEOUT; 10330 } 10331 10332 @Override 10333 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10334 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10335 != PackageManager.PERMISSION_GRANTED) { 10336 throw new SecurityException("Requires permission " 10337 + android.Manifest.permission.FILTER_EVENTS); 10338 } 10339 ProcessRecord proc; 10340 long timeout; 10341 synchronized (this) { 10342 synchronized (mPidsSelfLocked) { 10343 proc = mPidsSelfLocked.get(pid); 10344 } 10345 timeout = getInputDispatchingTimeoutLocked(proc); 10346 } 10347 10348 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10349 return -1; 10350 } 10351 10352 return timeout; 10353 } 10354 10355 /** 10356 * Handle input dispatching timeouts. 10357 * Returns whether input dispatching should be aborted or not. 10358 */ 10359 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10360 final ActivityRecord activity, final ActivityRecord parent, 10361 final boolean aboveSystem, String reason) { 10362 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10363 != PackageManager.PERMISSION_GRANTED) { 10364 throw new SecurityException("Requires permission " 10365 + android.Manifest.permission.FILTER_EVENTS); 10366 } 10367 10368 final String annotation; 10369 if (reason == null) { 10370 annotation = "Input dispatching timed out"; 10371 } else { 10372 annotation = "Input dispatching timed out (" + reason + ")"; 10373 } 10374 10375 if (proc != null) { 10376 synchronized (this) { 10377 if (proc.debugging) { 10378 return false; 10379 } 10380 10381 if (mDidDexOpt) { 10382 // Give more time since we were dexopting. 10383 mDidDexOpt = false; 10384 return false; 10385 } 10386 10387 if (proc.instrumentationClass != null) { 10388 Bundle info = new Bundle(); 10389 info.putString("shortMsg", "keyDispatchingTimedOut"); 10390 info.putString("longMsg", annotation); 10391 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10392 return true; 10393 } 10394 } 10395 mHandler.post(new Runnable() { 10396 @Override 10397 public void run() { 10398 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10399 } 10400 }); 10401 } 10402 10403 return true; 10404 } 10405 10406 public Bundle getAssistContextExtras(int requestType) { 10407 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10408 UserHandle.getCallingUserId()); 10409 if (pae == null) { 10410 return null; 10411 } 10412 synchronized (pae) { 10413 while (!pae.haveResult) { 10414 try { 10415 pae.wait(); 10416 } catch (InterruptedException e) { 10417 } 10418 } 10419 if (pae.result != null) { 10420 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10421 } 10422 } 10423 synchronized (this) { 10424 mPendingAssistExtras.remove(pae); 10425 mHandler.removeCallbacks(pae); 10426 } 10427 return pae.extras; 10428 } 10429 10430 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10431 int userHandle) { 10432 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10433 "getAssistContextExtras()"); 10434 PendingAssistExtras pae; 10435 Bundle extras = new Bundle(); 10436 synchronized (this) { 10437 ActivityRecord activity = getFocusedStack().mResumedActivity; 10438 if (activity == null) { 10439 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10440 return null; 10441 } 10442 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10443 if (activity.app == null || activity.app.thread == null) { 10444 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10445 return null; 10446 } 10447 if (activity.app.pid == Binder.getCallingPid()) { 10448 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10449 return null; 10450 } 10451 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10452 try { 10453 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10454 requestType); 10455 mPendingAssistExtras.add(pae); 10456 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10457 } catch (RemoteException e) { 10458 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10459 return null; 10460 } 10461 return pae; 10462 } 10463 } 10464 10465 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10466 PendingAssistExtras pae = (PendingAssistExtras)token; 10467 synchronized (pae) { 10468 pae.result = extras; 10469 pae.haveResult = true; 10470 pae.notifyAll(); 10471 if (pae.intent == null) { 10472 // Caller is just waiting for the result. 10473 return; 10474 } 10475 } 10476 10477 // We are now ready to launch the assist activity. 10478 synchronized (this) { 10479 boolean exists = mPendingAssistExtras.remove(pae); 10480 mHandler.removeCallbacks(pae); 10481 if (!exists) { 10482 // Timed out. 10483 return; 10484 } 10485 } 10486 pae.intent.replaceExtras(extras); 10487 if (pae.hint != null) { 10488 pae.intent.putExtra(pae.hint, true); 10489 } 10490 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10491 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10492 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10493 closeSystemDialogs("assist"); 10494 try { 10495 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10496 } catch (ActivityNotFoundException e) { 10497 Slog.w(TAG, "No activity to handle assist action.", e); 10498 } 10499 } 10500 10501 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10502 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10503 } 10504 10505 public void registerProcessObserver(IProcessObserver observer) { 10506 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10507 "registerProcessObserver()"); 10508 synchronized (this) { 10509 mProcessObservers.register(observer); 10510 } 10511 } 10512 10513 @Override 10514 public void unregisterProcessObserver(IProcessObserver observer) { 10515 synchronized (this) { 10516 mProcessObservers.unregister(observer); 10517 } 10518 } 10519 10520 @Override 10521 public boolean convertFromTranslucent(IBinder token) { 10522 final long origId = Binder.clearCallingIdentity(); 10523 try { 10524 synchronized (this) { 10525 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10526 if (r == null) { 10527 return false; 10528 } 10529 final boolean translucentChanged = r.changeWindowTranslucency(true); 10530 if (translucentChanged) { 10531 r.task.stack.releaseBackgroundResources(); 10532 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10533 } 10534 mWindowManager.setAppFullscreen(token, true); 10535 return translucentChanged; 10536 } 10537 } finally { 10538 Binder.restoreCallingIdentity(origId); 10539 } 10540 } 10541 10542 @Override 10543 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10544 final long origId = Binder.clearCallingIdentity(); 10545 try { 10546 synchronized (this) { 10547 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10548 if (r == null) { 10549 return false; 10550 } 10551 int index = r.task.mActivities.lastIndexOf(r); 10552 if (index > 0) { 10553 ActivityRecord under = r.task.mActivities.get(index - 1); 10554 under.returningOptions = options; 10555 } 10556 final boolean translucentChanged = r.changeWindowTranslucency(false); 10557 if (translucentChanged) { 10558 r.task.stack.convertToTranslucent(r); 10559 } 10560 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10561 mWindowManager.setAppFullscreen(token, false); 10562 return translucentChanged; 10563 } 10564 } finally { 10565 Binder.restoreCallingIdentity(origId); 10566 } 10567 } 10568 10569 @Override 10570 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10571 final long origId = Binder.clearCallingIdentity(); 10572 try { 10573 synchronized (this) { 10574 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10575 if (r != null) { 10576 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10577 } 10578 } 10579 return false; 10580 } finally { 10581 Binder.restoreCallingIdentity(origId); 10582 } 10583 } 10584 10585 @Override 10586 public boolean isBackgroundVisibleBehind(IBinder token) { 10587 final long origId = Binder.clearCallingIdentity(); 10588 try { 10589 synchronized (this) { 10590 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10591 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10592 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10593 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10594 return visible; 10595 } 10596 } finally { 10597 Binder.restoreCallingIdentity(origId); 10598 } 10599 } 10600 10601 @Override 10602 public ActivityOptions getActivityOptions(IBinder token) { 10603 final long origId = Binder.clearCallingIdentity(); 10604 try { 10605 synchronized (this) { 10606 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10607 if (r != null) { 10608 final ActivityOptions activityOptions = r.pendingOptions; 10609 r.pendingOptions = null; 10610 return activityOptions; 10611 } 10612 return null; 10613 } 10614 } finally { 10615 Binder.restoreCallingIdentity(origId); 10616 } 10617 } 10618 10619 @Override 10620 public void setImmersive(IBinder token, boolean immersive) { 10621 synchronized(this) { 10622 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10623 if (r == null) { 10624 throw new IllegalArgumentException(); 10625 } 10626 r.immersive = immersive; 10627 10628 // update associated state if we're frontmost 10629 if (r == mFocusedActivity) { 10630 if (DEBUG_IMMERSIVE) { 10631 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10632 } 10633 applyUpdateLockStateLocked(r); 10634 } 10635 } 10636 } 10637 10638 @Override 10639 public boolean isImmersive(IBinder token) { 10640 synchronized (this) { 10641 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10642 if (r == null) { 10643 throw new IllegalArgumentException(); 10644 } 10645 return r.immersive; 10646 } 10647 } 10648 10649 public boolean isTopActivityImmersive() { 10650 enforceNotIsolatedCaller("startActivity"); 10651 synchronized (this) { 10652 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10653 return (r != null) ? r.immersive : false; 10654 } 10655 } 10656 10657 @Override 10658 public boolean isTopOfTask(IBinder token) { 10659 synchronized (this) { 10660 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10661 if (r == null) { 10662 throw new IllegalArgumentException(); 10663 } 10664 return r.task.getTopActivity() == r; 10665 } 10666 } 10667 10668 public final void enterSafeMode() { 10669 synchronized(this) { 10670 // It only makes sense to do this before the system is ready 10671 // and started launching other packages. 10672 if (!mSystemReady) { 10673 try { 10674 AppGlobals.getPackageManager().enterSafeMode(); 10675 } catch (RemoteException e) { 10676 } 10677 } 10678 10679 mSafeMode = true; 10680 } 10681 } 10682 10683 public final void showSafeModeOverlay() { 10684 View v = LayoutInflater.from(mContext).inflate( 10685 com.android.internal.R.layout.safe_mode, null); 10686 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10687 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10688 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10689 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10690 lp.gravity = Gravity.BOTTOM | Gravity.START; 10691 lp.format = v.getBackground().getOpacity(); 10692 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10693 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10694 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10695 ((WindowManager)mContext.getSystemService( 10696 Context.WINDOW_SERVICE)).addView(v, lp); 10697 } 10698 10699 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10700 if (!(sender instanceof PendingIntentRecord)) { 10701 return; 10702 } 10703 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10704 synchronized (stats) { 10705 if (mBatteryStatsService.isOnBattery()) { 10706 mBatteryStatsService.enforceCallingPermission(); 10707 PendingIntentRecord rec = (PendingIntentRecord)sender; 10708 int MY_UID = Binder.getCallingUid(); 10709 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10710 BatteryStatsImpl.Uid.Pkg pkg = 10711 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10712 sourcePkg != null ? sourcePkg : rec.key.packageName); 10713 pkg.incWakeupsLocked(); 10714 } 10715 } 10716 } 10717 10718 public boolean killPids(int[] pids, String pReason, boolean secure) { 10719 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10720 throw new SecurityException("killPids only available to the system"); 10721 } 10722 String reason = (pReason == null) ? "Unknown" : pReason; 10723 // XXX Note: don't acquire main activity lock here, because the window 10724 // manager calls in with its locks held. 10725 10726 boolean killed = false; 10727 synchronized (mPidsSelfLocked) { 10728 int[] types = new int[pids.length]; 10729 int worstType = 0; 10730 for (int i=0; i<pids.length; i++) { 10731 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10732 if (proc != null) { 10733 int type = proc.setAdj; 10734 types[i] = type; 10735 if (type > worstType) { 10736 worstType = type; 10737 } 10738 } 10739 } 10740 10741 // If the worst oom_adj is somewhere in the cached proc LRU range, 10742 // then constrain it so we will kill all cached procs. 10743 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10744 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10745 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10746 } 10747 10748 // If this is not a secure call, don't let it kill processes that 10749 // are important. 10750 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10751 worstType = ProcessList.SERVICE_ADJ; 10752 } 10753 10754 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10755 for (int i=0; i<pids.length; i++) { 10756 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10757 if (proc == null) { 10758 continue; 10759 } 10760 int adj = proc.setAdj; 10761 if (adj >= worstType && !proc.killedByAm) { 10762 proc.kill(reason, true); 10763 killed = true; 10764 } 10765 } 10766 } 10767 return killed; 10768 } 10769 10770 @Override 10771 public void killUid(int uid, String reason) { 10772 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10773 throw new SecurityException("killUid only available to the system"); 10774 } 10775 synchronized (this) { 10776 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10777 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10778 reason != null ? reason : "kill uid"); 10779 } 10780 } 10781 10782 @Override 10783 public boolean killProcessesBelowForeground(String reason) { 10784 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10785 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10786 } 10787 10788 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10789 } 10790 10791 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10792 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10793 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10794 } 10795 10796 boolean killed = false; 10797 synchronized (mPidsSelfLocked) { 10798 final int size = mPidsSelfLocked.size(); 10799 for (int i = 0; i < size; i++) { 10800 final int pid = mPidsSelfLocked.keyAt(i); 10801 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10802 if (proc == null) continue; 10803 10804 final int adj = proc.setAdj; 10805 if (adj > belowAdj && !proc.killedByAm) { 10806 proc.kill(reason, true); 10807 killed = true; 10808 } 10809 } 10810 } 10811 return killed; 10812 } 10813 10814 @Override 10815 public void hang(final IBinder who, boolean allowRestart) { 10816 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10817 != PackageManager.PERMISSION_GRANTED) { 10818 throw new SecurityException("Requires permission " 10819 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10820 } 10821 10822 final IBinder.DeathRecipient death = new DeathRecipient() { 10823 @Override 10824 public void binderDied() { 10825 synchronized (this) { 10826 notifyAll(); 10827 } 10828 } 10829 }; 10830 10831 try { 10832 who.linkToDeath(death, 0); 10833 } catch (RemoteException e) { 10834 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10835 return; 10836 } 10837 10838 synchronized (this) { 10839 Watchdog.getInstance().setAllowRestart(allowRestart); 10840 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10841 synchronized (death) { 10842 while (who.isBinderAlive()) { 10843 try { 10844 death.wait(); 10845 } catch (InterruptedException e) { 10846 } 10847 } 10848 } 10849 Watchdog.getInstance().setAllowRestart(true); 10850 } 10851 } 10852 10853 @Override 10854 public void restart() { 10855 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10856 != PackageManager.PERMISSION_GRANTED) { 10857 throw new SecurityException("Requires permission " 10858 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10859 } 10860 10861 Log.i(TAG, "Sending shutdown broadcast..."); 10862 10863 BroadcastReceiver br = new BroadcastReceiver() { 10864 @Override public void onReceive(Context context, Intent intent) { 10865 // Now the broadcast is done, finish up the low-level shutdown. 10866 Log.i(TAG, "Shutting down activity manager..."); 10867 shutdown(10000); 10868 Log.i(TAG, "Shutdown complete, restarting!"); 10869 Process.killProcess(Process.myPid()); 10870 System.exit(10); 10871 } 10872 }; 10873 10874 // First send the high-level shut down broadcast. 10875 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10876 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10877 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10878 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10879 mContext.sendOrderedBroadcastAsUser(intent, 10880 UserHandle.ALL, null, br, mHandler, 0, null, null); 10881 */ 10882 br.onReceive(mContext, intent); 10883 } 10884 10885 private long getLowRamTimeSinceIdle(long now) { 10886 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10887 } 10888 10889 @Override 10890 public void performIdleMaintenance() { 10891 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10892 != PackageManager.PERMISSION_GRANTED) { 10893 throw new SecurityException("Requires permission " 10894 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10895 } 10896 10897 synchronized (this) { 10898 final long now = SystemClock.uptimeMillis(); 10899 final long timeSinceLastIdle = now - mLastIdleTime; 10900 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10901 mLastIdleTime = now; 10902 mLowRamTimeSinceLastIdle = 0; 10903 if (mLowRamStartTime != 0) { 10904 mLowRamStartTime = now; 10905 } 10906 10907 StringBuilder sb = new StringBuilder(128); 10908 sb.append("Idle maintenance over "); 10909 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10910 sb.append(" low RAM for "); 10911 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10912 Slog.i(TAG, sb.toString()); 10913 10914 // If at least 1/3 of our time since the last idle period has been spent 10915 // with RAM low, then we want to kill processes. 10916 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10917 10918 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10919 ProcessRecord proc = mLruProcesses.get(i); 10920 if (proc.notCachedSinceIdle) { 10921 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10922 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10923 if (doKilling && proc.initialIdlePss != 0 10924 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10925 sb = new StringBuilder(128); 10926 sb.append("Kill"); 10927 sb.append(proc.processName); 10928 sb.append(" in idle maint: pss="); 10929 sb.append(proc.lastPss); 10930 sb.append(", initialPss="); 10931 sb.append(proc.initialIdlePss); 10932 sb.append(", period="); 10933 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10934 sb.append(", lowRamPeriod="); 10935 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10936 Slog.wtfQuiet(TAG, sb.toString()); 10937 proc.kill("idle maint (pss " + proc.lastPss 10938 + " from " + proc.initialIdlePss + ")", true); 10939 } 10940 } 10941 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10942 proc.notCachedSinceIdle = true; 10943 proc.initialIdlePss = 0; 10944 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10945 mTestPssMode, isSleeping(), now); 10946 } 10947 } 10948 10949 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10950 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10951 } 10952 } 10953 10954 private void retrieveSettings() { 10955 final ContentResolver resolver = mContext.getContentResolver(); 10956 String debugApp = Settings.Global.getString( 10957 resolver, Settings.Global.DEBUG_APP); 10958 boolean waitForDebugger = Settings.Global.getInt( 10959 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10960 boolean alwaysFinishActivities = Settings.Global.getInt( 10961 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10962 boolean forceRtl = Settings.Global.getInt( 10963 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10964 // Transfer any global setting for forcing RTL layout, into a System Property 10965 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10966 10967 Configuration configuration = new Configuration(); 10968 Settings.System.getConfiguration(resolver, configuration); 10969 if (forceRtl) { 10970 // This will take care of setting the correct layout direction flags 10971 configuration.setLayoutDirection(configuration.locale); 10972 } 10973 10974 synchronized (this) { 10975 mDebugApp = mOrigDebugApp = debugApp; 10976 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10977 mAlwaysFinishActivities = alwaysFinishActivities; 10978 // This happens before any activities are started, so we can 10979 // change mConfiguration in-place. 10980 updateConfigurationLocked(configuration, null, false, true); 10981 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10982 } 10983 } 10984 10985 /** Loads resources after the current configuration has been set. */ 10986 private void loadResourcesOnSystemReady() { 10987 final Resources res = mContext.getResources(); 10988 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10989 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10990 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10991 } 10992 10993 public boolean testIsSystemReady() { 10994 // no need to synchronize(this) just to read & return the value 10995 return mSystemReady; 10996 } 10997 10998 private static File getCalledPreBootReceiversFile() { 10999 File dataDir = Environment.getDataDirectory(); 11000 File systemDir = new File(dataDir, "system"); 11001 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11002 return fname; 11003 } 11004 11005 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11006 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11007 File file = getCalledPreBootReceiversFile(); 11008 FileInputStream fis = null; 11009 try { 11010 fis = new FileInputStream(file); 11011 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11012 int fvers = dis.readInt(); 11013 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11014 String vers = dis.readUTF(); 11015 String codename = dis.readUTF(); 11016 String build = dis.readUTF(); 11017 if (android.os.Build.VERSION.RELEASE.equals(vers) 11018 && android.os.Build.VERSION.CODENAME.equals(codename) 11019 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11020 int num = dis.readInt(); 11021 while (num > 0) { 11022 num--; 11023 String pkg = dis.readUTF(); 11024 String cls = dis.readUTF(); 11025 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11026 } 11027 } 11028 } 11029 } catch (FileNotFoundException e) { 11030 } catch (IOException e) { 11031 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11032 } finally { 11033 if (fis != null) { 11034 try { 11035 fis.close(); 11036 } catch (IOException e) { 11037 } 11038 } 11039 } 11040 return lastDoneReceivers; 11041 } 11042 11043 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11044 File file = getCalledPreBootReceiversFile(); 11045 FileOutputStream fos = null; 11046 DataOutputStream dos = null; 11047 try { 11048 fos = new FileOutputStream(file); 11049 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11050 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11051 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11052 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11053 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11054 dos.writeInt(list.size()); 11055 for (int i=0; i<list.size(); i++) { 11056 dos.writeUTF(list.get(i).getPackageName()); 11057 dos.writeUTF(list.get(i).getClassName()); 11058 } 11059 } catch (IOException e) { 11060 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11061 file.delete(); 11062 } finally { 11063 FileUtils.sync(fos); 11064 if (dos != null) { 11065 try { 11066 dos.close(); 11067 } catch (IOException e) { 11068 // TODO Auto-generated catch block 11069 e.printStackTrace(); 11070 } 11071 } 11072 } 11073 } 11074 11075 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11076 ArrayList<ComponentName> doneReceivers, int userId) { 11077 boolean waitingUpdate = false; 11078 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11079 List<ResolveInfo> ris = null; 11080 try { 11081 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11082 intent, null, 0, userId); 11083 } catch (RemoteException e) { 11084 } 11085 if (ris != null) { 11086 for (int i=ris.size()-1; i>=0; i--) { 11087 if ((ris.get(i).activityInfo.applicationInfo.flags 11088 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11089 ris.remove(i); 11090 } 11091 } 11092 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11093 11094 // For User 0, load the version number. When delivering to a new user, deliver 11095 // to all receivers. 11096 if (userId == UserHandle.USER_OWNER) { 11097 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11098 for (int i=0; i<ris.size(); i++) { 11099 ActivityInfo ai = ris.get(i).activityInfo; 11100 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11101 if (lastDoneReceivers.contains(comp)) { 11102 // We already did the pre boot receiver for this app with the current 11103 // platform version, so don't do it again... 11104 ris.remove(i); 11105 i--; 11106 // ...however, do keep it as one that has been done, so we don't 11107 // forget about it when rewriting the file of last done receivers. 11108 doneReceivers.add(comp); 11109 } 11110 } 11111 } 11112 11113 // If primary user, send broadcast to all available users, else just to userId 11114 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11115 : new int[] { userId }; 11116 for (int i = 0; i < ris.size(); i++) { 11117 ActivityInfo ai = ris.get(i).activityInfo; 11118 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11119 doneReceivers.add(comp); 11120 intent.setComponent(comp); 11121 for (int j=0; j<users.length; j++) { 11122 IIntentReceiver finisher = null; 11123 // On last receiver and user, set up a completion callback 11124 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11125 finisher = new IIntentReceiver.Stub() { 11126 public void performReceive(Intent intent, int resultCode, 11127 String data, Bundle extras, boolean ordered, 11128 boolean sticky, int sendingUser) { 11129 // The raw IIntentReceiver interface is called 11130 // with the AM lock held, so redispatch to 11131 // execute our code without the lock. 11132 mHandler.post(onFinishCallback); 11133 } 11134 }; 11135 } 11136 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11137 + " for user " + users[j]); 11138 broadcastIntentLocked(null, null, intent, null, finisher, 11139 0, null, null, null, AppOpsManager.OP_NONE, 11140 true, false, MY_PID, Process.SYSTEM_UID, 11141 users[j]); 11142 if (finisher != null) { 11143 waitingUpdate = true; 11144 } 11145 } 11146 } 11147 } 11148 11149 return waitingUpdate; 11150 } 11151 11152 public void systemReady(final Runnable goingCallback) { 11153 synchronized(this) { 11154 if (mSystemReady) { 11155 // If we're done calling all the receivers, run the next "boot phase" passed in 11156 // by the SystemServer 11157 if (goingCallback != null) { 11158 goingCallback.run(); 11159 } 11160 return; 11161 } 11162 11163 // Make sure we have the current profile info, since it is needed for 11164 // security checks. 11165 updateCurrentProfileIdsLocked(); 11166 11167 if (mRecentTasks == null) { 11168 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11169 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11170 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11171 mTaskPersister.startPersisting(); 11172 } 11173 11174 // Check to see if there are any update receivers to run. 11175 if (!mDidUpdate) { 11176 if (mWaitingUpdate) { 11177 return; 11178 } 11179 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11180 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11181 public void run() { 11182 synchronized (ActivityManagerService.this) { 11183 mDidUpdate = true; 11184 } 11185 writeLastDonePreBootReceivers(doneReceivers); 11186 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11187 false); 11188 systemReady(goingCallback); 11189 } 11190 }, doneReceivers, UserHandle.USER_OWNER); 11191 11192 if (mWaitingUpdate) { 11193 return; 11194 } 11195 mDidUpdate = true; 11196 } 11197 11198 mAppOpsService.systemReady(); 11199 mSystemReady = true; 11200 } 11201 11202 ArrayList<ProcessRecord> procsToKill = null; 11203 synchronized(mPidsSelfLocked) { 11204 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11205 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11206 if (!isAllowedWhileBooting(proc.info)){ 11207 if (procsToKill == null) { 11208 procsToKill = new ArrayList<ProcessRecord>(); 11209 } 11210 procsToKill.add(proc); 11211 } 11212 } 11213 } 11214 11215 synchronized(this) { 11216 if (procsToKill != null) { 11217 for (int i=procsToKill.size()-1; i>=0; i--) { 11218 ProcessRecord proc = procsToKill.get(i); 11219 Slog.i(TAG, "Removing system update proc: " + proc); 11220 removeProcessLocked(proc, true, false, "system update done"); 11221 } 11222 } 11223 11224 // Now that we have cleaned up any update processes, we 11225 // are ready to start launching real processes and know that 11226 // we won't trample on them any more. 11227 mProcessesReady = true; 11228 } 11229 11230 Slog.i(TAG, "System now ready"); 11231 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11232 SystemClock.uptimeMillis()); 11233 11234 synchronized(this) { 11235 // Make sure we have no pre-ready processes sitting around. 11236 11237 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11238 ResolveInfo ri = mContext.getPackageManager() 11239 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11240 STOCK_PM_FLAGS); 11241 CharSequence errorMsg = null; 11242 if (ri != null) { 11243 ActivityInfo ai = ri.activityInfo; 11244 ApplicationInfo app = ai.applicationInfo; 11245 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11246 mTopAction = Intent.ACTION_FACTORY_TEST; 11247 mTopData = null; 11248 mTopComponent = new ComponentName(app.packageName, 11249 ai.name); 11250 } else { 11251 errorMsg = mContext.getResources().getText( 11252 com.android.internal.R.string.factorytest_not_system); 11253 } 11254 } else { 11255 errorMsg = mContext.getResources().getText( 11256 com.android.internal.R.string.factorytest_no_action); 11257 } 11258 if (errorMsg != null) { 11259 mTopAction = null; 11260 mTopData = null; 11261 mTopComponent = null; 11262 Message msg = Message.obtain(); 11263 msg.what = SHOW_FACTORY_ERROR_MSG; 11264 msg.getData().putCharSequence("msg", errorMsg); 11265 mHandler.sendMessage(msg); 11266 } 11267 } 11268 } 11269 11270 retrieveSettings(); 11271 loadResourcesOnSystemReady(); 11272 11273 synchronized (this) { 11274 readGrantedUriPermissionsLocked(); 11275 } 11276 11277 if (goingCallback != null) goingCallback.run(); 11278 11279 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11280 Integer.toString(mCurrentUserId), mCurrentUserId); 11281 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11282 Integer.toString(mCurrentUserId), mCurrentUserId); 11283 mSystemServiceManager.startUser(mCurrentUserId); 11284 11285 synchronized (this) { 11286 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11287 try { 11288 List apps = AppGlobals.getPackageManager(). 11289 getPersistentApplications(STOCK_PM_FLAGS); 11290 if (apps != null) { 11291 int N = apps.size(); 11292 int i; 11293 for (i=0; i<N; i++) { 11294 ApplicationInfo info 11295 = (ApplicationInfo)apps.get(i); 11296 if (info != null && 11297 !info.packageName.equals("android")) { 11298 addAppLocked(info, false, null /* ABI override */); 11299 } 11300 } 11301 } 11302 } catch (RemoteException ex) { 11303 // pm is in same process, this will never happen. 11304 } 11305 } 11306 11307 // Start up initial activity. 11308 mBooting = true; 11309 startHomeActivityLocked(mCurrentUserId); 11310 11311 try { 11312 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11313 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11314 + " data partition or your device will be unstable."); 11315 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11316 } 11317 } catch (RemoteException e) { 11318 } 11319 11320 if (!Build.isFingerprintConsistent()) { 11321 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11322 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11323 } 11324 11325 long ident = Binder.clearCallingIdentity(); 11326 try { 11327 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11328 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11329 | Intent.FLAG_RECEIVER_FOREGROUND); 11330 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11331 broadcastIntentLocked(null, null, intent, 11332 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11333 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11334 intent = new Intent(Intent.ACTION_USER_STARTING); 11335 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11336 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11337 broadcastIntentLocked(null, null, intent, 11338 null, new IIntentReceiver.Stub() { 11339 @Override 11340 public void performReceive(Intent intent, int resultCode, String data, 11341 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11342 throws RemoteException { 11343 } 11344 }, 0, null, null, 11345 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11346 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11347 } catch (Throwable t) { 11348 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11349 } finally { 11350 Binder.restoreCallingIdentity(ident); 11351 } 11352 mStackSupervisor.resumeTopActivitiesLocked(); 11353 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11354 } 11355 } 11356 11357 private boolean makeAppCrashingLocked(ProcessRecord app, 11358 String shortMsg, String longMsg, String stackTrace) { 11359 app.crashing = true; 11360 app.crashingReport = generateProcessError(app, 11361 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11362 startAppProblemLocked(app); 11363 app.stopFreezingAllLocked(); 11364 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11365 } 11366 11367 private void makeAppNotRespondingLocked(ProcessRecord app, 11368 String activity, String shortMsg, String longMsg) { 11369 app.notResponding = true; 11370 app.notRespondingReport = generateProcessError(app, 11371 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11372 activity, shortMsg, longMsg, null); 11373 startAppProblemLocked(app); 11374 app.stopFreezingAllLocked(); 11375 } 11376 11377 /** 11378 * Generate a process error record, suitable for attachment to a ProcessRecord. 11379 * 11380 * @param app The ProcessRecord in which the error occurred. 11381 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11382 * ActivityManager.AppErrorStateInfo 11383 * @param activity The activity associated with the crash, if known. 11384 * @param shortMsg Short message describing the crash. 11385 * @param longMsg Long message describing the crash. 11386 * @param stackTrace Full crash stack trace, may be null. 11387 * 11388 * @return Returns a fully-formed AppErrorStateInfo record. 11389 */ 11390 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11391 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11392 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11393 11394 report.condition = condition; 11395 report.processName = app.processName; 11396 report.pid = app.pid; 11397 report.uid = app.info.uid; 11398 report.tag = activity; 11399 report.shortMsg = shortMsg; 11400 report.longMsg = longMsg; 11401 report.stackTrace = stackTrace; 11402 11403 return report; 11404 } 11405 11406 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11407 synchronized (this) { 11408 app.crashing = false; 11409 app.crashingReport = null; 11410 app.notResponding = false; 11411 app.notRespondingReport = null; 11412 if (app.anrDialog == fromDialog) { 11413 app.anrDialog = null; 11414 } 11415 if (app.waitDialog == fromDialog) { 11416 app.waitDialog = null; 11417 } 11418 if (app.pid > 0 && app.pid != MY_PID) { 11419 handleAppCrashLocked(app, null, null, null); 11420 app.kill("user request after error", true); 11421 } 11422 } 11423 } 11424 11425 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11426 String stackTrace) { 11427 long now = SystemClock.uptimeMillis(); 11428 11429 Long crashTime; 11430 if (!app.isolated) { 11431 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11432 } else { 11433 crashTime = null; 11434 } 11435 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11436 // This process loses! 11437 Slog.w(TAG, "Process " + app.info.processName 11438 + " has crashed too many times: killing!"); 11439 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11440 app.userId, app.info.processName, app.uid); 11441 mStackSupervisor.handleAppCrashLocked(app); 11442 if (!app.persistent) { 11443 // We don't want to start this process again until the user 11444 // explicitly does so... but for persistent process, we really 11445 // need to keep it running. If a persistent process is actually 11446 // repeatedly crashing, then badness for everyone. 11447 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11448 app.info.processName); 11449 if (!app.isolated) { 11450 // XXX We don't have a way to mark isolated processes 11451 // as bad, since they don't have a peristent identity. 11452 mBadProcesses.put(app.info.processName, app.uid, 11453 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11454 mProcessCrashTimes.remove(app.info.processName, app.uid); 11455 } 11456 app.bad = true; 11457 app.removed = true; 11458 // Don't let services in this process be restarted and potentially 11459 // annoy the user repeatedly. Unless it is persistent, since those 11460 // processes run critical code. 11461 removeProcessLocked(app, false, false, "crash"); 11462 mStackSupervisor.resumeTopActivitiesLocked(); 11463 return false; 11464 } 11465 mStackSupervisor.resumeTopActivitiesLocked(); 11466 } else { 11467 mStackSupervisor.finishTopRunningActivityLocked(app); 11468 } 11469 11470 // Bump up the crash count of any services currently running in the proc. 11471 for (int i=app.services.size()-1; i>=0; i--) { 11472 // Any services running in the application need to be placed 11473 // back in the pending list. 11474 ServiceRecord sr = app.services.valueAt(i); 11475 sr.crashCount++; 11476 } 11477 11478 // If the crashing process is what we consider to be the "home process" and it has been 11479 // replaced by a third-party app, clear the package preferred activities from packages 11480 // with a home activity running in the process to prevent a repeatedly crashing app 11481 // from blocking the user to manually clear the list. 11482 final ArrayList<ActivityRecord> activities = app.activities; 11483 if (app == mHomeProcess && activities.size() > 0 11484 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11485 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11486 final ActivityRecord r = activities.get(activityNdx); 11487 if (r.isHomeActivity()) { 11488 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11489 try { 11490 ActivityThread.getPackageManager() 11491 .clearPackagePreferredActivities(r.packageName); 11492 } catch (RemoteException c) { 11493 // pm is in same process, this will never happen. 11494 } 11495 } 11496 } 11497 } 11498 11499 if (!app.isolated) { 11500 // XXX Can't keep track of crash times for isolated processes, 11501 // because they don't have a perisistent identity. 11502 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11503 } 11504 11505 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11506 return true; 11507 } 11508 11509 void startAppProblemLocked(ProcessRecord app) { 11510 // If this app is not running under the current user, then we 11511 // can't give it a report button because that would require 11512 // launching the report UI under a different user. 11513 app.errorReportReceiver = null; 11514 11515 for (int userId : mCurrentProfileIds) { 11516 if (app.userId == userId) { 11517 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11518 mContext, app.info.packageName, app.info.flags); 11519 } 11520 } 11521 skipCurrentReceiverLocked(app); 11522 } 11523 11524 void skipCurrentReceiverLocked(ProcessRecord app) { 11525 for (BroadcastQueue queue : mBroadcastQueues) { 11526 queue.skipCurrentReceiverLocked(app); 11527 } 11528 } 11529 11530 /** 11531 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11532 * The application process will exit immediately after this call returns. 11533 * @param app object of the crashing app, null for the system server 11534 * @param crashInfo describing the exception 11535 */ 11536 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11537 ProcessRecord r = findAppProcess(app, "Crash"); 11538 final String processName = app == null ? "system_server" 11539 : (r == null ? "unknown" : r.processName); 11540 11541 handleApplicationCrashInner("crash", r, processName, crashInfo); 11542 } 11543 11544 /* Native crash reporting uses this inner version because it needs to be somewhat 11545 * decoupled from the AM-managed cleanup lifecycle 11546 */ 11547 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11548 ApplicationErrorReport.CrashInfo crashInfo) { 11549 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11550 UserHandle.getUserId(Binder.getCallingUid()), processName, 11551 r == null ? -1 : r.info.flags, 11552 crashInfo.exceptionClassName, 11553 crashInfo.exceptionMessage, 11554 crashInfo.throwFileName, 11555 crashInfo.throwLineNumber); 11556 11557 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11558 11559 crashApplication(r, crashInfo); 11560 } 11561 11562 public void handleApplicationStrictModeViolation( 11563 IBinder app, 11564 int violationMask, 11565 StrictMode.ViolationInfo info) { 11566 ProcessRecord r = findAppProcess(app, "StrictMode"); 11567 if (r == null) { 11568 return; 11569 } 11570 11571 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11572 Integer stackFingerprint = info.hashCode(); 11573 boolean logIt = true; 11574 synchronized (mAlreadyLoggedViolatedStacks) { 11575 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11576 logIt = false; 11577 // TODO: sub-sample into EventLog for these, with 11578 // the info.durationMillis? Then we'd get 11579 // the relative pain numbers, without logging all 11580 // the stack traces repeatedly. We'd want to do 11581 // likewise in the client code, which also does 11582 // dup suppression, before the Binder call. 11583 } else { 11584 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11585 mAlreadyLoggedViolatedStacks.clear(); 11586 } 11587 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11588 } 11589 } 11590 if (logIt) { 11591 logStrictModeViolationToDropBox(r, info); 11592 } 11593 } 11594 11595 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11596 AppErrorResult result = new AppErrorResult(); 11597 synchronized (this) { 11598 final long origId = Binder.clearCallingIdentity(); 11599 11600 Message msg = Message.obtain(); 11601 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11602 HashMap<String, Object> data = new HashMap<String, Object>(); 11603 data.put("result", result); 11604 data.put("app", r); 11605 data.put("violationMask", violationMask); 11606 data.put("info", info); 11607 msg.obj = data; 11608 mHandler.sendMessage(msg); 11609 11610 Binder.restoreCallingIdentity(origId); 11611 } 11612 int res = result.get(); 11613 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11614 } 11615 } 11616 11617 // Depending on the policy in effect, there could be a bunch of 11618 // these in quick succession so we try to batch these together to 11619 // minimize disk writes, number of dropbox entries, and maximize 11620 // compression, by having more fewer, larger records. 11621 private void logStrictModeViolationToDropBox( 11622 ProcessRecord process, 11623 StrictMode.ViolationInfo info) { 11624 if (info == null) { 11625 return; 11626 } 11627 final boolean isSystemApp = process == null || 11628 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11629 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11630 final String processName = process == null ? "unknown" : process.processName; 11631 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11632 final DropBoxManager dbox = (DropBoxManager) 11633 mContext.getSystemService(Context.DROPBOX_SERVICE); 11634 11635 // Exit early if the dropbox isn't configured to accept this report type. 11636 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11637 11638 boolean bufferWasEmpty; 11639 boolean needsFlush; 11640 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11641 synchronized (sb) { 11642 bufferWasEmpty = sb.length() == 0; 11643 appendDropBoxProcessHeaders(process, processName, sb); 11644 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11645 sb.append("System-App: ").append(isSystemApp).append("\n"); 11646 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11647 if (info.violationNumThisLoop != 0) { 11648 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11649 } 11650 if (info.numAnimationsRunning != 0) { 11651 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11652 } 11653 if (info.broadcastIntentAction != null) { 11654 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11655 } 11656 if (info.durationMillis != -1) { 11657 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11658 } 11659 if (info.numInstances != -1) { 11660 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11661 } 11662 if (info.tags != null) { 11663 for (String tag : info.tags) { 11664 sb.append("Span-Tag: ").append(tag).append("\n"); 11665 } 11666 } 11667 sb.append("\n"); 11668 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11669 sb.append(info.crashInfo.stackTrace); 11670 } 11671 sb.append("\n"); 11672 11673 // Only buffer up to ~64k. Various logging bits truncate 11674 // things at 128k. 11675 needsFlush = (sb.length() > 64 * 1024); 11676 } 11677 11678 // Flush immediately if the buffer's grown too large, or this 11679 // is a non-system app. Non-system apps are isolated with a 11680 // different tag & policy and not batched. 11681 // 11682 // Batching is useful during internal testing with 11683 // StrictMode settings turned up high. Without batching, 11684 // thousands of separate files could be created on boot. 11685 if (!isSystemApp || needsFlush) { 11686 new Thread("Error dump: " + dropboxTag) { 11687 @Override 11688 public void run() { 11689 String report; 11690 synchronized (sb) { 11691 report = sb.toString(); 11692 sb.delete(0, sb.length()); 11693 sb.trimToSize(); 11694 } 11695 if (report.length() != 0) { 11696 dbox.addText(dropboxTag, report); 11697 } 11698 } 11699 }.start(); 11700 return; 11701 } 11702 11703 // System app batching: 11704 if (!bufferWasEmpty) { 11705 // An existing dropbox-writing thread is outstanding, so 11706 // we don't need to start it up. The existing thread will 11707 // catch the buffer appends we just did. 11708 return; 11709 } 11710 11711 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11712 // (After this point, we shouldn't access AMS internal data structures.) 11713 new Thread("Error dump: " + dropboxTag) { 11714 @Override 11715 public void run() { 11716 // 5 second sleep to let stacks arrive and be batched together 11717 try { 11718 Thread.sleep(5000); // 5 seconds 11719 } catch (InterruptedException e) {} 11720 11721 String errorReport; 11722 synchronized (mStrictModeBuffer) { 11723 errorReport = mStrictModeBuffer.toString(); 11724 if (errorReport.length() == 0) { 11725 return; 11726 } 11727 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11728 mStrictModeBuffer.trimToSize(); 11729 } 11730 dbox.addText(dropboxTag, errorReport); 11731 } 11732 }.start(); 11733 } 11734 11735 /** 11736 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11737 * @param app object of the crashing app, null for the system server 11738 * @param tag reported by the caller 11739 * @param system whether this wtf is coming from the system 11740 * @param crashInfo describing the context of the error 11741 * @return true if the process should exit immediately (WTF is fatal) 11742 */ 11743 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11744 final ApplicationErrorReport.CrashInfo crashInfo) { 11745 final int callingUid = Binder.getCallingUid(); 11746 final int callingPid = Binder.getCallingPid(); 11747 11748 if (system) { 11749 // If this is coming from the system, we could very well have low-level 11750 // system locks held, so we want to do this all asynchronously. And we 11751 // never want this to become fatal, so there is that too. 11752 mHandler.post(new Runnable() { 11753 @Override public void run() { 11754 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11755 } 11756 }); 11757 return false; 11758 } 11759 11760 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11761 crashInfo); 11762 11763 if (r != null && r.pid != Process.myPid() && 11764 Settings.Global.getInt(mContext.getContentResolver(), 11765 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11766 crashApplication(r, crashInfo); 11767 return true; 11768 } else { 11769 return false; 11770 } 11771 } 11772 11773 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11774 final ApplicationErrorReport.CrashInfo crashInfo) { 11775 final ProcessRecord r = findAppProcess(app, "WTF"); 11776 final String processName = app == null ? "system_server" 11777 : (r == null ? "unknown" : r.processName); 11778 11779 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11780 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11781 11782 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11783 11784 return r; 11785 } 11786 11787 /** 11788 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11789 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11790 */ 11791 private ProcessRecord findAppProcess(IBinder app, String reason) { 11792 if (app == null) { 11793 return null; 11794 } 11795 11796 synchronized (this) { 11797 final int NP = mProcessNames.getMap().size(); 11798 for (int ip=0; ip<NP; ip++) { 11799 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11800 final int NA = apps.size(); 11801 for (int ia=0; ia<NA; ia++) { 11802 ProcessRecord p = apps.valueAt(ia); 11803 if (p.thread != null && p.thread.asBinder() == app) { 11804 return p; 11805 } 11806 } 11807 } 11808 11809 Slog.w(TAG, "Can't find mystery application for " + reason 11810 + " from pid=" + Binder.getCallingPid() 11811 + " uid=" + Binder.getCallingUid() + ": " + app); 11812 return null; 11813 } 11814 } 11815 11816 /** 11817 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11818 * to append various headers to the dropbox log text. 11819 */ 11820 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11821 StringBuilder sb) { 11822 // Watchdog thread ends up invoking this function (with 11823 // a null ProcessRecord) to add the stack file to dropbox. 11824 // Do not acquire a lock on this (am) in such cases, as it 11825 // could cause a potential deadlock, if and when watchdog 11826 // is invoked due to unavailability of lock on am and it 11827 // would prevent watchdog from killing system_server. 11828 if (process == null) { 11829 sb.append("Process: ").append(processName).append("\n"); 11830 return; 11831 } 11832 // Note: ProcessRecord 'process' is guarded by the service 11833 // instance. (notably process.pkgList, which could otherwise change 11834 // concurrently during execution of this method) 11835 synchronized (this) { 11836 sb.append("Process: ").append(processName).append("\n"); 11837 int flags = process.info.flags; 11838 IPackageManager pm = AppGlobals.getPackageManager(); 11839 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11840 for (int ip=0; ip<process.pkgList.size(); ip++) { 11841 String pkg = process.pkgList.keyAt(ip); 11842 sb.append("Package: ").append(pkg); 11843 try { 11844 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11845 if (pi != null) { 11846 sb.append(" v").append(pi.versionCode); 11847 if (pi.versionName != null) { 11848 sb.append(" (").append(pi.versionName).append(")"); 11849 } 11850 } 11851 } catch (RemoteException e) { 11852 Slog.e(TAG, "Error getting package info: " + pkg, e); 11853 } 11854 sb.append("\n"); 11855 } 11856 } 11857 } 11858 11859 private static String processClass(ProcessRecord process) { 11860 if (process == null || process.pid == MY_PID) { 11861 return "system_server"; 11862 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11863 return "system_app"; 11864 } else { 11865 return "data_app"; 11866 } 11867 } 11868 11869 /** 11870 * Write a description of an error (crash, WTF, ANR) to the drop box. 11871 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11872 * @param process which caused the error, null means the system server 11873 * @param activity which triggered the error, null if unknown 11874 * @param parent activity related to the error, null if unknown 11875 * @param subject line related to the error, null if absent 11876 * @param report in long form describing the error, null if absent 11877 * @param logFile to include in the report, null if none 11878 * @param crashInfo giving an application stack trace, null if absent 11879 */ 11880 public void addErrorToDropBox(String eventType, 11881 ProcessRecord process, String processName, ActivityRecord activity, 11882 ActivityRecord parent, String subject, 11883 final String report, final File logFile, 11884 final ApplicationErrorReport.CrashInfo crashInfo) { 11885 // NOTE -- this must never acquire the ActivityManagerService lock, 11886 // otherwise the watchdog may be prevented from resetting the system. 11887 11888 final String dropboxTag = processClass(process) + "_" + eventType; 11889 final DropBoxManager dbox = (DropBoxManager) 11890 mContext.getSystemService(Context.DROPBOX_SERVICE); 11891 11892 // Exit early if the dropbox isn't configured to accept this report type. 11893 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11894 11895 final StringBuilder sb = new StringBuilder(1024); 11896 appendDropBoxProcessHeaders(process, processName, sb); 11897 if (activity != null) { 11898 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11899 } 11900 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11901 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11902 } 11903 if (parent != null && parent != activity) { 11904 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11905 } 11906 if (subject != null) { 11907 sb.append("Subject: ").append(subject).append("\n"); 11908 } 11909 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11910 if (Debug.isDebuggerConnected()) { 11911 sb.append("Debugger: Connected\n"); 11912 } 11913 sb.append("\n"); 11914 11915 // Do the rest in a worker thread to avoid blocking the caller on I/O 11916 // (After this point, we shouldn't access AMS internal data structures.) 11917 Thread worker = new Thread("Error dump: " + dropboxTag) { 11918 @Override 11919 public void run() { 11920 if (report != null) { 11921 sb.append(report); 11922 } 11923 if (logFile != null) { 11924 try { 11925 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11926 "\n\n[[TRUNCATED]]")); 11927 } catch (IOException e) { 11928 Slog.e(TAG, "Error reading " + logFile, e); 11929 } 11930 } 11931 if (crashInfo != null && crashInfo.stackTrace != null) { 11932 sb.append(crashInfo.stackTrace); 11933 } 11934 11935 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11936 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11937 if (lines > 0) { 11938 sb.append("\n"); 11939 11940 // Merge several logcat streams, and take the last N lines 11941 InputStreamReader input = null; 11942 try { 11943 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11944 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11945 "-b", "crash", 11946 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11947 11948 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11949 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11950 input = new InputStreamReader(logcat.getInputStream()); 11951 11952 int num; 11953 char[] buf = new char[8192]; 11954 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11955 } catch (IOException e) { 11956 Slog.e(TAG, "Error running logcat", e); 11957 } finally { 11958 if (input != null) try { input.close(); } catch (IOException e) {} 11959 } 11960 } 11961 11962 dbox.addText(dropboxTag, sb.toString()); 11963 } 11964 }; 11965 11966 if (process == null) { 11967 // If process is null, we are being called from some internal code 11968 // and may be about to die -- run this synchronously. 11969 worker.run(); 11970 } else { 11971 worker.start(); 11972 } 11973 } 11974 11975 /** 11976 * Bring up the "unexpected error" dialog box for a crashing app. 11977 * Deal with edge cases (intercepts from instrumented applications, 11978 * ActivityController, error intent receivers, that sort of thing). 11979 * @param r the application crashing 11980 * @param crashInfo describing the failure 11981 */ 11982 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11983 long timeMillis = System.currentTimeMillis(); 11984 String shortMsg = crashInfo.exceptionClassName; 11985 String longMsg = crashInfo.exceptionMessage; 11986 String stackTrace = crashInfo.stackTrace; 11987 if (shortMsg != null && longMsg != null) { 11988 longMsg = shortMsg + ": " + longMsg; 11989 } else if (shortMsg != null) { 11990 longMsg = shortMsg; 11991 } 11992 11993 AppErrorResult result = new AppErrorResult(); 11994 synchronized (this) { 11995 if (mController != null) { 11996 try { 11997 String name = r != null ? r.processName : null; 11998 int pid = r != null ? r.pid : Binder.getCallingPid(); 11999 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12000 if (!mController.appCrashed(name, pid, 12001 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12002 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12003 && "Native crash".equals(crashInfo.exceptionClassName)) { 12004 Slog.w(TAG, "Skip killing native crashed app " + name 12005 + "(" + pid + ") during testing"); 12006 } else { 12007 Slog.w(TAG, "Force-killing crashed app " + name 12008 + " at watcher's request"); 12009 if (r != null) { 12010 r.kill("crash", true); 12011 } else { 12012 // Huh. 12013 Process.killProcess(pid); 12014 Process.killProcessGroup(uid, pid); 12015 } 12016 } 12017 return; 12018 } 12019 } catch (RemoteException e) { 12020 mController = null; 12021 Watchdog.getInstance().setActivityController(null); 12022 } 12023 } 12024 12025 final long origId = Binder.clearCallingIdentity(); 12026 12027 // If this process is running instrumentation, finish it. 12028 if (r != null && r.instrumentationClass != null) { 12029 Slog.w(TAG, "Error in app " + r.processName 12030 + " running instrumentation " + r.instrumentationClass + ":"); 12031 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12032 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12033 Bundle info = new Bundle(); 12034 info.putString("shortMsg", shortMsg); 12035 info.putString("longMsg", longMsg); 12036 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12037 Binder.restoreCallingIdentity(origId); 12038 return; 12039 } 12040 12041 // Log crash in battery stats. 12042 if (r != null) { 12043 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12044 } 12045 12046 // If we can't identify the process or it's already exceeded its crash quota, 12047 // quit right away without showing a crash dialog. 12048 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12049 Binder.restoreCallingIdentity(origId); 12050 return; 12051 } 12052 12053 Message msg = Message.obtain(); 12054 msg.what = SHOW_ERROR_MSG; 12055 HashMap data = new HashMap(); 12056 data.put("result", result); 12057 data.put("app", r); 12058 msg.obj = data; 12059 mHandler.sendMessage(msg); 12060 12061 Binder.restoreCallingIdentity(origId); 12062 } 12063 12064 int res = result.get(); 12065 12066 Intent appErrorIntent = null; 12067 synchronized (this) { 12068 if (r != null && !r.isolated) { 12069 // XXX Can't keep track of crash time for isolated processes, 12070 // since they don't have a persistent identity. 12071 mProcessCrashTimes.put(r.info.processName, r.uid, 12072 SystemClock.uptimeMillis()); 12073 } 12074 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12075 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12076 } 12077 } 12078 12079 if (appErrorIntent != null) { 12080 try { 12081 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12082 } catch (ActivityNotFoundException e) { 12083 Slog.w(TAG, "bug report receiver dissappeared", e); 12084 } 12085 } 12086 } 12087 12088 Intent createAppErrorIntentLocked(ProcessRecord r, 12089 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12090 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12091 if (report == null) { 12092 return null; 12093 } 12094 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12095 result.setComponent(r.errorReportReceiver); 12096 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12097 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12098 return result; 12099 } 12100 12101 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12102 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12103 if (r.errorReportReceiver == null) { 12104 return null; 12105 } 12106 12107 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12108 return null; 12109 } 12110 12111 ApplicationErrorReport report = new ApplicationErrorReport(); 12112 report.packageName = r.info.packageName; 12113 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12114 report.processName = r.processName; 12115 report.time = timeMillis; 12116 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12117 12118 if (r.crashing || r.forceCrashReport) { 12119 report.type = ApplicationErrorReport.TYPE_CRASH; 12120 report.crashInfo = crashInfo; 12121 } else if (r.notResponding) { 12122 report.type = ApplicationErrorReport.TYPE_ANR; 12123 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12124 12125 report.anrInfo.activity = r.notRespondingReport.tag; 12126 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12127 report.anrInfo.info = r.notRespondingReport.longMsg; 12128 } 12129 12130 return report; 12131 } 12132 12133 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12134 enforceNotIsolatedCaller("getProcessesInErrorState"); 12135 // assume our apps are happy - lazy create the list 12136 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12137 12138 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12139 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12140 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12141 12142 synchronized (this) { 12143 12144 // iterate across all processes 12145 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12146 ProcessRecord app = mLruProcesses.get(i); 12147 if (!allUsers && app.userId != userId) { 12148 continue; 12149 } 12150 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12151 // This one's in trouble, so we'll generate a report for it 12152 // crashes are higher priority (in case there's a crash *and* an anr) 12153 ActivityManager.ProcessErrorStateInfo report = null; 12154 if (app.crashing) { 12155 report = app.crashingReport; 12156 } else if (app.notResponding) { 12157 report = app.notRespondingReport; 12158 } 12159 12160 if (report != null) { 12161 if (errList == null) { 12162 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12163 } 12164 errList.add(report); 12165 } else { 12166 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12167 " crashing = " + app.crashing + 12168 " notResponding = " + app.notResponding); 12169 } 12170 } 12171 } 12172 } 12173 12174 return errList; 12175 } 12176 12177 static int procStateToImportance(int procState, int memAdj, 12178 ActivityManager.RunningAppProcessInfo currApp) { 12179 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12180 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12181 currApp.lru = memAdj; 12182 } else { 12183 currApp.lru = 0; 12184 } 12185 return imp; 12186 } 12187 12188 private void fillInProcMemInfo(ProcessRecord app, 12189 ActivityManager.RunningAppProcessInfo outInfo) { 12190 outInfo.pid = app.pid; 12191 outInfo.uid = app.info.uid; 12192 if (mHeavyWeightProcess == app) { 12193 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12194 } 12195 if (app.persistent) { 12196 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12197 } 12198 if (app.activities.size() > 0) { 12199 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12200 } 12201 outInfo.lastTrimLevel = app.trimMemoryLevel; 12202 int adj = app.curAdj; 12203 int procState = app.curProcState; 12204 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12205 outInfo.importanceReasonCode = app.adjTypeCode; 12206 outInfo.processState = app.curProcState; 12207 } 12208 12209 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12210 enforceNotIsolatedCaller("getRunningAppProcesses"); 12211 // Lazy instantiation of list 12212 List<ActivityManager.RunningAppProcessInfo> runList = null; 12213 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12214 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12215 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12216 synchronized (this) { 12217 // Iterate across all processes 12218 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12219 ProcessRecord app = mLruProcesses.get(i); 12220 if (!allUsers && app.userId != userId) { 12221 continue; 12222 } 12223 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12224 // Generate process state info for running application 12225 ActivityManager.RunningAppProcessInfo currApp = 12226 new ActivityManager.RunningAppProcessInfo(app.processName, 12227 app.pid, app.getPackageList()); 12228 fillInProcMemInfo(app, currApp); 12229 if (app.adjSource instanceof ProcessRecord) { 12230 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12231 currApp.importanceReasonImportance = 12232 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12233 app.adjSourceProcState); 12234 } else if (app.adjSource instanceof ActivityRecord) { 12235 ActivityRecord r = (ActivityRecord)app.adjSource; 12236 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12237 } 12238 if (app.adjTarget instanceof ComponentName) { 12239 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12240 } 12241 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12242 // + " lru=" + currApp.lru); 12243 if (runList == null) { 12244 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12245 } 12246 runList.add(currApp); 12247 } 12248 } 12249 } 12250 return runList; 12251 } 12252 12253 public List<ApplicationInfo> getRunningExternalApplications() { 12254 enforceNotIsolatedCaller("getRunningExternalApplications"); 12255 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12256 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12257 if (runningApps != null && runningApps.size() > 0) { 12258 Set<String> extList = new HashSet<String>(); 12259 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12260 if (app.pkgList != null) { 12261 for (String pkg : app.pkgList) { 12262 extList.add(pkg); 12263 } 12264 } 12265 } 12266 IPackageManager pm = AppGlobals.getPackageManager(); 12267 for (String pkg : extList) { 12268 try { 12269 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12270 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12271 retList.add(info); 12272 } 12273 } catch (RemoteException e) { 12274 } 12275 } 12276 } 12277 return retList; 12278 } 12279 12280 @Override 12281 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12282 enforceNotIsolatedCaller("getMyMemoryState"); 12283 synchronized (this) { 12284 ProcessRecord proc; 12285 synchronized (mPidsSelfLocked) { 12286 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12287 } 12288 fillInProcMemInfo(proc, outInfo); 12289 } 12290 } 12291 12292 @Override 12293 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12294 if (checkCallingPermission(android.Manifest.permission.DUMP) 12295 != PackageManager.PERMISSION_GRANTED) { 12296 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12297 + Binder.getCallingPid() 12298 + ", uid=" + Binder.getCallingUid() 12299 + " without permission " 12300 + android.Manifest.permission.DUMP); 12301 return; 12302 } 12303 12304 boolean dumpAll = false; 12305 boolean dumpClient = false; 12306 String dumpPackage = null; 12307 12308 int opti = 0; 12309 while (opti < args.length) { 12310 String opt = args[opti]; 12311 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12312 break; 12313 } 12314 opti++; 12315 if ("-a".equals(opt)) { 12316 dumpAll = true; 12317 } else if ("-c".equals(opt)) { 12318 dumpClient = true; 12319 } else if ("-h".equals(opt)) { 12320 pw.println("Activity manager dump options:"); 12321 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12322 pw.println(" cmd may be one of:"); 12323 pw.println(" a[ctivities]: activity stack state"); 12324 pw.println(" r[recents]: recent activities state"); 12325 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12326 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12327 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12328 pw.println(" o[om]: out of memory management"); 12329 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12330 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12331 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12332 pw.println(" service [COMP_SPEC]: service client-side state"); 12333 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12334 pw.println(" all: dump all activities"); 12335 pw.println(" top: dump the top activity"); 12336 pw.println(" write: write all pending state to storage"); 12337 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12338 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12339 pw.println(" a partial substring in a component name, a"); 12340 pw.println(" hex object identifier."); 12341 pw.println(" -a: include all available server state."); 12342 pw.println(" -c: include client state."); 12343 return; 12344 } else { 12345 pw.println("Unknown argument: " + opt + "; use -h for help"); 12346 } 12347 } 12348 12349 long origId = Binder.clearCallingIdentity(); 12350 boolean more = false; 12351 // Is the caller requesting to dump a particular piece of data? 12352 if (opti < args.length) { 12353 String cmd = args[opti]; 12354 opti++; 12355 if ("activities".equals(cmd) || "a".equals(cmd)) { 12356 synchronized (this) { 12357 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12358 } 12359 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12360 synchronized (this) { 12361 dumpRecentsLocked(fd, pw, args, opti, true, null); 12362 } 12363 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12364 String[] newArgs; 12365 String name; 12366 if (opti >= args.length) { 12367 name = null; 12368 newArgs = EMPTY_STRING_ARRAY; 12369 } else { 12370 name = args[opti]; 12371 opti++; 12372 newArgs = new String[args.length - opti]; 12373 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12374 args.length - opti); 12375 } 12376 synchronized (this) { 12377 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12378 } 12379 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12380 String[] newArgs; 12381 String name; 12382 if (opti >= args.length) { 12383 name = null; 12384 newArgs = EMPTY_STRING_ARRAY; 12385 } else { 12386 name = args[opti]; 12387 opti++; 12388 newArgs = new String[args.length - opti]; 12389 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12390 args.length - opti); 12391 } 12392 synchronized (this) { 12393 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12394 } 12395 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12396 String[] newArgs; 12397 String name; 12398 if (opti >= args.length) { 12399 name = null; 12400 newArgs = EMPTY_STRING_ARRAY; 12401 } else { 12402 name = args[opti]; 12403 opti++; 12404 newArgs = new String[args.length - opti]; 12405 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12406 args.length - opti); 12407 } 12408 synchronized (this) { 12409 dumpProcessesLocked(fd, pw, args, opti, true, name); 12410 } 12411 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12412 synchronized (this) { 12413 dumpOomLocked(fd, pw, args, opti, true); 12414 } 12415 } else if ("provider".equals(cmd)) { 12416 String[] newArgs; 12417 String name; 12418 if (opti >= args.length) { 12419 name = null; 12420 newArgs = EMPTY_STRING_ARRAY; 12421 } else { 12422 name = args[opti]; 12423 opti++; 12424 newArgs = new String[args.length - opti]; 12425 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12426 } 12427 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12428 pw.println("No providers match: " + name); 12429 pw.println("Use -h for help."); 12430 } 12431 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12432 synchronized (this) { 12433 dumpProvidersLocked(fd, pw, args, opti, true, null); 12434 } 12435 } else if ("service".equals(cmd)) { 12436 String[] newArgs; 12437 String name; 12438 if (opti >= args.length) { 12439 name = null; 12440 newArgs = EMPTY_STRING_ARRAY; 12441 } else { 12442 name = args[opti]; 12443 opti++; 12444 newArgs = new String[args.length - opti]; 12445 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12446 args.length - opti); 12447 } 12448 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12449 pw.println("No services match: " + name); 12450 pw.println("Use -h for help."); 12451 } 12452 } else if ("package".equals(cmd)) { 12453 String[] newArgs; 12454 if (opti >= args.length) { 12455 pw.println("package: no package name specified"); 12456 pw.println("Use -h for help."); 12457 } else { 12458 dumpPackage = args[opti]; 12459 opti++; 12460 newArgs = new String[args.length - opti]; 12461 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12462 args.length - opti); 12463 args = newArgs; 12464 opti = 0; 12465 more = true; 12466 } 12467 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12468 synchronized (this) { 12469 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12470 } 12471 } else if ("write".equals(cmd)) { 12472 mTaskPersister.flush(); 12473 pw.println("All tasks persisted."); 12474 return; 12475 } else { 12476 // Dumping a single activity? 12477 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12478 pw.println("Bad activity command, or no activities match: " + cmd); 12479 pw.println("Use -h for help."); 12480 } 12481 } 12482 if (!more) { 12483 Binder.restoreCallingIdentity(origId); 12484 return; 12485 } 12486 } 12487 12488 // No piece of data specified, dump everything. 12489 synchronized (this) { 12490 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12491 pw.println(); 12492 if (dumpAll) { 12493 pw.println("-------------------------------------------------------------------------------"); 12494 } 12495 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12496 pw.println(); 12497 if (dumpAll) { 12498 pw.println("-------------------------------------------------------------------------------"); 12499 } 12500 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12501 pw.println(); 12502 if (dumpAll) { 12503 pw.println("-------------------------------------------------------------------------------"); 12504 } 12505 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12506 pw.println(); 12507 if (dumpAll) { 12508 pw.println("-------------------------------------------------------------------------------"); 12509 } 12510 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12511 pw.println(); 12512 if (dumpAll) { 12513 pw.println("-------------------------------------------------------------------------------"); 12514 } 12515 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12516 pw.println(); 12517 if (dumpAll) { 12518 pw.println("-------------------------------------------------------------------------------"); 12519 } 12520 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12521 } 12522 Binder.restoreCallingIdentity(origId); 12523 } 12524 12525 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12526 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12527 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12528 12529 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12530 dumpPackage); 12531 boolean needSep = printedAnything; 12532 12533 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12534 dumpPackage, needSep, " mFocusedActivity: "); 12535 if (printed) { 12536 printedAnything = true; 12537 needSep = false; 12538 } 12539 12540 if (dumpPackage == null) { 12541 if (needSep) { 12542 pw.println(); 12543 } 12544 needSep = true; 12545 printedAnything = true; 12546 mStackSupervisor.dump(pw, " "); 12547 } 12548 12549 if (!printedAnything) { 12550 pw.println(" (nothing)"); 12551 } 12552 } 12553 12554 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12555 int opti, boolean dumpAll, String dumpPackage) { 12556 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12557 12558 boolean printedAnything = false; 12559 12560 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12561 boolean printedHeader = false; 12562 12563 final int N = mRecentTasks.size(); 12564 for (int i=0; i<N; i++) { 12565 TaskRecord tr = mRecentTasks.get(i); 12566 if (dumpPackage != null) { 12567 if (tr.realActivity == null || 12568 !dumpPackage.equals(tr.realActivity)) { 12569 continue; 12570 } 12571 } 12572 if (!printedHeader) { 12573 pw.println(" Recent tasks:"); 12574 printedHeader = true; 12575 printedAnything = true; 12576 } 12577 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12578 pw.println(tr); 12579 if (dumpAll) { 12580 mRecentTasks.get(i).dump(pw, " "); 12581 } 12582 } 12583 } 12584 12585 if (!printedAnything) { 12586 pw.println(" (nothing)"); 12587 } 12588 } 12589 12590 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12591 int opti, boolean dumpAll, String dumpPackage) { 12592 boolean needSep = false; 12593 boolean printedAnything = false; 12594 int numPers = 0; 12595 12596 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12597 12598 if (dumpAll) { 12599 final int NP = mProcessNames.getMap().size(); 12600 for (int ip=0; ip<NP; ip++) { 12601 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12602 final int NA = procs.size(); 12603 for (int ia=0; ia<NA; ia++) { 12604 ProcessRecord r = procs.valueAt(ia); 12605 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12606 continue; 12607 } 12608 if (!needSep) { 12609 pw.println(" All known processes:"); 12610 needSep = true; 12611 printedAnything = true; 12612 } 12613 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12614 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12615 pw.print(" "); pw.println(r); 12616 r.dump(pw, " "); 12617 if (r.persistent) { 12618 numPers++; 12619 } 12620 } 12621 } 12622 } 12623 12624 if (mIsolatedProcesses.size() > 0) { 12625 boolean printed = false; 12626 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12627 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12628 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12629 continue; 12630 } 12631 if (!printed) { 12632 if (needSep) { 12633 pw.println(); 12634 } 12635 pw.println(" Isolated process list (sorted by uid):"); 12636 printedAnything = true; 12637 printed = true; 12638 needSep = true; 12639 } 12640 pw.println(String.format("%sIsolated #%2d: %s", 12641 " ", i, r.toString())); 12642 } 12643 } 12644 12645 if (mLruProcesses.size() > 0) { 12646 if (needSep) { 12647 pw.println(); 12648 } 12649 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12650 pw.print(" total, non-act at "); 12651 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12652 pw.print(", non-svc at "); 12653 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12654 pw.println("):"); 12655 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12656 needSep = true; 12657 printedAnything = true; 12658 } 12659 12660 if (dumpAll || dumpPackage != null) { 12661 synchronized (mPidsSelfLocked) { 12662 boolean printed = false; 12663 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12664 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12665 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12666 continue; 12667 } 12668 if (!printed) { 12669 if (needSep) pw.println(); 12670 needSep = true; 12671 pw.println(" PID mappings:"); 12672 printed = true; 12673 printedAnything = true; 12674 } 12675 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12676 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12677 } 12678 } 12679 } 12680 12681 if (mForegroundProcesses.size() > 0) { 12682 synchronized (mPidsSelfLocked) { 12683 boolean printed = false; 12684 for (int i=0; i<mForegroundProcesses.size(); i++) { 12685 ProcessRecord r = mPidsSelfLocked.get( 12686 mForegroundProcesses.valueAt(i).pid); 12687 if (dumpPackage != null && (r == null 12688 || !r.pkgList.containsKey(dumpPackage))) { 12689 continue; 12690 } 12691 if (!printed) { 12692 if (needSep) pw.println(); 12693 needSep = true; 12694 pw.println(" Foreground Processes:"); 12695 printed = true; 12696 printedAnything = true; 12697 } 12698 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12699 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12700 } 12701 } 12702 } 12703 12704 if (mPersistentStartingProcesses.size() > 0) { 12705 if (needSep) pw.println(); 12706 needSep = true; 12707 printedAnything = true; 12708 pw.println(" Persisent processes that are starting:"); 12709 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12710 "Starting Norm", "Restarting PERS", dumpPackage); 12711 } 12712 12713 if (mRemovedProcesses.size() > 0) { 12714 if (needSep) pw.println(); 12715 needSep = true; 12716 printedAnything = true; 12717 pw.println(" Processes that are being removed:"); 12718 dumpProcessList(pw, this, mRemovedProcesses, " ", 12719 "Removed Norm", "Removed PERS", dumpPackage); 12720 } 12721 12722 if (mProcessesOnHold.size() > 0) { 12723 if (needSep) pw.println(); 12724 needSep = true; 12725 printedAnything = true; 12726 pw.println(" Processes that are on old until the system is ready:"); 12727 dumpProcessList(pw, this, mProcessesOnHold, " ", 12728 "OnHold Norm", "OnHold PERS", dumpPackage); 12729 } 12730 12731 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12732 12733 if (mProcessCrashTimes.getMap().size() > 0) { 12734 boolean printed = false; 12735 long now = SystemClock.uptimeMillis(); 12736 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12737 final int NP = pmap.size(); 12738 for (int ip=0; ip<NP; ip++) { 12739 String pname = pmap.keyAt(ip); 12740 SparseArray<Long> uids = pmap.valueAt(ip); 12741 final int N = uids.size(); 12742 for (int i=0; i<N; i++) { 12743 int puid = uids.keyAt(i); 12744 ProcessRecord r = mProcessNames.get(pname, puid); 12745 if (dumpPackage != null && (r == null 12746 || !r.pkgList.containsKey(dumpPackage))) { 12747 continue; 12748 } 12749 if (!printed) { 12750 if (needSep) pw.println(); 12751 needSep = true; 12752 pw.println(" Time since processes crashed:"); 12753 printed = true; 12754 printedAnything = true; 12755 } 12756 pw.print(" Process "); pw.print(pname); 12757 pw.print(" uid "); pw.print(puid); 12758 pw.print(": last crashed "); 12759 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12760 pw.println(" ago"); 12761 } 12762 } 12763 } 12764 12765 if (mBadProcesses.getMap().size() > 0) { 12766 boolean printed = false; 12767 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12768 final int NP = pmap.size(); 12769 for (int ip=0; ip<NP; ip++) { 12770 String pname = pmap.keyAt(ip); 12771 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12772 final int N = uids.size(); 12773 for (int i=0; i<N; i++) { 12774 int puid = uids.keyAt(i); 12775 ProcessRecord r = mProcessNames.get(pname, puid); 12776 if (dumpPackage != null && (r == null 12777 || !r.pkgList.containsKey(dumpPackage))) { 12778 continue; 12779 } 12780 if (!printed) { 12781 if (needSep) pw.println(); 12782 needSep = true; 12783 pw.println(" Bad processes:"); 12784 printedAnything = true; 12785 } 12786 BadProcessInfo info = uids.valueAt(i); 12787 pw.print(" Bad process "); pw.print(pname); 12788 pw.print(" uid "); pw.print(puid); 12789 pw.print(": crashed at time "); pw.println(info.time); 12790 if (info.shortMsg != null) { 12791 pw.print(" Short msg: "); pw.println(info.shortMsg); 12792 } 12793 if (info.longMsg != null) { 12794 pw.print(" Long msg: "); pw.println(info.longMsg); 12795 } 12796 if (info.stack != null) { 12797 pw.println(" Stack:"); 12798 int lastPos = 0; 12799 for (int pos=0; pos<info.stack.length(); pos++) { 12800 if (info.stack.charAt(pos) == '\n') { 12801 pw.print(" "); 12802 pw.write(info.stack, lastPos, pos-lastPos); 12803 pw.println(); 12804 lastPos = pos+1; 12805 } 12806 } 12807 if (lastPos < info.stack.length()) { 12808 pw.print(" "); 12809 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12810 pw.println(); 12811 } 12812 } 12813 } 12814 } 12815 } 12816 12817 if (dumpPackage == null) { 12818 pw.println(); 12819 needSep = false; 12820 pw.println(" mStartedUsers:"); 12821 for (int i=0; i<mStartedUsers.size(); i++) { 12822 UserStartedState uss = mStartedUsers.valueAt(i); 12823 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12824 pw.print(": "); uss.dump("", pw); 12825 } 12826 pw.print(" mStartedUserArray: ["); 12827 for (int i=0; i<mStartedUserArray.length; i++) { 12828 if (i > 0) pw.print(", "); 12829 pw.print(mStartedUserArray[i]); 12830 } 12831 pw.println("]"); 12832 pw.print(" mUserLru: ["); 12833 for (int i=0; i<mUserLru.size(); i++) { 12834 if (i > 0) pw.print(", "); 12835 pw.print(mUserLru.get(i)); 12836 } 12837 pw.println("]"); 12838 if (dumpAll) { 12839 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12840 } 12841 synchronized (mUserProfileGroupIdsSelfLocked) { 12842 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12843 pw.println(" mUserProfileGroupIds:"); 12844 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12845 pw.print(" User #"); 12846 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12847 pw.print(" -> profile #"); 12848 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12849 } 12850 } 12851 } 12852 } 12853 if (mHomeProcess != null && (dumpPackage == null 12854 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12855 if (needSep) { 12856 pw.println(); 12857 needSep = false; 12858 } 12859 pw.println(" mHomeProcess: " + mHomeProcess); 12860 } 12861 if (mPreviousProcess != null && (dumpPackage == null 12862 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12863 if (needSep) { 12864 pw.println(); 12865 needSep = false; 12866 } 12867 pw.println(" mPreviousProcess: " + mPreviousProcess); 12868 } 12869 if (dumpAll) { 12870 StringBuilder sb = new StringBuilder(128); 12871 sb.append(" mPreviousProcessVisibleTime: "); 12872 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12873 pw.println(sb); 12874 } 12875 if (mHeavyWeightProcess != null && (dumpPackage == null 12876 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12877 if (needSep) { 12878 pw.println(); 12879 needSep = false; 12880 } 12881 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12882 } 12883 if (dumpPackage == null) { 12884 pw.println(" mConfiguration: " + mConfiguration); 12885 } 12886 if (dumpAll) { 12887 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12888 if (mCompatModePackages.getPackages().size() > 0) { 12889 boolean printed = false; 12890 for (Map.Entry<String, Integer> entry 12891 : mCompatModePackages.getPackages().entrySet()) { 12892 String pkg = entry.getKey(); 12893 int mode = entry.getValue(); 12894 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12895 continue; 12896 } 12897 if (!printed) { 12898 pw.println(" mScreenCompatPackages:"); 12899 printed = true; 12900 } 12901 pw.print(" "); pw.print(pkg); pw.print(": "); 12902 pw.print(mode); pw.println(); 12903 } 12904 } 12905 } 12906 if (dumpPackage == null) { 12907 pw.println(" mWakefulness=" 12908 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12909 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12910 + lockScreenShownToString()); 12911 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 12912 + " mTestPssMode=" + mTestPssMode); 12913 } 12914 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12915 || mOrigWaitForDebugger) { 12916 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12917 || dumpPackage.equals(mOrigDebugApp)) { 12918 if (needSep) { 12919 pw.println(); 12920 needSep = false; 12921 } 12922 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12923 + " mDebugTransient=" + mDebugTransient 12924 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12925 } 12926 } 12927 if (mOpenGlTraceApp != null) { 12928 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12929 if (needSep) { 12930 pw.println(); 12931 needSep = false; 12932 } 12933 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12934 } 12935 } 12936 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12937 || mProfileFd != null) { 12938 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12939 if (needSep) { 12940 pw.println(); 12941 needSep = false; 12942 } 12943 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12944 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12945 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12946 + mAutoStopProfiler); 12947 pw.println(" mProfileType=" + mProfileType); 12948 } 12949 } 12950 if (dumpPackage == null) { 12951 if (mAlwaysFinishActivities || mController != null) { 12952 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12953 + " mController=" + mController); 12954 } 12955 if (dumpAll) { 12956 pw.println(" Total persistent processes: " + numPers); 12957 pw.println(" mProcessesReady=" + mProcessesReady 12958 + " mSystemReady=" + mSystemReady 12959 + " mBooted=" + mBooted 12960 + " mFactoryTest=" + mFactoryTest); 12961 pw.println(" mBooting=" + mBooting 12962 + " mCallFinishBooting=" + mCallFinishBooting 12963 + " mBootAnimationComplete=" + mBootAnimationComplete); 12964 pw.print(" mLastPowerCheckRealtime="); 12965 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12966 pw.println(""); 12967 pw.print(" mLastPowerCheckUptime="); 12968 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12969 pw.println(""); 12970 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12971 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12972 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12973 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12974 + " (" + mLruProcesses.size() + " total)" 12975 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12976 + " mNumServiceProcs=" + mNumServiceProcs 12977 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12978 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12979 + " mLastMemoryLevel" + mLastMemoryLevel 12980 + " mLastNumProcesses" + mLastNumProcesses); 12981 long now = SystemClock.uptimeMillis(); 12982 pw.print(" mLastIdleTime="); 12983 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12984 pw.print(" mLowRamSinceLastIdle="); 12985 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12986 pw.println(); 12987 } 12988 } 12989 12990 if (!printedAnything) { 12991 pw.println(" (nothing)"); 12992 } 12993 } 12994 12995 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12996 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12997 if (mProcessesToGc.size() > 0) { 12998 boolean printed = false; 12999 long now = SystemClock.uptimeMillis(); 13000 for (int i=0; i<mProcessesToGc.size(); i++) { 13001 ProcessRecord proc = mProcessesToGc.get(i); 13002 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13003 continue; 13004 } 13005 if (!printed) { 13006 if (needSep) pw.println(); 13007 needSep = true; 13008 pw.println(" Processes that are waiting to GC:"); 13009 printed = true; 13010 } 13011 pw.print(" Process "); pw.println(proc); 13012 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13013 pw.print(", last gced="); 13014 pw.print(now-proc.lastRequestedGc); 13015 pw.print(" ms ago, last lowMem="); 13016 pw.print(now-proc.lastLowMemory); 13017 pw.println(" ms ago"); 13018 13019 } 13020 } 13021 return needSep; 13022 } 13023 13024 void printOomLevel(PrintWriter pw, String name, int adj) { 13025 pw.print(" "); 13026 if (adj >= 0) { 13027 pw.print(' '); 13028 if (adj < 10) pw.print(' '); 13029 } else { 13030 if (adj > -10) pw.print(' '); 13031 } 13032 pw.print(adj); 13033 pw.print(": "); 13034 pw.print(name); 13035 pw.print(" ("); 13036 pw.print(mProcessList.getMemLevel(adj)/1024); 13037 pw.println(" kB)"); 13038 } 13039 13040 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13041 int opti, boolean dumpAll) { 13042 boolean needSep = false; 13043 13044 if (mLruProcesses.size() > 0) { 13045 if (needSep) pw.println(); 13046 needSep = true; 13047 pw.println(" OOM levels:"); 13048 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13049 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13050 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13051 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13052 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13053 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13054 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13055 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13056 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13057 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13058 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13059 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13060 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13061 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13062 13063 if (needSep) pw.println(); 13064 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13065 pw.print(" total, non-act at "); 13066 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13067 pw.print(", non-svc at "); 13068 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13069 pw.println("):"); 13070 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13071 needSep = true; 13072 } 13073 13074 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13075 13076 pw.println(); 13077 pw.println(" mHomeProcess: " + mHomeProcess); 13078 pw.println(" mPreviousProcess: " + mPreviousProcess); 13079 if (mHeavyWeightProcess != null) { 13080 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13081 } 13082 13083 return true; 13084 } 13085 13086 /** 13087 * There are three ways to call this: 13088 * - no provider specified: dump all the providers 13089 * - a flattened component name that matched an existing provider was specified as the 13090 * first arg: dump that one provider 13091 * - the first arg isn't the flattened component name of an existing provider: 13092 * dump all providers whose component contains the first arg as a substring 13093 */ 13094 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13095 int opti, boolean dumpAll) { 13096 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13097 } 13098 13099 static class ItemMatcher { 13100 ArrayList<ComponentName> components; 13101 ArrayList<String> strings; 13102 ArrayList<Integer> objects; 13103 boolean all; 13104 13105 ItemMatcher() { 13106 all = true; 13107 } 13108 13109 void build(String name) { 13110 ComponentName componentName = ComponentName.unflattenFromString(name); 13111 if (componentName != null) { 13112 if (components == null) { 13113 components = new ArrayList<ComponentName>(); 13114 } 13115 components.add(componentName); 13116 all = false; 13117 } else { 13118 int objectId = 0; 13119 // Not a '/' separated full component name; maybe an object ID? 13120 try { 13121 objectId = Integer.parseInt(name, 16); 13122 if (objects == null) { 13123 objects = new ArrayList<Integer>(); 13124 } 13125 objects.add(objectId); 13126 all = false; 13127 } catch (RuntimeException e) { 13128 // Not an integer; just do string match. 13129 if (strings == null) { 13130 strings = new ArrayList<String>(); 13131 } 13132 strings.add(name); 13133 all = false; 13134 } 13135 } 13136 } 13137 13138 int build(String[] args, int opti) { 13139 for (; opti<args.length; opti++) { 13140 String name = args[opti]; 13141 if ("--".equals(name)) { 13142 return opti+1; 13143 } 13144 build(name); 13145 } 13146 return opti; 13147 } 13148 13149 boolean match(Object object, ComponentName comp) { 13150 if (all) { 13151 return true; 13152 } 13153 if (components != null) { 13154 for (int i=0; i<components.size(); i++) { 13155 if (components.get(i).equals(comp)) { 13156 return true; 13157 } 13158 } 13159 } 13160 if (objects != null) { 13161 for (int i=0; i<objects.size(); i++) { 13162 if (System.identityHashCode(object) == objects.get(i)) { 13163 return true; 13164 } 13165 } 13166 } 13167 if (strings != null) { 13168 String flat = comp.flattenToString(); 13169 for (int i=0; i<strings.size(); i++) { 13170 if (flat.contains(strings.get(i))) { 13171 return true; 13172 } 13173 } 13174 } 13175 return false; 13176 } 13177 } 13178 13179 /** 13180 * There are three things that cmd can be: 13181 * - a flattened component name that matches an existing activity 13182 * - the cmd arg isn't the flattened component name of an existing activity: 13183 * dump all activity whose component contains the cmd as a substring 13184 * - A hex number of the ActivityRecord object instance. 13185 */ 13186 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13187 int opti, boolean dumpAll) { 13188 ArrayList<ActivityRecord> activities; 13189 13190 synchronized (this) { 13191 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13192 } 13193 13194 if (activities.size() <= 0) { 13195 return false; 13196 } 13197 13198 String[] newArgs = new String[args.length - opti]; 13199 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13200 13201 TaskRecord lastTask = null; 13202 boolean needSep = false; 13203 for (int i=activities.size()-1; i>=0; i--) { 13204 ActivityRecord r = activities.get(i); 13205 if (needSep) { 13206 pw.println(); 13207 } 13208 needSep = true; 13209 synchronized (this) { 13210 if (lastTask != r.task) { 13211 lastTask = r.task; 13212 pw.print("TASK "); pw.print(lastTask.affinity); 13213 pw.print(" id="); pw.println(lastTask.taskId); 13214 if (dumpAll) { 13215 lastTask.dump(pw, " "); 13216 } 13217 } 13218 } 13219 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13220 } 13221 return true; 13222 } 13223 13224 /** 13225 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13226 * there is a thread associated with the activity. 13227 */ 13228 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13229 final ActivityRecord r, String[] args, boolean dumpAll) { 13230 String innerPrefix = prefix + " "; 13231 synchronized (this) { 13232 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13233 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13234 pw.print(" pid="); 13235 if (r.app != null) pw.println(r.app.pid); 13236 else pw.println("(not running)"); 13237 if (dumpAll) { 13238 r.dump(pw, innerPrefix); 13239 } 13240 } 13241 if (r.app != null && r.app.thread != null) { 13242 // flush anything that is already in the PrintWriter since the thread is going 13243 // to write to the file descriptor directly 13244 pw.flush(); 13245 try { 13246 TransferPipe tp = new TransferPipe(); 13247 try { 13248 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13249 r.appToken, innerPrefix, args); 13250 tp.go(fd); 13251 } finally { 13252 tp.kill(); 13253 } 13254 } catch (IOException e) { 13255 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13256 } catch (RemoteException e) { 13257 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13258 } 13259 } 13260 } 13261 13262 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13263 int opti, boolean dumpAll, String dumpPackage) { 13264 boolean needSep = false; 13265 boolean onlyHistory = false; 13266 boolean printedAnything = false; 13267 13268 if ("history".equals(dumpPackage)) { 13269 if (opti < args.length && "-s".equals(args[opti])) { 13270 dumpAll = false; 13271 } 13272 onlyHistory = true; 13273 dumpPackage = null; 13274 } 13275 13276 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13277 if (!onlyHistory && dumpAll) { 13278 if (mRegisteredReceivers.size() > 0) { 13279 boolean printed = false; 13280 Iterator it = mRegisteredReceivers.values().iterator(); 13281 while (it.hasNext()) { 13282 ReceiverList r = (ReceiverList)it.next(); 13283 if (dumpPackage != null && (r.app == null || 13284 !dumpPackage.equals(r.app.info.packageName))) { 13285 continue; 13286 } 13287 if (!printed) { 13288 pw.println(" Registered Receivers:"); 13289 needSep = true; 13290 printed = true; 13291 printedAnything = true; 13292 } 13293 pw.print(" * "); pw.println(r); 13294 r.dump(pw, " "); 13295 } 13296 } 13297 13298 if (mReceiverResolver.dump(pw, needSep ? 13299 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13300 " ", dumpPackage, false, false)) { 13301 needSep = true; 13302 printedAnything = true; 13303 } 13304 } 13305 13306 for (BroadcastQueue q : mBroadcastQueues) { 13307 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13308 printedAnything |= needSep; 13309 } 13310 13311 needSep = true; 13312 13313 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13314 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13315 if (needSep) { 13316 pw.println(); 13317 } 13318 needSep = true; 13319 printedAnything = true; 13320 pw.print(" Sticky broadcasts for user "); 13321 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13322 StringBuilder sb = new StringBuilder(128); 13323 for (Map.Entry<String, ArrayList<Intent>> ent 13324 : mStickyBroadcasts.valueAt(user).entrySet()) { 13325 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13326 if (dumpAll) { 13327 pw.println(":"); 13328 ArrayList<Intent> intents = ent.getValue(); 13329 final int N = intents.size(); 13330 for (int i=0; i<N; i++) { 13331 sb.setLength(0); 13332 sb.append(" Intent: "); 13333 intents.get(i).toShortString(sb, false, true, false, false); 13334 pw.println(sb.toString()); 13335 Bundle bundle = intents.get(i).getExtras(); 13336 if (bundle != null) { 13337 pw.print(" "); 13338 pw.println(bundle.toString()); 13339 } 13340 } 13341 } else { 13342 pw.println(""); 13343 } 13344 } 13345 } 13346 } 13347 13348 if (!onlyHistory && dumpAll) { 13349 pw.println(); 13350 for (BroadcastQueue queue : mBroadcastQueues) { 13351 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13352 + queue.mBroadcastsScheduled); 13353 } 13354 pw.println(" mHandler:"); 13355 mHandler.dump(new PrintWriterPrinter(pw), " "); 13356 needSep = true; 13357 printedAnything = true; 13358 } 13359 13360 if (!printedAnything) { 13361 pw.println(" (nothing)"); 13362 } 13363 } 13364 13365 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13366 int opti, boolean dumpAll, String dumpPackage) { 13367 boolean needSep; 13368 boolean printedAnything = false; 13369 13370 ItemMatcher matcher = new ItemMatcher(); 13371 matcher.build(args, opti); 13372 13373 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13374 13375 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13376 printedAnything |= needSep; 13377 13378 if (mLaunchingProviders.size() > 0) { 13379 boolean printed = false; 13380 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13381 ContentProviderRecord r = mLaunchingProviders.get(i); 13382 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13383 continue; 13384 } 13385 if (!printed) { 13386 if (needSep) pw.println(); 13387 needSep = true; 13388 pw.println(" Launching content providers:"); 13389 printed = true; 13390 printedAnything = true; 13391 } 13392 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13393 pw.println(r); 13394 } 13395 } 13396 13397 if (mGrantedUriPermissions.size() > 0) { 13398 boolean printed = false; 13399 int dumpUid = -2; 13400 if (dumpPackage != null) { 13401 try { 13402 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13403 } catch (NameNotFoundException e) { 13404 dumpUid = -1; 13405 } 13406 } 13407 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13408 int uid = mGrantedUriPermissions.keyAt(i); 13409 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13410 continue; 13411 } 13412 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13413 if (!printed) { 13414 if (needSep) pw.println(); 13415 needSep = true; 13416 pw.println(" Granted Uri Permissions:"); 13417 printed = true; 13418 printedAnything = true; 13419 } 13420 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13421 for (UriPermission perm : perms.values()) { 13422 pw.print(" "); pw.println(perm); 13423 if (dumpAll) { 13424 perm.dump(pw, " "); 13425 } 13426 } 13427 } 13428 } 13429 13430 if (!printedAnything) { 13431 pw.println(" (nothing)"); 13432 } 13433 } 13434 13435 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13436 int opti, boolean dumpAll, String dumpPackage) { 13437 boolean printed = false; 13438 13439 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13440 13441 if (mIntentSenderRecords.size() > 0) { 13442 Iterator<WeakReference<PendingIntentRecord>> it 13443 = mIntentSenderRecords.values().iterator(); 13444 while (it.hasNext()) { 13445 WeakReference<PendingIntentRecord> ref = it.next(); 13446 PendingIntentRecord rec = ref != null ? ref.get(): null; 13447 if (dumpPackage != null && (rec == null 13448 || !dumpPackage.equals(rec.key.packageName))) { 13449 continue; 13450 } 13451 printed = true; 13452 if (rec != null) { 13453 pw.print(" * "); pw.println(rec); 13454 if (dumpAll) { 13455 rec.dump(pw, " "); 13456 } 13457 } else { 13458 pw.print(" * "); pw.println(ref); 13459 } 13460 } 13461 } 13462 13463 if (!printed) { 13464 pw.println(" (nothing)"); 13465 } 13466 } 13467 13468 private static final int dumpProcessList(PrintWriter pw, 13469 ActivityManagerService service, List list, 13470 String prefix, String normalLabel, String persistentLabel, 13471 String dumpPackage) { 13472 int numPers = 0; 13473 final int N = list.size()-1; 13474 for (int i=N; i>=0; i--) { 13475 ProcessRecord r = (ProcessRecord)list.get(i); 13476 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13477 continue; 13478 } 13479 pw.println(String.format("%s%s #%2d: %s", 13480 prefix, (r.persistent ? persistentLabel : normalLabel), 13481 i, r.toString())); 13482 if (r.persistent) { 13483 numPers++; 13484 } 13485 } 13486 return numPers; 13487 } 13488 13489 private static final boolean dumpProcessOomList(PrintWriter pw, 13490 ActivityManagerService service, List<ProcessRecord> origList, 13491 String prefix, String normalLabel, String persistentLabel, 13492 boolean inclDetails, String dumpPackage) { 13493 13494 ArrayList<Pair<ProcessRecord, Integer>> list 13495 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13496 for (int i=0; i<origList.size(); i++) { 13497 ProcessRecord r = origList.get(i); 13498 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13499 continue; 13500 } 13501 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13502 } 13503 13504 if (list.size() <= 0) { 13505 return false; 13506 } 13507 13508 Comparator<Pair<ProcessRecord, Integer>> comparator 13509 = new Comparator<Pair<ProcessRecord, Integer>>() { 13510 @Override 13511 public int compare(Pair<ProcessRecord, Integer> object1, 13512 Pair<ProcessRecord, Integer> object2) { 13513 if (object1.first.setAdj != object2.first.setAdj) { 13514 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13515 } 13516 if (object1.second.intValue() != object2.second.intValue()) { 13517 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13518 } 13519 return 0; 13520 } 13521 }; 13522 13523 Collections.sort(list, comparator); 13524 13525 final long curRealtime = SystemClock.elapsedRealtime(); 13526 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13527 final long curUptime = SystemClock.uptimeMillis(); 13528 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13529 13530 for (int i=list.size()-1; i>=0; i--) { 13531 ProcessRecord r = list.get(i).first; 13532 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13533 char schedGroup; 13534 switch (r.setSchedGroup) { 13535 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13536 schedGroup = 'B'; 13537 break; 13538 case Process.THREAD_GROUP_DEFAULT: 13539 schedGroup = 'F'; 13540 break; 13541 default: 13542 schedGroup = '?'; 13543 break; 13544 } 13545 char foreground; 13546 if (r.foregroundActivities) { 13547 foreground = 'A'; 13548 } else if (r.foregroundServices) { 13549 foreground = 'S'; 13550 } else { 13551 foreground = ' '; 13552 } 13553 String procState = ProcessList.makeProcStateString(r.curProcState); 13554 pw.print(prefix); 13555 pw.print(r.persistent ? persistentLabel : normalLabel); 13556 pw.print(" #"); 13557 int num = (origList.size()-1)-list.get(i).second; 13558 if (num < 10) pw.print(' '); 13559 pw.print(num); 13560 pw.print(": "); 13561 pw.print(oomAdj); 13562 pw.print(' '); 13563 pw.print(schedGroup); 13564 pw.print('/'); 13565 pw.print(foreground); 13566 pw.print('/'); 13567 pw.print(procState); 13568 pw.print(" trm:"); 13569 if (r.trimMemoryLevel < 10) pw.print(' '); 13570 pw.print(r.trimMemoryLevel); 13571 pw.print(' '); 13572 pw.print(r.toShortString()); 13573 pw.print(" ("); 13574 pw.print(r.adjType); 13575 pw.println(')'); 13576 if (r.adjSource != null || r.adjTarget != null) { 13577 pw.print(prefix); 13578 pw.print(" "); 13579 if (r.adjTarget instanceof ComponentName) { 13580 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13581 } else if (r.adjTarget != null) { 13582 pw.print(r.adjTarget.toString()); 13583 } else { 13584 pw.print("{null}"); 13585 } 13586 pw.print("<="); 13587 if (r.adjSource instanceof ProcessRecord) { 13588 pw.print("Proc{"); 13589 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13590 pw.println("}"); 13591 } else if (r.adjSource != null) { 13592 pw.println(r.adjSource.toString()); 13593 } else { 13594 pw.println("{null}"); 13595 } 13596 } 13597 if (inclDetails) { 13598 pw.print(prefix); 13599 pw.print(" "); 13600 pw.print("oom: max="); pw.print(r.maxAdj); 13601 pw.print(" curRaw="); pw.print(r.curRawAdj); 13602 pw.print(" setRaw="); pw.print(r.setRawAdj); 13603 pw.print(" cur="); pw.print(r.curAdj); 13604 pw.print(" set="); pw.println(r.setAdj); 13605 pw.print(prefix); 13606 pw.print(" "); 13607 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13608 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13609 pw.print(" lastPss="); pw.print(r.lastPss); 13610 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13611 pw.print(prefix); 13612 pw.print(" "); 13613 pw.print("cached="); pw.print(r.cached); 13614 pw.print(" empty="); pw.print(r.empty); 13615 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13616 13617 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13618 if (r.lastWakeTime != 0) { 13619 long wtime; 13620 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13621 synchronized (stats) { 13622 wtime = stats.getProcessWakeTime(r.info.uid, 13623 r.pid, curRealtime); 13624 } 13625 long timeUsed = wtime - r.lastWakeTime; 13626 pw.print(prefix); 13627 pw.print(" "); 13628 pw.print("keep awake over "); 13629 TimeUtils.formatDuration(realtimeSince, pw); 13630 pw.print(" used "); 13631 TimeUtils.formatDuration(timeUsed, pw); 13632 pw.print(" ("); 13633 pw.print((timeUsed*100)/realtimeSince); 13634 pw.println("%)"); 13635 } 13636 if (r.lastCpuTime != 0) { 13637 long timeUsed = r.curCpuTime - r.lastCpuTime; 13638 pw.print(prefix); 13639 pw.print(" "); 13640 pw.print("run cpu over "); 13641 TimeUtils.formatDuration(uptimeSince, pw); 13642 pw.print(" used "); 13643 TimeUtils.formatDuration(timeUsed, pw); 13644 pw.print(" ("); 13645 pw.print((timeUsed*100)/uptimeSince); 13646 pw.println("%)"); 13647 } 13648 } 13649 } 13650 } 13651 return true; 13652 } 13653 13654 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13655 String[] args) { 13656 ArrayList<ProcessRecord> procs; 13657 synchronized (this) { 13658 if (args != null && args.length > start 13659 && args[start].charAt(0) != '-') { 13660 procs = new ArrayList<ProcessRecord>(); 13661 int pid = -1; 13662 try { 13663 pid = Integer.parseInt(args[start]); 13664 } catch (NumberFormatException e) { 13665 } 13666 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13667 ProcessRecord proc = mLruProcesses.get(i); 13668 if (proc.pid == pid) { 13669 procs.add(proc); 13670 } else if (allPkgs && proc.pkgList != null 13671 && proc.pkgList.containsKey(args[start])) { 13672 procs.add(proc); 13673 } else if (proc.processName.equals(args[start])) { 13674 procs.add(proc); 13675 } 13676 } 13677 if (procs.size() <= 0) { 13678 return null; 13679 } 13680 } else { 13681 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13682 } 13683 } 13684 return procs; 13685 } 13686 13687 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13688 PrintWriter pw, String[] args) { 13689 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13690 if (procs == null) { 13691 pw.println("No process found for: " + args[0]); 13692 return; 13693 } 13694 13695 long uptime = SystemClock.uptimeMillis(); 13696 long realtime = SystemClock.elapsedRealtime(); 13697 pw.println("Applications Graphics Acceleration Info:"); 13698 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13699 13700 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13701 ProcessRecord r = procs.get(i); 13702 if (r.thread != null) { 13703 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13704 pw.flush(); 13705 try { 13706 TransferPipe tp = new TransferPipe(); 13707 try { 13708 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13709 tp.go(fd); 13710 } finally { 13711 tp.kill(); 13712 } 13713 } catch (IOException e) { 13714 pw.println("Failure while dumping the app: " + r); 13715 pw.flush(); 13716 } catch (RemoteException e) { 13717 pw.println("Got a RemoteException while dumping the app " + r); 13718 pw.flush(); 13719 } 13720 } 13721 } 13722 } 13723 13724 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13725 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13726 if (procs == null) { 13727 pw.println("No process found for: " + args[0]); 13728 return; 13729 } 13730 13731 pw.println("Applications Database Info:"); 13732 13733 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13734 ProcessRecord r = procs.get(i); 13735 if (r.thread != null) { 13736 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13737 pw.flush(); 13738 try { 13739 TransferPipe tp = new TransferPipe(); 13740 try { 13741 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13742 tp.go(fd); 13743 } finally { 13744 tp.kill(); 13745 } 13746 } catch (IOException e) { 13747 pw.println("Failure while dumping the app: " + r); 13748 pw.flush(); 13749 } catch (RemoteException e) { 13750 pw.println("Got a RemoteException while dumping the app " + r); 13751 pw.flush(); 13752 } 13753 } 13754 } 13755 } 13756 13757 final static class MemItem { 13758 final boolean isProc; 13759 final String label; 13760 final String shortLabel; 13761 final long pss; 13762 final int id; 13763 final boolean hasActivities; 13764 ArrayList<MemItem> subitems; 13765 13766 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13767 boolean _hasActivities) { 13768 isProc = true; 13769 label = _label; 13770 shortLabel = _shortLabel; 13771 pss = _pss; 13772 id = _id; 13773 hasActivities = _hasActivities; 13774 } 13775 13776 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13777 isProc = false; 13778 label = _label; 13779 shortLabel = _shortLabel; 13780 pss = _pss; 13781 id = _id; 13782 hasActivities = false; 13783 } 13784 } 13785 13786 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13787 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13788 if (sort && !isCompact) { 13789 Collections.sort(items, new Comparator<MemItem>() { 13790 @Override 13791 public int compare(MemItem lhs, MemItem rhs) { 13792 if (lhs.pss < rhs.pss) { 13793 return 1; 13794 } else if (lhs.pss > rhs.pss) { 13795 return -1; 13796 } 13797 return 0; 13798 } 13799 }); 13800 } 13801 13802 for (int i=0; i<items.size(); i++) { 13803 MemItem mi = items.get(i); 13804 if (!isCompact) { 13805 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13806 } else if (mi.isProc) { 13807 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13808 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13809 pw.println(mi.hasActivities ? ",a" : ",e"); 13810 } else { 13811 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13812 pw.println(mi.pss); 13813 } 13814 if (mi.subitems != null) { 13815 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13816 true, isCompact); 13817 } 13818 } 13819 } 13820 13821 // These are in KB. 13822 static final long[] DUMP_MEM_BUCKETS = new long[] { 13823 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13824 120*1024, 160*1024, 200*1024, 13825 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13826 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13827 }; 13828 13829 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13830 boolean stackLike) { 13831 int start = label.lastIndexOf('.'); 13832 if (start >= 0) start++; 13833 else start = 0; 13834 int end = label.length(); 13835 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13836 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13837 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13838 out.append(bucket); 13839 out.append(stackLike ? "MB." : "MB "); 13840 out.append(label, start, end); 13841 return; 13842 } 13843 } 13844 out.append(memKB/1024); 13845 out.append(stackLike ? "MB." : "MB "); 13846 out.append(label, start, end); 13847 } 13848 13849 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13850 ProcessList.NATIVE_ADJ, 13851 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13852 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13853 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13854 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13855 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13856 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13857 }; 13858 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13859 "Native", 13860 "System", "Persistent", "Persistent Service", "Foreground", 13861 "Visible", "Perceptible", 13862 "Heavy Weight", "Backup", 13863 "A Services", "Home", 13864 "Previous", "B Services", "Cached" 13865 }; 13866 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13867 "native", 13868 "sys", "pers", "persvc", "fore", 13869 "vis", "percept", 13870 "heavy", "backup", 13871 "servicea", "home", 13872 "prev", "serviceb", "cached" 13873 }; 13874 13875 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13876 long realtime, boolean isCheckinRequest, boolean isCompact) { 13877 if (isCheckinRequest || isCompact) { 13878 // short checkin version 13879 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13880 } else { 13881 pw.println("Applications Memory Usage (kB):"); 13882 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13883 } 13884 } 13885 13886 private static final int KSM_SHARED = 0; 13887 private static final int KSM_SHARING = 1; 13888 private static final int KSM_UNSHARED = 2; 13889 private static final int KSM_VOLATILE = 3; 13890 13891 private final long[] getKsmInfo() { 13892 long[] longOut = new long[4]; 13893 final int[] SINGLE_LONG_FORMAT = new int[] { 13894 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13895 }; 13896 long[] longTmp = new long[1]; 13897 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13898 SINGLE_LONG_FORMAT, null, longTmp, null); 13899 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13900 longTmp[0] = 0; 13901 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13902 SINGLE_LONG_FORMAT, null, longTmp, null); 13903 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13904 longTmp[0] = 0; 13905 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13906 SINGLE_LONG_FORMAT, null, longTmp, null); 13907 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13908 longTmp[0] = 0; 13909 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13910 SINGLE_LONG_FORMAT, null, longTmp, null); 13911 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13912 return longOut; 13913 } 13914 13915 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13916 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13917 boolean dumpDetails = false; 13918 boolean dumpFullDetails = false; 13919 boolean dumpDalvik = false; 13920 boolean oomOnly = false; 13921 boolean isCompact = false; 13922 boolean localOnly = false; 13923 boolean packages = false; 13924 13925 int opti = 0; 13926 while (opti < args.length) { 13927 String opt = args[opti]; 13928 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13929 break; 13930 } 13931 opti++; 13932 if ("-a".equals(opt)) { 13933 dumpDetails = true; 13934 dumpFullDetails = true; 13935 dumpDalvik = true; 13936 } else if ("-d".equals(opt)) { 13937 dumpDalvik = true; 13938 } else if ("-c".equals(opt)) { 13939 isCompact = true; 13940 } else if ("--oom".equals(opt)) { 13941 oomOnly = true; 13942 } else if ("--local".equals(opt)) { 13943 localOnly = true; 13944 } else if ("--package".equals(opt)) { 13945 packages = true; 13946 } else if ("-h".equals(opt)) { 13947 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13948 pw.println(" -a: include all available information for each process."); 13949 pw.println(" -d: include dalvik details when dumping process details."); 13950 pw.println(" -c: dump in a compact machine-parseable representation."); 13951 pw.println(" --oom: only show processes organized by oom adj."); 13952 pw.println(" --local: only collect details locally, don't call process."); 13953 pw.println(" --package: interpret process arg as package, dumping all"); 13954 pw.println(" processes that have loaded that package."); 13955 pw.println("If [process] is specified it can be the name or "); 13956 pw.println("pid of a specific process to dump."); 13957 return; 13958 } else { 13959 pw.println("Unknown argument: " + opt + "; use -h for help"); 13960 } 13961 } 13962 13963 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13964 long uptime = SystemClock.uptimeMillis(); 13965 long realtime = SystemClock.elapsedRealtime(); 13966 final long[] tmpLong = new long[1]; 13967 13968 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13969 if (procs == null) { 13970 // No Java processes. Maybe they want to print a native process. 13971 if (args != null && args.length > opti 13972 && args[opti].charAt(0) != '-') { 13973 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13974 = new ArrayList<ProcessCpuTracker.Stats>(); 13975 updateCpuStatsNow(); 13976 int findPid = -1; 13977 try { 13978 findPid = Integer.parseInt(args[opti]); 13979 } catch (NumberFormatException e) { 13980 } 13981 synchronized (mProcessCpuTracker) { 13982 final int N = mProcessCpuTracker.countStats(); 13983 for (int i=0; i<N; i++) { 13984 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13985 if (st.pid == findPid || (st.baseName != null 13986 && st.baseName.equals(args[opti]))) { 13987 nativeProcs.add(st); 13988 } 13989 } 13990 } 13991 if (nativeProcs.size() > 0) { 13992 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13993 isCompact); 13994 Debug.MemoryInfo mi = null; 13995 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13996 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13997 final int pid = r.pid; 13998 if (!isCheckinRequest && dumpDetails) { 13999 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14000 } 14001 if (mi == null) { 14002 mi = new Debug.MemoryInfo(); 14003 } 14004 if (dumpDetails || (!brief && !oomOnly)) { 14005 Debug.getMemoryInfo(pid, mi); 14006 } else { 14007 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14008 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14009 } 14010 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14011 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14012 if (isCheckinRequest) { 14013 pw.println(); 14014 } 14015 } 14016 return; 14017 } 14018 } 14019 pw.println("No process found for: " + args[opti]); 14020 return; 14021 } 14022 14023 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14024 dumpDetails = true; 14025 } 14026 14027 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14028 14029 String[] innerArgs = new String[args.length-opti]; 14030 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14031 14032 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14033 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14034 long nativePss = 0; 14035 long dalvikPss = 0; 14036 long otherPss = 0; 14037 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14038 14039 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14040 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14041 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14042 14043 long totalPss = 0; 14044 long cachedPss = 0; 14045 14046 Debug.MemoryInfo mi = null; 14047 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14048 final ProcessRecord r = procs.get(i); 14049 final IApplicationThread thread; 14050 final int pid; 14051 final int oomAdj; 14052 final boolean hasActivities; 14053 synchronized (this) { 14054 thread = r.thread; 14055 pid = r.pid; 14056 oomAdj = r.getSetAdjWithServices(); 14057 hasActivities = r.activities.size() > 0; 14058 } 14059 if (thread != null) { 14060 if (!isCheckinRequest && dumpDetails) { 14061 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14062 } 14063 if (mi == null) { 14064 mi = new Debug.MemoryInfo(); 14065 } 14066 if (dumpDetails || (!brief && !oomOnly)) { 14067 Debug.getMemoryInfo(pid, mi); 14068 } else { 14069 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14070 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14071 } 14072 if (dumpDetails) { 14073 if (localOnly) { 14074 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14075 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14076 if (isCheckinRequest) { 14077 pw.println(); 14078 } 14079 } else { 14080 try { 14081 pw.flush(); 14082 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14083 dumpDalvik, innerArgs); 14084 } catch (RemoteException e) { 14085 if (!isCheckinRequest) { 14086 pw.println("Got RemoteException!"); 14087 pw.flush(); 14088 } 14089 } 14090 } 14091 } 14092 14093 final long myTotalPss = mi.getTotalPss(); 14094 final long myTotalUss = mi.getTotalUss(); 14095 14096 synchronized (this) { 14097 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14098 // Record this for posterity if the process has been stable. 14099 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14100 } 14101 } 14102 14103 if (!isCheckinRequest && mi != null) { 14104 totalPss += myTotalPss; 14105 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14106 (hasActivities ? " / activities)" : ")"), 14107 r.processName, myTotalPss, pid, hasActivities); 14108 procMems.add(pssItem); 14109 procMemsMap.put(pid, pssItem); 14110 14111 nativePss += mi.nativePss; 14112 dalvikPss += mi.dalvikPss; 14113 otherPss += mi.otherPss; 14114 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14115 long mem = mi.getOtherPss(j); 14116 miscPss[j] += mem; 14117 otherPss -= mem; 14118 } 14119 14120 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14121 cachedPss += myTotalPss; 14122 } 14123 14124 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14125 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14126 || oomIndex == (oomPss.length-1)) { 14127 oomPss[oomIndex] += myTotalPss; 14128 if (oomProcs[oomIndex] == null) { 14129 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14130 } 14131 oomProcs[oomIndex].add(pssItem); 14132 break; 14133 } 14134 } 14135 } 14136 } 14137 } 14138 14139 long nativeProcTotalPss = 0; 14140 14141 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14142 // If we are showing aggregations, also look for native processes to 14143 // include so that our aggregations are more accurate. 14144 updateCpuStatsNow(); 14145 mi = null; 14146 synchronized (mProcessCpuTracker) { 14147 final int N = mProcessCpuTracker.countStats(); 14148 for (int i=0; i<N; i++) { 14149 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14150 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14151 if (mi == null) { 14152 mi = new Debug.MemoryInfo(); 14153 } 14154 if (!brief && !oomOnly) { 14155 Debug.getMemoryInfo(st.pid, mi); 14156 } else { 14157 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14158 mi.nativePrivateDirty = (int)tmpLong[0]; 14159 } 14160 14161 final long myTotalPss = mi.getTotalPss(); 14162 totalPss += myTotalPss; 14163 nativeProcTotalPss += myTotalPss; 14164 14165 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14166 st.name, myTotalPss, st.pid, false); 14167 procMems.add(pssItem); 14168 14169 nativePss += mi.nativePss; 14170 dalvikPss += mi.dalvikPss; 14171 otherPss += mi.otherPss; 14172 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14173 long mem = mi.getOtherPss(j); 14174 miscPss[j] += mem; 14175 otherPss -= mem; 14176 } 14177 oomPss[0] += myTotalPss; 14178 if (oomProcs[0] == null) { 14179 oomProcs[0] = new ArrayList<MemItem>(); 14180 } 14181 oomProcs[0].add(pssItem); 14182 } 14183 } 14184 } 14185 14186 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14187 14188 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14189 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14190 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14191 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14192 String label = Debug.MemoryInfo.getOtherLabel(j); 14193 catMems.add(new MemItem(label, label, miscPss[j], j)); 14194 } 14195 14196 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14197 for (int j=0; j<oomPss.length; j++) { 14198 if (oomPss[j] != 0) { 14199 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14200 : DUMP_MEM_OOM_LABEL[j]; 14201 MemItem item = new MemItem(label, label, oomPss[j], 14202 DUMP_MEM_OOM_ADJ[j]); 14203 item.subitems = oomProcs[j]; 14204 oomMems.add(item); 14205 } 14206 } 14207 14208 if (!brief && !oomOnly && !isCompact) { 14209 pw.println(); 14210 pw.println("Total PSS by process:"); 14211 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14212 pw.println(); 14213 } 14214 if (!isCompact) { 14215 pw.println("Total PSS by OOM adjustment:"); 14216 } 14217 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14218 if (!brief && !oomOnly) { 14219 PrintWriter out = categoryPw != null ? categoryPw : pw; 14220 if (!isCompact) { 14221 out.println(); 14222 out.println("Total PSS by category:"); 14223 } 14224 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14225 } 14226 if (!isCompact) { 14227 pw.println(); 14228 } 14229 MemInfoReader memInfo = new MemInfoReader(); 14230 memInfo.readMemInfo(); 14231 if (nativeProcTotalPss > 0) { 14232 synchronized (this) { 14233 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14234 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14235 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14236 } 14237 } 14238 if (!brief) { 14239 if (!isCompact) { 14240 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14241 pw.print(" kB (status "); 14242 switch (mLastMemoryLevel) { 14243 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14244 pw.println("normal)"); 14245 break; 14246 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14247 pw.println("moderate)"); 14248 break; 14249 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14250 pw.println("low)"); 14251 break; 14252 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14253 pw.println("critical)"); 14254 break; 14255 default: 14256 pw.print(mLastMemoryLevel); 14257 pw.println(")"); 14258 break; 14259 } 14260 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14261 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14262 pw.print(cachedPss); pw.print(" cached pss + "); 14263 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14264 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14265 } else { 14266 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14267 pw.print(cachedPss + memInfo.getCachedSizeKb() 14268 + memInfo.getFreeSizeKb()); pw.print(","); 14269 pw.println(totalPss - cachedPss); 14270 } 14271 } 14272 if (!isCompact) { 14273 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14274 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14275 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14276 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14277 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14278 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14279 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14280 } 14281 if (!brief) { 14282 if (memInfo.getZramTotalSizeKb() != 0) { 14283 if (!isCompact) { 14284 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14285 pw.print(" kB physical used for "); 14286 pw.print(memInfo.getSwapTotalSizeKb() 14287 - memInfo.getSwapFreeSizeKb()); 14288 pw.print(" kB in swap ("); 14289 pw.print(memInfo.getSwapTotalSizeKb()); 14290 pw.println(" kB total swap)"); 14291 } else { 14292 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14293 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14294 pw.println(memInfo.getSwapFreeSizeKb()); 14295 } 14296 } 14297 final long[] ksm = getKsmInfo(); 14298 if (!isCompact) { 14299 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14300 || ksm[KSM_VOLATILE] != 0) { 14301 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14302 pw.print(" kB saved from shared "); 14303 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14304 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14305 pw.print(" kB unshared; "); 14306 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14307 } 14308 pw.print(" Tuning: "); 14309 pw.print(ActivityManager.staticGetMemoryClass()); 14310 pw.print(" (large "); 14311 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14312 pw.print("), oom "); 14313 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14314 pw.print(" kB"); 14315 pw.print(", restore limit "); 14316 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14317 pw.print(" kB"); 14318 if (ActivityManager.isLowRamDeviceStatic()) { 14319 pw.print(" (low-ram)"); 14320 } 14321 if (ActivityManager.isHighEndGfx()) { 14322 pw.print(" (high-end-gfx)"); 14323 } 14324 pw.println(); 14325 } else { 14326 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14327 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14328 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14329 pw.print("tuning,"); 14330 pw.print(ActivityManager.staticGetMemoryClass()); 14331 pw.print(','); 14332 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14333 pw.print(','); 14334 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14335 if (ActivityManager.isLowRamDeviceStatic()) { 14336 pw.print(",low-ram"); 14337 } 14338 if (ActivityManager.isHighEndGfx()) { 14339 pw.print(",high-end-gfx"); 14340 } 14341 pw.println(); 14342 } 14343 } 14344 } 14345 } 14346 14347 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14348 long memtrack, String name) { 14349 sb.append(" "); 14350 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14351 sb.append(' '); 14352 sb.append(ProcessList.makeProcStateString(procState)); 14353 sb.append(' '); 14354 ProcessList.appendRamKb(sb, pss); 14355 sb.append(" kB: "); 14356 sb.append(name); 14357 if (memtrack > 0) { 14358 sb.append(" ("); 14359 sb.append(memtrack); 14360 sb.append(" kB memtrack)"); 14361 } 14362 } 14363 14364 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14365 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14366 sb.append(" (pid "); 14367 sb.append(mi.pid); 14368 sb.append(") "); 14369 sb.append(mi.adjType); 14370 sb.append('\n'); 14371 if (mi.adjReason != null) { 14372 sb.append(" "); 14373 sb.append(mi.adjReason); 14374 sb.append('\n'); 14375 } 14376 } 14377 14378 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14379 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14380 for (int i=0, N=memInfos.size(); i<N; i++) { 14381 ProcessMemInfo mi = memInfos.get(i); 14382 infoMap.put(mi.pid, mi); 14383 } 14384 updateCpuStatsNow(); 14385 long[] memtrackTmp = new long[1]; 14386 synchronized (mProcessCpuTracker) { 14387 final int N = mProcessCpuTracker.countStats(); 14388 for (int i=0; i<N; i++) { 14389 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14390 if (st.vsize > 0) { 14391 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14392 if (pss > 0) { 14393 if (infoMap.indexOfKey(st.pid) < 0) { 14394 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14395 ProcessList.NATIVE_ADJ, -1, "native", null); 14396 mi.pss = pss; 14397 mi.memtrack = memtrackTmp[0]; 14398 memInfos.add(mi); 14399 } 14400 } 14401 } 14402 } 14403 } 14404 14405 long totalPss = 0; 14406 long totalMemtrack = 0; 14407 for (int i=0, N=memInfos.size(); i<N; i++) { 14408 ProcessMemInfo mi = memInfos.get(i); 14409 if (mi.pss == 0) { 14410 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14411 mi.memtrack = memtrackTmp[0]; 14412 } 14413 totalPss += mi.pss; 14414 totalMemtrack += mi.memtrack; 14415 } 14416 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14417 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14418 if (lhs.oomAdj != rhs.oomAdj) { 14419 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14420 } 14421 if (lhs.pss != rhs.pss) { 14422 return lhs.pss < rhs.pss ? 1 : -1; 14423 } 14424 return 0; 14425 } 14426 }); 14427 14428 StringBuilder tag = new StringBuilder(128); 14429 StringBuilder stack = new StringBuilder(128); 14430 tag.append("Low on memory -- "); 14431 appendMemBucket(tag, totalPss, "total", false); 14432 appendMemBucket(stack, totalPss, "total", true); 14433 14434 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14435 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14436 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14437 14438 boolean firstLine = true; 14439 int lastOomAdj = Integer.MIN_VALUE; 14440 long extraNativeRam = 0; 14441 long extraNativeMemtrack = 0; 14442 long cachedPss = 0; 14443 for (int i=0, N=memInfos.size(); i<N; i++) { 14444 ProcessMemInfo mi = memInfos.get(i); 14445 14446 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14447 cachedPss += mi.pss; 14448 } 14449 14450 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14451 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14452 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14453 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14454 if (lastOomAdj != mi.oomAdj) { 14455 lastOomAdj = mi.oomAdj; 14456 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14457 tag.append(" / "); 14458 } 14459 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14460 if (firstLine) { 14461 stack.append(":"); 14462 firstLine = false; 14463 } 14464 stack.append("\n\t at "); 14465 } else { 14466 stack.append("$"); 14467 } 14468 } else { 14469 tag.append(" "); 14470 stack.append("$"); 14471 } 14472 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14473 appendMemBucket(tag, mi.pss, mi.name, false); 14474 } 14475 appendMemBucket(stack, mi.pss, mi.name, true); 14476 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14477 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14478 stack.append("("); 14479 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14480 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14481 stack.append(DUMP_MEM_OOM_LABEL[k]); 14482 stack.append(":"); 14483 stack.append(DUMP_MEM_OOM_ADJ[k]); 14484 } 14485 } 14486 stack.append(")"); 14487 } 14488 } 14489 14490 appendMemInfo(fullNativeBuilder, mi); 14491 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14492 // The short form only has native processes that are >= 512K. 14493 if (mi.pss >= 512) { 14494 appendMemInfo(shortNativeBuilder, mi); 14495 } else { 14496 extraNativeRam += mi.pss; 14497 extraNativeMemtrack += mi.memtrack; 14498 } 14499 } else { 14500 // Short form has all other details, but if we have collected RAM 14501 // from smaller native processes let's dump a summary of that. 14502 if (extraNativeRam > 0) { 14503 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14504 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14505 shortNativeBuilder.append('\n'); 14506 extraNativeRam = 0; 14507 } 14508 appendMemInfo(fullJavaBuilder, mi); 14509 } 14510 } 14511 14512 fullJavaBuilder.append(" "); 14513 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14514 fullJavaBuilder.append(" kB: TOTAL"); 14515 if (totalMemtrack > 0) { 14516 fullJavaBuilder.append(" ("); 14517 fullJavaBuilder.append(totalMemtrack); 14518 fullJavaBuilder.append(" kB memtrack)"); 14519 } else { 14520 } 14521 fullJavaBuilder.append("\n"); 14522 14523 MemInfoReader memInfo = new MemInfoReader(); 14524 memInfo.readMemInfo(); 14525 final long[] infos = memInfo.getRawInfo(); 14526 14527 StringBuilder memInfoBuilder = new StringBuilder(1024); 14528 Debug.getMemInfo(infos); 14529 memInfoBuilder.append(" MemInfo: "); 14530 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14531 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14532 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14533 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14534 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14535 memInfoBuilder.append(" "); 14536 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14537 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14538 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14539 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14540 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14541 memInfoBuilder.append(" ZRAM: "); 14542 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14543 memInfoBuilder.append(" kB RAM, "); 14544 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14545 memInfoBuilder.append(" kB swap total, "); 14546 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14547 memInfoBuilder.append(" kB swap free\n"); 14548 } 14549 final long[] ksm = getKsmInfo(); 14550 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14551 || ksm[KSM_VOLATILE] != 0) { 14552 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14553 memInfoBuilder.append(" kB saved from shared "); 14554 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14555 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14556 memInfoBuilder.append(" kB unshared; "); 14557 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14558 } 14559 memInfoBuilder.append(" Free RAM: "); 14560 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14561 + memInfo.getFreeSizeKb()); 14562 memInfoBuilder.append(" kB\n"); 14563 memInfoBuilder.append(" Used RAM: "); 14564 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14565 memInfoBuilder.append(" kB\n"); 14566 memInfoBuilder.append(" Lost RAM: "); 14567 memInfoBuilder.append(memInfo.getTotalSizeKb() 14568 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14569 - memInfo.getKernelUsedSizeKb()); 14570 memInfoBuilder.append(" kB\n"); 14571 Slog.i(TAG, "Low on memory:"); 14572 Slog.i(TAG, shortNativeBuilder.toString()); 14573 Slog.i(TAG, fullJavaBuilder.toString()); 14574 Slog.i(TAG, memInfoBuilder.toString()); 14575 14576 StringBuilder dropBuilder = new StringBuilder(1024); 14577 /* 14578 StringWriter oomSw = new StringWriter(); 14579 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14580 StringWriter catSw = new StringWriter(); 14581 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14582 String[] emptyArgs = new String[] { }; 14583 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14584 oomPw.flush(); 14585 String oomString = oomSw.toString(); 14586 */ 14587 dropBuilder.append("Low on memory:"); 14588 dropBuilder.append(stack); 14589 dropBuilder.append('\n'); 14590 dropBuilder.append(fullNativeBuilder); 14591 dropBuilder.append(fullJavaBuilder); 14592 dropBuilder.append('\n'); 14593 dropBuilder.append(memInfoBuilder); 14594 dropBuilder.append('\n'); 14595 /* 14596 dropBuilder.append(oomString); 14597 dropBuilder.append('\n'); 14598 */ 14599 StringWriter catSw = new StringWriter(); 14600 synchronized (ActivityManagerService.this) { 14601 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14602 String[] emptyArgs = new String[] { }; 14603 catPw.println(); 14604 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14605 catPw.println(); 14606 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14607 false, false, null); 14608 catPw.println(); 14609 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14610 catPw.flush(); 14611 } 14612 dropBuilder.append(catSw.toString()); 14613 addErrorToDropBox("lowmem", null, "system_server", null, 14614 null, tag.toString(), dropBuilder.toString(), null, null); 14615 //Slog.i(TAG, "Sent to dropbox:"); 14616 //Slog.i(TAG, dropBuilder.toString()); 14617 synchronized (ActivityManagerService.this) { 14618 long now = SystemClock.uptimeMillis(); 14619 if (mLastMemUsageReportTime < now) { 14620 mLastMemUsageReportTime = now; 14621 } 14622 } 14623 } 14624 14625 /** 14626 * Searches array of arguments for the specified string 14627 * @param args array of argument strings 14628 * @param value value to search for 14629 * @return true if the value is contained in the array 14630 */ 14631 private static boolean scanArgs(String[] args, String value) { 14632 if (args != null) { 14633 for (String arg : args) { 14634 if (value.equals(arg)) { 14635 return true; 14636 } 14637 } 14638 } 14639 return false; 14640 } 14641 14642 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14643 ContentProviderRecord cpr, boolean always) { 14644 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14645 14646 if (!inLaunching || always) { 14647 synchronized (cpr) { 14648 cpr.launchingApp = null; 14649 cpr.notifyAll(); 14650 } 14651 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14652 String names[] = cpr.info.authority.split(";"); 14653 for (int j = 0; j < names.length; j++) { 14654 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14655 } 14656 } 14657 14658 for (int i=0; i<cpr.connections.size(); i++) { 14659 ContentProviderConnection conn = cpr.connections.get(i); 14660 if (conn.waiting) { 14661 // If this connection is waiting for the provider, then we don't 14662 // need to mess with its process unless we are always removing 14663 // or for some reason the provider is not currently launching. 14664 if (inLaunching && !always) { 14665 continue; 14666 } 14667 } 14668 ProcessRecord capp = conn.client; 14669 conn.dead = true; 14670 if (conn.stableCount > 0) { 14671 if (!capp.persistent && capp.thread != null 14672 && capp.pid != 0 14673 && capp.pid != MY_PID) { 14674 capp.kill("depends on provider " 14675 + cpr.name.flattenToShortString() 14676 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14677 } 14678 } else if (capp.thread != null && conn.provider.provider != null) { 14679 try { 14680 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14681 } catch (RemoteException e) { 14682 } 14683 // In the protocol here, we don't expect the client to correctly 14684 // clean up this connection, we'll just remove it. 14685 cpr.connections.remove(i); 14686 conn.client.conProviders.remove(conn); 14687 } 14688 } 14689 14690 if (inLaunching && always) { 14691 mLaunchingProviders.remove(cpr); 14692 } 14693 return inLaunching; 14694 } 14695 14696 /** 14697 * Main code for cleaning up a process when it has gone away. This is 14698 * called both as a result of the process dying, or directly when stopping 14699 * a process when running in single process mode. 14700 * 14701 * @return Returns true if the given process has been restarted, so the 14702 * app that was passed in must remain on the process lists. 14703 */ 14704 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14705 boolean restarting, boolean allowRestart, int index) { 14706 if (index >= 0) { 14707 removeLruProcessLocked(app); 14708 ProcessList.remove(app.pid); 14709 } 14710 14711 mProcessesToGc.remove(app); 14712 mPendingPssProcesses.remove(app); 14713 14714 // Dismiss any open dialogs. 14715 if (app.crashDialog != null && !app.forceCrashReport) { 14716 app.crashDialog.dismiss(); 14717 app.crashDialog = null; 14718 } 14719 if (app.anrDialog != null) { 14720 app.anrDialog.dismiss(); 14721 app.anrDialog = null; 14722 } 14723 if (app.waitDialog != null) { 14724 app.waitDialog.dismiss(); 14725 app.waitDialog = null; 14726 } 14727 14728 app.crashing = false; 14729 app.notResponding = false; 14730 14731 app.resetPackageList(mProcessStats); 14732 app.unlinkDeathRecipient(); 14733 app.makeInactive(mProcessStats); 14734 app.waitingToKill = null; 14735 app.forcingToForeground = null; 14736 updateProcessForegroundLocked(app, false, false); 14737 app.foregroundActivities = false; 14738 app.hasShownUi = false; 14739 app.treatLikeActivity = false; 14740 app.hasAboveClient = false; 14741 app.hasClientActivities = false; 14742 14743 mServices.killServicesLocked(app, allowRestart); 14744 14745 boolean restart = false; 14746 14747 // Remove published content providers. 14748 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14749 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14750 final boolean always = app.bad || !allowRestart; 14751 if (removeDyingProviderLocked(app, cpr, always) || always) { 14752 // We left the provider in the launching list, need to 14753 // restart it. 14754 restart = true; 14755 } 14756 14757 cpr.provider = null; 14758 cpr.proc = null; 14759 } 14760 app.pubProviders.clear(); 14761 14762 // Take care of any launching providers waiting for this process. 14763 if (checkAppInLaunchingProvidersLocked(app, false)) { 14764 restart = true; 14765 } 14766 14767 // Unregister from connected content providers. 14768 if (!app.conProviders.isEmpty()) { 14769 for (int i=0; i<app.conProviders.size(); i++) { 14770 ContentProviderConnection conn = app.conProviders.get(i); 14771 conn.provider.connections.remove(conn); 14772 } 14773 app.conProviders.clear(); 14774 } 14775 14776 // At this point there may be remaining entries in mLaunchingProviders 14777 // where we were the only one waiting, so they are no longer of use. 14778 // Look for these and clean up if found. 14779 // XXX Commented out for now. Trying to figure out a way to reproduce 14780 // the actual situation to identify what is actually going on. 14781 if (false) { 14782 for (int i=0; i<mLaunchingProviders.size(); i++) { 14783 ContentProviderRecord cpr = (ContentProviderRecord) 14784 mLaunchingProviders.get(i); 14785 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14786 synchronized (cpr) { 14787 cpr.launchingApp = null; 14788 cpr.notifyAll(); 14789 } 14790 } 14791 } 14792 } 14793 14794 skipCurrentReceiverLocked(app); 14795 14796 // Unregister any receivers. 14797 for (int i=app.receivers.size()-1; i>=0; i--) { 14798 removeReceiverLocked(app.receivers.valueAt(i)); 14799 } 14800 app.receivers.clear(); 14801 14802 // If the app is undergoing backup, tell the backup manager about it 14803 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14804 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14805 + mBackupTarget.appInfo + " died during backup"); 14806 try { 14807 IBackupManager bm = IBackupManager.Stub.asInterface( 14808 ServiceManager.getService(Context.BACKUP_SERVICE)); 14809 bm.agentDisconnected(app.info.packageName); 14810 } catch (RemoteException e) { 14811 // can't happen; backup manager is local 14812 } 14813 } 14814 14815 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14816 ProcessChangeItem item = mPendingProcessChanges.get(i); 14817 if (item.pid == app.pid) { 14818 mPendingProcessChanges.remove(i); 14819 mAvailProcessChanges.add(item); 14820 } 14821 } 14822 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14823 14824 // If the caller is restarting this app, then leave it in its 14825 // current lists and let the caller take care of it. 14826 if (restarting) { 14827 return false; 14828 } 14829 14830 if (!app.persistent || app.isolated) { 14831 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14832 "Removing non-persistent process during cleanup: " + app); 14833 mProcessNames.remove(app.processName, app.uid); 14834 mIsolatedProcesses.remove(app.uid); 14835 if (mHeavyWeightProcess == app) { 14836 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14837 mHeavyWeightProcess.userId, 0)); 14838 mHeavyWeightProcess = null; 14839 } 14840 } else if (!app.removed) { 14841 // This app is persistent, so we need to keep its record around. 14842 // If it is not already on the pending app list, add it there 14843 // and start a new process for it. 14844 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14845 mPersistentStartingProcesses.add(app); 14846 restart = true; 14847 } 14848 } 14849 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14850 "Clean-up removing on hold: " + app); 14851 mProcessesOnHold.remove(app); 14852 14853 if (app == mHomeProcess) { 14854 mHomeProcess = null; 14855 } 14856 if (app == mPreviousProcess) { 14857 mPreviousProcess = null; 14858 } 14859 14860 if (restart && !app.isolated) { 14861 // We have components that still need to be running in the 14862 // process, so re-launch it. 14863 if (index < 0) { 14864 ProcessList.remove(app.pid); 14865 } 14866 mProcessNames.put(app.processName, app.uid, app); 14867 startProcessLocked(app, "restart", app.processName); 14868 return true; 14869 } else if (app.pid > 0 && app.pid != MY_PID) { 14870 // Goodbye! 14871 boolean removed; 14872 synchronized (mPidsSelfLocked) { 14873 mPidsSelfLocked.remove(app.pid); 14874 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14875 } 14876 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14877 if (app.isolated) { 14878 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14879 } 14880 app.setPid(0); 14881 } 14882 return false; 14883 } 14884 14885 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14886 // Look through the content providers we are waiting to have launched, 14887 // and if any run in this process then either schedule a restart of 14888 // the process or kill the client waiting for it if this process has 14889 // gone bad. 14890 int NL = mLaunchingProviders.size(); 14891 boolean restart = false; 14892 for (int i=0; i<NL; i++) { 14893 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14894 if (cpr.launchingApp == app) { 14895 if (!alwaysBad && !app.bad) { 14896 restart = true; 14897 } else { 14898 removeDyingProviderLocked(app, cpr, true); 14899 // cpr should have been removed from mLaunchingProviders 14900 NL = mLaunchingProviders.size(); 14901 i--; 14902 } 14903 } 14904 } 14905 return restart; 14906 } 14907 14908 // ========================================================= 14909 // SERVICES 14910 // ========================================================= 14911 14912 @Override 14913 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14914 int flags) { 14915 enforceNotIsolatedCaller("getServices"); 14916 synchronized (this) { 14917 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14918 } 14919 } 14920 14921 @Override 14922 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14923 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14924 synchronized (this) { 14925 return mServices.getRunningServiceControlPanelLocked(name); 14926 } 14927 } 14928 14929 @Override 14930 public ComponentName startService(IApplicationThread caller, Intent service, 14931 String resolvedType, int userId) { 14932 enforceNotIsolatedCaller("startService"); 14933 // Refuse possible leaked file descriptors 14934 if (service != null && service.hasFileDescriptors() == true) { 14935 throw new IllegalArgumentException("File descriptors passed in Intent"); 14936 } 14937 14938 if (DEBUG_SERVICE) 14939 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14940 synchronized(this) { 14941 final int callingPid = Binder.getCallingPid(); 14942 final int callingUid = Binder.getCallingUid(); 14943 final long origId = Binder.clearCallingIdentity(); 14944 ComponentName res = mServices.startServiceLocked(caller, service, 14945 resolvedType, callingPid, callingUid, userId); 14946 Binder.restoreCallingIdentity(origId); 14947 return res; 14948 } 14949 } 14950 14951 ComponentName startServiceInPackage(int uid, 14952 Intent service, String resolvedType, int userId) { 14953 synchronized(this) { 14954 if (DEBUG_SERVICE) 14955 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14956 final long origId = Binder.clearCallingIdentity(); 14957 ComponentName res = mServices.startServiceLocked(null, service, 14958 resolvedType, -1, uid, userId); 14959 Binder.restoreCallingIdentity(origId); 14960 return res; 14961 } 14962 } 14963 14964 @Override 14965 public int stopService(IApplicationThread caller, Intent service, 14966 String resolvedType, int userId) { 14967 enforceNotIsolatedCaller("stopService"); 14968 // Refuse possible leaked file descriptors 14969 if (service != null && service.hasFileDescriptors() == true) { 14970 throw new IllegalArgumentException("File descriptors passed in Intent"); 14971 } 14972 14973 synchronized(this) { 14974 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14975 } 14976 } 14977 14978 @Override 14979 public IBinder peekService(Intent service, String resolvedType) { 14980 enforceNotIsolatedCaller("peekService"); 14981 // Refuse possible leaked file descriptors 14982 if (service != null && service.hasFileDescriptors() == true) { 14983 throw new IllegalArgumentException("File descriptors passed in Intent"); 14984 } 14985 synchronized(this) { 14986 return mServices.peekServiceLocked(service, resolvedType); 14987 } 14988 } 14989 14990 @Override 14991 public boolean stopServiceToken(ComponentName className, IBinder token, 14992 int startId) { 14993 synchronized(this) { 14994 return mServices.stopServiceTokenLocked(className, token, startId); 14995 } 14996 } 14997 14998 @Override 14999 public void setServiceForeground(ComponentName className, IBinder token, 15000 int id, Notification notification, boolean removeNotification) { 15001 synchronized(this) { 15002 mServices.setServiceForegroundLocked(className, token, id, notification, 15003 removeNotification); 15004 } 15005 } 15006 15007 @Override 15008 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15009 boolean requireFull, String name, String callerPackage) { 15010 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15011 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15012 } 15013 15014 int unsafeConvertIncomingUser(int userId) { 15015 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15016 ? mCurrentUserId : userId; 15017 } 15018 15019 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15020 int allowMode, String name, String callerPackage) { 15021 final int callingUserId = UserHandle.getUserId(callingUid); 15022 if (callingUserId == userId) { 15023 return userId; 15024 } 15025 15026 // Note that we may be accessing mCurrentUserId outside of a lock... 15027 // shouldn't be a big deal, if this is being called outside 15028 // of a locked context there is intrinsically a race with 15029 // the value the caller will receive and someone else changing it. 15030 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15031 // we will switch to the calling user if access to the current user fails. 15032 int targetUserId = unsafeConvertIncomingUser(userId); 15033 15034 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15035 final boolean allow; 15036 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15037 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15038 // If the caller has this permission, they always pass go. And collect $200. 15039 allow = true; 15040 } else if (allowMode == ALLOW_FULL_ONLY) { 15041 // We require full access, sucks to be you. 15042 allow = false; 15043 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15044 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15045 // If the caller does not have either permission, they are always doomed. 15046 allow = false; 15047 } else if (allowMode == ALLOW_NON_FULL) { 15048 // We are blanket allowing non-full access, you lucky caller! 15049 allow = true; 15050 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15051 // We may or may not allow this depending on whether the two users are 15052 // in the same profile. 15053 synchronized (mUserProfileGroupIdsSelfLocked) { 15054 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15055 UserInfo.NO_PROFILE_GROUP_ID); 15056 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15057 UserInfo.NO_PROFILE_GROUP_ID); 15058 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15059 && callingProfile == targetProfile; 15060 } 15061 } else { 15062 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15063 } 15064 if (!allow) { 15065 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15066 // In this case, they would like to just execute as their 15067 // owner user instead of failing. 15068 targetUserId = callingUserId; 15069 } else { 15070 StringBuilder builder = new StringBuilder(128); 15071 builder.append("Permission Denial: "); 15072 builder.append(name); 15073 if (callerPackage != null) { 15074 builder.append(" from "); 15075 builder.append(callerPackage); 15076 } 15077 builder.append(" asks to run as user "); 15078 builder.append(userId); 15079 builder.append(" but is calling from user "); 15080 builder.append(UserHandle.getUserId(callingUid)); 15081 builder.append("; this requires "); 15082 builder.append(INTERACT_ACROSS_USERS_FULL); 15083 if (allowMode != ALLOW_FULL_ONLY) { 15084 builder.append(" or "); 15085 builder.append(INTERACT_ACROSS_USERS); 15086 } 15087 String msg = builder.toString(); 15088 Slog.w(TAG, msg); 15089 throw new SecurityException(msg); 15090 } 15091 } 15092 } 15093 if (!allowAll && targetUserId < 0) { 15094 throw new IllegalArgumentException( 15095 "Call does not support special user #" + targetUserId); 15096 } 15097 // Check shell permission 15098 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15099 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15100 targetUserId)) { 15101 throw new SecurityException("Shell does not have permission to access user " 15102 + targetUserId + "\n " + Debug.getCallers(3)); 15103 } 15104 } 15105 return targetUserId; 15106 } 15107 15108 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15109 String className, int flags) { 15110 boolean result = false; 15111 // For apps that don't have pre-defined UIDs, check for permission 15112 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15113 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15114 if (ActivityManager.checkUidPermission( 15115 INTERACT_ACROSS_USERS, 15116 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15117 ComponentName comp = new ComponentName(aInfo.packageName, className); 15118 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15119 + " requests FLAG_SINGLE_USER, but app does not hold " 15120 + INTERACT_ACROSS_USERS; 15121 Slog.w(TAG, msg); 15122 throw new SecurityException(msg); 15123 } 15124 // Permission passed 15125 result = true; 15126 } 15127 } else if ("system".equals(componentProcessName)) { 15128 result = true; 15129 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15130 // Phone app and persistent apps are allowed to export singleuser providers. 15131 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15132 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15133 } 15134 if (DEBUG_MU) { 15135 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15136 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15137 } 15138 return result; 15139 } 15140 15141 /** 15142 * Checks to see if the caller is in the same app as the singleton 15143 * component, or the component is in a special app. It allows special apps 15144 * to export singleton components but prevents exporting singleton 15145 * components for regular apps. 15146 */ 15147 boolean isValidSingletonCall(int callingUid, int componentUid) { 15148 int componentAppId = UserHandle.getAppId(componentUid); 15149 return UserHandle.isSameApp(callingUid, componentUid) 15150 || componentAppId == Process.SYSTEM_UID 15151 || componentAppId == Process.PHONE_UID 15152 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15153 == PackageManager.PERMISSION_GRANTED; 15154 } 15155 15156 public int bindService(IApplicationThread caller, IBinder token, 15157 Intent service, String resolvedType, 15158 IServiceConnection connection, int flags, int userId) { 15159 enforceNotIsolatedCaller("bindService"); 15160 15161 // Refuse possible leaked file descriptors 15162 if (service != null && service.hasFileDescriptors() == true) { 15163 throw new IllegalArgumentException("File descriptors passed in Intent"); 15164 } 15165 15166 synchronized(this) { 15167 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15168 connection, flags, userId); 15169 } 15170 } 15171 15172 public boolean unbindService(IServiceConnection connection) { 15173 synchronized (this) { 15174 return mServices.unbindServiceLocked(connection); 15175 } 15176 } 15177 15178 public void publishService(IBinder token, Intent intent, IBinder service) { 15179 // Refuse possible leaked file descriptors 15180 if (intent != null && intent.hasFileDescriptors() == true) { 15181 throw new IllegalArgumentException("File descriptors passed in Intent"); 15182 } 15183 15184 synchronized(this) { 15185 if (!(token instanceof ServiceRecord)) { 15186 throw new IllegalArgumentException("Invalid service token"); 15187 } 15188 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15189 } 15190 } 15191 15192 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15193 // Refuse possible leaked file descriptors 15194 if (intent != null && intent.hasFileDescriptors() == true) { 15195 throw new IllegalArgumentException("File descriptors passed in Intent"); 15196 } 15197 15198 synchronized(this) { 15199 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15200 } 15201 } 15202 15203 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15204 synchronized(this) { 15205 if (!(token instanceof ServiceRecord)) { 15206 throw new IllegalArgumentException("Invalid service token"); 15207 } 15208 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15209 } 15210 } 15211 15212 // ========================================================= 15213 // BACKUP AND RESTORE 15214 // ========================================================= 15215 15216 // Cause the target app to be launched if necessary and its backup agent 15217 // instantiated. The backup agent will invoke backupAgentCreated() on the 15218 // activity manager to announce its creation. 15219 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15220 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15221 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15222 15223 synchronized(this) { 15224 // !!! TODO: currently no check here that we're already bound 15225 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15226 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15227 synchronized (stats) { 15228 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15229 } 15230 15231 // Backup agent is now in use, its package can't be stopped. 15232 try { 15233 AppGlobals.getPackageManager().setPackageStoppedState( 15234 app.packageName, false, UserHandle.getUserId(app.uid)); 15235 } catch (RemoteException e) { 15236 } catch (IllegalArgumentException e) { 15237 Slog.w(TAG, "Failed trying to unstop package " 15238 + app.packageName + ": " + e); 15239 } 15240 15241 BackupRecord r = new BackupRecord(ss, app, backupMode); 15242 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15243 ? new ComponentName(app.packageName, app.backupAgentName) 15244 : new ComponentName("android", "FullBackupAgent"); 15245 // startProcessLocked() returns existing proc's record if it's already running 15246 ProcessRecord proc = startProcessLocked(app.processName, app, 15247 false, 0, "backup", hostingName, false, false, false); 15248 if (proc == null) { 15249 Slog.e(TAG, "Unable to start backup agent process " + r); 15250 return false; 15251 } 15252 15253 r.app = proc; 15254 mBackupTarget = r; 15255 mBackupAppName = app.packageName; 15256 15257 // Try not to kill the process during backup 15258 updateOomAdjLocked(proc); 15259 15260 // If the process is already attached, schedule the creation of the backup agent now. 15261 // If it is not yet live, this will be done when it attaches to the framework. 15262 if (proc.thread != null) { 15263 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15264 try { 15265 proc.thread.scheduleCreateBackupAgent(app, 15266 compatibilityInfoForPackageLocked(app), backupMode); 15267 } catch (RemoteException e) { 15268 // Will time out on the backup manager side 15269 } 15270 } else { 15271 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15272 } 15273 // Invariants: at this point, the target app process exists and the application 15274 // is either already running or in the process of coming up. mBackupTarget and 15275 // mBackupAppName describe the app, so that when it binds back to the AM we 15276 // know that it's scheduled for a backup-agent operation. 15277 } 15278 15279 return true; 15280 } 15281 15282 @Override 15283 public void clearPendingBackup() { 15284 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15285 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15286 15287 synchronized (this) { 15288 mBackupTarget = null; 15289 mBackupAppName = null; 15290 } 15291 } 15292 15293 // A backup agent has just come up 15294 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15295 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15296 + " = " + agent); 15297 15298 synchronized(this) { 15299 if (!agentPackageName.equals(mBackupAppName)) { 15300 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15301 return; 15302 } 15303 } 15304 15305 long oldIdent = Binder.clearCallingIdentity(); 15306 try { 15307 IBackupManager bm = IBackupManager.Stub.asInterface( 15308 ServiceManager.getService(Context.BACKUP_SERVICE)); 15309 bm.agentConnected(agentPackageName, agent); 15310 } catch (RemoteException e) { 15311 // can't happen; the backup manager service is local 15312 } catch (Exception e) { 15313 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15314 e.printStackTrace(); 15315 } finally { 15316 Binder.restoreCallingIdentity(oldIdent); 15317 } 15318 } 15319 15320 // done with this agent 15321 public void unbindBackupAgent(ApplicationInfo appInfo) { 15322 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15323 if (appInfo == null) { 15324 Slog.w(TAG, "unbind backup agent for null app"); 15325 return; 15326 } 15327 15328 synchronized(this) { 15329 try { 15330 if (mBackupAppName == null) { 15331 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15332 return; 15333 } 15334 15335 if (!mBackupAppName.equals(appInfo.packageName)) { 15336 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15337 return; 15338 } 15339 15340 // Not backing this app up any more; reset its OOM adjustment 15341 final ProcessRecord proc = mBackupTarget.app; 15342 updateOomAdjLocked(proc); 15343 15344 // If the app crashed during backup, 'thread' will be null here 15345 if (proc.thread != null) { 15346 try { 15347 proc.thread.scheduleDestroyBackupAgent(appInfo, 15348 compatibilityInfoForPackageLocked(appInfo)); 15349 } catch (Exception e) { 15350 Slog.e(TAG, "Exception when unbinding backup agent:"); 15351 e.printStackTrace(); 15352 } 15353 } 15354 } finally { 15355 mBackupTarget = null; 15356 mBackupAppName = null; 15357 } 15358 } 15359 } 15360 // ========================================================= 15361 // BROADCASTS 15362 // ========================================================= 15363 15364 private final List getStickiesLocked(String action, IntentFilter filter, 15365 List cur, int userId) { 15366 final ContentResolver resolver = mContext.getContentResolver(); 15367 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15368 if (stickies == null) { 15369 return cur; 15370 } 15371 final ArrayList<Intent> list = stickies.get(action); 15372 if (list == null) { 15373 return cur; 15374 } 15375 int N = list.size(); 15376 for (int i=0; i<N; i++) { 15377 Intent intent = list.get(i); 15378 if (filter.match(resolver, intent, true, TAG) >= 0) { 15379 if (cur == null) { 15380 cur = new ArrayList<Intent>(); 15381 } 15382 cur.add(intent); 15383 } 15384 } 15385 return cur; 15386 } 15387 15388 boolean isPendingBroadcastProcessLocked(int pid) { 15389 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15390 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15391 } 15392 15393 void skipPendingBroadcastLocked(int pid) { 15394 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15395 for (BroadcastQueue queue : mBroadcastQueues) { 15396 queue.skipPendingBroadcastLocked(pid); 15397 } 15398 } 15399 15400 // The app just attached; send any pending broadcasts that it should receive 15401 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15402 boolean didSomething = false; 15403 for (BroadcastQueue queue : mBroadcastQueues) { 15404 didSomething |= queue.sendPendingBroadcastsLocked(app); 15405 } 15406 return didSomething; 15407 } 15408 15409 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15410 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15411 enforceNotIsolatedCaller("registerReceiver"); 15412 int callingUid; 15413 int callingPid; 15414 synchronized(this) { 15415 ProcessRecord callerApp = null; 15416 if (caller != null) { 15417 callerApp = getRecordForAppLocked(caller); 15418 if (callerApp == null) { 15419 throw new SecurityException( 15420 "Unable to find app for caller " + caller 15421 + " (pid=" + Binder.getCallingPid() 15422 + ") when registering receiver " + receiver); 15423 } 15424 if (callerApp.info.uid != Process.SYSTEM_UID && 15425 !callerApp.pkgList.containsKey(callerPackage) && 15426 !"android".equals(callerPackage)) { 15427 throw new SecurityException("Given caller package " + callerPackage 15428 + " is not running in process " + callerApp); 15429 } 15430 callingUid = callerApp.info.uid; 15431 callingPid = callerApp.pid; 15432 } else { 15433 callerPackage = null; 15434 callingUid = Binder.getCallingUid(); 15435 callingPid = Binder.getCallingPid(); 15436 } 15437 15438 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15439 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15440 15441 List allSticky = null; 15442 15443 // Look for any matching sticky broadcasts... 15444 Iterator actions = filter.actionsIterator(); 15445 if (actions != null) { 15446 while (actions.hasNext()) { 15447 String action = (String)actions.next(); 15448 allSticky = getStickiesLocked(action, filter, allSticky, 15449 UserHandle.USER_ALL); 15450 allSticky = getStickiesLocked(action, filter, allSticky, 15451 UserHandle.getUserId(callingUid)); 15452 } 15453 } else { 15454 allSticky = getStickiesLocked(null, filter, allSticky, 15455 UserHandle.USER_ALL); 15456 allSticky = getStickiesLocked(null, filter, allSticky, 15457 UserHandle.getUserId(callingUid)); 15458 } 15459 15460 // The first sticky in the list is returned directly back to 15461 // the client. 15462 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15463 15464 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15465 + ": " + sticky); 15466 15467 if (receiver == null) { 15468 return sticky; 15469 } 15470 15471 ReceiverList rl 15472 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15473 if (rl == null) { 15474 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15475 userId, receiver); 15476 if (rl.app != null) { 15477 rl.app.receivers.add(rl); 15478 } else { 15479 try { 15480 receiver.asBinder().linkToDeath(rl, 0); 15481 } catch (RemoteException e) { 15482 return sticky; 15483 } 15484 rl.linkedToDeath = true; 15485 } 15486 mRegisteredReceivers.put(receiver.asBinder(), rl); 15487 } else if (rl.uid != callingUid) { 15488 throw new IllegalArgumentException( 15489 "Receiver requested to register for uid " + callingUid 15490 + " was previously registered for uid " + rl.uid); 15491 } else if (rl.pid != callingPid) { 15492 throw new IllegalArgumentException( 15493 "Receiver requested to register for pid " + callingPid 15494 + " was previously registered for pid " + rl.pid); 15495 } else if (rl.userId != userId) { 15496 throw new IllegalArgumentException( 15497 "Receiver requested to register for user " + userId 15498 + " was previously registered for user " + rl.userId); 15499 } 15500 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15501 permission, callingUid, userId); 15502 rl.add(bf); 15503 if (!bf.debugCheck()) { 15504 Slog.w(TAG, "==> For Dynamic broadast"); 15505 } 15506 mReceiverResolver.addFilter(bf); 15507 15508 // Enqueue broadcasts for all existing stickies that match 15509 // this filter. 15510 if (allSticky != null) { 15511 ArrayList receivers = new ArrayList(); 15512 receivers.add(bf); 15513 15514 int N = allSticky.size(); 15515 for (int i=0; i<N; i++) { 15516 Intent intent = (Intent)allSticky.get(i); 15517 BroadcastQueue queue = broadcastQueueForIntent(intent); 15518 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15519 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15520 null, null, false, true, true, -1); 15521 queue.enqueueParallelBroadcastLocked(r); 15522 queue.scheduleBroadcastsLocked(); 15523 } 15524 } 15525 15526 return sticky; 15527 } 15528 } 15529 15530 public void unregisterReceiver(IIntentReceiver receiver) { 15531 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15532 15533 final long origId = Binder.clearCallingIdentity(); 15534 try { 15535 boolean doTrim = false; 15536 15537 synchronized(this) { 15538 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15539 if (rl != null) { 15540 if (rl.curBroadcast != null) { 15541 BroadcastRecord r = rl.curBroadcast; 15542 final boolean doNext = finishReceiverLocked( 15543 receiver.asBinder(), r.resultCode, r.resultData, 15544 r.resultExtras, r.resultAbort); 15545 if (doNext) { 15546 doTrim = true; 15547 r.queue.processNextBroadcast(false); 15548 } 15549 } 15550 15551 if (rl.app != null) { 15552 rl.app.receivers.remove(rl); 15553 } 15554 removeReceiverLocked(rl); 15555 if (rl.linkedToDeath) { 15556 rl.linkedToDeath = false; 15557 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15558 } 15559 } 15560 } 15561 15562 // If we actually concluded any broadcasts, we might now be able 15563 // to trim the recipients' apps from our working set 15564 if (doTrim) { 15565 trimApplications(); 15566 return; 15567 } 15568 15569 } finally { 15570 Binder.restoreCallingIdentity(origId); 15571 } 15572 } 15573 15574 void removeReceiverLocked(ReceiverList rl) { 15575 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15576 int N = rl.size(); 15577 for (int i=0; i<N; i++) { 15578 mReceiverResolver.removeFilter(rl.get(i)); 15579 } 15580 } 15581 15582 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15583 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15584 ProcessRecord r = mLruProcesses.get(i); 15585 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15586 try { 15587 r.thread.dispatchPackageBroadcast(cmd, packages); 15588 } catch (RemoteException ex) { 15589 } 15590 } 15591 } 15592 } 15593 15594 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15595 int callingUid, int[] users) { 15596 List<ResolveInfo> receivers = null; 15597 try { 15598 HashSet<ComponentName> singleUserReceivers = null; 15599 boolean scannedFirstReceivers = false; 15600 for (int user : users) { 15601 // Skip users that have Shell restrictions 15602 if (callingUid == Process.SHELL_UID 15603 && getUserManagerLocked().hasUserRestriction( 15604 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15605 continue; 15606 } 15607 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15608 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15609 if (user != 0 && newReceivers != null) { 15610 // If this is not the primary user, we need to check for 15611 // any receivers that should be filtered out. 15612 for (int i=0; i<newReceivers.size(); i++) { 15613 ResolveInfo ri = newReceivers.get(i); 15614 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15615 newReceivers.remove(i); 15616 i--; 15617 } 15618 } 15619 } 15620 if (newReceivers != null && newReceivers.size() == 0) { 15621 newReceivers = null; 15622 } 15623 if (receivers == null) { 15624 receivers = newReceivers; 15625 } else if (newReceivers != null) { 15626 // We need to concatenate the additional receivers 15627 // found with what we have do far. This would be easy, 15628 // but we also need to de-dup any receivers that are 15629 // singleUser. 15630 if (!scannedFirstReceivers) { 15631 // Collect any single user receivers we had already retrieved. 15632 scannedFirstReceivers = true; 15633 for (int i=0; i<receivers.size(); i++) { 15634 ResolveInfo ri = receivers.get(i); 15635 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15636 ComponentName cn = new ComponentName( 15637 ri.activityInfo.packageName, ri.activityInfo.name); 15638 if (singleUserReceivers == null) { 15639 singleUserReceivers = new HashSet<ComponentName>(); 15640 } 15641 singleUserReceivers.add(cn); 15642 } 15643 } 15644 } 15645 // Add the new results to the existing results, tracking 15646 // and de-dupping single user receivers. 15647 for (int i=0; i<newReceivers.size(); i++) { 15648 ResolveInfo ri = newReceivers.get(i); 15649 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15650 ComponentName cn = new ComponentName( 15651 ri.activityInfo.packageName, ri.activityInfo.name); 15652 if (singleUserReceivers == null) { 15653 singleUserReceivers = new HashSet<ComponentName>(); 15654 } 15655 if (!singleUserReceivers.contains(cn)) { 15656 singleUserReceivers.add(cn); 15657 receivers.add(ri); 15658 } 15659 } else { 15660 receivers.add(ri); 15661 } 15662 } 15663 } 15664 } 15665 } catch (RemoteException ex) { 15666 // pm is in same process, this will never happen. 15667 } 15668 return receivers; 15669 } 15670 15671 private final int broadcastIntentLocked(ProcessRecord callerApp, 15672 String callerPackage, Intent intent, String resolvedType, 15673 IIntentReceiver resultTo, int resultCode, String resultData, 15674 Bundle map, String requiredPermission, int appOp, 15675 boolean ordered, boolean sticky, int callingPid, int callingUid, 15676 int userId) { 15677 intent = new Intent(intent); 15678 15679 // By default broadcasts do not go to stopped apps. 15680 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15681 15682 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15683 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15684 + " ordered=" + ordered + " userid=" + userId); 15685 if ((resultTo != null) && !ordered) { 15686 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15687 } 15688 15689 userId = handleIncomingUser(callingPid, callingUid, userId, 15690 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15691 15692 // Make sure that the user who is receiving this broadcast is running. 15693 // If not, we will just skip it. Make an exception for shutdown broadcasts 15694 // and upgrade steps. 15695 15696 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15697 if ((callingUid != Process.SYSTEM_UID 15698 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15699 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15700 Slog.w(TAG, "Skipping broadcast of " + intent 15701 + ": user " + userId + " is stopped"); 15702 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15703 } 15704 } 15705 15706 /* 15707 * Prevent non-system code (defined here to be non-persistent 15708 * processes) from sending protected broadcasts. 15709 */ 15710 int callingAppId = UserHandle.getAppId(callingUid); 15711 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15712 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15713 || callingAppId == Process.NFC_UID || callingUid == 0) { 15714 // Always okay. 15715 } else if (callerApp == null || !callerApp.persistent) { 15716 try { 15717 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15718 intent.getAction())) { 15719 String msg = "Permission Denial: not allowed to send broadcast " 15720 + intent.getAction() + " from pid=" 15721 + callingPid + ", uid=" + callingUid; 15722 Slog.w(TAG, msg); 15723 throw new SecurityException(msg); 15724 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15725 // Special case for compatibility: we don't want apps to send this, 15726 // but historically it has not been protected and apps may be using it 15727 // to poke their own app widget. So, instead of making it protected, 15728 // just limit it to the caller. 15729 if (callerApp == null) { 15730 String msg = "Permission Denial: not allowed to send broadcast " 15731 + intent.getAction() + " from unknown caller."; 15732 Slog.w(TAG, msg); 15733 throw new SecurityException(msg); 15734 } else if (intent.getComponent() != null) { 15735 // They are good enough to send to an explicit component... verify 15736 // it is being sent to the calling app. 15737 if (!intent.getComponent().getPackageName().equals( 15738 callerApp.info.packageName)) { 15739 String msg = "Permission Denial: not allowed to send broadcast " 15740 + intent.getAction() + " to " 15741 + intent.getComponent().getPackageName() + " from " 15742 + callerApp.info.packageName; 15743 Slog.w(TAG, msg); 15744 throw new SecurityException(msg); 15745 } 15746 } else { 15747 // Limit broadcast to their own package. 15748 intent.setPackage(callerApp.info.packageName); 15749 } 15750 } 15751 } catch (RemoteException e) { 15752 Slog.w(TAG, "Remote exception", e); 15753 return ActivityManager.BROADCAST_SUCCESS; 15754 } 15755 } 15756 15757 final String action = intent.getAction(); 15758 if (action != null) { 15759 switch (action) { 15760 case Intent.ACTION_UID_REMOVED: 15761 case Intent.ACTION_PACKAGE_REMOVED: 15762 case Intent.ACTION_PACKAGE_CHANGED: 15763 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15764 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15765 // Handle special intents: if this broadcast is from the package 15766 // manager about a package being removed, we need to remove all of 15767 // its activities from the history stack. 15768 if (checkComponentPermission( 15769 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15770 callingPid, callingUid, -1, true) 15771 != PackageManager.PERMISSION_GRANTED) { 15772 String msg = "Permission Denial: " + intent.getAction() 15773 + " broadcast from " + callerPackage + " (pid=" + callingPid 15774 + ", uid=" + callingUid + ")" 15775 + " requires " 15776 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15777 Slog.w(TAG, msg); 15778 throw new SecurityException(msg); 15779 } 15780 switch (action) { 15781 case Intent.ACTION_UID_REMOVED: 15782 final Bundle intentExtras = intent.getExtras(); 15783 final int uid = intentExtras != null 15784 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15785 if (uid >= 0) { 15786 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15787 synchronized (bs) { 15788 bs.removeUidStatsLocked(uid); 15789 } 15790 mAppOpsService.uidRemoved(uid); 15791 } 15792 break; 15793 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15794 // If resources are unavailable just force stop all those packages 15795 // and flush the attribute cache as well. 15796 String list[] = 15797 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15798 if (list != null && list.length > 0) { 15799 for (int i = 0; i < list.length; i++) { 15800 forceStopPackageLocked(list[i], -1, false, true, true, 15801 false, false, userId, "storage unmount"); 15802 } 15803 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15804 sendPackageBroadcastLocked( 15805 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15806 userId); 15807 } 15808 break; 15809 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15810 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15811 break; 15812 case Intent.ACTION_PACKAGE_REMOVED: 15813 case Intent.ACTION_PACKAGE_CHANGED: 15814 Uri data = intent.getData(); 15815 String ssp; 15816 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15817 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15818 boolean fullUninstall = removed && 15819 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15820 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15821 forceStopPackageLocked(ssp, UserHandle.getAppId( 15822 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15823 false, true, true, false, fullUninstall, userId, 15824 removed ? "pkg removed" : "pkg changed"); 15825 } 15826 if (removed) { 15827 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15828 new String[] {ssp}, userId); 15829 if (fullUninstall) { 15830 mAppOpsService.packageRemoved( 15831 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15832 15833 // Remove all permissions granted from/to this package 15834 removeUriPermissionsForPackageLocked(ssp, userId, true); 15835 15836 removeTasksByPackageNameLocked(ssp, userId); 15837 } 15838 } else { 15839 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15840 if (userId == UserHandle.USER_OWNER) { 15841 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15842 } 15843 } 15844 } 15845 break; 15846 } 15847 break; 15848 case Intent.ACTION_PACKAGE_ADDED: 15849 // Special case for adding a package: by default turn on compatibility mode. 15850 Uri data = intent.getData(); 15851 String ssp; 15852 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15853 final boolean replacing = 15854 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15855 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15856 15857 if (replacing) { 15858 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15859 } 15860 if (userId == UserHandle.USER_OWNER) { 15861 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 15862 } 15863 } 15864 break; 15865 case Intent.ACTION_TIMEZONE_CHANGED: 15866 // If this is the time zone changed action, queue up a message that will reset 15867 // the timezone of all currently running processes. This message will get 15868 // queued up before the broadcast happens. 15869 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15870 break; 15871 case Intent.ACTION_TIME_CHANGED: 15872 // If the user set the time, let all running processes know. 15873 final int is24Hour = 15874 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15875 : 0; 15876 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15877 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15878 synchronized (stats) { 15879 stats.noteCurrentTimeChangedLocked(); 15880 } 15881 break; 15882 case Intent.ACTION_CLEAR_DNS_CACHE: 15883 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15884 break; 15885 case Proxy.PROXY_CHANGE_ACTION: 15886 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15887 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15888 break; 15889 } 15890 } 15891 15892 // Add to the sticky list if requested. 15893 if (sticky) { 15894 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15895 callingPid, callingUid) 15896 != PackageManager.PERMISSION_GRANTED) { 15897 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15898 + callingPid + ", uid=" + callingUid 15899 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15900 Slog.w(TAG, msg); 15901 throw new SecurityException(msg); 15902 } 15903 if (requiredPermission != null) { 15904 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15905 + " and enforce permission " + requiredPermission); 15906 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15907 } 15908 if (intent.getComponent() != null) { 15909 throw new SecurityException( 15910 "Sticky broadcasts can't target a specific component"); 15911 } 15912 // We use userId directly here, since the "all" target is maintained 15913 // as a separate set of sticky broadcasts. 15914 if (userId != UserHandle.USER_ALL) { 15915 // But first, if this is not a broadcast to all users, then 15916 // make sure it doesn't conflict with an existing broadcast to 15917 // all users. 15918 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15919 UserHandle.USER_ALL); 15920 if (stickies != null) { 15921 ArrayList<Intent> list = stickies.get(intent.getAction()); 15922 if (list != null) { 15923 int N = list.size(); 15924 int i; 15925 for (i=0; i<N; i++) { 15926 if (intent.filterEquals(list.get(i))) { 15927 throw new IllegalArgumentException( 15928 "Sticky broadcast " + intent + " for user " 15929 + userId + " conflicts with existing global broadcast"); 15930 } 15931 } 15932 } 15933 } 15934 } 15935 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15936 if (stickies == null) { 15937 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15938 mStickyBroadcasts.put(userId, stickies); 15939 } 15940 ArrayList<Intent> list = stickies.get(intent.getAction()); 15941 if (list == null) { 15942 list = new ArrayList<Intent>(); 15943 stickies.put(intent.getAction(), list); 15944 } 15945 int N = list.size(); 15946 int i; 15947 for (i=0; i<N; i++) { 15948 if (intent.filterEquals(list.get(i))) { 15949 // This sticky already exists, replace it. 15950 list.set(i, new Intent(intent)); 15951 break; 15952 } 15953 } 15954 if (i >= N) { 15955 list.add(new Intent(intent)); 15956 } 15957 } 15958 15959 int[] users; 15960 if (userId == UserHandle.USER_ALL) { 15961 // Caller wants broadcast to go to all started users. 15962 users = mStartedUserArray; 15963 } else { 15964 // Caller wants broadcast to go to one specific user. 15965 users = new int[] {userId}; 15966 } 15967 15968 // Figure out who all will receive this broadcast. 15969 List receivers = null; 15970 List<BroadcastFilter> registeredReceivers = null; 15971 // Need to resolve the intent to interested receivers... 15972 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15973 == 0) { 15974 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15975 } 15976 if (intent.getComponent() == null) { 15977 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15978 // Query one target user at a time, excluding shell-restricted users 15979 UserManagerService ums = getUserManagerLocked(); 15980 for (int i = 0; i < users.length; i++) { 15981 if (ums.hasUserRestriction( 15982 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15983 continue; 15984 } 15985 List<BroadcastFilter> registeredReceiversForUser = 15986 mReceiverResolver.queryIntent(intent, 15987 resolvedType, false, users[i]); 15988 if (registeredReceivers == null) { 15989 registeredReceivers = registeredReceiversForUser; 15990 } else if (registeredReceiversForUser != null) { 15991 registeredReceivers.addAll(registeredReceiversForUser); 15992 } 15993 } 15994 } else { 15995 registeredReceivers = mReceiverResolver.queryIntent(intent, 15996 resolvedType, false, userId); 15997 } 15998 } 15999 16000 final boolean replacePending = 16001 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16002 16003 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16004 + " replacePending=" + replacePending); 16005 16006 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16007 if (!ordered && NR > 0) { 16008 // If we are not serializing this broadcast, then send the 16009 // registered receivers separately so they don't wait for the 16010 // components to be launched. 16011 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16012 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16013 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16014 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16015 ordered, sticky, false, userId); 16016 if (DEBUG_BROADCAST) Slog.v( 16017 TAG, "Enqueueing parallel broadcast " + r); 16018 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16019 if (!replaced) { 16020 queue.enqueueParallelBroadcastLocked(r); 16021 queue.scheduleBroadcastsLocked(); 16022 } 16023 registeredReceivers = null; 16024 NR = 0; 16025 } 16026 16027 // Merge into one list. 16028 int ir = 0; 16029 if (receivers != null) { 16030 // A special case for PACKAGE_ADDED: do not allow the package 16031 // being added to see this broadcast. This prevents them from 16032 // using this as a back door to get run as soon as they are 16033 // installed. Maybe in the future we want to have a special install 16034 // broadcast or such for apps, but we'd like to deliberately make 16035 // this decision. 16036 String skipPackages[] = null; 16037 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16038 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16039 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16040 Uri data = intent.getData(); 16041 if (data != null) { 16042 String pkgName = data.getSchemeSpecificPart(); 16043 if (pkgName != null) { 16044 skipPackages = new String[] { pkgName }; 16045 } 16046 } 16047 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16048 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16049 } 16050 if (skipPackages != null && (skipPackages.length > 0)) { 16051 for (String skipPackage : skipPackages) { 16052 if (skipPackage != null) { 16053 int NT = receivers.size(); 16054 for (int it=0; it<NT; it++) { 16055 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16056 if (curt.activityInfo.packageName.equals(skipPackage)) { 16057 receivers.remove(it); 16058 it--; 16059 NT--; 16060 } 16061 } 16062 } 16063 } 16064 } 16065 16066 int NT = receivers != null ? receivers.size() : 0; 16067 int it = 0; 16068 ResolveInfo curt = null; 16069 BroadcastFilter curr = null; 16070 while (it < NT && ir < NR) { 16071 if (curt == null) { 16072 curt = (ResolveInfo)receivers.get(it); 16073 } 16074 if (curr == null) { 16075 curr = registeredReceivers.get(ir); 16076 } 16077 if (curr.getPriority() >= curt.priority) { 16078 // Insert this broadcast record into the final list. 16079 receivers.add(it, curr); 16080 ir++; 16081 curr = null; 16082 it++; 16083 NT++; 16084 } else { 16085 // Skip to the next ResolveInfo in the final list. 16086 it++; 16087 curt = null; 16088 } 16089 } 16090 } 16091 while (ir < NR) { 16092 if (receivers == null) { 16093 receivers = new ArrayList(); 16094 } 16095 receivers.add(registeredReceivers.get(ir)); 16096 ir++; 16097 } 16098 16099 if ((receivers != null && receivers.size() > 0) 16100 || resultTo != null) { 16101 BroadcastQueue queue = broadcastQueueForIntent(intent); 16102 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16103 callerPackage, callingPid, callingUid, resolvedType, 16104 requiredPermission, appOp, receivers, resultTo, resultCode, 16105 resultData, map, ordered, sticky, false, userId); 16106 if (DEBUG_BROADCAST) Slog.v( 16107 TAG, "Enqueueing ordered broadcast " + r 16108 + ": prev had " + queue.mOrderedBroadcasts.size()); 16109 if (DEBUG_BROADCAST) { 16110 int seq = r.intent.getIntExtra("seq", -1); 16111 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16112 } 16113 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16114 if (!replaced) { 16115 queue.enqueueOrderedBroadcastLocked(r); 16116 queue.scheduleBroadcastsLocked(); 16117 } 16118 } 16119 16120 return ActivityManager.BROADCAST_SUCCESS; 16121 } 16122 16123 final Intent verifyBroadcastLocked(Intent intent) { 16124 // Refuse possible leaked file descriptors 16125 if (intent != null && intent.hasFileDescriptors() == true) { 16126 throw new IllegalArgumentException("File descriptors passed in Intent"); 16127 } 16128 16129 int flags = intent.getFlags(); 16130 16131 if (!mProcessesReady) { 16132 // if the caller really truly claims to know what they're doing, go 16133 // ahead and allow the broadcast without launching any receivers 16134 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16135 intent = new Intent(intent); 16136 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16137 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16138 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16139 + " before boot completion"); 16140 throw new IllegalStateException("Cannot broadcast before boot completed"); 16141 } 16142 } 16143 16144 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16145 throw new IllegalArgumentException( 16146 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16147 } 16148 16149 return intent; 16150 } 16151 16152 public final int broadcastIntent(IApplicationThread caller, 16153 Intent intent, String resolvedType, IIntentReceiver resultTo, 16154 int resultCode, String resultData, Bundle map, 16155 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16156 enforceNotIsolatedCaller("broadcastIntent"); 16157 synchronized(this) { 16158 intent = verifyBroadcastLocked(intent); 16159 16160 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16161 final int callingPid = Binder.getCallingPid(); 16162 final int callingUid = Binder.getCallingUid(); 16163 final long origId = Binder.clearCallingIdentity(); 16164 int res = broadcastIntentLocked(callerApp, 16165 callerApp != null ? callerApp.info.packageName : null, 16166 intent, resolvedType, resultTo, 16167 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16168 callingPid, callingUid, userId); 16169 Binder.restoreCallingIdentity(origId); 16170 return res; 16171 } 16172 } 16173 16174 int broadcastIntentInPackage(String packageName, int uid, 16175 Intent intent, String resolvedType, IIntentReceiver resultTo, 16176 int resultCode, String resultData, Bundle map, 16177 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16178 synchronized(this) { 16179 intent = verifyBroadcastLocked(intent); 16180 16181 final long origId = Binder.clearCallingIdentity(); 16182 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16183 resultTo, resultCode, resultData, map, requiredPermission, 16184 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16185 Binder.restoreCallingIdentity(origId); 16186 return res; 16187 } 16188 } 16189 16190 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16191 // Refuse possible leaked file descriptors 16192 if (intent != null && intent.hasFileDescriptors() == true) { 16193 throw new IllegalArgumentException("File descriptors passed in Intent"); 16194 } 16195 16196 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16197 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16198 16199 synchronized(this) { 16200 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16201 != PackageManager.PERMISSION_GRANTED) { 16202 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16203 + Binder.getCallingPid() 16204 + ", uid=" + Binder.getCallingUid() 16205 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16206 Slog.w(TAG, msg); 16207 throw new SecurityException(msg); 16208 } 16209 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16210 if (stickies != null) { 16211 ArrayList<Intent> list = stickies.get(intent.getAction()); 16212 if (list != null) { 16213 int N = list.size(); 16214 int i; 16215 for (i=0; i<N; i++) { 16216 if (intent.filterEquals(list.get(i))) { 16217 list.remove(i); 16218 break; 16219 } 16220 } 16221 if (list.size() <= 0) { 16222 stickies.remove(intent.getAction()); 16223 } 16224 } 16225 if (stickies.size() <= 0) { 16226 mStickyBroadcasts.remove(userId); 16227 } 16228 } 16229 } 16230 } 16231 16232 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16233 String resultData, Bundle resultExtras, boolean resultAbort) { 16234 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16235 if (r == null) { 16236 Slog.w(TAG, "finishReceiver called but not found on queue"); 16237 return false; 16238 } 16239 16240 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16241 } 16242 16243 void backgroundServicesFinishedLocked(int userId) { 16244 for (BroadcastQueue queue : mBroadcastQueues) { 16245 queue.backgroundServicesFinishedLocked(userId); 16246 } 16247 } 16248 16249 public void finishReceiver(IBinder who, int resultCode, String resultData, 16250 Bundle resultExtras, boolean resultAbort) { 16251 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16252 16253 // Refuse possible leaked file descriptors 16254 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16255 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16256 } 16257 16258 final long origId = Binder.clearCallingIdentity(); 16259 try { 16260 boolean doNext = false; 16261 BroadcastRecord r; 16262 16263 synchronized(this) { 16264 r = broadcastRecordForReceiverLocked(who); 16265 if (r != null) { 16266 doNext = r.queue.finishReceiverLocked(r, resultCode, 16267 resultData, resultExtras, resultAbort, true); 16268 } 16269 } 16270 16271 if (doNext) { 16272 r.queue.processNextBroadcast(false); 16273 } 16274 trimApplications(); 16275 } finally { 16276 Binder.restoreCallingIdentity(origId); 16277 } 16278 } 16279 16280 // ========================================================= 16281 // INSTRUMENTATION 16282 // ========================================================= 16283 16284 public boolean startInstrumentation(ComponentName className, 16285 String profileFile, int flags, Bundle arguments, 16286 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16287 int userId, String abiOverride) { 16288 enforceNotIsolatedCaller("startInstrumentation"); 16289 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16290 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16291 // Refuse possible leaked file descriptors 16292 if (arguments != null && arguments.hasFileDescriptors()) { 16293 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16294 } 16295 16296 synchronized(this) { 16297 InstrumentationInfo ii = null; 16298 ApplicationInfo ai = null; 16299 try { 16300 ii = mContext.getPackageManager().getInstrumentationInfo( 16301 className, STOCK_PM_FLAGS); 16302 ai = AppGlobals.getPackageManager().getApplicationInfo( 16303 ii.targetPackage, STOCK_PM_FLAGS, userId); 16304 } catch (PackageManager.NameNotFoundException e) { 16305 } catch (RemoteException e) { 16306 } 16307 if (ii == null) { 16308 reportStartInstrumentationFailure(watcher, className, 16309 "Unable to find instrumentation info for: " + className); 16310 return false; 16311 } 16312 if (ai == null) { 16313 reportStartInstrumentationFailure(watcher, className, 16314 "Unable to find instrumentation target package: " + ii.targetPackage); 16315 return false; 16316 } 16317 16318 int match = mContext.getPackageManager().checkSignatures( 16319 ii.targetPackage, ii.packageName); 16320 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16321 String msg = "Permission Denial: starting instrumentation " 16322 + className + " from pid=" 16323 + Binder.getCallingPid() 16324 + ", uid=" + Binder.getCallingPid() 16325 + " not allowed because package " + ii.packageName 16326 + " does not have a signature matching the target " 16327 + ii.targetPackage; 16328 reportStartInstrumentationFailure(watcher, className, msg); 16329 throw new SecurityException(msg); 16330 } 16331 16332 final long origId = Binder.clearCallingIdentity(); 16333 // Instrumentation can kill and relaunch even persistent processes 16334 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16335 "start instr"); 16336 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16337 app.instrumentationClass = className; 16338 app.instrumentationInfo = ai; 16339 app.instrumentationProfileFile = profileFile; 16340 app.instrumentationArguments = arguments; 16341 app.instrumentationWatcher = watcher; 16342 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16343 app.instrumentationResultClass = className; 16344 Binder.restoreCallingIdentity(origId); 16345 } 16346 16347 return true; 16348 } 16349 16350 /** 16351 * Report errors that occur while attempting to start Instrumentation. Always writes the 16352 * error to the logs, but if somebody is watching, send the report there too. This enables 16353 * the "am" command to report errors with more information. 16354 * 16355 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16356 * @param cn The component name of the instrumentation. 16357 * @param report The error report. 16358 */ 16359 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16360 ComponentName cn, String report) { 16361 Slog.w(TAG, report); 16362 try { 16363 if (watcher != null) { 16364 Bundle results = new Bundle(); 16365 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16366 results.putString("Error", report); 16367 watcher.instrumentationStatus(cn, -1, results); 16368 } 16369 } catch (RemoteException e) { 16370 Slog.w(TAG, e); 16371 } 16372 } 16373 16374 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16375 if (app.instrumentationWatcher != null) { 16376 try { 16377 // NOTE: IInstrumentationWatcher *must* be oneway here 16378 app.instrumentationWatcher.instrumentationFinished( 16379 app.instrumentationClass, 16380 resultCode, 16381 results); 16382 } catch (RemoteException e) { 16383 } 16384 } 16385 if (app.instrumentationUiAutomationConnection != null) { 16386 try { 16387 app.instrumentationUiAutomationConnection.shutdown(); 16388 } catch (RemoteException re) { 16389 /* ignore */ 16390 } 16391 // Only a UiAutomation can set this flag and now that 16392 // it is finished we make sure it is reset to its default. 16393 mUserIsMonkey = false; 16394 } 16395 app.instrumentationWatcher = null; 16396 app.instrumentationUiAutomationConnection = null; 16397 app.instrumentationClass = null; 16398 app.instrumentationInfo = null; 16399 app.instrumentationProfileFile = null; 16400 app.instrumentationArguments = null; 16401 16402 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16403 "finished inst"); 16404 } 16405 16406 public void finishInstrumentation(IApplicationThread target, 16407 int resultCode, Bundle results) { 16408 int userId = UserHandle.getCallingUserId(); 16409 // Refuse possible leaked file descriptors 16410 if (results != null && results.hasFileDescriptors()) { 16411 throw new IllegalArgumentException("File descriptors passed in Intent"); 16412 } 16413 16414 synchronized(this) { 16415 ProcessRecord app = getRecordForAppLocked(target); 16416 if (app == null) { 16417 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16418 return; 16419 } 16420 final long origId = Binder.clearCallingIdentity(); 16421 finishInstrumentationLocked(app, resultCode, results); 16422 Binder.restoreCallingIdentity(origId); 16423 } 16424 } 16425 16426 // ========================================================= 16427 // CONFIGURATION 16428 // ========================================================= 16429 16430 public ConfigurationInfo getDeviceConfigurationInfo() { 16431 ConfigurationInfo config = new ConfigurationInfo(); 16432 synchronized (this) { 16433 config.reqTouchScreen = mConfiguration.touchscreen; 16434 config.reqKeyboardType = mConfiguration.keyboard; 16435 config.reqNavigation = mConfiguration.navigation; 16436 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16437 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16438 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16439 } 16440 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16441 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16442 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16443 } 16444 config.reqGlEsVersion = GL_ES_VERSION; 16445 } 16446 return config; 16447 } 16448 16449 ActivityStack getFocusedStack() { 16450 return mStackSupervisor.getFocusedStack(); 16451 } 16452 16453 public Configuration getConfiguration() { 16454 Configuration ci; 16455 synchronized(this) { 16456 ci = new Configuration(mConfiguration); 16457 } 16458 return ci; 16459 } 16460 16461 public void updatePersistentConfiguration(Configuration values) { 16462 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16463 "updateConfiguration()"); 16464 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16465 "updateConfiguration()"); 16466 if (values == null) { 16467 throw new NullPointerException("Configuration must not be null"); 16468 } 16469 16470 synchronized(this) { 16471 final long origId = Binder.clearCallingIdentity(); 16472 updateConfigurationLocked(values, null, true, false); 16473 Binder.restoreCallingIdentity(origId); 16474 } 16475 } 16476 16477 public void updateConfiguration(Configuration values) { 16478 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16479 "updateConfiguration()"); 16480 16481 synchronized(this) { 16482 if (values == null && mWindowManager != null) { 16483 // sentinel: fetch the current configuration from the window manager 16484 values = mWindowManager.computeNewConfiguration(); 16485 } 16486 16487 if (mWindowManager != null) { 16488 mProcessList.applyDisplaySize(mWindowManager); 16489 } 16490 16491 final long origId = Binder.clearCallingIdentity(); 16492 if (values != null) { 16493 Settings.System.clearConfiguration(values); 16494 } 16495 updateConfigurationLocked(values, null, false, false); 16496 Binder.restoreCallingIdentity(origId); 16497 } 16498 } 16499 16500 /** 16501 * Do either or both things: (1) change the current configuration, and (2) 16502 * make sure the given activity is running with the (now) current 16503 * configuration. Returns true if the activity has been left running, or 16504 * false if <var>starting</var> is being destroyed to match the new 16505 * configuration. 16506 * @param persistent TODO 16507 */ 16508 boolean updateConfigurationLocked(Configuration values, 16509 ActivityRecord starting, boolean persistent, boolean initLocale) { 16510 int changes = 0; 16511 16512 if (values != null) { 16513 Configuration newConfig = new Configuration(mConfiguration); 16514 changes = newConfig.updateFrom(values); 16515 if (changes != 0) { 16516 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16517 Slog.i(TAG, "Updating configuration to: " + values); 16518 } 16519 16520 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16521 16522 if (values.locale != null && !initLocale) { 16523 saveLocaleLocked(values.locale, 16524 !values.locale.equals(mConfiguration.locale), 16525 values.userSetLocale); 16526 } 16527 16528 mConfigurationSeq++; 16529 if (mConfigurationSeq <= 0) { 16530 mConfigurationSeq = 1; 16531 } 16532 newConfig.seq = mConfigurationSeq; 16533 mConfiguration = newConfig; 16534 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16535 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16536 //mUsageStatsService.noteStartConfig(newConfig); 16537 16538 final Configuration configCopy = new Configuration(mConfiguration); 16539 16540 // TODO: If our config changes, should we auto dismiss any currently 16541 // showing dialogs? 16542 mShowDialogs = shouldShowDialogs(newConfig); 16543 16544 AttributeCache ac = AttributeCache.instance(); 16545 if (ac != null) { 16546 ac.updateConfiguration(configCopy); 16547 } 16548 16549 // Make sure all resources in our process are updated 16550 // right now, so that anyone who is going to retrieve 16551 // resource values after we return will be sure to get 16552 // the new ones. This is especially important during 16553 // boot, where the first config change needs to guarantee 16554 // all resources have that config before following boot 16555 // code is executed. 16556 mSystemThread.applyConfigurationToResources(configCopy); 16557 16558 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16559 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16560 msg.obj = new Configuration(configCopy); 16561 mHandler.sendMessage(msg); 16562 } 16563 16564 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16565 ProcessRecord app = mLruProcesses.get(i); 16566 try { 16567 if (app.thread != null) { 16568 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16569 + app.processName + " new config " + mConfiguration); 16570 app.thread.scheduleConfigurationChanged(configCopy); 16571 } 16572 } catch (Exception e) { 16573 } 16574 } 16575 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16576 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16577 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16578 | Intent.FLAG_RECEIVER_FOREGROUND); 16579 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16580 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16581 Process.SYSTEM_UID, UserHandle.USER_ALL); 16582 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16583 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16584 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16585 broadcastIntentLocked(null, null, intent, 16586 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16587 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16588 } 16589 } 16590 } 16591 16592 boolean kept = true; 16593 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16594 // mainStack is null during startup. 16595 if (mainStack != null) { 16596 if (changes != 0 && starting == null) { 16597 // If the configuration changed, and the caller is not already 16598 // in the process of starting an activity, then find the top 16599 // activity to check if its configuration needs to change. 16600 starting = mainStack.topRunningActivityLocked(null); 16601 } 16602 16603 if (starting != null) { 16604 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16605 // And we need to make sure at this point that all other activities 16606 // are made visible with the correct configuration. 16607 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16608 } 16609 } 16610 16611 if (values != null && mWindowManager != null) { 16612 mWindowManager.setNewConfiguration(mConfiguration); 16613 } 16614 16615 return kept; 16616 } 16617 16618 /** 16619 * Decide based on the configuration whether we should shouw the ANR, 16620 * crash, etc dialogs. The idea is that if there is no affordnace to 16621 * press the on-screen buttons, we shouldn't show the dialog. 16622 * 16623 * A thought: SystemUI might also want to get told about this, the Power 16624 * dialog / global actions also might want different behaviors. 16625 */ 16626 private static final boolean shouldShowDialogs(Configuration config) { 16627 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16628 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16629 } 16630 16631 /** 16632 * Save the locale. You must be inside a synchronized (this) block. 16633 */ 16634 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16635 if(isDiff) { 16636 SystemProperties.set("user.language", l.getLanguage()); 16637 SystemProperties.set("user.region", l.getCountry()); 16638 } 16639 16640 if(isPersist) { 16641 SystemProperties.set("persist.sys.language", l.getLanguage()); 16642 SystemProperties.set("persist.sys.country", l.getCountry()); 16643 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16644 16645 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16646 } 16647 } 16648 16649 @Override 16650 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16651 synchronized (this) { 16652 ActivityRecord srec = ActivityRecord.forToken(token); 16653 if (srec.task != null && srec.task.stack != null) { 16654 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16655 } 16656 } 16657 return false; 16658 } 16659 16660 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16661 Intent resultData) { 16662 16663 synchronized (this) { 16664 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16665 if (stack != null) { 16666 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16667 } 16668 return false; 16669 } 16670 } 16671 16672 public int getLaunchedFromUid(IBinder activityToken) { 16673 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16674 if (srec == null) { 16675 return -1; 16676 } 16677 return srec.launchedFromUid; 16678 } 16679 16680 public String getLaunchedFromPackage(IBinder activityToken) { 16681 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16682 if (srec == null) { 16683 return null; 16684 } 16685 return srec.launchedFromPackage; 16686 } 16687 16688 // ========================================================= 16689 // LIFETIME MANAGEMENT 16690 // ========================================================= 16691 16692 // Returns which broadcast queue the app is the current [or imminent] receiver 16693 // on, or 'null' if the app is not an active broadcast recipient. 16694 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16695 BroadcastRecord r = app.curReceiver; 16696 if (r != null) { 16697 return r.queue; 16698 } 16699 16700 // It's not the current receiver, but it might be starting up to become one 16701 synchronized (this) { 16702 for (BroadcastQueue queue : mBroadcastQueues) { 16703 r = queue.mPendingBroadcast; 16704 if (r != null && r.curApp == app) { 16705 // found it; report which queue it's in 16706 return queue; 16707 } 16708 } 16709 } 16710 16711 return null; 16712 } 16713 16714 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16715 boolean doingAll, long now) { 16716 if (mAdjSeq == app.adjSeq) { 16717 // This adjustment has already been computed. 16718 return app.curRawAdj; 16719 } 16720 16721 if (app.thread == null) { 16722 app.adjSeq = mAdjSeq; 16723 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16724 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16725 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16726 } 16727 16728 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16729 app.adjSource = null; 16730 app.adjTarget = null; 16731 app.empty = false; 16732 app.cached = false; 16733 16734 final int activitiesSize = app.activities.size(); 16735 16736 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16737 // The max adjustment doesn't allow this app to be anything 16738 // below foreground, so it is not worth doing work for it. 16739 app.adjType = "fixed"; 16740 app.adjSeq = mAdjSeq; 16741 app.curRawAdj = app.maxAdj; 16742 app.foregroundActivities = false; 16743 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16744 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16745 // System processes can do UI, and when they do we want to have 16746 // them trim their memory after the user leaves the UI. To 16747 // facilitate this, here we need to determine whether or not it 16748 // is currently showing UI. 16749 app.systemNoUi = true; 16750 if (app == TOP_APP) { 16751 app.systemNoUi = false; 16752 } else if (activitiesSize > 0) { 16753 for (int j = 0; j < activitiesSize; j++) { 16754 final ActivityRecord r = app.activities.get(j); 16755 if (r.visible) { 16756 app.systemNoUi = false; 16757 } 16758 } 16759 } 16760 if (!app.systemNoUi) { 16761 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16762 } 16763 return (app.curAdj=app.maxAdj); 16764 } 16765 16766 app.systemNoUi = false; 16767 16768 // Determine the importance of the process, starting with most 16769 // important to least, and assign an appropriate OOM adjustment. 16770 int adj; 16771 int schedGroup; 16772 int procState; 16773 boolean foregroundActivities = false; 16774 BroadcastQueue queue; 16775 if (app == TOP_APP) { 16776 // The last app on the list is the foreground app. 16777 adj = ProcessList.FOREGROUND_APP_ADJ; 16778 schedGroup = Process.THREAD_GROUP_DEFAULT; 16779 app.adjType = "top-activity"; 16780 foregroundActivities = true; 16781 procState = ActivityManager.PROCESS_STATE_TOP; 16782 } else if (app.instrumentationClass != null) { 16783 // Don't want to kill running instrumentation. 16784 adj = ProcessList.FOREGROUND_APP_ADJ; 16785 schedGroup = Process.THREAD_GROUP_DEFAULT; 16786 app.adjType = "instrumentation"; 16787 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16788 } else if ((queue = isReceivingBroadcast(app)) != null) { 16789 // An app that is currently receiving a broadcast also 16790 // counts as being in the foreground for OOM killer purposes. 16791 // It's placed in a sched group based on the nature of the 16792 // broadcast as reflected by which queue it's active in. 16793 adj = ProcessList.FOREGROUND_APP_ADJ; 16794 schedGroup = (queue == mFgBroadcastQueue) 16795 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16796 app.adjType = "broadcast"; 16797 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16798 } else if (app.executingServices.size() > 0) { 16799 // An app that is currently executing a service callback also 16800 // counts as being in the foreground. 16801 adj = ProcessList.FOREGROUND_APP_ADJ; 16802 schedGroup = app.execServicesFg ? 16803 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16804 app.adjType = "exec-service"; 16805 procState = ActivityManager.PROCESS_STATE_SERVICE; 16806 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16807 } else { 16808 // As far as we know the process is empty. We may change our mind later. 16809 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16810 // At this point we don't actually know the adjustment. Use the cached adj 16811 // value that the caller wants us to. 16812 adj = cachedAdj; 16813 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16814 app.cached = true; 16815 app.empty = true; 16816 app.adjType = "cch-empty"; 16817 } 16818 16819 // Examine all activities if not already foreground. 16820 if (!foregroundActivities && activitiesSize > 0) { 16821 for (int j = 0; j < activitiesSize; j++) { 16822 final ActivityRecord r = app.activities.get(j); 16823 if (r.app != app) { 16824 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16825 + app + "?!?"); 16826 continue; 16827 } 16828 if (r.visible) { 16829 // App has a visible activity; only upgrade adjustment. 16830 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16831 adj = ProcessList.VISIBLE_APP_ADJ; 16832 app.adjType = "visible"; 16833 } 16834 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16835 procState = ActivityManager.PROCESS_STATE_TOP; 16836 } 16837 schedGroup = Process.THREAD_GROUP_DEFAULT; 16838 app.cached = false; 16839 app.empty = false; 16840 foregroundActivities = true; 16841 break; 16842 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16843 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16844 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16845 app.adjType = "pausing"; 16846 } 16847 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16848 procState = ActivityManager.PROCESS_STATE_TOP; 16849 } 16850 schedGroup = Process.THREAD_GROUP_DEFAULT; 16851 app.cached = false; 16852 app.empty = false; 16853 foregroundActivities = true; 16854 } else if (r.state == ActivityState.STOPPING) { 16855 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16856 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16857 app.adjType = "stopping"; 16858 } 16859 // For the process state, we will at this point consider the 16860 // process to be cached. It will be cached either as an activity 16861 // or empty depending on whether the activity is finishing. We do 16862 // this so that we can treat the process as cached for purposes of 16863 // memory trimming (determing current memory level, trim command to 16864 // send to process) since there can be an arbitrary number of stopping 16865 // processes and they should soon all go into the cached state. 16866 if (!r.finishing) { 16867 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16868 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16869 } 16870 } 16871 app.cached = false; 16872 app.empty = false; 16873 foregroundActivities = true; 16874 } else { 16875 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16876 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16877 app.adjType = "cch-act"; 16878 } 16879 } 16880 } 16881 } 16882 16883 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16884 if (app.foregroundServices) { 16885 // The user is aware of this app, so make it visible. 16886 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16887 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16888 app.cached = false; 16889 app.adjType = "fg-service"; 16890 schedGroup = Process.THREAD_GROUP_DEFAULT; 16891 } else if (app.forcingToForeground != null) { 16892 // The user is aware of this app, so make it visible. 16893 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16894 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16895 app.cached = false; 16896 app.adjType = "force-fg"; 16897 app.adjSource = app.forcingToForeground; 16898 schedGroup = Process.THREAD_GROUP_DEFAULT; 16899 } 16900 } 16901 16902 if (app == mHeavyWeightProcess) { 16903 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16904 // We don't want to kill the current heavy-weight process. 16905 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16906 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16907 app.cached = false; 16908 app.adjType = "heavy"; 16909 } 16910 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16911 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16912 } 16913 } 16914 16915 if (app == mHomeProcess) { 16916 if (adj > ProcessList.HOME_APP_ADJ) { 16917 // This process is hosting what we currently consider to be the 16918 // home app, so we don't want to let it go into the background. 16919 adj = ProcessList.HOME_APP_ADJ; 16920 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16921 app.cached = false; 16922 app.adjType = "home"; 16923 } 16924 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16925 procState = ActivityManager.PROCESS_STATE_HOME; 16926 } 16927 } 16928 16929 if (app == mPreviousProcess && app.activities.size() > 0) { 16930 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16931 // This was the previous process that showed UI to the user. 16932 // We want to try to keep it around more aggressively, to give 16933 // a good experience around switching between two apps. 16934 adj = ProcessList.PREVIOUS_APP_ADJ; 16935 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16936 app.cached = false; 16937 app.adjType = "previous"; 16938 } 16939 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16940 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16941 } 16942 } 16943 16944 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16945 + " reason=" + app.adjType); 16946 16947 // By default, we use the computed adjustment. It may be changed if 16948 // there are applications dependent on our services or providers, but 16949 // this gives us a baseline and makes sure we don't get into an 16950 // infinite recursion. 16951 app.adjSeq = mAdjSeq; 16952 app.curRawAdj = adj; 16953 app.hasStartedServices = false; 16954 16955 if (mBackupTarget != null && app == mBackupTarget.app) { 16956 // If possible we want to avoid killing apps while they're being backed up 16957 if (adj > ProcessList.BACKUP_APP_ADJ) { 16958 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16959 adj = ProcessList.BACKUP_APP_ADJ; 16960 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16961 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16962 } 16963 app.adjType = "backup"; 16964 app.cached = false; 16965 } 16966 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16967 procState = ActivityManager.PROCESS_STATE_BACKUP; 16968 } 16969 } 16970 16971 boolean mayBeTop = false; 16972 16973 for (int is = app.services.size()-1; 16974 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16975 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16976 || procState > ActivityManager.PROCESS_STATE_TOP); 16977 is--) { 16978 ServiceRecord s = app.services.valueAt(is); 16979 if (s.startRequested) { 16980 app.hasStartedServices = true; 16981 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16982 procState = ActivityManager.PROCESS_STATE_SERVICE; 16983 } 16984 if (app.hasShownUi && app != mHomeProcess) { 16985 // If this process has shown some UI, let it immediately 16986 // go to the LRU list because it may be pretty heavy with 16987 // UI stuff. We'll tag it with a label just to help 16988 // debug and understand what is going on. 16989 if (adj > ProcessList.SERVICE_ADJ) { 16990 app.adjType = "cch-started-ui-services"; 16991 } 16992 } else { 16993 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16994 // This service has seen some activity within 16995 // recent memory, so we will keep its process ahead 16996 // of the background processes. 16997 if (adj > ProcessList.SERVICE_ADJ) { 16998 adj = ProcessList.SERVICE_ADJ; 16999 app.adjType = "started-services"; 17000 app.cached = false; 17001 } 17002 } 17003 // If we have let the service slide into the background 17004 // state, still have some text describing what it is doing 17005 // even though the service no longer has an impact. 17006 if (adj > ProcessList.SERVICE_ADJ) { 17007 app.adjType = "cch-started-services"; 17008 } 17009 } 17010 } 17011 for (int conni = s.connections.size()-1; 17012 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17013 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17014 || procState > ActivityManager.PROCESS_STATE_TOP); 17015 conni--) { 17016 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17017 for (int i = 0; 17018 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17019 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17020 || procState > ActivityManager.PROCESS_STATE_TOP); 17021 i++) { 17022 // XXX should compute this based on the max of 17023 // all connected clients. 17024 ConnectionRecord cr = clist.get(i); 17025 if (cr.binding.client == app) { 17026 // Binding to ourself is not interesting. 17027 continue; 17028 } 17029 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17030 ProcessRecord client = cr.binding.client; 17031 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17032 TOP_APP, doingAll, now); 17033 int clientProcState = client.curProcState; 17034 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17035 // If the other app is cached for any reason, for purposes here 17036 // we are going to consider it empty. The specific cached state 17037 // doesn't propagate except under certain conditions. 17038 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17039 } 17040 String adjType = null; 17041 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17042 // Not doing bind OOM management, so treat 17043 // this guy more like a started service. 17044 if (app.hasShownUi && app != mHomeProcess) { 17045 // If this process has shown some UI, let it immediately 17046 // go to the LRU list because it may be pretty heavy with 17047 // UI stuff. We'll tag it with a label just to help 17048 // debug and understand what is going on. 17049 if (adj > clientAdj) { 17050 adjType = "cch-bound-ui-services"; 17051 } 17052 app.cached = false; 17053 clientAdj = adj; 17054 clientProcState = procState; 17055 } else { 17056 if (now >= (s.lastActivity 17057 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17058 // This service has not seen activity within 17059 // recent memory, so allow it to drop to the 17060 // LRU list if there is no other reason to keep 17061 // it around. We'll also tag it with a label just 17062 // to help debug and undertand what is going on. 17063 if (adj > clientAdj) { 17064 adjType = "cch-bound-services"; 17065 } 17066 clientAdj = adj; 17067 } 17068 } 17069 } 17070 if (adj > clientAdj) { 17071 // If this process has recently shown UI, and 17072 // the process that is binding to it is less 17073 // important than being visible, then we don't 17074 // care about the binding as much as we care 17075 // about letting this process get into the LRU 17076 // list to be killed and restarted if needed for 17077 // memory. 17078 if (app.hasShownUi && app != mHomeProcess 17079 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17080 adjType = "cch-bound-ui-services"; 17081 } else { 17082 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17083 |Context.BIND_IMPORTANT)) != 0) { 17084 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17085 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17086 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17087 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17088 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17089 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17090 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17091 adj = clientAdj; 17092 } else { 17093 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17094 adj = ProcessList.VISIBLE_APP_ADJ; 17095 } 17096 } 17097 if (!client.cached) { 17098 app.cached = false; 17099 } 17100 adjType = "service"; 17101 } 17102 } 17103 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17104 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17105 schedGroup = Process.THREAD_GROUP_DEFAULT; 17106 } 17107 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17108 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17109 // Special handling of clients who are in the top state. 17110 // We *may* want to consider this process to be in the 17111 // top state as well, but only if there is not another 17112 // reason for it to be running. Being on the top is a 17113 // special state, meaning you are specifically running 17114 // for the current top app. If the process is already 17115 // running in the background for some other reason, it 17116 // is more important to continue considering it to be 17117 // in the background state. 17118 mayBeTop = true; 17119 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17120 } else { 17121 // Special handling for above-top states (persistent 17122 // processes). These should not bring the current process 17123 // into the top state, since they are not on top. Instead 17124 // give them the best state after that. 17125 clientProcState = 17126 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17127 } 17128 } 17129 } else { 17130 if (clientProcState < 17131 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17132 clientProcState = 17133 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17134 } 17135 } 17136 if (procState > clientProcState) { 17137 procState = clientProcState; 17138 } 17139 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17140 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17141 app.pendingUiClean = true; 17142 } 17143 if (adjType != null) { 17144 app.adjType = adjType; 17145 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17146 .REASON_SERVICE_IN_USE; 17147 app.adjSource = cr.binding.client; 17148 app.adjSourceProcState = clientProcState; 17149 app.adjTarget = s.name; 17150 } 17151 } 17152 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17153 app.treatLikeActivity = true; 17154 } 17155 final ActivityRecord a = cr.activity; 17156 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17157 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17158 (a.visible || a.state == ActivityState.RESUMED 17159 || a.state == ActivityState.PAUSING)) { 17160 adj = ProcessList.FOREGROUND_APP_ADJ; 17161 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17162 schedGroup = Process.THREAD_GROUP_DEFAULT; 17163 } 17164 app.cached = false; 17165 app.adjType = "service"; 17166 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17167 .REASON_SERVICE_IN_USE; 17168 app.adjSource = a; 17169 app.adjSourceProcState = procState; 17170 app.adjTarget = s.name; 17171 } 17172 } 17173 } 17174 } 17175 } 17176 17177 for (int provi = app.pubProviders.size()-1; 17178 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17179 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17180 || procState > ActivityManager.PROCESS_STATE_TOP); 17181 provi--) { 17182 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17183 for (int i = cpr.connections.size()-1; 17184 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17185 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17186 || procState > ActivityManager.PROCESS_STATE_TOP); 17187 i--) { 17188 ContentProviderConnection conn = cpr.connections.get(i); 17189 ProcessRecord client = conn.client; 17190 if (client == app) { 17191 // Being our own client is not interesting. 17192 continue; 17193 } 17194 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17195 int clientProcState = client.curProcState; 17196 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17197 // If the other app is cached for any reason, for purposes here 17198 // we are going to consider it empty. 17199 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17200 } 17201 if (adj > clientAdj) { 17202 if (app.hasShownUi && app != mHomeProcess 17203 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17204 app.adjType = "cch-ui-provider"; 17205 } else { 17206 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17207 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17208 app.adjType = "provider"; 17209 } 17210 app.cached &= client.cached; 17211 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17212 .REASON_PROVIDER_IN_USE; 17213 app.adjSource = client; 17214 app.adjSourceProcState = clientProcState; 17215 app.adjTarget = cpr.name; 17216 } 17217 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17218 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17219 // Special handling of clients who are in the top state. 17220 // We *may* want to consider this process to be in the 17221 // top state as well, but only if there is not another 17222 // reason for it to be running. Being on the top is a 17223 // special state, meaning you are specifically running 17224 // for the current top app. If the process is already 17225 // running in the background for some other reason, it 17226 // is more important to continue considering it to be 17227 // in the background state. 17228 mayBeTop = true; 17229 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17230 } else { 17231 // Special handling for above-top states (persistent 17232 // processes). These should not bring the current process 17233 // into the top state, since they are not on top. Instead 17234 // give them the best state after that. 17235 clientProcState = 17236 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17237 } 17238 } 17239 if (procState > clientProcState) { 17240 procState = clientProcState; 17241 } 17242 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17243 schedGroup = Process.THREAD_GROUP_DEFAULT; 17244 } 17245 } 17246 // If the provider has external (non-framework) process 17247 // dependencies, ensure that its adjustment is at least 17248 // FOREGROUND_APP_ADJ. 17249 if (cpr.hasExternalProcessHandles()) { 17250 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17251 adj = ProcessList.FOREGROUND_APP_ADJ; 17252 schedGroup = Process.THREAD_GROUP_DEFAULT; 17253 app.cached = false; 17254 app.adjType = "provider"; 17255 app.adjTarget = cpr.name; 17256 } 17257 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17258 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17259 } 17260 } 17261 } 17262 17263 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17264 // A client of one of our services or providers is in the top state. We 17265 // *may* want to be in the top state, but not if we are already running in 17266 // the background for some other reason. For the decision here, we are going 17267 // to pick out a few specific states that we want to remain in when a client 17268 // is top (states that tend to be longer-term) and otherwise allow it to go 17269 // to the top state. 17270 switch (procState) { 17271 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17272 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17273 case ActivityManager.PROCESS_STATE_SERVICE: 17274 // These all are longer-term states, so pull them up to the top 17275 // of the background states, but not all the way to the top state. 17276 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17277 break; 17278 default: 17279 // Otherwise, top is a better choice, so take it. 17280 procState = ActivityManager.PROCESS_STATE_TOP; 17281 break; 17282 } 17283 } 17284 17285 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17286 if (app.hasClientActivities) { 17287 // This is a cached process, but with client activities. Mark it so. 17288 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17289 app.adjType = "cch-client-act"; 17290 } else if (app.treatLikeActivity) { 17291 // This is a cached process, but somebody wants us to treat it like it has 17292 // an activity, okay! 17293 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17294 app.adjType = "cch-as-act"; 17295 } 17296 } 17297 17298 if (adj == ProcessList.SERVICE_ADJ) { 17299 if (doingAll) { 17300 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17301 mNewNumServiceProcs++; 17302 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17303 if (!app.serviceb) { 17304 // This service isn't far enough down on the LRU list to 17305 // normally be a B service, but if we are low on RAM and it 17306 // is large we want to force it down since we would prefer to 17307 // keep launcher over it. 17308 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17309 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17310 app.serviceHighRam = true; 17311 app.serviceb = true; 17312 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17313 } else { 17314 mNewNumAServiceProcs++; 17315 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17316 } 17317 } else { 17318 app.serviceHighRam = false; 17319 } 17320 } 17321 if (app.serviceb) { 17322 adj = ProcessList.SERVICE_B_ADJ; 17323 } 17324 } 17325 17326 app.curRawAdj = adj; 17327 17328 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17329 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17330 if (adj > app.maxAdj) { 17331 adj = app.maxAdj; 17332 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17333 schedGroup = Process.THREAD_GROUP_DEFAULT; 17334 } 17335 } 17336 17337 // Do final modification to adj. Everything we do between here and applying 17338 // the final setAdj must be done in this function, because we will also use 17339 // it when computing the final cached adj later. Note that we don't need to 17340 // worry about this for max adj above, since max adj will always be used to 17341 // keep it out of the cached vaues. 17342 app.curAdj = app.modifyRawOomAdj(adj); 17343 app.curSchedGroup = schedGroup; 17344 app.curProcState = procState; 17345 app.foregroundActivities = foregroundActivities; 17346 17347 return app.curRawAdj; 17348 } 17349 17350 /** 17351 * Record new PSS sample for a process. 17352 */ 17353 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17354 proc.lastPssTime = now; 17355 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17356 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17357 + ": " + pss + " lastPss=" + proc.lastPss 17358 + " state=" + ProcessList.makeProcStateString(procState)); 17359 if (proc.initialIdlePss == 0) { 17360 proc.initialIdlePss = pss; 17361 } 17362 proc.lastPss = pss; 17363 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17364 proc.lastCachedPss = pss; 17365 } 17366 } 17367 17368 /** 17369 * Schedule PSS collection of a process. 17370 */ 17371 void requestPssLocked(ProcessRecord proc, int procState) { 17372 if (mPendingPssProcesses.contains(proc)) { 17373 return; 17374 } 17375 if (mPendingPssProcesses.size() == 0) { 17376 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17377 } 17378 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17379 proc.pssProcState = procState; 17380 mPendingPssProcesses.add(proc); 17381 } 17382 17383 /** 17384 * Schedule PSS collection of all processes. 17385 */ 17386 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17387 if (!always) { 17388 if (now < (mLastFullPssTime + 17389 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17390 return; 17391 } 17392 } 17393 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17394 mLastFullPssTime = now; 17395 mFullPssPending = true; 17396 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17397 mPendingPssProcesses.clear(); 17398 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17399 ProcessRecord app = mLruProcesses.get(i); 17400 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17401 app.pssProcState = app.setProcState; 17402 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17403 mTestPssMode, isSleeping(), now); 17404 mPendingPssProcesses.add(app); 17405 } 17406 } 17407 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17408 } 17409 17410 public void setTestPssMode(boolean enabled) { 17411 synchronized (this) { 17412 mTestPssMode = enabled; 17413 if (enabled) { 17414 // Whenever we enable the mode, we want to take a snapshot all of current 17415 // process mem use. 17416 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17417 } 17418 } 17419 } 17420 17421 /** 17422 * Ask a given process to GC right now. 17423 */ 17424 final void performAppGcLocked(ProcessRecord app) { 17425 try { 17426 app.lastRequestedGc = SystemClock.uptimeMillis(); 17427 if (app.thread != null) { 17428 if (app.reportLowMemory) { 17429 app.reportLowMemory = false; 17430 app.thread.scheduleLowMemory(); 17431 } else { 17432 app.thread.processInBackground(); 17433 } 17434 } 17435 } catch (Exception e) { 17436 // whatever. 17437 } 17438 } 17439 17440 /** 17441 * Returns true if things are idle enough to perform GCs. 17442 */ 17443 private final boolean canGcNowLocked() { 17444 boolean processingBroadcasts = false; 17445 for (BroadcastQueue q : mBroadcastQueues) { 17446 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17447 processingBroadcasts = true; 17448 } 17449 } 17450 return !processingBroadcasts 17451 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17452 } 17453 17454 /** 17455 * Perform GCs on all processes that are waiting for it, but only 17456 * if things are idle. 17457 */ 17458 final void performAppGcsLocked() { 17459 final int N = mProcessesToGc.size(); 17460 if (N <= 0) { 17461 return; 17462 } 17463 if (canGcNowLocked()) { 17464 while (mProcessesToGc.size() > 0) { 17465 ProcessRecord proc = mProcessesToGc.remove(0); 17466 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17467 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17468 <= SystemClock.uptimeMillis()) { 17469 // To avoid spamming the system, we will GC processes one 17470 // at a time, waiting a few seconds between each. 17471 performAppGcLocked(proc); 17472 scheduleAppGcsLocked(); 17473 return; 17474 } else { 17475 // It hasn't been long enough since we last GCed this 17476 // process... put it in the list to wait for its time. 17477 addProcessToGcListLocked(proc); 17478 break; 17479 } 17480 } 17481 } 17482 17483 scheduleAppGcsLocked(); 17484 } 17485 } 17486 17487 /** 17488 * If all looks good, perform GCs on all processes waiting for them. 17489 */ 17490 final void performAppGcsIfAppropriateLocked() { 17491 if (canGcNowLocked()) { 17492 performAppGcsLocked(); 17493 return; 17494 } 17495 // Still not idle, wait some more. 17496 scheduleAppGcsLocked(); 17497 } 17498 17499 /** 17500 * Schedule the execution of all pending app GCs. 17501 */ 17502 final void scheduleAppGcsLocked() { 17503 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17504 17505 if (mProcessesToGc.size() > 0) { 17506 // Schedule a GC for the time to the next process. 17507 ProcessRecord proc = mProcessesToGc.get(0); 17508 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17509 17510 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17511 long now = SystemClock.uptimeMillis(); 17512 if (when < (now+GC_TIMEOUT)) { 17513 when = now + GC_TIMEOUT; 17514 } 17515 mHandler.sendMessageAtTime(msg, when); 17516 } 17517 } 17518 17519 /** 17520 * Add a process to the array of processes waiting to be GCed. Keeps the 17521 * list in sorted order by the last GC time. The process can't already be 17522 * on the list. 17523 */ 17524 final void addProcessToGcListLocked(ProcessRecord proc) { 17525 boolean added = false; 17526 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17527 if (mProcessesToGc.get(i).lastRequestedGc < 17528 proc.lastRequestedGc) { 17529 added = true; 17530 mProcessesToGc.add(i+1, proc); 17531 break; 17532 } 17533 } 17534 if (!added) { 17535 mProcessesToGc.add(0, proc); 17536 } 17537 } 17538 17539 /** 17540 * Set up to ask a process to GC itself. This will either do it 17541 * immediately, or put it on the list of processes to gc the next 17542 * time things are idle. 17543 */ 17544 final void scheduleAppGcLocked(ProcessRecord app) { 17545 long now = SystemClock.uptimeMillis(); 17546 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17547 return; 17548 } 17549 if (!mProcessesToGc.contains(app)) { 17550 addProcessToGcListLocked(app); 17551 scheduleAppGcsLocked(); 17552 } 17553 } 17554 17555 final void checkExcessivePowerUsageLocked(boolean doKills) { 17556 updateCpuStatsNow(); 17557 17558 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17559 boolean doWakeKills = doKills; 17560 boolean doCpuKills = doKills; 17561 if (mLastPowerCheckRealtime == 0) { 17562 doWakeKills = false; 17563 } 17564 if (mLastPowerCheckUptime == 0) { 17565 doCpuKills = false; 17566 } 17567 if (stats.isScreenOn()) { 17568 doWakeKills = false; 17569 } 17570 final long curRealtime = SystemClock.elapsedRealtime(); 17571 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17572 final long curUptime = SystemClock.uptimeMillis(); 17573 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17574 mLastPowerCheckRealtime = curRealtime; 17575 mLastPowerCheckUptime = curUptime; 17576 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17577 doWakeKills = false; 17578 } 17579 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17580 doCpuKills = false; 17581 } 17582 int i = mLruProcesses.size(); 17583 while (i > 0) { 17584 i--; 17585 ProcessRecord app = mLruProcesses.get(i); 17586 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17587 long wtime; 17588 synchronized (stats) { 17589 wtime = stats.getProcessWakeTime(app.info.uid, 17590 app.pid, curRealtime); 17591 } 17592 long wtimeUsed = wtime - app.lastWakeTime; 17593 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17594 if (DEBUG_POWER) { 17595 StringBuilder sb = new StringBuilder(128); 17596 sb.append("Wake for "); 17597 app.toShortString(sb); 17598 sb.append(": over "); 17599 TimeUtils.formatDuration(realtimeSince, sb); 17600 sb.append(" used "); 17601 TimeUtils.formatDuration(wtimeUsed, sb); 17602 sb.append(" ("); 17603 sb.append((wtimeUsed*100)/realtimeSince); 17604 sb.append("%)"); 17605 Slog.i(TAG, sb.toString()); 17606 sb.setLength(0); 17607 sb.append("CPU for "); 17608 app.toShortString(sb); 17609 sb.append(": over "); 17610 TimeUtils.formatDuration(uptimeSince, sb); 17611 sb.append(" used "); 17612 TimeUtils.formatDuration(cputimeUsed, sb); 17613 sb.append(" ("); 17614 sb.append((cputimeUsed*100)/uptimeSince); 17615 sb.append("%)"); 17616 Slog.i(TAG, sb.toString()); 17617 } 17618 // If a process has held a wake lock for more 17619 // than 50% of the time during this period, 17620 // that sounds bad. Kill! 17621 if (doWakeKills && realtimeSince > 0 17622 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17623 synchronized (stats) { 17624 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17625 realtimeSince, wtimeUsed); 17626 } 17627 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17628 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17629 } else if (doCpuKills && uptimeSince > 0 17630 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17631 synchronized (stats) { 17632 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17633 uptimeSince, cputimeUsed); 17634 } 17635 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17636 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17637 } else { 17638 app.lastWakeTime = wtime; 17639 app.lastCpuTime = app.curCpuTime; 17640 } 17641 } 17642 } 17643 } 17644 17645 private final boolean applyOomAdjLocked(ProcessRecord app, 17646 ProcessRecord TOP_APP, boolean doingAll, long now) { 17647 boolean success = true; 17648 17649 if (app.curRawAdj != app.setRawAdj) { 17650 app.setRawAdj = app.curRawAdj; 17651 } 17652 17653 int changes = 0; 17654 17655 if (app.curAdj != app.setAdj) { 17656 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17657 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17658 TAG, "Set " + app.pid + " " + app.processName + 17659 " adj " + app.curAdj + ": " + app.adjType); 17660 app.setAdj = app.curAdj; 17661 } 17662 17663 if (app.setSchedGroup != app.curSchedGroup) { 17664 app.setSchedGroup = app.curSchedGroup; 17665 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17666 "Setting process group of " + app.processName 17667 + " to " + app.curSchedGroup); 17668 if (app.waitingToKill != null && 17669 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17670 app.kill(app.waitingToKill, true); 17671 success = false; 17672 } else { 17673 if (true) { 17674 long oldId = Binder.clearCallingIdentity(); 17675 try { 17676 Process.setProcessGroup(app.pid, app.curSchedGroup); 17677 } catch (Exception e) { 17678 Slog.w(TAG, "Failed setting process group of " + app.pid 17679 + " to " + app.curSchedGroup); 17680 e.printStackTrace(); 17681 } finally { 17682 Binder.restoreCallingIdentity(oldId); 17683 } 17684 } else { 17685 if (app.thread != null) { 17686 try { 17687 app.thread.setSchedulingGroup(app.curSchedGroup); 17688 } catch (RemoteException e) { 17689 } 17690 } 17691 } 17692 Process.setSwappiness(app.pid, 17693 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17694 } 17695 } 17696 if (app.repForegroundActivities != app.foregroundActivities) { 17697 app.repForegroundActivities = app.foregroundActivities; 17698 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17699 } 17700 if (app.repProcState != app.curProcState) { 17701 app.repProcState = app.curProcState; 17702 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17703 if (app.thread != null) { 17704 try { 17705 if (false) { 17706 //RuntimeException h = new RuntimeException("here"); 17707 Slog.i(TAG, "Sending new process state " + app.repProcState 17708 + " to " + app /*, h*/); 17709 } 17710 app.thread.setProcessState(app.repProcState); 17711 } catch (RemoteException e) { 17712 } 17713 } 17714 } 17715 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17716 app.setProcState)) { 17717 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17718 // Experimental code to more aggressively collect pss while 17719 // running test... the problem is that this tends to collect 17720 // the data right when a process is transitioning between process 17721 // states, which well tend to give noisy data. 17722 long start = SystemClock.uptimeMillis(); 17723 long pss = Debug.getPss(app.pid, mTmpLong, null); 17724 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17725 mPendingPssProcesses.remove(app); 17726 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17727 + " to " + app.curProcState + ": " 17728 + (SystemClock.uptimeMillis()-start) + "ms"); 17729 } 17730 app.lastStateTime = now; 17731 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17732 mTestPssMode, isSleeping(), now); 17733 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17734 + ProcessList.makeProcStateString(app.setProcState) + " to " 17735 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17736 + (app.nextPssTime-now) + ": " + app); 17737 } else { 17738 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17739 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17740 mTestPssMode)))) { 17741 requestPssLocked(app, app.setProcState); 17742 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17743 mTestPssMode, isSleeping(), now); 17744 } else if (false && DEBUG_PSS) { 17745 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17746 } 17747 } 17748 if (app.setProcState != app.curProcState) { 17749 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17750 "Proc state change of " + app.processName 17751 + " to " + app.curProcState); 17752 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17753 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17754 if (setImportant && !curImportant) { 17755 // This app is no longer something we consider important enough to allow to 17756 // use arbitrary amounts of battery power. Note 17757 // its current wake lock time to later know to kill it if 17758 // it is not behaving well. 17759 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17760 synchronized (stats) { 17761 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17762 app.pid, SystemClock.elapsedRealtime()); 17763 } 17764 app.lastCpuTime = app.curCpuTime; 17765 17766 } 17767 app.setProcState = app.curProcState; 17768 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17769 app.notCachedSinceIdle = false; 17770 } 17771 if (!doingAll) { 17772 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17773 } else { 17774 app.procStateChanged = true; 17775 } 17776 } 17777 17778 if (changes != 0) { 17779 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17780 int i = mPendingProcessChanges.size()-1; 17781 ProcessChangeItem item = null; 17782 while (i >= 0) { 17783 item = mPendingProcessChanges.get(i); 17784 if (item.pid == app.pid) { 17785 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17786 break; 17787 } 17788 i--; 17789 } 17790 if (i < 0) { 17791 // No existing item in pending changes; need a new one. 17792 final int NA = mAvailProcessChanges.size(); 17793 if (NA > 0) { 17794 item = mAvailProcessChanges.remove(NA-1); 17795 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17796 } else { 17797 item = new ProcessChangeItem(); 17798 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17799 } 17800 item.changes = 0; 17801 item.pid = app.pid; 17802 item.uid = app.info.uid; 17803 if (mPendingProcessChanges.size() == 0) { 17804 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17805 "*** Enqueueing dispatch processes changed!"); 17806 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17807 } 17808 mPendingProcessChanges.add(item); 17809 } 17810 item.changes |= changes; 17811 item.processState = app.repProcState; 17812 item.foregroundActivities = app.repForegroundActivities; 17813 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17814 + Integer.toHexString(System.identityHashCode(item)) 17815 + " " + app.toShortString() + ": changes=" + item.changes 17816 + " procState=" + item.processState 17817 + " foreground=" + item.foregroundActivities 17818 + " type=" + app.adjType + " source=" + app.adjSource 17819 + " target=" + app.adjTarget); 17820 } 17821 17822 return success; 17823 } 17824 17825 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17826 if (proc.thread != null) { 17827 if (proc.baseProcessTracker != null) { 17828 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17829 } 17830 if (proc.repProcState >= 0) { 17831 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17832 proc.repProcState); 17833 } 17834 } 17835 } 17836 17837 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17838 ProcessRecord TOP_APP, boolean doingAll, long now) { 17839 if (app.thread == null) { 17840 return false; 17841 } 17842 17843 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17844 17845 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17846 } 17847 17848 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17849 boolean oomAdj) { 17850 if (isForeground != proc.foregroundServices) { 17851 proc.foregroundServices = isForeground; 17852 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17853 proc.info.uid); 17854 if (isForeground) { 17855 if (curProcs == null) { 17856 curProcs = new ArrayList<ProcessRecord>(); 17857 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17858 } 17859 if (!curProcs.contains(proc)) { 17860 curProcs.add(proc); 17861 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17862 proc.info.packageName, proc.info.uid); 17863 } 17864 } else { 17865 if (curProcs != null) { 17866 if (curProcs.remove(proc)) { 17867 mBatteryStatsService.noteEvent( 17868 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17869 proc.info.packageName, proc.info.uid); 17870 if (curProcs.size() <= 0) { 17871 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17872 } 17873 } 17874 } 17875 } 17876 if (oomAdj) { 17877 updateOomAdjLocked(); 17878 } 17879 } 17880 } 17881 17882 private final ActivityRecord resumedAppLocked() { 17883 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17884 String pkg; 17885 int uid; 17886 if (act != null) { 17887 pkg = act.packageName; 17888 uid = act.info.applicationInfo.uid; 17889 } else { 17890 pkg = null; 17891 uid = -1; 17892 } 17893 // Has the UID or resumed package name changed? 17894 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17895 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17896 if (mCurResumedPackage != null) { 17897 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17898 mCurResumedPackage, mCurResumedUid); 17899 } 17900 mCurResumedPackage = pkg; 17901 mCurResumedUid = uid; 17902 if (mCurResumedPackage != null) { 17903 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17904 mCurResumedPackage, mCurResumedUid); 17905 } 17906 } 17907 return act; 17908 } 17909 17910 final boolean updateOomAdjLocked(ProcessRecord app) { 17911 final ActivityRecord TOP_ACT = resumedAppLocked(); 17912 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17913 final boolean wasCached = app.cached; 17914 17915 mAdjSeq++; 17916 17917 // This is the desired cached adjusment we want to tell it to use. 17918 // If our app is currently cached, we know it, and that is it. Otherwise, 17919 // we don't know it yet, and it needs to now be cached we will then 17920 // need to do a complete oom adj. 17921 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17922 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17923 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17924 SystemClock.uptimeMillis()); 17925 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17926 // Changed to/from cached state, so apps after it in the LRU 17927 // list may also be changed. 17928 updateOomAdjLocked(); 17929 } 17930 return success; 17931 } 17932 17933 final void updateOomAdjLocked() { 17934 final ActivityRecord TOP_ACT = resumedAppLocked(); 17935 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17936 final long now = SystemClock.uptimeMillis(); 17937 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17938 final int N = mLruProcesses.size(); 17939 17940 if (false) { 17941 RuntimeException e = new RuntimeException(); 17942 e.fillInStackTrace(); 17943 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17944 } 17945 17946 mAdjSeq++; 17947 mNewNumServiceProcs = 0; 17948 mNewNumAServiceProcs = 0; 17949 17950 final int emptyProcessLimit; 17951 final int cachedProcessLimit; 17952 if (mProcessLimit <= 0) { 17953 emptyProcessLimit = cachedProcessLimit = 0; 17954 } else if (mProcessLimit == 1) { 17955 emptyProcessLimit = 1; 17956 cachedProcessLimit = 0; 17957 } else { 17958 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17959 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17960 } 17961 17962 // Let's determine how many processes we have running vs. 17963 // how many slots we have for background processes; we may want 17964 // to put multiple processes in a slot of there are enough of 17965 // them. 17966 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17967 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17968 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17969 if (numEmptyProcs > cachedProcessLimit) { 17970 // If there are more empty processes than our limit on cached 17971 // processes, then use the cached process limit for the factor. 17972 // This ensures that the really old empty processes get pushed 17973 // down to the bottom, so if we are running low on memory we will 17974 // have a better chance at keeping around more cached processes 17975 // instead of a gazillion empty processes. 17976 numEmptyProcs = cachedProcessLimit; 17977 } 17978 int emptyFactor = numEmptyProcs/numSlots; 17979 if (emptyFactor < 1) emptyFactor = 1; 17980 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17981 if (cachedFactor < 1) cachedFactor = 1; 17982 int stepCached = 0; 17983 int stepEmpty = 0; 17984 int numCached = 0; 17985 int numEmpty = 0; 17986 int numTrimming = 0; 17987 17988 mNumNonCachedProcs = 0; 17989 mNumCachedHiddenProcs = 0; 17990 17991 // First update the OOM adjustment for each of the 17992 // application processes based on their current state. 17993 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17994 int nextCachedAdj = curCachedAdj+1; 17995 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17996 int nextEmptyAdj = curEmptyAdj+2; 17997 for (int i=N-1; i>=0; i--) { 17998 ProcessRecord app = mLruProcesses.get(i); 17999 if (!app.killedByAm && app.thread != null) { 18000 app.procStateChanged = false; 18001 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18002 18003 // If we haven't yet assigned the final cached adj 18004 // to the process, do that now. 18005 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18006 switch (app.curProcState) { 18007 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18008 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18009 // This process is a cached process holding activities... 18010 // assign it the next cached value for that type, and then 18011 // step that cached level. 18012 app.curRawAdj = curCachedAdj; 18013 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18014 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18015 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18016 + ")"); 18017 if (curCachedAdj != nextCachedAdj) { 18018 stepCached++; 18019 if (stepCached >= cachedFactor) { 18020 stepCached = 0; 18021 curCachedAdj = nextCachedAdj; 18022 nextCachedAdj += 2; 18023 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18024 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18025 } 18026 } 18027 } 18028 break; 18029 default: 18030 // For everything else, assign next empty cached process 18031 // level and bump that up. Note that this means that 18032 // long-running services that have dropped down to the 18033 // cached level will be treated as empty (since their process 18034 // state is still as a service), which is what we want. 18035 app.curRawAdj = curEmptyAdj; 18036 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18037 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18038 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18039 + ")"); 18040 if (curEmptyAdj != nextEmptyAdj) { 18041 stepEmpty++; 18042 if (stepEmpty >= emptyFactor) { 18043 stepEmpty = 0; 18044 curEmptyAdj = nextEmptyAdj; 18045 nextEmptyAdj += 2; 18046 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18047 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18048 } 18049 } 18050 } 18051 break; 18052 } 18053 } 18054 18055 applyOomAdjLocked(app, TOP_APP, true, now); 18056 18057 // Count the number of process types. 18058 switch (app.curProcState) { 18059 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18060 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18061 mNumCachedHiddenProcs++; 18062 numCached++; 18063 if (numCached > cachedProcessLimit) { 18064 app.kill("cached #" + numCached, true); 18065 } 18066 break; 18067 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18068 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18069 && app.lastActivityTime < oldTime) { 18070 app.kill("empty for " 18071 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18072 / 1000) + "s", true); 18073 } else { 18074 numEmpty++; 18075 if (numEmpty > emptyProcessLimit) { 18076 app.kill("empty #" + numEmpty, true); 18077 } 18078 } 18079 break; 18080 default: 18081 mNumNonCachedProcs++; 18082 break; 18083 } 18084 18085 if (app.isolated && app.services.size() <= 0) { 18086 // If this is an isolated process, and there are no 18087 // services running in it, then the process is no longer 18088 // needed. We agressively kill these because we can by 18089 // definition not re-use the same process again, and it is 18090 // good to avoid having whatever code was running in them 18091 // left sitting around after no longer needed. 18092 app.kill("isolated not needed", true); 18093 } 18094 18095 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18096 && !app.killedByAm) { 18097 numTrimming++; 18098 } 18099 } 18100 } 18101 18102 mNumServiceProcs = mNewNumServiceProcs; 18103 18104 // Now determine the memory trimming level of background processes. 18105 // Unfortunately we need to start at the back of the list to do this 18106 // properly. We only do this if the number of background apps we 18107 // are managing to keep around is less than half the maximum we desire; 18108 // if we are keeping a good number around, we'll let them use whatever 18109 // memory they want. 18110 final int numCachedAndEmpty = numCached + numEmpty; 18111 int memFactor; 18112 if (numCached <= ProcessList.TRIM_CACHED_APPS 18113 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18114 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18115 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18116 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18117 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18118 } else { 18119 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18120 } 18121 } else { 18122 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18123 } 18124 // We always allow the memory level to go up (better). We only allow it to go 18125 // down if we are in a state where that is allowed, *and* the total number of processes 18126 // has gone down since last time. 18127 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18128 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18129 + " last=" + mLastNumProcesses); 18130 if (memFactor > mLastMemoryLevel) { 18131 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18132 memFactor = mLastMemoryLevel; 18133 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18134 } 18135 } 18136 mLastMemoryLevel = memFactor; 18137 mLastNumProcesses = mLruProcesses.size(); 18138 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18139 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18140 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18141 if (mLowRamStartTime == 0) { 18142 mLowRamStartTime = now; 18143 } 18144 int step = 0; 18145 int fgTrimLevel; 18146 switch (memFactor) { 18147 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18148 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18149 break; 18150 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18151 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18152 break; 18153 default: 18154 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18155 break; 18156 } 18157 int factor = numTrimming/3; 18158 int minFactor = 2; 18159 if (mHomeProcess != null) minFactor++; 18160 if (mPreviousProcess != null) minFactor++; 18161 if (factor < minFactor) factor = minFactor; 18162 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18163 for (int i=N-1; i>=0; i--) { 18164 ProcessRecord app = mLruProcesses.get(i); 18165 if (allChanged || app.procStateChanged) { 18166 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18167 app.procStateChanged = false; 18168 } 18169 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18170 && !app.killedByAm) { 18171 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18172 try { 18173 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18174 "Trimming memory of " + app.processName 18175 + " to " + curLevel); 18176 app.thread.scheduleTrimMemory(curLevel); 18177 } catch (RemoteException e) { 18178 } 18179 if (false) { 18180 // For now we won't do this; our memory trimming seems 18181 // to be good enough at this point that destroying 18182 // activities causes more harm than good. 18183 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18184 && app != mHomeProcess && app != mPreviousProcess) { 18185 // Need to do this on its own message because the stack may not 18186 // be in a consistent state at this point. 18187 // For these apps we will also finish their activities 18188 // to help them free memory. 18189 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18190 } 18191 } 18192 } 18193 app.trimMemoryLevel = curLevel; 18194 step++; 18195 if (step >= factor) { 18196 step = 0; 18197 switch (curLevel) { 18198 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18199 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18200 break; 18201 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18202 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18203 break; 18204 } 18205 } 18206 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18207 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18208 && app.thread != null) { 18209 try { 18210 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18211 "Trimming memory of heavy-weight " + app.processName 18212 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18213 app.thread.scheduleTrimMemory( 18214 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18215 } catch (RemoteException e) { 18216 } 18217 } 18218 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18219 } else { 18220 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18221 || app.systemNoUi) && app.pendingUiClean) { 18222 // If this application is now in the background and it 18223 // had done UI, then give it the special trim level to 18224 // have it free UI resources. 18225 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18226 if (app.trimMemoryLevel < level && app.thread != null) { 18227 try { 18228 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18229 "Trimming memory of bg-ui " + app.processName 18230 + " to " + level); 18231 app.thread.scheduleTrimMemory(level); 18232 } catch (RemoteException e) { 18233 } 18234 } 18235 app.pendingUiClean = false; 18236 } 18237 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18238 try { 18239 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18240 "Trimming memory of fg " + app.processName 18241 + " to " + fgTrimLevel); 18242 app.thread.scheduleTrimMemory(fgTrimLevel); 18243 } catch (RemoteException e) { 18244 } 18245 } 18246 app.trimMemoryLevel = fgTrimLevel; 18247 } 18248 } 18249 } else { 18250 if (mLowRamStartTime != 0) { 18251 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18252 mLowRamStartTime = 0; 18253 } 18254 for (int i=N-1; i>=0; i--) { 18255 ProcessRecord app = mLruProcesses.get(i); 18256 if (allChanged || app.procStateChanged) { 18257 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18258 app.procStateChanged = false; 18259 } 18260 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18261 || app.systemNoUi) && app.pendingUiClean) { 18262 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18263 && app.thread != null) { 18264 try { 18265 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18266 "Trimming memory of ui hidden " + app.processName 18267 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18268 app.thread.scheduleTrimMemory( 18269 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18270 } catch (RemoteException e) { 18271 } 18272 } 18273 app.pendingUiClean = false; 18274 } 18275 app.trimMemoryLevel = 0; 18276 } 18277 } 18278 18279 if (mAlwaysFinishActivities) { 18280 // Need to do this on its own message because the stack may not 18281 // be in a consistent state at this point. 18282 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18283 } 18284 18285 if (allChanged) { 18286 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18287 } 18288 18289 if (mProcessStats.shouldWriteNowLocked(now)) { 18290 mHandler.post(new Runnable() { 18291 @Override public void run() { 18292 synchronized (ActivityManagerService.this) { 18293 mProcessStats.writeStateAsyncLocked(); 18294 } 18295 } 18296 }); 18297 } 18298 18299 if (DEBUG_OOM_ADJ) { 18300 if (false) { 18301 RuntimeException here = new RuntimeException("here"); 18302 here.fillInStackTrace(); 18303 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18304 } else { 18305 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18306 } 18307 } 18308 } 18309 18310 final void trimApplications() { 18311 synchronized (this) { 18312 int i; 18313 18314 // First remove any unused application processes whose package 18315 // has been removed. 18316 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18317 final ProcessRecord app = mRemovedProcesses.get(i); 18318 if (app.activities.size() == 0 18319 && app.curReceiver == null && app.services.size() == 0) { 18320 Slog.i( 18321 TAG, "Exiting empty application process " 18322 + app.processName + " (" 18323 + (app.thread != null ? app.thread.asBinder() : null) 18324 + ")\n"); 18325 if (app.pid > 0 && app.pid != MY_PID) { 18326 app.kill("empty", false); 18327 } else { 18328 try { 18329 app.thread.scheduleExit(); 18330 } catch (Exception e) { 18331 // Ignore exceptions. 18332 } 18333 } 18334 cleanUpApplicationRecordLocked(app, false, true, -1); 18335 mRemovedProcesses.remove(i); 18336 18337 if (app.persistent) { 18338 addAppLocked(app.info, false, null /* ABI override */); 18339 } 18340 } 18341 } 18342 18343 // Now update the oom adj for all processes. 18344 updateOomAdjLocked(); 18345 } 18346 } 18347 18348 /** This method sends the specified signal to each of the persistent apps */ 18349 public void signalPersistentProcesses(int sig) throws RemoteException { 18350 if (sig != Process.SIGNAL_USR1) { 18351 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18352 } 18353 18354 synchronized (this) { 18355 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18356 != PackageManager.PERMISSION_GRANTED) { 18357 throw new SecurityException("Requires permission " 18358 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18359 } 18360 18361 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18362 ProcessRecord r = mLruProcesses.get(i); 18363 if (r.thread != null && r.persistent) { 18364 Process.sendSignal(r.pid, sig); 18365 } 18366 } 18367 } 18368 } 18369 18370 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18371 if (proc == null || proc == mProfileProc) { 18372 proc = mProfileProc; 18373 profileType = mProfileType; 18374 clearProfilerLocked(); 18375 } 18376 if (proc == null) { 18377 return; 18378 } 18379 try { 18380 proc.thread.profilerControl(false, null, profileType); 18381 } catch (RemoteException e) { 18382 throw new IllegalStateException("Process disappeared"); 18383 } 18384 } 18385 18386 private void clearProfilerLocked() { 18387 if (mProfileFd != null) { 18388 try { 18389 mProfileFd.close(); 18390 } catch (IOException e) { 18391 } 18392 } 18393 mProfileApp = null; 18394 mProfileProc = null; 18395 mProfileFile = null; 18396 mProfileType = 0; 18397 mAutoStopProfiler = false; 18398 mSamplingInterval = 0; 18399 } 18400 18401 public boolean profileControl(String process, int userId, boolean start, 18402 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18403 18404 try { 18405 synchronized (this) { 18406 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18407 // its own permission. 18408 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18409 != PackageManager.PERMISSION_GRANTED) { 18410 throw new SecurityException("Requires permission " 18411 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18412 } 18413 18414 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18415 throw new IllegalArgumentException("null profile info or fd"); 18416 } 18417 18418 ProcessRecord proc = null; 18419 if (process != null) { 18420 proc = findProcessLocked(process, userId, "profileControl"); 18421 } 18422 18423 if (start && (proc == null || proc.thread == null)) { 18424 throw new IllegalArgumentException("Unknown process: " + process); 18425 } 18426 18427 if (start) { 18428 stopProfilerLocked(null, 0); 18429 setProfileApp(proc.info, proc.processName, profilerInfo); 18430 mProfileProc = proc; 18431 mProfileType = profileType; 18432 ParcelFileDescriptor fd = profilerInfo.profileFd; 18433 try { 18434 fd = fd.dup(); 18435 } catch (IOException e) { 18436 fd = null; 18437 } 18438 profilerInfo.profileFd = fd; 18439 proc.thread.profilerControl(start, profilerInfo, profileType); 18440 fd = null; 18441 mProfileFd = null; 18442 } else { 18443 stopProfilerLocked(proc, profileType); 18444 if (profilerInfo != null && profilerInfo.profileFd != null) { 18445 try { 18446 profilerInfo.profileFd.close(); 18447 } catch (IOException e) { 18448 } 18449 } 18450 } 18451 18452 return true; 18453 } 18454 } catch (RemoteException e) { 18455 throw new IllegalStateException("Process disappeared"); 18456 } finally { 18457 if (profilerInfo != null && profilerInfo.profileFd != null) { 18458 try { 18459 profilerInfo.profileFd.close(); 18460 } catch (IOException e) { 18461 } 18462 } 18463 } 18464 } 18465 18466 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18467 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18468 userId, true, ALLOW_FULL_ONLY, callName, null); 18469 ProcessRecord proc = null; 18470 try { 18471 int pid = Integer.parseInt(process); 18472 synchronized (mPidsSelfLocked) { 18473 proc = mPidsSelfLocked.get(pid); 18474 } 18475 } catch (NumberFormatException e) { 18476 } 18477 18478 if (proc == null) { 18479 ArrayMap<String, SparseArray<ProcessRecord>> all 18480 = mProcessNames.getMap(); 18481 SparseArray<ProcessRecord> procs = all.get(process); 18482 if (procs != null && procs.size() > 0) { 18483 proc = procs.valueAt(0); 18484 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18485 for (int i=1; i<procs.size(); i++) { 18486 ProcessRecord thisProc = procs.valueAt(i); 18487 if (thisProc.userId == userId) { 18488 proc = thisProc; 18489 break; 18490 } 18491 } 18492 } 18493 } 18494 } 18495 18496 return proc; 18497 } 18498 18499 public boolean dumpHeap(String process, int userId, boolean managed, 18500 String path, ParcelFileDescriptor fd) throws RemoteException { 18501 18502 try { 18503 synchronized (this) { 18504 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18505 // its own permission (same as profileControl). 18506 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18507 != PackageManager.PERMISSION_GRANTED) { 18508 throw new SecurityException("Requires permission " 18509 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18510 } 18511 18512 if (fd == null) { 18513 throw new IllegalArgumentException("null fd"); 18514 } 18515 18516 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18517 if (proc == null || proc.thread == null) { 18518 throw new IllegalArgumentException("Unknown process: " + process); 18519 } 18520 18521 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18522 if (!isDebuggable) { 18523 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18524 throw new SecurityException("Process not debuggable: " + proc); 18525 } 18526 } 18527 18528 proc.thread.dumpHeap(managed, path, fd); 18529 fd = null; 18530 return true; 18531 } 18532 } catch (RemoteException e) { 18533 throw new IllegalStateException("Process disappeared"); 18534 } finally { 18535 if (fd != null) { 18536 try { 18537 fd.close(); 18538 } catch (IOException e) { 18539 } 18540 } 18541 } 18542 } 18543 18544 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18545 public void monitor() { 18546 synchronized (this) { } 18547 } 18548 18549 void onCoreSettingsChange(Bundle settings) { 18550 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18551 ProcessRecord processRecord = mLruProcesses.get(i); 18552 try { 18553 if (processRecord.thread != null) { 18554 processRecord.thread.setCoreSettings(settings); 18555 } 18556 } catch (RemoteException re) { 18557 /* ignore */ 18558 } 18559 } 18560 } 18561 18562 // Multi-user methods 18563 18564 /** 18565 * Start user, if its not already running, but don't bring it to foreground. 18566 */ 18567 @Override 18568 public boolean startUserInBackground(final int userId) { 18569 return startUser(userId, /* foreground */ false); 18570 } 18571 18572 /** 18573 * Start user, if its not already running, and bring it to foreground. 18574 */ 18575 boolean startUserInForeground(final int userId, Dialog dlg) { 18576 boolean result = startUser(userId, /* foreground */ true); 18577 dlg.dismiss(); 18578 return result; 18579 } 18580 18581 /** 18582 * Refreshes the list of users related to the current user when either a 18583 * user switch happens or when a new related user is started in the 18584 * background. 18585 */ 18586 private void updateCurrentProfileIdsLocked() { 18587 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18588 mCurrentUserId, false /* enabledOnly */); 18589 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18590 for (int i = 0; i < currentProfileIds.length; i++) { 18591 currentProfileIds[i] = profiles.get(i).id; 18592 } 18593 mCurrentProfileIds = currentProfileIds; 18594 18595 synchronized (mUserProfileGroupIdsSelfLocked) { 18596 mUserProfileGroupIdsSelfLocked.clear(); 18597 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18598 for (int i = 0; i < users.size(); i++) { 18599 UserInfo user = users.get(i); 18600 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18601 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18602 } 18603 } 18604 } 18605 } 18606 18607 private Set getProfileIdsLocked(int userId) { 18608 Set userIds = new HashSet<Integer>(); 18609 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18610 userId, false /* enabledOnly */); 18611 for (UserInfo user : profiles) { 18612 userIds.add(Integer.valueOf(user.id)); 18613 } 18614 return userIds; 18615 } 18616 18617 @Override 18618 public boolean switchUser(final int userId) { 18619 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18620 String userName; 18621 synchronized (this) { 18622 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18623 if (userInfo == null) { 18624 Slog.w(TAG, "No user info for user #" + userId); 18625 return false; 18626 } 18627 if (userInfo.isManagedProfile()) { 18628 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18629 return false; 18630 } 18631 userName = userInfo.name; 18632 mTargetUserId = userId; 18633 } 18634 mHandler.removeMessages(START_USER_SWITCH_MSG); 18635 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18636 return true; 18637 } 18638 18639 private void showUserSwitchDialog(int userId, String userName) { 18640 // The dialog will show and then initiate the user switch by calling startUserInForeground 18641 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18642 true /* above system */); 18643 d.show(); 18644 } 18645 18646 private boolean startUser(final int userId, final boolean foreground) { 18647 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18648 != PackageManager.PERMISSION_GRANTED) { 18649 String msg = "Permission Denial: switchUser() from pid=" 18650 + Binder.getCallingPid() 18651 + ", uid=" + Binder.getCallingUid() 18652 + " requires " + INTERACT_ACROSS_USERS_FULL; 18653 Slog.w(TAG, msg); 18654 throw new SecurityException(msg); 18655 } 18656 18657 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18658 18659 final long ident = Binder.clearCallingIdentity(); 18660 try { 18661 synchronized (this) { 18662 final int oldUserId = mCurrentUserId; 18663 if (oldUserId == userId) { 18664 return true; 18665 } 18666 18667 mStackSupervisor.setLockTaskModeLocked(null, false); 18668 18669 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18670 if (userInfo == null) { 18671 Slog.w(TAG, "No user info for user #" + userId); 18672 return false; 18673 } 18674 if (foreground && userInfo.isManagedProfile()) { 18675 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18676 return false; 18677 } 18678 18679 if (foreground) { 18680 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18681 R.anim.screen_user_enter); 18682 } 18683 18684 boolean needStart = false; 18685 18686 // If the user we are switching to is not currently started, then 18687 // we need to start it now. 18688 if (mStartedUsers.get(userId) == null) { 18689 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18690 updateStartedUserArrayLocked(); 18691 needStart = true; 18692 } 18693 18694 final Integer userIdInt = Integer.valueOf(userId); 18695 mUserLru.remove(userIdInt); 18696 mUserLru.add(userIdInt); 18697 18698 if (foreground) { 18699 mCurrentUserId = userId; 18700 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18701 updateCurrentProfileIdsLocked(); 18702 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18703 // Once the internal notion of the active user has switched, we lock the device 18704 // with the option to show the user switcher on the keyguard. 18705 mWindowManager.lockNow(null); 18706 } else { 18707 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18708 updateCurrentProfileIdsLocked(); 18709 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18710 mUserLru.remove(currentUserIdInt); 18711 mUserLru.add(currentUserIdInt); 18712 } 18713 18714 final UserStartedState uss = mStartedUsers.get(userId); 18715 18716 // Make sure user is in the started state. If it is currently 18717 // stopping, we need to knock that off. 18718 if (uss.mState == UserStartedState.STATE_STOPPING) { 18719 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18720 // so we can just fairly silently bring the user back from 18721 // the almost-dead. 18722 uss.mState = UserStartedState.STATE_RUNNING; 18723 updateStartedUserArrayLocked(); 18724 needStart = true; 18725 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18726 // This means ACTION_SHUTDOWN has been sent, so we will 18727 // need to treat this as a new boot of the user. 18728 uss.mState = UserStartedState.STATE_BOOTING; 18729 updateStartedUserArrayLocked(); 18730 needStart = true; 18731 } 18732 18733 if (uss.mState == UserStartedState.STATE_BOOTING) { 18734 // Booting up a new user, need to tell system services about it. 18735 // Note that this is on the same handler as scheduling of broadcasts, 18736 // which is important because it needs to go first. 18737 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18738 } 18739 18740 if (foreground) { 18741 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18742 oldUserId)); 18743 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18744 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18745 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18746 oldUserId, userId, uss)); 18747 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18748 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18749 } 18750 18751 if (needStart) { 18752 // Send USER_STARTED broadcast 18753 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18754 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18755 | Intent.FLAG_RECEIVER_FOREGROUND); 18756 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18757 broadcastIntentLocked(null, null, intent, 18758 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18759 false, false, MY_PID, Process.SYSTEM_UID, userId); 18760 } 18761 18762 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18763 if (userId != UserHandle.USER_OWNER) { 18764 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18765 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18766 broadcastIntentLocked(null, null, intent, null, 18767 new IIntentReceiver.Stub() { 18768 public void performReceive(Intent intent, int resultCode, 18769 String data, Bundle extras, boolean ordered, 18770 boolean sticky, int sendingUser) { 18771 onUserInitialized(uss, foreground, oldUserId, userId); 18772 } 18773 }, 0, null, null, null, AppOpsManager.OP_NONE, 18774 true, false, MY_PID, Process.SYSTEM_UID, 18775 userId); 18776 uss.initializing = true; 18777 } else { 18778 getUserManagerLocked().makeInitialized(userInfo.id); 18779 } 18780 } 18781 18782 if (foreground) { 18783 if (!uss.initializing) { 18784 moveUserToForeground(uss, oldUserId, userId); 18785 } 18786 } else { 18787 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18788 } 18789 18790 if (needStart) { 18791 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18792 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18793 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18794 broadcastIntentLocked(null, null, intent, 18795 null, new IIntentReceiver.Stub() { 18796 @Override 18797 public void performReceive(Intent intent, int resultCode, String data, 18798 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18799 throws RemoteException { 18800 } 18801 }, 0, null, null, 18802 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18803 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18804 } 18805 } 18806 } finally { 18807 Binder.restoreCallingIdentity(ident); 18808 } 18809 18810 return true; 18811 } 18812 18813 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18814 long ident = Binder.clearCallingIdentity(); 18815 try { 18816 Intent intent; 18817 if (oldUserId >= 0) { 18818 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18819 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18820 int count = profiles.size(); 18821 for (int i = 0; i < count; i++) { 18822 int profileUserId = profiles.get(i).id; 18823 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18824 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18825 | Intent.FLAG_RECEIVER_FOREGROUND); 18826 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18827 broadcastIntentLocked(null, null, intent, 18828 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18829 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18830 } 18831 } 18832 if (newUserId >= 0) { 18833 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18834 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18835 int count = profiles.size(); 18836 for (int i = 0; i < count; i++) { 18837 int profileUserId = profiles.get(i).id; 18838 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18839 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18840 | Intent.FLAG_RECEIVER_FOREGROUND); 18841 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18842 broadcastIntentLocked(null, null, intent, 18843 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18844 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18845 } 18846 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18847 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18848 | Intent.FLAG_RECEIVER_FOREGROUND); 18849 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18850 broadcastIntentLocked(null, null, intent, 18851 null, null, 0, null, null, 18852 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18853 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18854 } 18855 } finally { 18856 Binder.restoreCallingIdentity(ident); 18857 } 18858 } 18859 18860 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18861 final int newUserId) { 18862 final int N = mUserSwitchObservers.beginBroadcast(); 18863 if (N > 0) { 18864 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18865 int mCount = 0; 18866 @Override 18867 public void sendResult(Bundle data) throws RemoteException { 18868 synchronized (ActivityManagerService.this) { 18869 if (mCurUserSwitchCallback == this) { 18870 mCount++; 18871 if (mCount == N) { 18872 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18873 } 18874 } 18875 } 18876 } 18877 }; 18878 synchronized (this) { 18879 uss.switching = true; 18880 mCurUserSwitchCallback = callback; 18881 } 18882 for (int i=0; i<N; i++) { 18883 try { 18884 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18885 newUserId, callback); 18886 } catch (RemoteException e) { 18887 } 18888 } 18889 } else { 18890 synchronized (this) { 18891 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18892 } 18893 } 18894 mUserSwitchObservers.finishBroadcast(); 18895 } 18896 18897 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18898 synchronized (this) { 18899 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18900 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18901 } 18902 } 18903 18904 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18905 mCurUserSwitchCallback = null; 18906 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18907 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18908 oldUserId, newUserId, uss)); 18909 } 18910 18911 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18912 synchronized (this) { 18913 if (foreground) { 18914 moveUserToForeground(uss, oldUserId, newUserId); 18915 } 18916 } 18917 18918 completeSwitchAndInitalize(uss, newUserId, true, false); 18919 } 18920 18921 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18922 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18923 if (homeInFront) { 18924 startHomeActivityLocked(newUserId); 18925 } else { 18926 mStackSupervisor.resumeTopActivitiesLocked(); 18927 } 18928 EventLogTags.writeAmSwitchUser(newUserId); 18929 getUserManagerLocked().userForeground(newUserId); 18930 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18931 } 18932 18933 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18934 completeSwitchAndInitalize(uss, newUserId, false, true); 18935 } 18936 18937 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18938 boolean clearInitializing, boolean clearSwitching) { 18939 boolean unfrozen = false; 18940 synchronized (this) { 18941 if (clearInitializing) { 18942 uss.initializing = false; 18943 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18944 } 18945 if (clearSwitching) { 18946 uss.switching = false; 18947 } 18948 if (!uss.switching && !uss.initializing) { 18949 mWindowManager.stopFreezingScreen(); 18950 unfrozen = true; 18951 } 18952 } 18953 if (unfrozen) { 18954 final int N = mUserSwitchObservers.beginBroadcast(); 18955 for (int i=0; i<N; i++) { 18956 try { 18957 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18958 } catch (RemoteException e) { 18959 } 18960 } 18961 mUserSwitchObservers.finishBroadcast(); 18962 } 18963 stopGuestUserIfBackground(); 18964 } 18965 18966 /** 18967 * Stops the guest user if it has gone to the background. 18968 */ 18969 private void stopGuestUserIfBackground() { 18970 synchronized (this) { 18971 final int num = mUserLru.size(); 18972 for (int i = 0; i < num; i++) { 18973 Integer oldUserId = mUserLru.get(i); 18974 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18975 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 18976 || oldUss.mState == UserStartedState.STATE_STOPPING 18977 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18978 continue; 18979 } 18980 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 18981 if (userInfo.isGuest()) { 18982 // This is a user to be stopped. 18983 stopUserLocked(oldUserId, null); 18984 break; 18985 } 18986 } 18987 } 18988 } 18989 18990 void scheduleStartProfilesLocked() { 18991 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18992 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18993 DateUtils.SECOND_IN_MILLIS); 18994 } 18995 } 18996 18997 void startProfilesLocked() { 18998 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18999 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19000 mCurrentUserId, false /* enabledOnly */); 19001 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19002 for (UserInfo user : profiles) { 19003 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19004 && user.id != mCurrentUserId) { 19005 toStart.add(user); 19006 } 19007 } 19008 final int n = toStart.size(); 19009 int i = 0; 19010 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19011 startUserInBackground(toStart.get(i).id); 19012 } 19013 if (i < n) { 19014 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19015 } 19016 } 19017 19018 void finishUserBoot(UserStartedState uss) { 19019 synchronized (this) { 19020 if (uss.mState == UserStartedState.STATE_BOOTING 19021 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19022 uss.mState = UserStartedState.STATE_RUNNING; 19023 final int userId = uss.mHandle.getIdentifier(); 19024 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19025 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19026 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19027 broadcastIntentLocked(null, null, intent, 19028 null, null, 0, null, null, 19029 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19030 true, false, MY_PID, Process.SYSTEM_UID, userId); 19031 } 19032 } 19033 } 19034 19035 void finishUserSwitch(UserStartedState uss) { 19036 synchronized (this) { 19037 finishUserBoot(uss); 19038 19039 startProfilesLocked(); 19040 19041 int num = mUserLru.size(); 19042 int i = 0; 19043 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19044 Integer oldUserId = mUserLru.get(i); 19045 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19046 if (oldUss == null) { 19047 // Shouldn't happen, but be sane if it does. 19048 mUserLru.remove(i); 19049 num--; 19050 continue; 19051 } 19052 if (oldUss.mState == UserStartedState.STATE_STOPPING 19053 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19054 // This user is already stopping, doesn't count. 19055 num--; 19056 i++; 19057 continue; 19058 } 19059 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19060 // Owner and current can't be stopped, but count as running. 19061 i++; 19062 continue; 19063 } 19064 // This is a user to be stopped. 19065 stopUserLocked(oldUserId, null); 19066 num--; 19067 i++; 19068 } 19069 } 19070 } 19071 19072 @Override 19073 public int stopUser(final int userId, final IStopUserCallback callback) { 19074 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19075 != PackageManager.PERMISSION_GRANTED) { 19076 String msg = "Permission Denial: switchUser() from pid=" 19077 + Binder.getCallingPid() 19078 + ", uid=" + Binder.getCallingUid() 19079 + " requires " + INTERACT_ACROSS_USERS_FULL; 19080 Slog.w(TAG, msg); 19081 throw new SecurityException(msg); 19082 } 19083 if (userId <= 0) { 19084 throw new IllegalArgumentException("Can't stop primary user " + userId); 19085 } 19086 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19087 synchronized (this) { 19088 return stopUserLocked(userId, callback); 19089 } 19090 } 19091 19092 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19093 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19094 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19095 return ActivityManager.USER_OP_IS_CURRENT; 19096 } 19097 19098 final UserStartedState uss = mStartedUsers.get(userId); 19099 if (uss == null) { 19100 // User is not started, nothing to do... but we do need to 19101 // callback if requested. 19102 if (callback != null) { 19103 mHandler.post(new Runnable() { 19104 @Override 19105 public void run() { 19106 try { 19107 callback.userStopped(userId); 19108 } catch (RemoteException e) { 19109 } 19110 } 19111 }); 19112 } 19113 return ActivityManager.USER_OP_SUCCESS; 19114 } 19115 19116 if (callback != null) { 19117 uss.mStopCallbacks.add(callback); 19118 } 19119 19120 if (uss.mState != UserStartedState.STATE_STOPPING 19121 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19122 uss.mState = UserStartedState.STATE_STOPPING; 19123 updateStartedUserArrayLocked(); 19124 19125 long ident = Binder.clearCallingIdentity(); 19126 try { 19127 // We are going to broadcast ACTION_USER_STOPPING and then 19128 // once that is done send a final ACTION_SHUTDOWN and then 19129 // stop the user. 19130 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19131 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19132 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19133 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19134 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19135 // This is the result receiver for the final shutdown broadcast. 19136 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19137 @Override 19138 public void performReceive(Intent intent, int resultCode, String data, 19139 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19140 finishUserStop(uss); 19141 } 19142 }; 19143 // This is the result receiver for the initial stopping broadcast. 19144 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19145 @Override 19146 public void performReceive(Intent intent, int resultCode, String data, 19147 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19148 // On to the next. 19149 synchronized (ActivityManagerService.this) { 19150 if (uss.mState != UserStartedState.STATE_STOPPING) { 19151 // Whoops, we are being started back up. Abort, abort! 19152 return; 19153 } 19154 uss.mState = UserStartedState.STATE_SHUTDOWN; 19155 } 19156 mBatteryStatsService.noteEvent( 19157 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19158 Integer.toString(userId), userId); 19159 mSystemServiceManager.stopUser(userId); 19160 broadcastIntentLocked(null, null, shutdownIntent, 19161 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19162 true, false, MY_PID, Process.SYSTEM_UID, userId); 19163 } 19164 }; 19165 // Kick things off. 19166 broadcastIntentLocked(null, null, stoppingIntent, 19167 null, stoppingReceiver, 0, null, null, 19168 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19169 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19170 } finally { 19171 Binder.restoreCallingIdentity(ident); 19172 } 19173 } 19174 19175 return ActivityManager.USER_OP_SUCCESS; 19176 } 19177 19178 void finishUserStop(UserStartedState uss) { 19179 final int userId = uss.mHandle.getIdentifier(); 19180 boolean stopped; 19181 ArrayList<IStopUserCallback> callbacks; 19182 synchronized (this) { 19183 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19184 if (mStartedUsers.get(userId) != uss) { 19185 stopped = false; 19186 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19187 stopped = false; 19188 } else { 19189 stopped = true; 19190 // User can no longer run. 19191 mStartedUsers.remove(userId); 19192 mUserLru.remove(Integer.valueOf(userId)); 19193 updateStartedUserArrayLocked(); 19194 19195 // Clean up all state and processes associated with the user. 19196 // Kill all the processes for the user. 19197 forceStopUserLocked(userId, "finish user"); 19198 } 19199 19200 // Explicitly remove the old information in mRecentTasks. 19201 removeRecentTasksForUserLocked(userId); 19202 } 19203 19204 for (int i=0; i<callbacks.size(); i++) { 19205 try { 19206 if (stopped) callbacks.get(i).userStopped(userId); 19207 else callbacks.get(i).userStopAborted(userId); 19208 } catch (RemoteException e) { 19209 } 19210 } 19211 19212 if (stopped) { 19213 mSystemServiceManager.cleanupUser(userId); 19214 synchronized (this) { 19215 mStackSupervisor.removeUserLocked(userId); 19216 } 19217 } 19218 } 19219 19220 @Override 19221 public UserInfo getCurrentUser() { 19222 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19223 != PackageManager.PERMISSION_GRANTED) && ( 19224 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19225 != PackageManager.PERMISSION_GRANTED)) { 19226 String msg = "Permission Denial: getCurrentUser() from pid=" 19227 + Binder.getCallingPid() 19228 + ", uid=" + Binder.getCallingUid() 19229 + " requires " + INTERACT_ACROSS_USERS; 19230 Slog.w(TAG, msg); 19231 throw new SecurityException(msg); 19232 } 19233 synchronized (this) { 19234 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19235 return getUserManagerLocked().getUserInfo(userId); 19236 } 19237 } 19238 19239 int getCurrentUserIdLocked() { 19240 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19241 } 19242 19243 @Override 19244 public boolean isUserRunning(int userId, boolean orStopped) { 19245 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19246 != PackageManager.PERMISSION_GRANTED) { 19247 String msg = "Permission Denial: isUserRunning() from pid=" 19248 + Binder.getCallingPid() 19249 + ", uid=" + Binder.getCallingUid() 19250 + " requires " + INTERACT_ACROSS_USERS; 19251 Slog.w(TAG, msg); 19252 throw new SecurityException(msg); 19253 } 19254 synchronized (this) { 19255 return isUserRunningLocked(userId, orStopped); 19256 } 19257 } 19258 19259 boolean isUserRunningLocked(int userId, boolean orStopped) { 19260 UserStartedState state = mStartedUsers.get(userId); 19261 if (state == null) { 19262 return false; 19263 } 19264 if (orStopped) { 19265 return true; 19266 } 19267 return state.mState != UserStartedState.STATE_STOPPING 19268 && state.mState != UserStartedState.STATE_SHUTDOWN; 19269 } 19270 19271 @Override 19272 public int[] getRunningUserIds() { 19273 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19274 != PackageManager.PERMISSION_GRANTED) { 19275 String msg = "Permission Denial: isUserRunning() from pid=" 19276 + Binder.getCallingPid() 19277 + ", uid=" + Binder.getCallingUid() 19278 + " requires " + INTERACT_ACROSS_USERS; 19279 Slog.w(TAG, msg); 19280 throw new SecurityException(msg); 19281 } 19282 synchronized (this) { 19283 return mStartedUserArray; 19284 } 19285 } 19286 19287 private void updateStartedUserArrayLocked() { 19288 int num = 0; 19289 for (int i=0; i<mStartedUsers.size(); i++) { 19290 UserStartedState uss = mStartedUsers.valueAt(i); 19291 // This list does not include stopping users. 19292 if (uss.mState != UserStartedState.STATE_STOPPING 19293 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19294 num++; 19295 } 19296 } 19297 mStartedUserArray = new int[num]; 19298 num = 0; 19299 for (int i=0; i<mStartedUsers.size(); i++) { 19300 UserStartedState uss = mStartedUsers.valueAt(i); 19301 if (uss.mState != UserStartedState.STATE_STOPPING 19302 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19303 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19304 num++; 19305 } 19306 } 19307 } 19308 19309 @Override 19310 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19311 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19312 != PackageManager.PERMISSION_GRANTED) { 19313 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19314 + Binder.getCallingPid() 19315 + ", uid=" + Binder.getCallingUid() 19316 + " requires " + INTERACT_ACROSS_USERS_FULL; 19317 Slog.w(TAG, msg); 19318 throw new SecurityException(msg); 19319 } 19320 19321 mUserSwitchObservers.register(observer); 19322 } 19323 19324 @Override 19325 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19326 mUserSwitchObservers.unregister(observer); 19327 } 19328 19329 private boolean userExists(int userId) { 19330 if (userId == 0) { 19331 return true; 19332 } 19333 UserManagerService ums = getUserManagerLocked(); 19334 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19335 } 19336 19337 int[] getUsersLocked() { 19338 UserManagerService ums = getUserManagerLocked(); 19339 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19340 } 19341 19342 UserManagerService getUserManagerLocked() { 19343 if (mUserManager == null) { 19344 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19345 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19346 } 19347 return mUserManager; 19348 } 19349 19350 private int applyUserId(int uid, int userId) { 19351 return UserHandle.getUid(userId, uid); 19352 } 19353 19354 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19355 if (info == null) return null; 19356 ApplicationInfo newInfo = new ApplicationInfo(info); 19357 newInfo.uid = applyUserId(info.uid, userId); 19358 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19359 + info.packageName; 19360 return newInfo; 19361 } 19362 19363 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19364 if (aInfo == null 19365 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19366 return aInfo; 19367 } 19368 19369 ActivityInfo info = new ActivityInfo(aInfo); 19370 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19371 return info; 19372 } 19373 19374 private final class LocalService extends ActivityManagerInternal { 19375 @Override 19376 public void onWakefulnessChanged(int wakefulness) { 19377 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19378 } 19379 19380 @Override 19381 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19382 String processName, String abiOverride, int uid, Runnable crashHandler) { 19383 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19384 processName, abiOverride, uid, crashHandler); 19385 } 19386 } 19387 19388 /** 19389 * An implementation of IAppTask, that allows an app to manage its own tasks via 19390 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19391 * only the process that calls getAppTasks() can call the AppTask methods. 19392 */ 19393 class AppTaskImpl extends IAppTask.Stub { 19394 private int mTaskId; 19395 private int mCallingUid; 19396 19397 public AppTaskImpl(int taskId, int callingUid) { 19398 mTaskId = taskId; 19399 mCallingUid = callingUid; 19400 } 19401 19402 private void checkCaller() { 19403 if (mCallingUid != Binder.getCallingUid()) { 19404 throw new SecurityException("Caller " + mCallingUid 19405 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19406 } 19407 } 19408 19409 @Override 19410 public void finishAndRemoveTask() { 19411 checkCaller(); 19412 19413 synchronized (ActivityManagerService.this) { 19414 long origId = Binder.clearCallingIdentity(); 19415 try { 19416 if (!removeTaskByIdLocked(mTaskId, false)) { 19417 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19418 } 19419 } finally { 19420 Binder.restoreCallingIdentity(origId); 19421 } 19422 } 19423 } 19424 19425 @Override 19426 public ActivityManager.RecentTaskInfo getTaskInfo() { 19427 checkCaller(); 19428 19429 synchronized (ActivityManagerService.this) { 19430 long origId = Binder.clearCallingIdentity(); 19431 try { 19432 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19433 if (tr == null) { 19434 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19435 } 19436 return createRecentTaskInfoFromTaskRecord(tr); 19437 } finally { 19438 Binder.restoreCallingIdentity(origId); 19439 } 19440 } 19441 } 19442 19443 @Override 19444 public void moveToFront() { 19445 checkCaller(); 19446 19447 final TaskRecord tr; 19448 synchronized (ActivityManagerService.this) { 19449 tr = recentTaskForIdLocked(mTaskId); 19450 if (tr == null) { 19451 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19452 } 19453 if (tr.getRootActivity() != null) { 19454 moveTaskToFrontLocked(tr.taskId, 0, null); 19455 return; 19456 } 19457 } 19458 19459 startActivityFromRecentsInner(tr.taskId, null); 19460 } 19461 19462 @Override 19463 public int startActivity(IBinder whoThread, String callingPackage, 19464 Intent intent, String resolvedType, Bundle options) { 19465 checkCaller(); 19466 19467 int callingUser = UserHandle.getCallingUserId(); 19468 TaskRecord tr; 19469 IApplicationThread appThread; 19470 synchronized (ActivityManagerService.this) { 19471 tr = recentTaskForIdLocked(mTaskId); 19472 if (tr == null) { 19473 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19474 } 19475 appThread = ApplicationThreadNative.asInterface(whoThread); 19476 if (appThread == null) { 19477 throw new IllegalArgumentException("Bad app thread " + appThread); 19478 } 19479 } 19480 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19481 resolvedType, null, null, null, null, 0, 0, null, null, 19482 null, options, callingUser, null, tr); 19483 } 19484 19485 @Override 19486 public void setExcludeFromRecents(boolean exclude) { 19487 checkCaller(); 19488 19489 synchronized (ActivityManagerService.this) { 19490 long origId = Binder.clearCallingIdentity(); 19491 try { 19492 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19493 if (tr == null) { 19494 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19495 } 19496 Intent intent = tr.getBaseIntent(); 19497 if (exclude) { 19498 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19499 } else { 19500 intent.setFlags(intent.getFlags() 19501 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19502 } 19503 } finally { 19504 Binder.restoreCallingIdentity(origId); 19505 } 19506 } 19507 } 19508 } 19509} 19510