ActivityManagerService.java revision 343f478241fab49c909b229d6876ff8405e7b0d5
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.Installer; 85import com.android.server.pm.UserManagerService; 86import com.android.server.wm.AppTransition; 87import com.android.server.wm.WindowManagerService; 88import com.google.android.collect.Lists; 89import com.google.android.collect.Maps; 90 91import libcore.io.IoUtils; 92 93import org.xmlpull.v1.XmlPullParser; 94import org.xmlpull.v1.XmlPullParserException; 95import org.xmlpull.v1.XmlSerializer; 96 97import android.app.Activity; 98import android.app.ActivityManager; 99import android.app.ActivityManager.RunningTaskInfo; 100import android.app.ActivityManager.StackInfo; 101import android.app.ActivityManagerInternal; 102import android.app.ActivityManagerNative; 103import android.app.ActivityOptions; 104import android.app.ActivityThread; 105import android.app.AlertDialog; 106import android.app.AppGlobals; 107import android.app.ApplicationErrorReport; 108import android.app.Dialog; 109import android.app.IActivityController; 110import android.app.IApplicationThread; 111import android.app.IInstrumentationWatcher; 112import android.app.INotificationManager; 113import android.app.IProcessObserver; 114import android.app.IServiceConnection; 115import android.app.IStopUserCallback; 116import android.app.IUiAutomationConnection; 117import android.app.IUserSwitchObserver; 118import android.app.Instrumentation; 119import android.app.Notification; 120import android.app.NotificationManager; 121import android.app.PendingIntent; 122import android.app.backup.IBackupManager; 123import android.content.ActivityNotFoundException; 124import android.content.BroadcastReceiver; 125import android.content.ClipData; 126import android.content.ComponentCallbacks2; 127import android.content.ComponentName; 128import android.content.ContentProvider; 129import android.content.ContentResolver; 130import android.content.Context; 131import android.content.DialogInterface; 132import android.content.IContentProvider; 133import android.content.IIntentReceiver; 134import android.content.IIntentSender; 135import android.content.Intent; 136import android.content.IntentFilter; 137import android.content.IntentSender; 138import android.content.pm.ActivityInfo; 139import android.content.pm.ApplicationInfo; 140import android.content.pm.ConfigurationInfo; 141import android.content.pm.IPackageDataObserver; 142import android.content.pm.IPackageManager; 143import android.content.pm.InstrumentationInfo; 144import android.content.pm.PackageInfo; 145import android.content.pm.PackageManager; 146import android.content.pm.ParceledListSlice; 147import android.content.pm.UserInfo; 148import android.content.pm.PackageManager.NameNotFoundException; 149import android.content.pm.PathPermission; 150import android.content.pm.ProviderInfo; 151import android.content.pm.ResolveInfo; 152import android.content.pm.ServiceInfo; 153import android.content.res.CompatibilityInfo; 154import android.content.res.Configuration; 155import android.net.Proxy; 156import android.net.ProxyInfo; 157import android.net.Uri; 158import android.os.Binder; 159import android.os.Build; 160import android.os.Bundle; 161import android.os.Debug; 162import android.os.DropBoxManager; 163import android.os.Environment; 164import android.os.FactoryTest; 165import android.os.FileObserver; 166import android.os.FileUtils; 167import android.os.Handler; 168import android.os.IBinder; 169import android.os.IPermissionController; 170import android.os.IRemoteCallback; 171import android.os.IUserManager; 172import android.os.Looper; 173import android.os.Message; 174import android.os.Parcel; 175import android.os.ParcelFileDescriptor; 176import android.os.Process; 177import android.os.RemoteCallbackList; 178import android.os.RemoteException; 179import android.os.SELinux; 180import android.os.ServiceManager; 181import android.os.StrictMode; 182import android.os.SystemClock; 183import android.os.SystemProperties; 184import android.os.UpdateLock; 185import android.os.UserHandle; 186import android.os.UserManager; 187import android.provider.Settings; 188import android.text.format.DateUtils; 189import android.text.format.Time; 190import android.util.AtomicFile; 191import android.util.EventLog; 192import android.util.Log; 193import android.util.Pair; 194import android.util.PrintWriterPrinter; 195import android.util.Slog; 196import android.util.SparseArray; 197import android.util.TimeUtils; 198import android.util.Xml; 199import android.view.Gravity; 200import android.view.LayoutInflater; 201import android.view.View; 202import android.view.WindowManager; 203import dalvik.system.VMRuntime; 204 205import java.io.BufferedInputStream; 206import java.io.BufferedOutputStream; 207import java.io.DataInputStream; 208import java.io.DataOutputStream; 209import java.io.File; 210import java.io.FileDescriptor; 211import java.io.FileInputStream; 212import java.io.FileNotFoundException; 213import java.io.FileOutputStream; 214import java.io.IOException; 215import java.io.InputStreamReader; 216import java.io.PrintWriter; 217import java.io.StringWriter; 218import java.lang.ref.WeakReference; 219import java.util.ArrayList; 220import java.util.Arrays; 221import java.util.Collections; 222import java.util.Comparator; 223import java.util.HashMap; 224import java.util.HashSet; 225import java.util.Iterator; 226import java.util.List; 227import java.util.Locale; 228import java.util.Map; 229import java.util.Set; 230import java.util.concurrent.atomic.AtomicBoolean; 231import java.util.concurrent.atomic.AtomicLong; 232 233public final class ActivityManagerService extends ActivityManagerNative 234 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 235 236 private static final String USER_DATA_DIR = "/data/user/"; 237 // File that stores last updated system version and called preboot receivers 238 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 239 240 static final String TAG = "ActivityManager"; 241 static final String TAG_MU = "ActivityManagerServiceMU"; 242 static final boolean DEBUG = false; 243 static final boolean localLOGV = DEBUG; 244 static final boolean DEBUG_BACKUP = localLOGV || false; 245 static final boolean DEBUG_BROADCAST = localLOGV || false; 246 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 248 static final boolean DEBUG_CLEANUP = localLOGV || false; 249 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 250 static final boolean DEBUG_FOCUS = false; 251 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 252 static final boolean DEBUG_MU = localLOGV || false; 253 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 254 static final boolean DEBUG_LRU = localLOGV || false; 255 static final boolean DEBUG_PAUSE = localLOGV || false; 256 static final boolean DEBUG_POWER = localLOGV || false; 257 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 258 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 259 static final boolean DEBUG_PROCESSES = localLOGV || false; 260 static final boolean DEBUG_PROVIDER = localLOGV || false; 261 static final boolean DEBUG_RESULTS = localLOGV || false; 262 static final boolean DEBUG_SERVICE = localLOGV || false; 263 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 264 static final boolean DEBUG_STACK = localLOGV || false; 265 static final boolean DEBUG_SWITCH = localLOGV || false; 266 static final boolean DEBUG_TASKS = localLOGV || false; 267 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 268 static final boolean DEBUG_TRANSITION = localLOGV || false; 269 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 270 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 271 static final boolean DEBUG_VISBILITY = localLOGV || false; 272 static final boolean DEBUG_PSS = localLOGV || false; 273 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 274 static final boolean DEBUG_RECENTS = localLOGV || false; 275 static final boolean VALIDATE_TOKENS = false; 276 static final boolean SHOW_ACTIVITY_START_TIME = true; 277 278 // Control over CPU and battery monitoring. 279 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 280 static final boolean MONITOR_CPU_USAGE = true; 281 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 282 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 283 static final boolean MONITOR_THREAD_CPU_USAGE = false; 284 285 // The flags that are set for all calls we make to the package manager. 286 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 287 288 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 289 290 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 291 292 // Maximum number recent bitmaps to keep in memory. 293 static final int MAX_RECENT_BITMAPS = 5; 294 295 // Amount of time after a call to stopAppSwitches() during which we will 296 // prevent further untrusted switches from happening. 297 static final long APP_SWITCH_DELAY_TIME = 5*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real. 301 static final int PROC_START_TIMEOUT = 10*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, when the process was 305 // started with a wrapper for instrumentation (such as Valgrind) because it 306 // could take much longer than usual. 307 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 308 309 // How long to wait after going idle before forcing apps to GC. 310 static final int GC_TIMEOUT = 5*1000; 311 312 // The minimum amount of time between successive GC requests for a process. 313 static final int GC_MIN_INTERVAL = 60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process. 316 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 317 318 // The minimum amount of time between successive PSS requests for a process 319 // when the request is due to the memory state being lowered. 320 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 321 322 // The rate at which we check for apps using excessive power -- 15 mins. 323 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on wake locks to start killing things. 327 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // The minimum sample duration we will allow before deciding we have 330 // enough data on CPU usage to start killing things. 331 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 332 333 // How long we allow a receiver to run before giving up on it. 334 static final int BROADCAST_FG_TIMEOUT = 10*1000; 335 static final int BROADCAST_BG_TIMEOUT = 60*1000; 336 337 // How long we wait until we timeout on key dispatching. 338 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 339 340 // How long we wait until we timeout on key dispatching during instrumentation. 341 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 342 343 // Amount of time we wait for observers to handle a user switch before 344 // giving up on them and unfreezing the screen. 345 static final int USER_SWITCH_TIMEOUT = 2*1000; 346 347 // Maximum number of users we allow to be running at a time. 348 static final int MAX_RUNNING_USERS = 3; 349 350 // How long to wait in getAssistContextExtras for the activity and foreground services 351 // to respond with the result. 352 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 353 354 // Maximum number of persisted Uri grants a package is allowed 355 static final int MAX_PERSISTED_URI_GRANTS = 128; 356 357 static final int MY_PID = Process.myPid(); 358 359 static final String[] EMPTY_STRING_ARRAY = new String[0]; 360 361 // How many bytes to write into the dropbox log before truncating 362 static final int DROPBOX_MAX_SIZE = 256 * 1024; 363 364 // Access modes for handleIncomingUser. 365 static final int ALLOW_NON_FULL = 0; 366 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 367 static final int ALLOW_FULL_ONLY = 2; 368 369 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 370 371 /** All system services */ 372 SystemServiceManager mSystemServiceManager; 373 374 private Installer mInstaller; 375 376 /** Run all ActivityStacks through this */ 377 ActivityStackSupervisor mStackSupervisor; 378 379 public IntentFirewall mIntentFirewall; 380 381 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 382 // default actuion automatically. Important for devices without direct input 383 // devices. 384 private boolean mShowDialogs = true; 385 386 BroadcastQueue mFgBroadcastQueue; 387 BroadcastQueue mBgBroadcastQueue; 388 // Convenient for easy iteration over the queues. Foreground is first 389 // so that dispatch of foreground broadcasts gets precedence. 390 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 391 392 BroadcastQueue broadcastQueueForIntent(Intent intent) { 393 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 394 if (DEBUG_BACKGROUND_BROADCAST) { 395 Slog.i(TAG, "Broadcast intent " + intent + " on " 396 + (isFg ? "foreground" : "background") 397 + " queue"); 398 } 399 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 400 } 401 402 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 403 for (BroadcastQueue queue : mBroadcastQueues) { 404 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 405 if (r != null) { 406 return r; 407 } 408 } 409 return null; 410 } 411 412 /** 413 * Activity we have told the window manager to have key focus. 414 */ 415 ActivityRecord mFocusedActivity = null; 416 417 /** 418 * List of intents that were used to start the most recent tasks. 419 */ 420 ArrayList<TaskRecord> mRecentTasks; 421 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 422 423 /** 424 * For addAppTask: cached of the last activity component that was added. 425 */ 426 ComponentName mLastAddedTaskComponent; 427 428 /** 429 * For addAppTask: cached of the last activity uid that was added. 430 */ 431 int mLastAddedTaskUid; 432 433 /** 434 * For addAppTask: cached of the last ActivityInfo that was added. 435 */ 436 ActivityInfo mLastAddedTaskActivity; 437 438 public class PendingAssistExtras extends Binder implements Runnable { 439 public final ActivityRecord activity; 440 public final Bundle extras; 441 public final Intent intent; 442 public final String hint; 443 public final int userHandle; 444 public boolean haveResult = false; 445 public Bundle result = null; 446 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 447 String _hint, int _userHandle) { 448 activity = _activity; 449 extras = _extras; 450 intent = _intent; 451 hint = _hint; 452 userHandle = _userHandle; 453 } 454 @Override 455 public void run() { 456 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 457 synchronized (this) { 458 haveResult = true; 459 notifyAll(); 460 } 461 } 462 } 463 464 final ArrayList<PendingAssistExtras> mPendingAssistExtras 465 = new ArrayList<PendingAssistExtras>(); 466 467 /** 468 * Process management. 469 */ 470 final ProcessList mProcessList = new ProcessList(); 471 472 /** 473 * All of the applications we currently have running organized by name. 474 * The keys are strings of the application package name (as 475 * returned by the package manager), and the keys are ApplicationRecord 476 * objects. 477 */ 478 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 479 480 /** 481 * Tracking long-term execution of processes to look for abuse and other 482 * bad app behavior. 483 */ 484 final ProcessStatsService mProcessStats; 485 486 /** 487 * The currently running isolated processes. 488 */ 489 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 490 491 /** 492 * Counter for assigning isolated process uids, to avoid frequently reusing the 493 * same ones. 494 */ 495 int mNextIsolatedProcessUid = 0; 496 497 /** 498 * The currently running heavy-weight process, if any. 499 */ 500 ProcessRecord mHeavyWeightProcess = null; 501 502 /** 503 * The last time that various processes have crashed. 504 */ 505 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 506 507 /** 508 * Information about a process that is currently marked as bad. 509 */ 510 static final class BadProcessInfo { 511 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 512 this.time = time; 513 this.shortMsg = shortMsg; 514 this.longMsg = longMsg; 515 this.stack = stack; 516 } 517 518 final long time; 519 final String shortMsg; 520 final String longMsg; 521 final String stack; 522 } 523 524 /** 525 * Set of applications that we consider to be bad, and will reject 526 * incoming broadcasts from (which the user has no control over). 527 * Processes are added to this set when they have crashed twice within 528 * a minimum amount of time; they are removed from it when they are 529 * later restarted (hopefully due to some user action). The value is the 530 * time it was added to the list. 531 */ 532 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 533 534 /** 535 * All of the processes we currently have running organized by pid. 536 * The keys are the pid running the application. 537 * 538 * <p>NOTE: This object is protected by its own lock, NOT the global 539 * activity manager lock! 540 */ 541 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 542 543 /** 544 * All of the processes that have been forced to be foreground. The key 545 * is the pid of the caller who requested it (we hold a death 546 * link on it). 547 */ 548 abstract class ForegroundToken implements IBinder.DeathRecipient { 549 int pid; 550 IBinder token; 551 } 552 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 553 554 /** 555 * List of records for processes that someone had tried to start before the 556 * system was ready. We don't start them at that point, but ensure they 557 * are started by the time booting is complete. 558 */ 559 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 560 561 /** 562 * List of persistent applications that are in the process 563 * of being started. 564 */ 565 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 566 567 /** 568 * Processes that are being forcibly torn down. 569 */ 570 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 571 572 /** 573 * List of running applications, sorted by recent usage. 574 * The first entry in the list is the least recently used. 575 */ 576 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Where in mLruProcesses that the processes hosting activities start. 580 */ 581 int mLruProcessActivityStart = 0; 582 583 /** 584 * Where in mLruProcesses that the processes hosting services start. 585 * This is after (lower index) than mLruProcessesActivityStart. 586 */ 587 int mLruProcessServiceStart = 0; 588 589 /** 590 * List of processes that should gc as soon as things are idle. 591 */ 592 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 593 594 /** 595 * Processes we want to collect PSS data from. 596 */ 597 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 598 599 /** 600 * Last time we requested PSS data of all processes. 601 */ 602 long mLastFullPssTime = SystemClock.uptimeMillis(); 603 604 /** 605 * If set, the next time we collect PSS data we should do a full collection 606 * with data from native processes and the kernel. 607 */ 608 boolean mFullPssPending = false; 609 610 /** 611 * This is the process holding what we currently consider to be 612 * the "home" activity. 613 */ 614 ProcessRecord mHomeProcess; 615 616 /** 617 * This is the process holding the activity the user last visited that 618 * is in a different process from the one they are currently in. 619 */ 620 ProcessRecord mPreviousProcess; 621 622 /** 623 * The time at which the previous process was last visible. 624 */ 625 long mPreviousProcessVisibleTime; 626 627 /** 628 * Which uses have been started, so are allowed to run code. 629 */ 630 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 631 632 /** 633 * LRU list of history of current users. Most recently current is at the end. 634 */ 635 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 636 637 /** 638 * Constant array of the users that are currently started. 639 */ 640 int[] mStartedUserArray = new int[] { 0 }; 641 642 /** 643 * Registered observers of the user switching mechanics. 644 */ 645 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 646 = new RemoteCallbackList<IUserSwitchObserver>(); 647 648 /** 649 * Currently active user switch. 650 */ 651 Object mCurUserSwitchCallback; 652 653 /** 654 * Packages that the user has asked to have run in screen size 655 * compatibility mode instead of filling the screen. 656 */ 657 final CompatModePackages mCompatModePackages; 658 659 /** 660 * Set of IntentSenderRecord objects that are currently active. 661 */ 662 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 663 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 664 665 /** 666 * Fingerprints (hashCode()) of stack traces that we've 667 * already logged DropBox entries for. Guarded by itself. If 668 * something (rogue user app) forces this over 669 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 670 */ 671 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 672 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 673 674 /** 675 * Strict Mode background batched logging state. 676 * 677 * The string buffer is guarded by itself, and its lock is also 678 * used to determine if another batched write is already 679 * in-flight. 680 */ 681 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 682 683 /** 684 * Keeps track of all IIntentReceivers that have been registered for 685 * broadcasts. Hash keys are the receiver IBinder, hash value is 686 * a ReceiverList. 687 */ 688 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 689 new HashMap<IBinder, ReceiverList>(); 690 691 /** 692 * Resolver for broadcast intents to registered receivers. 693 * Holds BroadcastFilter (subclass of IntentFilter). 694 */ 695 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 696 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 697 @Override 698 protected boolean allowFilterResult( 699 BroadcastFilter filter, List<BroadcastFilter> dest) { 700 IBinder target = filter.receiverList.receiver.asBinder(); 701 for (int i=dest.size()-1; i>=0; i--) { 702 if (dest.get(i).receiverList.receiver.asBinder() == target) { 703 return false; 704 } 705 } 706 return true; 707 } 708 709 @Override 710 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 711 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 712 || userId == filter.owningUserId) { 713 return super.newResult(filter, match, userId); 714 } 715 return null; 716 } 717 718 @Override 719 protected BroadcastFilter[] newArray(int size) { 720 return new BroadcastFilter[size]; 721 } 722 723 @Override 724 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 725 return packageName.equals(filter.packageName); 726 } 727 }; 728 729 /** 730 * State of all active sticky broadcasts per user. Keys are the action of the 731 * sticky Intent, values are an ArrayList of all broadcasted intents with 732 * that action (which should usually be one). The SparseArray is keyed 733 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 734 * for stickies that are sent to all users. 735 */ 736 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 737 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 738 739 final ActiveServices mServices; 740 741 /** 742 * Backup/restore process management 743 */ 744 String mBackupAppName = null; 745 BackupRecord mBackupTarget = null; 746 747 final ProviderMap mProviderMap; 748 749 /** 750 * List of content providers who have clients waiting for them. The 751 * application is currently being launched and the provider will be 752 * removed from this list once it is published. 753 */ 754 final ArrayList<ContentProviderRecord> mLaunchingProviders 755 = new ArrayList<ContentProviderRecord>(); 756 757 /** 758 * File storing persisted {@link #mGrantedUriPermissions}. 759 */ 760 private final AtomicFile mGrantFile; 761 762 /** XML constants used in {@link #mGrantFile} */ 763 private static final String TAG_URI_GRANTS = "uri-grants"; 764 private static final String TAG_URI_GRANT = "uri-grant"; 765 private static final String ATTR_USER_HANDLE = "userHandle"; 766 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 767 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 768 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 769 private static final String ATTR_TARGET_PKG = "targetPkg"; 770 private static final String ATTR_URI = "uri"; 771 private static final String ATTR_MODE_FLAGS = "modeFlags"; 772 private static final String ATTR_CREATED_TIME = "createdTime"; 773 private static final String ATTR_PREFIX = "prefix"; 774 775 /** 776 * Global set of specific {@link Uri} permissions that have been granted. 777 * This optimized lookup structure maps from {@link UriPermission#targetUid} 778 * to {@link UriPermission#uri} to {@link UriPermission}. 779 */ 780 @GuardedBy("this") 781 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 782 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 783 784 public static class GrantUri { 785 public final int sourceUserId; 786 public final Uri uri; 787 public boolean prefix; 788 789 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 790 this.sourceUserId = sourceUserId; 791 this.uri = uri; 792 this.prefix = prefix; 793 } 794 795 @Override 796 public int hashCode() { 797 return toString().hashCode(); 798 } 799 800 @Override 801 public boolean equals(Object o) { 802 if (o instanceof GrantUri) { 803 GrantUri other = (GrantUri) o; 804 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 805 && prefix == other.prefix; 806 } 807 return false; 808 } 809 810 @Override 811 public String toString() { 812 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 813 if (prefix) result += " [prefix]"; 814 return result; 815 } 816 817 public String toSafeString() { 818 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 819 if (prefix) result += " [prefix]"; 820 return result; 821 } 822 823 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 824 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 825 ContentProvider.getUriWithoutUserId(uri), false); 826 } 827 } 828 829 CoreSettingsObserver mCoreSettingsObserver; 830 831 /** 832 * Thread-local storage used to carry caller permissions over through 833 * indirect content-provider access. 834 */ 835 private class Identity { 836 public int pid; 837 public int uid; 838 839 Identity(int _pid, int _uid) { 840 pid = _pid; 841 uid = _uid; 842 } 843 } 844 845 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 846 847 /** 848 * All information we have collected about the runtime performance of 849 * any user id that can impact battery performance. 850 */ 851 final BatteryStatsService mBatteryStatsService; 852 853 /** 854 * Information about component usage 855 */ 856 UsageStatsManagerInternal mUsageStatsService; 857 858 /** 859 * Information about and control over application operations 860 */ 861 final AppOpsService mAppOpsService; 862 863 /** 864 * Save recent tasks information across reboots. 865 */ 866 final TaskPersister mTaskPersister; 867 868 /** 869 * Current configuration information. HistoryRecord objects are given 870 * a reference to this object to indicate which configuration they are 871 * currently running in, so this object must be kept immutable. 872 */ 873 Configuration mConfiguration = new Configuration(); 874 875 /** 876 * Current sequencing integer of the configuration, for skipping old 877 * configurations. 878 */ 879 int mConfigurationSeq = 0; 880 881 /** 882 * Hardware-reported OpenGLES version. 883 */ 884 final int GL_ES_VERSION; 885 886 /** 887 * List of initialization arguments to pass to all processes when binding applications to them. 888 * For example, references to the commonly used services. 889 */ 890 HashMap<String, IBinder> mAppBindArgs; 891 892 /** 893 * Temporary to avoid allocations. Protected by main lock. 894 */ 895 final StringBuilder mStringBuilder = new StringBuilder(256); 896 897 /** 898 * Used to control how we initialize the service. 899 */ 900 ComponentName mTopComponent; 901 String mTopAction = Intent.ACTION_MAIN; 902 String mTopData; 903 boolean mProcessesReady = false; 904 boolean mSystemReady = false; 905 boolean mBooting = false; 906 boolean mCallFinishBooting = false; 907 boolean mBootAnimationComplete = false; 908 boolean mWaitingUpdate = false; 909 boolean mDidUpdate = false; 910 boolean mOnBattery = false; 911 boolean mLaunchWarningShown = false; 912 913 Context mContext; 914 915 int mFactoryTest; 916 917 boolean mCheckedForSetup; 918 919 /** 920 * The time at which we will allow normal application switches again, 921 * after a call to {@link #stopAppSwitches()}. 922 */ 923 long mAppSwitchesAllowedTime; 924 925 /** 926 * This is set to true after the first switch after mAppSwitchesAllowedTime 927 * is set; any switches after that will clear the time. 928 */ 929 boolean mDidAppSwitch; 930 931 /** 932 * Last time (in realtime) at which we checked for power usage. 933 */ 934 long mLastPowerCheckRealtime; 935 936 /** 937 * Last time (in uptime) at which we checked for power usage. 938 */ 939 long mLastPowerCheckUptime; 940 941 /** 942 * Set while we are wanting to sleep, to prevent any 943 * activities from being started/resumed. 944 */ 945 private boolean mSleeping = false; 946 947 /** 948 * Set while we are running a voice interaction. This overrides 949 * sleeping while it is active. 950 */ 951 private boolean mRunningVoice = false; 952 953 /** 954 * State of external calls telling us if the device is asleep. 955 */ 956 private boolean mWentToSleep = false; 957 958 /** 959 * State of external call telling us if the lock screen is shown. 960 */ 961 private boolean mLockScreenShown = false; 962 963 /** 964 * Set if we are shutting down the system, similar to sleeping. 965 */ 966 boolean mShuttingDown = false; 967 968 /** 969 * Current sequence id for oom_adj computation traversal. 970 */ 971 int mAdjSeq = 0; 972 973 /** 974 * Current sequence id for process LRU updating. 975 */ 976 int mLruSeq = 0; 977 978 /** 979 * Keep track of the non-cached/empty process we last found, to help 980 * determine how to distribute cached/empty processes next time. 981 */ 982 int mNumNonCachedProcs = 0; 983 984 /** 985 * Keep track of the number of cached hidden procs, to balance oom adj 986 * distribution between those and empty procs. 987 */ 988 int mNumCachedHiddenProcs = 0; 989 990 /** 991 * Keep track of the number of service processes we last found, to 992 * determine on the next iteration which should be B services. 993 */ 994 int mNumServiceProcs = 0; 995 int mNewNumAServiceProcs = 0; 996 int mNewNumServiceProcs = 0; 997 998 /** 999 * Allow the current computed overall memory level of the system to go down? 1000 * This is set to false when we are killing processes for reasons other than 1001 * memory management, so that the now smaller process list will not be taken as 1002 * an indication that memory is tighter. 1003 */ 1004 boolean mAllowLowerMemLevel = false; 1005 1006 /** 1007 * The last computed memory level, for holding when we are in a state that 1008 * processes are going away for other reasons. 1009 */ 1010 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1011 1012 /** 1013 * The last total number of process we have, to determine if changes actually look 1014 * like a shrinking number of process due to lower RAM. 1015 */ 1016 int mLastNumProcesses; 1017 1018 /** 1019 * The uptime of the last time we performed idle maintenance. 1020 */ 1021 long mLastIdleTime = SystemClock.uptimeMillis(); 1022 1023 /** 1024 * Total time spent with RAM that has been added in the past since the last idle time. 1025 */ 1026 long mLowRamTimeSinceLastIdle = 0; 1027 1028 /** 1029 * If RAM is currently low, when that horrible situation started. 1030 */ 1031 long mLowRamStartTime = 0; 1032 1033 /** 1034 * For reporting to battery stats the current top application. 1035 */ 1036 private String mCurResumedPackage = null; 1037 private int mCurResumedUid = -1; 1038 1039 /** 1040 * For reporting to battery stats the apps currently running foreground 1041 * service. The ProcessMap is package/uid tuples; each of these contain 1042 * an array of the currently foreground processes. 1043 */ 1044 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1045 = new ProcessMap<ArrayList<ProcessRecord>>(); 1046 1047 /** 1048 * This is set if we had to do a delayed dexopt of an app before launching 1049 * it, to increase the ANR timeouts in that case. 1050 */ 1051 boolean mDidDexOpt; 1052 1053 /** 1054 * Set if the systemServer made a call to enterSafeMode. 1055 */ 1056 boolean mSafeMode; 1057 1058 String mDebugApp = null; 1059 boolean mWaitForDebugger = false; 1060 boolean mDebugTransient = false; 1061 String mOrigDebugApp = null; 1062 boolean mOrigWaitForDebugger = false; 1063 boolean mAlwaysFinishActivities = false; 1064 IActivityController mController = null; 1065 String mProfileApp = null; 1066 ProcessRecord mProfileProc = null; 1067 String mProfileFile; 1068 ParcelFileDescriptor mProfileFd; 1069 int mSamplingInterval = 0; 1070 boolean mAutoStopProfiler = false; 1071 int mProfileType = 0; 1072 String mOpenGlTraceApp = null; 1073 1074 static class ProcessChangeItem { 1075 static final int CHANGE_ACTIVITIES = 1<<0; 1076 static final int CHANGE_PROCESS_STATE = 1<<1; 1077 int changes; 1078 int uid; 1079 int pid; 1080 int processState; 1081 boolean foregroundActivities; 1082 } 1083 1084 final RemoteCallbackList<IProcessObserver> mProcessObservers 1085 = new RemoteCallbackList<IProcessObserver>(); 1086 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1087 1088 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1089 = new ArrayList<ProcessChangeItem>(); 1090 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1091 = new ArrayList<ProcessChangeItem>(); 1092 1093 /** 1094 * Runtime CPU use collection thread. This object's lock is used to 1095 * perform synchronization with the thread (notifying it to run). 1096 */ 1097 final Thread mProcessCpuThread; 1098 1099 /** 1100 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1101 * Must acquire this object's lock when accessing it. 1102 * NOTE: this lock will be held while doing long operations (trawling 1103 * through all processes in /proc), so it should never be acquired by 1104 * any critical paths such as when holding the main activity manager lock. 1105 */ 1106 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1107 MONITOR_THREAD_CPU_USAGE); 1108 final AtomicLong mLastCpuTime = new AtomicLong(0); 1109 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1110 1111 long mLastWriteTime = 0; 1112 1113 /** 1114 * Used to retain an update lock when the foreground activity is in 1115 * immersive mode. 1116 */ 1117 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1118 1119 /** 1120 * Set to true after the system has finished booting. 1121 */ 1122 boolean mBooted = false; 1123 1124 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1125 int mProcessLimitOverride = -1; 1126 1127 WindowManagerService mWindowManager; 1128 1129 final ActivityThread mSystemThread; 1130 1131 // Holds the current foreground user's id 1132 int mCurrentUserId = 0; 1133 // Holds the target user's id during a user switch 1134 int mTargetUserId = UserHandle.USER_NULL; 1135 // If there are multiple profiles for the current user, their ids are here 1136 // Currently only the primary user can have managed profiles 1137 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1138 1139 /** 1140 * Mapping from each known user ID to the profile group ID it is associated with. 1141 */ 1142 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1143 1144 private UserManagerService mUserManager; 1145 1146 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1147 final ProcessRecord mApp; 1148 final int mPid; 1149 final IApplicationThread mAppThread; 1150 1151 AppDeathRecipient(ProcessRecord app, int pid, 1152 IApplicationThread thread) { 1153 if (localLOGV) Slog.v( 1154 TAG, "New death recipient " + this 1155 + " for thread " + thread.asBinder()); 1156 mApp = app; 1157 mPid = pid; 1158 mAppThread = thread; 1159 } 1160 1161 @Override 1162 public void binderDied() { 1163 if (localLOGV) Slog.v( 1164 TAG, "Death received in " + this 1165 + " for thread " + mAppThread.asBinder()); 1166 synchronized(ActivityManagerService.this) { 1167 appDiedLocked(mApp, mPid, mAppThread); 1168 } 1169 } 1170 } 1171 1172 static final int SHOW_ERROR_MSG = 1; 1173 static final int SHOW_NOT_RESPONDING_MSG = 2; 1174 static final int SHOW_FACTORY_ERROR_MSG = 3; 1175 static final int UPDATE_CONFIGURATION_MSG = 4; 1176 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1177 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1178 static final int SERVICE_TIMEOUT_MSG = 12; 1179 static final int UPDATE_TIME_ZONE = 13; 1180 static final int SHOW_UID_ERROR_MSG = 14; 1181 static final int IM_FEELING_LUCKY_MSG = 15; 1182 static final int PROC_START_TIMEOUT_MSG = 20; 1183 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1184 static final int KILL_APPLICATION_MSG = 22; 1185 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1186 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1187 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1188 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1189 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1190 static final int CLEAR_DNS_CACHE_MSG = 28; 1191 static final int UPDATE_HTTP_PROXY_MSG = 29; 1192 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1193 static final int DISPATCH_PROCESSES_CHANGED = 31; 1194 static final int DISPATCH_PROCESS_DIED = 32; 1195 static final int REPORT_MEM_USAGE_MSG = 33; 1196 static final int REPORT_USER_SWITCH_MSG = 34; 1197 static final int CONTINUE_USER_SWITCH_MSG = 35; 1198 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1199 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1200 static final int PERSIST_URI_GRANTS_MSG = 38; 1201 static final int REQUEST_ALL_PSS_MSG = 39; 1202 static final int START_PROFILES_MSG = 40; 1203 static final int UPDATE_TIME = 41; 1204 static final int SYSTEM_USER_START_MSG = 42; 1205 static final int SYSTEM_USER_CURRENT_MSG = 43; 1206 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1207 static final int FINISH_BOOTING_MSG = 45; 1208 static final int START_USER_SWITCH_MSG = 46; 1209 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1210 1211 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1212 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1213 static final int FIRST_COMPAT_MODE_MSG = 300; 1214 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1215 1216 AlertDialog mUidAlert; 1217 CompatModeDialog mCompatModeDialog; 1218 long mLastMemUsageReportTime = 0; 1219 1220 private LockToAppRequestDialog mLockToAppRequest; 1221 1222 /** 1223 * Flag whether the current user is a "monkey", i.e. whether 1224 * the UI is driven by a UI automation tool. 1225 */ 1226 private boolean mUserIsMonkey; 1227 1228 /** Flag whether the device has a Recents UI */ 1229 boolean mHasRecents; 1230 1231 /** The dimensions of the thumbnails in the Recents UI. */ 1232 int mThumbnailWidth; 1233 int mThumbnailHeight; 1234 1235 final ServiceThread mHandlerThread; 1236 final MainHandler mHandler; 1237 1238 final class MainHandler extends Handler { 1239 public MainHandler(Looper looper) { 1240 super(looper, null, true); 1241 } 1242 1243 @Override 1244 public void handleMessage(Message msg) { 1245 switch (msg.what) { 1246 case SHOW_ERROR_MSG: { 1247 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1248 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1249 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1250 synchronized (ActivityManagerService.this) { 1251 ProcessRecord proc = (ProcessRecord)data.get("app"); 1252 AppErrorResult res = (AppErrorResult) data.get("result"); 1253 if (proc != null && proc.crashDialog != null) { 1254 Slog.e(TAG, "App already has crash dialog: " + proc); 1255 if (res != null) { 1256 res.set(0); 1257 } 1258 return; 1259 } 1260 boolean isBackground = (UserHandle.getAppId(proc.uid) 1261 >= Process.FIRST_APPLICATION_UID 1262 && proc.pid != MY_PID); 1263 for (int userId : mCurrentProfileIds) { 1264 isBackground &= (proc.userId != userId); 1265 } 1266 if (isBackground && !showBackground) { 1267 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1268 if (res != null) { 1269 res.set(0); 1270 } 1271 return; 1272 } 1273 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1274 Dialog d = new AppErrorDialog(mContext, 1275 ActivityManagerService.this, res, proc); 1276 d.show(); 1277 proc.crashDialog = d; 1278 } else { 1279 // The device is asleep, so just pretend that the user 1280 // saw a crash dialog and hit "force quit". 1281 if (res != null) { 1282 res.set(0); 1283 } 1284 } 1285 } 1286 1287 ensureBootCompleted(); 1288 } break; 1289 case SHOW_NOT_RESPONDING_MSG: { 1290 synchronized (ActivityManagerService.this) { 1291 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1292 ProcessRecord proc = (ProcessRecord)data.get("app"); 1293 if (proc != null && proc.anrDialog != null) { 1294 Slog.e(TAG, "App already has anr dialog: " + proc); 1295 return; 1296 } 1297 1298 Intent intent = new Intent("android.intent.action.ANR"); 1299 if (!mProcessesReady) { 1300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1301 | Intent.FLAG_RECEIVER_FOREGROUND); 1302 } 1303 broadcastIntentLocked(null, null, intent, 1304 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1305 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1306 1307 if (mShowDialogs) { 1308 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1309 mContext, proc, (ActivityRecord)data.get("activity"), 1310 msg.arg1 != 0); 1311 d.show(); 1312 proc.anrDialog = d; 1313 } else { 1314 // Just kill the app if there is no dialog to be shown. 1315 killAppAtUsersRequest(proc, null); 1316 } 1317 } 1318 1319 ensureBootCompleted(); 1320 } break; 1321 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1322 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1323 synchronized (ActivityManagerService.this) { 1324 ProcessRecord proc = (ProcessRecord) data.get("app"); 1325 if (proc == null) { 1326 Slog.e(TAG, "App not found when showing strict mode dialog."); 1327 break; 1328 } 1329 if (proc.crashDialog != null) { 1330 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1331 return; 1332 } 1333 AppErrorResult res = (AppErrorResult) data.get("result"); 1334 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1335 Dialog d = new StrictModeViolationDialog(mContext, 1336 ActivityManagerService.this, res, proc); 1337 d.show(); 1338 proc.crashDialog = d; 1339 } else { 1340 // The device is asleep, so just pretend that the user 1341 // saw a crash dialog and hit "force quit". 1342 res.set(0); 1343 } 1344 } 1345 ensureBootCompleted(); 1346 } break; 1347 case SHOW_FACTORY_ERROR_MSG: { 1348 Dialog d = new FactoryErrorDialog( 1349 mContext, msg.getData().getCharSequence("msg")); 1350 d.show(); 1351 ensureBootCompleted(); 1352 } break; 1353 case UPDATE_CONFIGURATION_MSG: { 1354 final ContentResolver resolver = mContext.getContentResolver(); 1355 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1356 } break; 1357 case GC_BACKGROUND_PROCESSES_MSG: { 1358 synchronized (ActivityManagerService.this) { 1359 performAppGcsIfAppropriateLocked(); 1360 } 1361 } break; 1362 case WAIT_FOR_DEBUGGER_MSG: { 1363 synchronized (ActivityManagerService.this) { 1364 ProcessRecord app = (ProcessRecord)msg.obj; 1365 if (msg.arg1 != 0) { 1366 if (!app.waitedForDebugger) { 1367 Dialog d = new AppWaitingForDebuggerDialog( 1368 ActivityManagerService.this, 1369 mContext, app); 1370 app.waitDialog = d; 1371 app.waitedForDebugger = true; 1372 d.show(); 1373 } 1374 } else { 1375 if (app.waitDialog != null) { 1376 app.waitDialog.dismiss(); 1377 app.waitDialog = null; 1378 } 1379 } 1380 } 1381 } break; 1382 case SERVICE_TIMEOUT_MSG: { 1383 if (mDidDexOpt) { 1384 mDidDexOpt = false; 1385 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1386 nmsg.obj = msg.obj; 1387 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1388 return; 1389 } 1390 mServices.serviceTimeout((ProcessRecord)msg.obj); 1391 } break; 1392 case UPDATE_TIME_ZONE: { 1393 synchronized (ActivityManagerService.this) { 1394 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1395 ProcessRecord r = mLruProcesses.get(i); 1396 if (r.thread != null) { 1397 try { 1398 r.thread.updateTimeZone(); 1399 } catch (RemoteException ex) { 1400 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1401 } 1402 } 1403 } 1404 } 1405 } break; 1406 case CLEAR_DNS_CACHE_MSG: { 1407 synchronized (ActivityManagerService.this) { 1408 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1409 ProcessRecord r = mLruProcesses.get(i); 1410 if (r.thread != null) { 1411 try { 1412 r.thread.clearDnsCache(); 1413 } catch (RemoteException ex) { 1414 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1415 } 1416 } 1417 } 1418 } 1419 } break; 1420 case UPDATE_HTTP_PROXY_MSG: { 1421 ProxyInfo proxy = (ProxyInfo)msg.obj; 1422 String host = ""; 1423 String port = ""; 1424 String exclList = ""; 1425 Uri pacFileUrl = Uri.EMPTY; 1426 if (proxy != null) { 1427 host = proxy.getHost(); 1428 port = Integer.toString(proxy.getPort()); 1429 exclList = proxy.getExclusionListAsString(); 1430 pacFileUrl = proxy.getPacFileUrl(); 1431 } 1432 synchronized (ActivityManagerService.this) { 1433 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1434 ProcessRecord r = mLruProcesses.get(i); 1435 if (r.thread != null) { 1436 try { 1437 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1438 } catch (RemoteException ex) { 1439 Slog.w(TAG, "Failed to update http proxy for: " + 1440 r.info.processName); 1441 } 1442 } 1443 } 1444 } 1445 } break; 1446 case SHOW_UID_ERROR_MSG: { 1447 String title = "System UIDs Inconsistent"; 1448 String text = "UIDs on the system are inconsistent, you need to wipe your" 1449 + " data partition or your device will be unstable."; 1450 Log.e(TAG, title + ": " + text); 1451 if (mShowDialogs) { 1452 // XXX This is a temporary dialog, no need to localize. 1453 AlertDialog d = new BaseErrorDialog(mContext); 1454 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1455 d.setCancelable(false); 1456 d.setTitle(title); 1457 d.setMessage(text); 1458 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1459 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1460 mUidAlert = d; 1461 d.show(); 1462 } 1463 } break; 1464 case IM_FEELING_LUCKY_MSG: { 1465 if (mUidAlert != null) { 1466 mUidAlert.dismiss(); 1467 mUidAlert = null; 1468 } 1469 } break; 1470 case PROC_START_TIMEOUT_MSG: { 1471 if (mDidDexOpt) { 1472 mDidDexOpt = false; 1473 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1474 nmsg.obj = msg.obj; 1475 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1476 return; 1477 } 1478 ProcessRecord app = (ProcessRecord)msg.obj; 1479 synchronized (ActivityManagerService.this) { 1480 processStartTimedOutLocked(app); 1481 } 1482 } break; 1483 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1484 synchronized (ActivityManagerService.this) { 1485 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1486 } 1487 } break; 1488 case KILL_APPLICATION_MSG: { 1489 synchronized (ActivityManagerService.this) { 1490 int appid = msg.arg1; 1491 boolean restart = (msg.arg2 == 1); 1492 Bundle bundle = (Bundle)msg.obj; 1493 String pkg = bundle.getString("pkg"); 1494 String reason = bundle.getString("reason"); 1495 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1496 false, UserHandle.USER_ALL, reason); 1497 } 1498 } break; 1499 case FINALIZE_PENDING_INTENT_MSG: { 1500 ((PendingIntentRecord)msg.obj).completeFinalize(); 1501 } break; 1502 case POST_HEAVY_NOTIFICATION_MSG: { 1503 INotificationManager inm = NotificationManager.getService(); 1504 if (inm == null) { 1505 return; 1506 } 1507 1508 ActivityRecord root = (ActivityRecord)msg.obj; 1509 ProcessRecord process = root.app; 1510 if (process == null) { 1511 return; 1512 } 1513 1514 try { 1515 Context context = mContext.createPackageContext(process.info.packageName, 0); 1516 String text = mContext.getString(R.string.heavy_weight_notification, 1517 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1518 Notification notification = new Notification(); 1519 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1520 notification.when = 0; 1521 notification.flags = Notification.FLAG_ONGOING_EVENT; 1522 notification.tickerText = text; 1523 notification.defaults = 0; // please be quiet 1524 notification.sound = null; 1525 notification.vibrate = null; 1526 notification.color = mContext.getResources().getColor( 1527 com.android.internal.R.color.system_notification_accent_color); 1528 notification.setLatestEventInfo(context, text, 1529 mContext.getText(R.string.heavy_weight_notification_detail), 1530 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1531 PendingIntent.FLAG_CANCEL_CURRENT, null, 1532 new UserHandle(root.userId))); 1533 1534 try { 1535 int[] outId = new int[1]; 1536 inm.enqueueNotificationWithTag("android", "android", null, 1537 R.string.heavy_weight_notification, 1538 notification, outId, root.userId); 1539 } catch (RuntimeException e) { 1540 Slog.w(ActivityManagerService.TAG, 1541 "Error showing notification for heavy-weight app", e); 1542 } catch (RemoteException e) { 1543 } 1544 } catch (NameNotFoundException e) { 1545 Slog.w(TAG, "Unable to create context for heavy notification", e); 1546 } 1547 } break; 1548 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1549 INotificationManager inm = NotificationManager.getService(); 1550 if (inm == null) { 1551 return; 1552 } 1553 try { 1554 inm.cancelNotificationWithTag("android", null, 1555 R.string.heavy_weight_notification, msg.arg1); 1556 } catch (RuntimeException e) { 1557 Slog.w(ActivityManagerService.TAG, 1558 "Error canceling notification for service", e); 1559 } catch (RemoteException e) { 1560 } 1561 } break; 1562 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1563 synchronized (ActivityManagerService.this) { 1564 checkExcessivePowerUsageLocked(true); 1565 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1566 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1567 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1568 } 1569 } break; 1570 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1571 synchronized (ActivityManagerService.this) { 1572 ActivityRecord ar = (ActivityRecord)msg.obj; 1573 if (mCompatModeDialog != null) { 1574 if (mCompatModeDialog.mAppInfo.packageName.equals( 1575 ar.info.applicationInfo.packageName)) { 1576 return; 1577 } 1578 mCompatModeDialog.dismiss(); 1579 mCompatModeDialog = null; 1580 } 1581 if (ar != null && false) { 1582 if (mCompatModePackages.getPackageAskCompatModeLocked( 1583 ar.packageName)) { 1584 int mode = mCompatModePackages.computeCompatModeLocked( 1585 ar.info.applicationInfo); 1586 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1587 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1588 mCompatModeDialog = new CompatModeDialog( 1589 ActivityManagerService.this, mContext, 1590 ar.info.applicationInfo); 1591 mCompatModeDialog.show(); 1592 } 1593 } 1594 } 1595 } 1596 break; 1597 } 1598 case DISPATCH_PROCESSES_CHANGED: { 1599 dispatchProcessesChanged(); 1600 break; 1601 } 1602 case DISPATCH_PROCESS_DIED: { 1603 final int pid = msg.arg1; 1604 final int uid = msg.arg2; 1605 dispatchProcessDied(pid, uid); 1606 break; 1607 } 1608 case REPORT_MEM_USAGE_MSG: { 1609 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1610 Thread thread = new Thread() { 1611 @Override public void run() { 1612 final SparseArray<ProcessMemInfo> infoMap 1613 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1614 for (int i=0, N=memInfos.size(); i<N; i++) { 1615 ProcessMemInfo mi = memInfos.get(i); 1616 infoMap.put(mi.pid, mi); 1617 } 1618 updateCpuStatsNow(); 1619 synchronized (mProcessCpuTracker) { 1620 final int N = mProcessCpuTracker.countStats(); 1621 for (int i=0; i<N; i++) { 1622 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1623 if (st.vsize > 0) { 1624 long pss = Debug.getPss(st.pid, null); 1625 if (pss > 0) { 1626 if (infoMap.indexOfKey(st.pid) < 0) { 1627 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1628 ProcessList.NATIVE_ADJ, -1, "native", null); 1629 mi.pss = pss; 1630 memInfos.add(mi); 1631 } 1632 } 1633 } 1634 } 1635 } 1636 1637 long totalPss = 0; 1638 for (int i=0, N=memInfos.size(); i<N; i++) { 1639 ProcessMemInfo mi = memInfos.get(i); 1640 if (mi.pss == 0) { 1641 mi.pss = Debug.getPss(mi.pid, null); 1642 } 1643 totalPss += mi.pss; 1644 } 1645 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1646 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1647 if (lhs.oomAdj != rhs.oomAdj) { 1648 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1649 } 1650 if (lhs.pss != rhs.pss) { 1651 return lhs.pss < rhs.pss ? 1 : -1; 1652 } 1653 return 0; 1654 } 1655 }); 1656 1657 StringBuilder tag = new StringBuilder(128); 1658 StringBuilder stack = new StringBuilder(128); 1659 tag.append("Low on memory -- "); 1660 appendMemBucket(tag, totalPss, "total", false); 1661 appendMemBucket(stack, totalPss, "total", true); 1662 1663 StringBuilder logBuilder = new StringBuilder(1024); 1664 logBuilder.append("Low on memory:\n"); 1665 1666 boolean firstLine = true; 1667 int lastOomAdj = Integer.MIN_VALUE; 1668 for (int i=0, N=memInfos.size(); i<N; i++) { 1669 ProcessMemInfo mi = memInfos.get(i); 1670 1671 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1672 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1673 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1674 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1675 if (lastOomAdj != mi.oomAdj) { 1676 lastOomAdj = mi.oomAdj; 1677 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1678 tag.append(" / "); 1679 } 1680 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1681 if (firstLine) { 1682 stack.append(":"); 1683 firstLine = false; 1684 } 1685 stack.append("\n\t at "); 1686 } else { 1687 stack.append("$"); 1688 } 1689 } else { 1690 tag.append(" "); 1691 stack.append("$"); 1692 } 1693 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1694 appendMemBucket(tag, mi.pss, mi.name, false); 1695 } 1696 appendMemBucket(stack, mi.pss, mi.name, true); 1697 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1698 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1699 stack.append("("); 1700 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1701 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1702 stack.append(DUMP_MEM_OOM_LABEL[k]); 1703 stack.append(":"); 1704 stack.append(DUMP_MEM_OOM_ADJ[k]); 1705 } 1706 } 1707 stack.append(")"); 1708 } 1709 } 1710 1711 logBuilder.append(" "); 1712 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1713 logBuilder.append(' '); 1714 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1715 logBuilder.append(' '); 1716 ProcessList.appendRamKb(logBuilder, mi.pss); 1717 logBuilder.append(" kB: "); 1718 logBuilder.append(mi.name); 1719 logBuilder.append(" ("); 1720 logBuilder.append(mi.pid); 1721 logBuilder.append(") "); 1722 logBuilder.append(mi.adjType); 1723 logBuilder.append('\n'); 1724 if (mi.adjReason != null) { 1725 logBuilder.append(" "); 1726 logBuilder.append(mi.adjReason); 1727 logBuilder.append('\n'); 1728 } 1729 } 1730 1731 logBuilder.append(" "); 1732 ProcessList.appendRamKb(logBuilder, totalPss); 1733 logBuilder.append(" kB: TOTAL\n"); 1734 1735 long[] infos = new long[Debug.MEMINFO_COUNT]; 1736 Debug.getMemInfo(infos); 1737 logBuilder.append(" MemInfo: "); 1738 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1739 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1740 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1741 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1742 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1743 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1744 logBuilder.append(" ZRAM: "); 1745 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1746 logBuilder.append(" kB RAM, "); 1747 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1748 logBuilder.append(" kB swap total, "); 1749 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1750 logBuilder.append(" kB swap free\n"); 1751 } 1752 Slog.i(TAG, logBuilder.toString()); 1753 1754 StringBuilder dropBuilder = new StringBuilder(1024); 1755 /* 1756 StringWriter oomSw = new StringWriter(); 1757 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1758 StringWriter catSw = new StringWriter(); 1759 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1760 String[] emptyArgs = new String[] { }; 1761 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1762 oomPw.flush(); 1763 String oomString = oomSw.toString(); 1764 */ 1765 dropBuilder.append(stack); 1766 dropBuilder.append('\n'); 1767 dropBuilder.append('\n'); 1768 dropBuilder.append(logBuilder); 1769 dropBuilder.append('\n'); 1770 /* 1771 dropBuilder.append(oomString); 1772 dropBuilder.append('\n'); 1773 */ 1774 StringWriter catSw = new StringWriter(); 1775 synchronized (ActivityManagerService.this) { 1776 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1777 String[] emptyArgs = new String[] { }; 1778 catPw.println(); 1779 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1780 catPw.println(); 1781 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1782 false, false, null); 1783 catPw.println(); 1784 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1785 catPw.flush(); 1786 } 1787 dropBuilder.append(catSw.toString()); 1788 addErrorToDropBox("lowmem", null, "system_server", null, 1789 null, tag.toString(), dropBuilder.toString(), null, null); 1790 //Slog.i(TAG, "Sent to dropbox:"); 1791 //Slog.i(TAG, dropBuilder.toString()); 1792 synchronized (ActivityManagerService.this) { 1793 long now = SystemClock.uptimeMillis(); 1794 if (mLastMemUsageReportTime < now) { 1795 mLastMemUsageReportTime = now; 1796 } 1797 } 1798 } 1799 }; 1800 thread.start(); 1801 break; 1802 } 1803 case START_USER_SWITCH_MSG: { 1804 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1805 break; 1806 } 1807 case REPORT_USER_SWITCH_MSG: { 1808 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1809 break; 1810 } 1811 case CONTINUE_USER_SWITCH_MSG: { 1812 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1813 break; 1814 } 1815 case USER_SWITCH_TIMEOUT_MSG: { 1816 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1817 break; 1818 } 1819 case IMMERSIVE_MODE_LOCK_MSG: { 1820 final boolean nextState = (msg.arg1 != 0); 1821 if (mUpdateLock.isHeld() != nextState) { 1822 if (DEBUG_IMMERSIVE) { 1823 final ActivityRecord r = (ActivityRecord) msg.obj; 1824 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1825 } 1826 if (nextState) { 1827 mUpdateLock.acquire(); 1828 } else { 1829 mUpdateLock.release(); 1830 } 1831 } 1832 break; 1833 } 1834 case PERSIST_URI_GRANTS_MSG: { 1835 writeGrantedUriPermissions(); 1836 break; 1837 } 1838 case REQUEST_ALL_PSS_MSG: { 1839 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1840 break; 1841 } 1842 case START_PROFILES_MSG: { 1843 synchronized (ActivityManagerService.this) { 1844 startProfilesLocked(); 1845 } 1846 break; 1847 } 1848 case UPDATE_TIME: { 1849 synchronized (ActivityManagerService.this) { 1850 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1851 ProcessRecord r = mLruProcesses.get(i); 1852 if (r.thread != null) { 1853 try { 1854 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1855 } catch (RemoteException ex) { 1856 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1857 } 1858 } 1859 } 1860 } 1861 break; 1862 } 1863 case SYSTEM_USER_START_MSG: { 1864 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1865 Integer.toString(msg.arg1), msg.arg1); 1866 mSystemServiceManager.startUser(msg.arg1); 1867 break; 1868 } 1869 case SYSTEM_USER_CURRENT_MSG: { 1870 mBatteryStatsService.noteEvent( 1871 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1872 Integer.toString(msg.arg2), msg.arg2); 1873 mBatteryStatsService.noteEvent( 1874 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1875 Integer.toString(msg.arg1), msg.arg1); 1876 mSystemServiceManager.switchUser(msg.arg1); 1877 mLockToAppRequest.clearPrompt(); 1878 break; 1879 } 1880 case ENTER_ANIMATION_COMPLETE_MSG: { 1881 synchronized (ActivityManagerService.this) { 1882 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1883 if (r != null && r.app != null && r.app.thread != null) { 1884 try { 1885 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1886 } catch (RemoteException e) { 1887 } 1888 } 1889 } 1890 break; 1891 } 1892 case FINISH_BOOTING_MSG: { 1893 if (msg.arg1 != 0) { 1894 finishBooting(); 1895 } 1896 if (msg.arg2 != 0) { 1897 enableScreenAfterBoot(); 1898 } 1899 break; 1900 } 1901 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1902 try { 1903 Locale l = (Locale) msg.obj; 1904 IBinder service = ServiceManager.getService("mount"); 1905 IMountService mountService = IMountService.Stub.asInterface(service); 1906 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1907 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1908 } catch (RemoteException e) { 1909 Log.e(TAG, "Error storing locale for decryption UI", e); 1910 } 1911 break; 1912 } 1913 } 1914 } 1915 }; 1916 1917 static final int COLLECT_PSS_BG_MSG = 1; 1918 1919 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1920 @Override 1921 public void handleMessage(Message msg) { 1922 switch (msg.what) { 1923 case COLLECT_PSS_BG_MSG: { 1924 long start = SystemClock.uptimeMillis(); 1925 MemInfoReader memInfo = null; 1926 synchronized (ActivityManagerService.this) { 1927 if (mFullPssPending) { 1928 mFullPssPending = false; 1929 memInfo = new MemInfoReader(); 1930 } 1931 } 1932 if (memInfo != null) { 1933 updateCpuStatsNow(); 1934 long nativeTotalPss = 0; 1935 synchronized (mProcessCpuTracker) { 1936 final int N = mProcessCpuTracker.countStats(); 1937 for (int j=0; j<N; j++) { 1938 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1939 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1940 // This is definitely an application process; skip it. 1941 continue; 1942 } 1943 synchronized (mPidsSelfLocked) { 1944 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1945 // This is one of our own processes; skip it. 1946 continue; 1947 } 1948 } 1949 nativeTotalPss += Debug.getPss(st.pid, null); 1950 } 1951 } 1952 memInfo.readMemInfo(); 1953 synchronized (ActivityManagerService.this) { 1954 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1955 + (SystemClock.uptimeMillis()-start) + "ms"); 1956 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1957 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1958 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1959 +memInfo.getSlabSizeKb(), 1960 nativeTotalPss); 1961 } 1962 } 1963 1964 int i=0, num=0; 1965 long[] tmp = new long[1]; 1966 do { 1967 ProcessRecord proc; 1968 int procState; 1969 int pid; 1970 synchronized (ActivityManagerService.this) { 1971 if (i >= mPendingPssProcesses.size()) { 1972 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1973 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1974 mPendingPssProcesses.clear(); 1975 return; 1976 } 1977 proc = mPendingPssProcesses.get(i); 1978 procState = proc.pssProcState; 1979 if (proc.thread != null && procState == proc.setProcState) { 1980 pid = proc.pid; 1981 } else { 1982 proc = null; 1983 pid = 0; 1984 } 1985 i++; 1986 } 1987 if (proc != null) { 1988 long pss = Debug.getPss(pid, tmp); 1989 synchronized (ActivityManagerService.this) { 1990 if (proc.thread != null && proc.setProcState == procState 1991 && proc.pid == pid) { 1992 num++; 1993 proc.lastPssTime = SystemClock.uptimeMillis(); 1994 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1995 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1996 + ": " + pss + " lastPss=" + proc.lastPss 1997 + " state=" + ProcessList.makeProcStateString(procState)); 1998 if (proc.initialIdlePss == 0) { 1999 proc.initialIdlePss = pss; 2000 } 2001 proc.lastPss = pss; 2002 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2003 proc.lastCachedPss = pss; 2004 } 2005 } 2006 } 2007 } 2008 } while (true); 2009 } 2010 } 2011 } 2012 }; 2013 2014 /** 2015 * Monitor for package changes and update our internal state. 2016 */ 2017 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2018 @Override 2019 public void onPackageRemoved(String packageName, int uid) { 2020 // Remove all tasks with activities in the specified package from the list of recent tasks 2021 final int eventUserId = getChangingUserId(); 2022 synchronized (ActivityManagerService.this) { 2023 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2024 TaskRecord tr = mRecentTasks.get(i); 2025 if (tr.userId != eventUserId) continue; 2026 2027 ComponentName cn = tr.intent.getComponent(); 2028 if (cn != null && cn.getPackageName().equals(packageName)) { 2029 // If the package name matches, remove the task and kill the process 2030 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2031 } 2032 } 2033 } 2034 } 2035 2036 @Override 2037 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2038 onPackageModified(packageName); 2039 return true; 2040 } 2041 2042 @Override 2043 public void onPackageModified(String packageName) { 2044 final int eventUserId = getChangingUserId(); 2045 final IPackageManager pm = AppGlobals.getPackageManager(); 2046 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2047 new ArrayList<Pair<Intent, Integer>>(); 2048 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2049 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2050 // Copy the list of recent tasks so that we don't hold onto the lock on 2051 // ActivityManagerService for long periods while checking if components exist. 2052 synchronized (ActivityManagerService.this) { 2053 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2054 TaskRecord tr = mRecentTasks.get(i); 2055 if (tr.userId != eventUserId) continue; 2056 2057 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2058 } 2059 } 2060 // Check the recent tasks and filter out all tasks with components that no longer exist. 2061 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2062 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2063 ComponentName cn = p.first.getComponent(); 2064 if (cn != null && cn.getPackageName().equals(packageName)) { 2065 if (componentsKnownToExist.contains(cn)) { 2066 // If we know that the component still exists in the package, then skip 2067 continue; 2068 } 2069 try { 2070 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2071 if (info != null) { 2072 componentsKnownToExist.add(cn); 2073 } else { 2074 tasksToRemove.add(p.second); 2075 } 2076 } catch (RemoteException e) { 2077 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2078 } 2079 } 2080 } 2081 // Prune all the tasks with removed components from the list of recent tasks 2082 synchronized (ActivityManagerService.this) { 2083 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2084 // Remove the task but don't kill the process (since other components in that 2085 // package may still be running and in the background) 2086 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2087 } 2088 } 2089 } 2090 2091 @Override 2092 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2093 // Force stop the specified packages 2094 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2095 if (packages != null) { 2096 for (String pkg : packages) { 2097 synchronized (ActivityManagerService.this) { 2098 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2099 userId, "finished booting")) { 2100 return true; 2101 } 2102 } 2103 } 2104 } 2105 return false; 2106 } 2107 }; 2108 2109 public void setSystemProcess() { 2110 try { 2111 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2112 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2113 ServiceManager.addService("meminfo", new MemBinder(this)); 2114 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2115 ServiceManager.addService("dbinfo", new DbBinder(this)); 2116 if (MONITOR_CPU_USAGE) { 2117 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2118 } 2119 ServiceManager.addService("permission", new PermissionController(this)); 2120 2121 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2122 "android", STOCK_PM_FLAGS); 2123 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2124 2125 synchronized (this) { 2126 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2127 app.persistent = true; 2128 app.pid = MY_PID; 2129 app.maxAdj = ProcessList.SYSTEM_ADJ; 2130 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2131 mProcessNames.put(app.processName, app.uid, app); 2132 synchronized (mPidsSelfLocked) { 2133 mPidsSelfLocked.put(app.pid, app); 2134 } 2135 updateLruProcessLocked(app, false, null); 2136 updateOomAdjLocked(); 2137 } 2138 } catch (PackageManager.NameNotFoundException e) { 2139 throw new RuntimeException( 2140 "Unable to find android system package", e); 2141 } 2142 } 2143 2144 public void setWindowManager(WindowManagerService wm) { 2145 mWindowManager = wm; 2146 mStackSupervisor.setWindowManager(wm); 2147 } 2148 2149 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2150 mUsageStatsService = usageStatsManager; 2151 } 2152 2153 public void startObservingNativeCrashes() { 2154 final NativeCrashListener ncl = new NativeCrashListener(this); 2155 ncl.start(); 2156 } 2157 2158 public IAppOpsService getAppOpsService() { 2159 return mAppOpsService; 2160 } 2161 2162 static class MemBinder extends Binder { 2163 ActivityManagerService mActivityManagerService; 2164 MemBinder(ActivityManagerService activityManagerService) { 2165 mActivityManagerService = activityManagerService; 2166 } 2167 2168 @Override 2169 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2170 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2171 != PackageManager.PERMISSION_GRANTED) { 2172 pw.println("Permission Denial: can't dump meminfo from from pid=" 2173 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2174 + " without permission " + android.Manifest.permission.DUMP); 2175 return; 2176 } 2177 2178 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2179 } 2180 } 2181 2182 static class GraphicsBinder extends Binder { 2183 ActivityManagerService mActivityManagerService; 2184 GraphicsBinder(ActivityManagerService activityManagerService) { 2185 mActivityManagerService = activityManagerService; 2186 } 2187 2188 @Override 2189 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2190 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2191 != PackageManager.PERMISSION_GRANTED) { 2192 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2193 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2194 + " without permission " + android.Manifest.permission.DUMP); 2195 return; 2196 } 2197 2198 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2199 } 2200 } 2201 2202 static class DbBinder extends Binder { 2203 ActivityManagerService mActivityManagerService; 2204 DbBinder(ActivityManagerService activityManagerService) { 2205 mActivityManagerService = activityManagerService; 2206 } 2207 2208 @Override 2209 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2210 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2211 != PackageManager.PERMISSION_GRANTED) { 2212 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2213 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2214 + " without permission " + android.Manifest.permission.DUMP); 2215 return; 2216 } 2217 2218 mActivityManagerService.dumpDbInfo(fd, pw, args); 2219 } 2220 } 2221 2222 static class CpuBinder extends Binder { 2223 ActivityManagerService mActivityManagerService; 2224 CpuBinder(ActivityManagerService activityManagerService) { 2225 mActivityManagerService = activityManagerService; 2226 } 2227 2228 @Override 2229 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2230 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2231 != PackageManager.PERMISSION_GRANTED) { 2232 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2233 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2234 + " without permission " + android.Manifest.permission.DUMP); 2235 return; 2236 } 2237 2238 synchronized (mActivityManagerService.mProcessCpuTracker) { 2239 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2240 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2241 SystemClock.uptimeMillis())); 2242 } 2243 } 2244 } 2245 2246 public static final class Lifecycle extends SystemService { 2247 private final ActivityManagerService mService; 2248 2249 public Lifecycle(Context context) { 2250 super(context); 2251 mService = new ActivityManagerService(context); 2252 } 2253 2254 @Override 2255 public void onStart() { 2256 mService.start(); 2257 } 2258 2259 public ActivityManagerService getService() { 2260 return mService; 2261 } 2262 } 2263 2264 // Note: This method is invoked on the main thread but may need to attach various 2265 // handlers to other threads. So take care to be explicit about the looper. 2266 public ActivityManagerService(Context systemContext) { 2267 mContext = systemContext; 2268 mFactoryTest = FactoryTest.getMode(); 2269 mSystemThread = ActivityThread.currentActivityThread(); 2270 2271 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2272 2273 mHandlerThread = new ServiceThread(TAG, 2274 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2275 mHandlerThread.start(); 2276 mHandler = new MainHandler(mHandlerThread.getLooper()); 2277 2278 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2279 "foreground", BROADCAST_FG_TIMEOUT, false); 2280 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2281 "background", BROADCAST_BG_TIMEOUT, true); 2282 mBroadcastQueues[0] = mFgBroadcastQueue; 2283 mBroadcastQueues[1] = mBgBroadcastQueue; 2284 2285 mServices = new ActiveServices(this); 2286 mProviderMap = new ProviderMap(this); 2287 2288 // TODO: Move creation of battery stats service outside of activity manager service. 2289 File dataDir = Environment.getDataDirectory(); 2290 File systemDir = new File(dataDir, "system"); 2291 systemDir.mkdirs(); 2292 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2293 mBatteryStatsService.getActiveStatistics().readLocked(); 2294 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2295 mOnBattery = DEBUG_POWER ? true 2296 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2297 mBatteryStatsService.getActiveStatistics().setCallback(this); 2298 2299 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2300 2301 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2302 2303 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2304 2305 // User 0 is the first and only user that runs at boot. 2306 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2307 mUserLru.add(Integer.valueOf(0)); 2308 updateStartedUserArrayLocked(); 2309 2310 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2311 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2312 2313 mConfiguration.setToDefaults(); 2314 mConfiguration.setLocale(Locale.getDefault()); 2315 2316 mConfigurationSeq = mConfiguration.seq = 1; 2317 mProcessCpuTracker.init(); 2318 2319 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2320 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2321 mStackSupervisor = new ActivityStackSupervisor(this); 2322 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2323 2324 mProcessCpuThread = new Thread("CpuTracker") { 2325 @Override 2326 public void run() { 2327 while (true) { 2328 try { 2329 try { 2330 synchronized(this) { 2331 final long now = SystemClock.uptimeMillis(); 2332 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2333 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2334 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2335 // + ", write delay=" + nextWriteDelay); 2336 if (nextWriteDelay < nextCpuDelay) { 2337 nextCpuDelay = nextWriteDelay; 2338 } 2339 if (nextCpuDelay > 0) { 2340 mProcessCpuMutexFree.set(true); 2341 this.wait(nextCpuDelay); 2342 } 2343 } 2344 } catch (InterruptedException e) { 2345 } 2346 updateCpuStatsNow(); 2347 } catch (Exception e) { 2348 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2349 } 2350 } 2351 } 2352 }; 2353 2354 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2355 2356 Watchdog.getInstance().addMonitor(this); 2357 Watchdog.getInstance().addThread(mHandler); 2358 } 2359 2360 public void setSystemServiceManager(SystemServiceManager mgr) { 2361 mSystemServiceManager = mgr; 2362 } 2363 2364 public void setInstaller(Installer installer) { 2365 mInstaller = installer; 2366 } 2367 2368 private void start() { 2369 Process.removeAllProcessGroups(); 2370 mProcessCpuThread.start(); 2371 2372 mBatteryStatsService.publish(mContext); 2373 mAppOpsService.publish(mContext); 2374 Slog.d("AppOps", "AppOpsService published"); 2375 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2376 } 2377 2378 public void initPowerManagement() { 2379 mStackSupervisor.initPowerManagement(); 2380 mBatteryStatsService.initPowerManagement(); 2381 } 2382 2383 @Override 2384 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2385 throws RemoteException { 2386 if (code == SYSPROPS_TRANSACTION) { 2387 // We need to tell all apps about the system property change. 2388 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2389 synchronized(this) { 2390 final int NP = mProcessNames.getMap().size(); 2391 for (int ip=0; ip<NP; ip++) { 2392 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2393 final int NA = apps.size(); 2394 for (int ia=0; ia<NA; ia++) { 2395 ProcessRecord app = apps.valueAt(ia); 2396 if (app.thread != null) { 2397 procs.add(app.thread.asBinder()); 2398 } 2399 } 2400 } 2401 } 2402 2403 int N = procs.size(); 2404 for (int i=0; i<N; i++) { 2405 Parcel data2 = Parcel.obtain(); 2406 try { 2407 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2408 } catch (RemoteException e) { 2409 } 2410 data2.recycle(); 2411 } 2412 } 2413 try { 2414 return super.onTransact(code, data, reply, flags); 2415 } catch (RuntimeException e) { 2416 // The activity manager only throws security exceptions, so let's 2417 // log all others. 2418 if (!(e instanceof SecurityException)) { 2419 Slog.wtf(TAG, "Activity Manager Crash", e); 2420 } 2421 throw e; 2422 } 2423 } 2424 2425 void updateCpuStats() { 2426 final long now = SystemClock.uptimeMillis(); 2427 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2428 return; 2429 } 2430 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2431 synchronized (mProcessCpuThread) { 2432 mProcessCpuThread.notify(); 2433 } 2434 } 2435 } 2436 2437 void updateCpuStatsNow() { 2438 synchronized (mProcessCpuTracker) { 2439 mProcessCpuMutexFree.set(false); 2440 final long now = SystemClock.uptimeMillis(); 2441 boolean haveNewCpuStats = false; 2442 2443 if (MONITOR_CPU_USAGE && 2444 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2445 mLastCpuTime.set(now); 2446 haveNewCpuStats = true; 2447 mProcessCpuTracker.update(); 2448 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2449 //Slog.i(TAG, "Total CPU usage: " 2450 // + mProcessCpu.getTotalCpuPercent() + "%"); 2451 2452 // Slog the cpu usage if the property is set. 2453 if ("true".equals(SystemProperties.get("events.cpu"))) { 2454 int user = mProcessCpuTracker.getLastUserTime(); 2455 int system = mProcessCpuTracker.getLastSystemTime(); 2456 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2457 int irq = mProcessCpuTracker.getLastIrqTime(); 2458 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2459 int idle = mProcessCpuTracker.getLastIdleTime(); 2460 2461 int total = user + system + iowait + irq + softIrq + idle; 2462 if (total == 0) total = 1; 2463 2464 EventLog.writeEvent(EventLogTags.CPU, 2465 ((user+system+iowait+irq+softIrq) * 100) / total, 2466 (user * 100) / total, 2467 (system * 100) / total, 2468 (iowait * 100) / total, 2469 (irq * 100) / total, 2470 (softIrq * 100) / total); 2471 } 2472 } 2473 2474 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2475 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2476 synchronized(bstats) { 2477 synchronized(mPidsSelfLocked) { 2478 if (haveNewCpuStats) { 2479 if (mOnBattery) { 2480 int perc = bstats.startAddingCpuLocked(); 2481 int totalUTime = 0; 2482 int totalSTime = 0; 2483 final int N = mProcessCpuTracker.countStats(); 2484 for (int i=0; i<N; i++) { 2485 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2486 if (!st.working) { 2487 continue; 2488 } 2489 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2490 int otherUTime = (st.rel_utime*perc)/100; 2491 int otherSTime = (st.rel_stime*perc)/100; 2492 totalUTime += otherUTime; 2493 totalSTime += otherSTime; 2494 if (pr != null) { 2495 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2496 if (ps == null || !ps.isActive()) { 2497 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2498 pr.info.uid, pr.processName); 2499 } 2500 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2501 st.rel_stime-otherSTime); 2502 ps.addSpeedStepTimes(cpuSpeedTimes); 2503 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2504 } else { 2505 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2506 if (ps == null || !ps.isActive()) { 2507 st.batteryStats = ps = bstats.getProcessStatsLocked( 2508 bstats.mapUid(st.uid), st.name); 2509 } 2510 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2511 st.rel_stime-otherSTime); 2512 ps.addSpeedStepTimes(cpuSpeedTimes); 2513 } 2514 } 2515 bstats.finishAddingCpuLocked(perc, totalUTime, 2516 totalSTime, cpuSpeedTimes); 2517 } 2518 } 2519 } 2520 2521 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2522 mLastWriteTime = now; 2523 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2524 } 2525 } 2526 } 2527 } 2528 2529 @Override 2530 public void batteryNeedsCpuUpdate() { 2531 updateCpuStatsNow(); 2532 } 2533 2534 @Override 2535 public void batteryPowerChanged(boolean onBattery) { 2536 // When plugging in, update the CPU stats first before changing 2537 // the plug state. 2538 updateCpuStatsNow(); 2539 synchronized (this) { 2540 synchronized(mPidsSelfLocked) { 2541 mOnBattery = DEBUG_POWER ? true : onBattery; 2542 } 2543 } 2544 } 2545 2546 /** 2547 * Initialize the application bind args. These are passed to each 2548 * process when the bindApplication() IPC is sent to the process. They're 2549 * lazily setup to make sure the services are running when they're asked for. 2550 */ 2551 private HashMap<String, IBinder> getCommonServicesLocked() { 2552 if (mAppBindArgs == null) { 2553 mAppBindArgs = new HashMap<String, IBinder>(); 2554 2555 // Setup the application init args 2556 mAppBindArgs.put("package", ServiceManager.getService("package")); 2557 mAppBindArgs.put("window", ServiceManager.getService("window")); 2558 mAppBindArgs.put(Context.ALARM_SERVICE, 2559 ServiceManager.getService(Context.ALARM_SERVICE)); 2560 } 2561 return mAppBindArgs; 2562 } 2563 2564 final void setFocusedActivityLocked(ActivityRecord r) { 2565 if (mFocusedActivity != r) { 2566 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2567 mFocusedActivity = r; 2568 if (r.task != null && r.task.voiceInteractor != null) { 2569 startRunningVoiceLocked(); 2570 } else { 2571 finishRunningVoiceLocked(); 2572 } 2573 mStackSupervisor.setFocusedStack(r); 2574 if (r != null) { 2575 mWindowManager.setFocusedApp(r.appToken, true); 2576 } 2577 applyUpdateLockStateLocked(r); 2578 } 2579 } 2580 2581 final void clearFocusedActivity(ActivityRecord r) { 2582 if (mFocusedActivity == r) { 2583 mFocusedActivity = null; 2584 } 2585 } 2586 2587 @Override 2588 public void setFocusedStack(int stackId) { 2589 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2590 synchronized (ActivityManagerService.this) { 2591 ActivityStack stack = mStackSupervisor.getStack(stackId); 2592 if (stack != null) { 2593 ActivityRecord r = stack.topRunningActivityLocked(null); 2594 if (r != null) { 2595 setFocusedActivityLocked(r); 2596 } 2597 } 2598 } 2599 } 2600 2601 @Override 2602 public void notifyActivityDrawn(IBinder token) { 2603 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2604 synchronized (this) { 2605 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2606 if (r != null) { 2607 r.task.stack.notifyActivityDrawnLocked(r); 2608 } 2609 } 2610 } 2611 2612 final void applyUpdateLockStateLocked(ActivityRecord r) { 2613 // Modifications to the UpdateLock state are done on our handler, outside 2614 // the activity manager's locks. The new state is determined based on the 2615 // state *now* of the relevant activity record. The object is passed to 2616 // the handler solely for logging detail, not to be consulted/modified. 2617 final boolean nextState = r != null && r.immersive; 2618 mHandler.sendMessage( 2619 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2620 } 2621 2622 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2623 Message msg = Message.obtain(); 2624 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2625 msg.obj = r.task.askedCompatMode ? null : r; 2626 mHandler.sendMessage(msg); 2627 } 2628 2629 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2630 String what, Object obj, ProcessRecord srcApp) { 2631 app.lastActivityTime = now; 2632 2633 if (app.activities.size() > 0) { 2634 // Don't want to touch dependent processes that are hosting activities. 2635 return index; 2636 } 2637 2638 int lrui = mLruProcesses.lastIndexOf(app); 2639 if (lrui < 0) { 2640 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2641 + what + " " + obj + " from " + srcApp); 2642 return index; 2643 } 2644 2645 if (lrui >= index) { 2646 // Don't want to cause this to move dependent processes *back* in the 2647 // list as if they were less frequently used. 2648 return index; 2649 } 2650 2651 if (lrui >= mLruProcessActivityStart) { 2652 // Don't want to touch dependent processes that are hosting activities. 2653 return index; 2654 } 2655 2656 mLruProcesses.remove(lrui); 2657 if (index > 0) { 2658 index--; 2659 } 2660 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2661 + " in LRU list: " + app); 2662 mLruProcesses.add(index, app); 2663 return index; 2664 } 2665 2666 final void removeLruProcessLocked(ProcessRecord app) { 2667 int lrui = mLruProcesses.lastIndexOf(app); 2668 if (lrui >= 0) { 2669 if (!app.killed) { 2670 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2671 Process.killProcessQuiet(app.pid); 2672 Process.killProcessGroup(app.info.uid, app.pid); 2673 } 2674 if (lrui <= mLruProcessActivityStart) { 2675 mLruProcessActivityStart--; 2676 } 2677 if (lrui <= mLruProcessServiceStart) { 2678 mLruProcessServiceStart--; 2679 } 2680 mLruProcesses.remove(lrui); 2681 } 2682 } 2683 2684 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2685 ProcessRecord client) { 2686 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2687 || app.treatLikeActivity; 2688 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2689 if (!activityChange && hasActivity) { 2690 // The process has activities, so we are only allowing activity-based adjustments 2691 // to move it. It should be kept in the front of the list with other 2692 // processes that have activities, and we don't want those to change their 2693 // order except due to activity operations. 2694 return; 2695 } 2696 2697 mLruSeq++; 2698 final long now = SystemClock.uptimeMillis(); 2699 app.lastActivityTime = now; 2700 2701 // First a quick reject: if the app is already at the position we will 2702 // put it, then there is nothing to do. 2703 if (hasActivity) { 2704 final int N = mLruProcesses.size(); 2705 if (N > 0 && mLruProcesses.get(N-1) == app) { 2706 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2707 return; 2708 } 2709 } else { 2710 if (mLruProcessServiceStart > 0 2711 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2712 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2713 return; 2714 } 2715 } 2716 2717 int lrui = mLruProcesses.lastIndexOf(app); 2718 2719 if (app.persistent && lrui >= 0) { 2720 // We don't care about the position of persistent processes, as long as 2721 // they are in the list. 2722 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2723 return; 2724 } 2725 2726 /* In progress: compute new position first, so we can avoid doing work 2727 if the process is not actually going to move. Not yet working. 2728 int addIndex; 2729 int nextIndex; 2730 boolean inActivity = false, inService = false; 2731 if (hasActivity) { 2732 // Process has activities, put it at the very tipsy-top. 2733 addIndex = mLruProcesses.size(); 2734 nextIndex = mLruProcessServiceStart; 2735 inActivity = true; 2736 } else if (hasService) { 2737 // Process has services, put it at the top of the service list. 2738 addIndex = mLruProcessActivityStart; 2739 nextIndex = mLruProcessServiceStart; 2740 inActivity = true; 2741 inService = true; 2742 } else { 2743 // Process not otherwise of interest, it goes to the top of the non-service area. 2744 addIndex = mLruProcessServiceStart; 2745 if (client != null) { 2746 int clientIndex = mLruProcesses.lastIndexOf(client); 2747 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2748 + app); 2749 if (clientIndex >= 0 && addIndex > clientIndex) { 2750 addIndex = clientIndex; 2751 } 2752 } 2753 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2754 } 2755 2756 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2757 + mLruProcessActivityStart + "): " + app); 2758 */ 2759 2760 if (lrui >= 0) { 2761 if (lrui < mLruProcessActivityStart) { 2762 mLruProcessActivityStart--; 2763 } 2764 if (lrui < mLruProcessServiceStart) { 2765 mLruProcessServiceStart--; 2766 } 2767 /* 2768 if (addIndex > lrui) { 2769 addIndex--; 2770 } 2771 if (nextIndex > lrui) { 2772 nextIndex--; 2773 } 2774 */ 2775 mLruProcesses.remove(lrui); 2776 } 2777 2778 /* 2779 mLruProcesses.add(addIndex, app); 2780 if (inActivity) { 2781 mLruProcessActivityStart++; 2782 } 2783 if (inService) { 2784 mLruProcessActivityStart++; 2785 } 2786 */ 2787 2788 int nextIndex; 2789 if (hasActivity) { 2790 final int N = mLruProcesses.size(); 2791 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2792 // Process doesn't have activities, but has clients with 2793 // activities... move it up, but one below the top (the top 2794 // should always have a real activity). 2795 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2796 mLruProcesses.add(N-1, app); 2797 // To keep it from spamming the LRU list (by making a bunch of clients), 2798 // we will push down any other entries owned by the app. 2799 final int uid = app.info.uid; 2800 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2801 ProcessRecord subProc = mLruProcesses.get(i); 2802 if (subProc.info.uid == uid) { 2803 // We want to push this one down the list. If the process after 2804 // it is for the same uid, however, don't do so, because we don't 2805 // want them internally to be re-ordered. 2806 if (mLruProcesses.get(i-1).info.uid != uid) { 2807 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2808 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2809 ProcessRecord tmp = mLruProcesses.get(i); 2810 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2811 mLruProcesses.set(i-1, tmp); 2812 i--; 2813 } 2814 } else { 2815 // A gap, we can stop here. 2816 break; 2817 } 2818 } 2819 } else { 2820 // Process has activities, put it at the very tipsy-top. 2821 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2822 mLruProcesses.add(app); 2823 } 2824 nextIndex = mLruProcessServiceStart; 2825 } else if (hasService) { 2826 // Process has services, put it at the top of the service list. 2827 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2828 mLruProcesses.add(mLruProcessActivityStart, app); 2829 nextIndex = mLruProcessServiceStart; 2830 mLruProcessActivityStart++; 2831 } else { 2832 // Process not otherwise of interest, it goes to the top of the non-service area. 2833 int index = mLruProcessServiceStart; 2834 if (client != null) { 2835 // If there is a client, don't allow the process to be moved up higher 2836 // in the list than that client. 2837 int clientIndex = mLruProcesses.lastIndexOf(client); 2838 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2839 + " when updating " + app); 2840 if (clientIndex <= lrui) { 2841 // Don't allow the client index restriction to push it down farther in the 2842 // list than it already is. 2843 clientIndex = lrui; 2844 } 2845 if (clientIndex >= 0 && index > clientIndex) { 2846 index = clientIndex; 2847 } 2848 } 2849 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2850 mLruProcesses.add(index, app); 2851 nextIndex = index-1; 2852 mLruProcessActivityStart++; 2853 mLruProcessServiceStart++; 2854 } 2855 2856 // If the app is currently using a content provider or service, 2857 // bump those processes as well. 2858 for (int j=app.connections.size()-1; j>=0; j--) { 2859 ConnectionRecord cr = app.connections.valueAt(j); 2860 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2861 && cr.binding.service.app != null 2862 && cr.binding.service.app.lruSeq != mLruSeq 2863 && !cr.binding.service.app.persistent) { 2864 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2865 "service connection", cr, app); 2866 } 2867 } 2868 for (int j=app.conProviders.size()-1; j>=0; j--) { 2869 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2870 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2871 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2872 "provider reference", cpr, app); 2873 } 2874 } 2875 } 2876 2877 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2878 if (uid == Process.SYSTEM_UID) { 2879 // The system gets to run in any process. If there are multiple 2880 // processes with the same uid, just pick the first (this 2881 // should never happen). 2882 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2883 if (procs == null) return null; 2884 final int N = procs.size(); 2885 for (int i = 0; i < N; i++) { 2886 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2887 } 2888 } 2889 ProcessRecord proc = mProcessNames.get(processName, uid); 2890 if (false && proc != null && !keepIfLarge 2891 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2892 && proc.lastCachedPss >= 4000) { 2893 // Turn this condition on to cause killing to happen regularly, for testing. 2894 if (proc.baseProcessTracker != null) { 2895 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2896 } 2897 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2898 } else if (proc != null && !keepIfLarge 2899 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2900 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2901 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2902 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2903 if (proc.baseProcessTracker != null) { 2904 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2905 } 2906 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2907 } 2908 } 2909 return proc; 2910 } 2911 2912 void ensurePackageDexOpt(String packageName) { 2913 IPackageManager pm = AppGlobals.getPackageManager(); 2914 try { 2915 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2916 mDidDexOpt = true; 2917 } 2918 } catch (RemoteException e) { 2919 } 2920 } 2921 2922 boolean isNextTransitionForward() { 2923 int transit = mWindowManager.getPendingAppTransition(); 2924 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2925 || transit == AppTransition.TRANSIT_TASK_OPEN 2926 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2927 } 2928 2929 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2930 String processName, String abiOverride, int uid, Runnable crashHandler) { 2931 synchronized(this) { 2932 ApplicationInfo info = new ApplicationInfo(); 2933 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2934 // For isolated processes, the former contains the parent's uid and the latter the 2935 // actual uid of the isolated process. 2936 // In the special case introduced by this method (which is, starting an isolated 2937 // process directly from the SystemServer without an actual parent app process) the 2938 // closest thing to a parent's uid is SYSTEM_UID. 2939 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2940 // the |isolated| logic in the ProcessRecord constructor. 2941 info.uid = Process.SYSTEM_UID; 2942 info.processName = processName; 2943 info.className = entryPoint; 2944 info.packageName = "android"; 2945 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2946 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2947 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2948 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2949 crashHandler); 2950 return proc != null ? proc.pid : 0; 2951 } 2952 } 2953 2954 final ProcessRecord startProcessLocked(String processName, 2955 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2956 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2957 boolean isolated, boolean keepIfLarge) { 2958 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2959 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2960 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2961 null /* crashHandler */); 2962 } 2963 2964 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2965 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2966 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2967 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2968 long startTime = SystemClock.elapsedRealtime(); 2969 ProcessRecord app; 2970 if (!isolated) { 2971 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2972 checkTime(startTime, "startProcess: after getProcessRecord"); 2973 } else { 2974 // If this is an isolated process, it can't re-use an existing process. 2975 app = null; 2976 } 2977 // We don't have to do anything more if: 2978 // (1) There is an existing application record; and 2979 // (2) The caller doesn't think it is dead, OR there is no thread 2980 // object attached to it so we know it couldn't have crashed; and 2981 // (3) There is a pid assigned to it, so it is either starting or 2982 // already running. 2983 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2984 + " app=" + app + " knownToBeDead=" + knownToBeDead 2985 + " thread=" + (app != null ? app.thread : null) 2986 + " pid=" + (app != null ? app.pid : -1)); 2987 if (app != null && app.pid > 0) { 2988 if (!knownToBeDead || app.thread == null) { 2989 // We already have the app running, or are waiting for it to 2990 // come up (we have a pid but not yet its thread), so keep it. 2991 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2992 // If this is a new package in the process, add the package to the list 2993 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2994 checkTime(startTime, "startProcess: done, added package to proc"); 2995 return app; 2996 } 2997 2998 // An application record is attached to a previous process, 2999 // clean it up now. 3000 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 3001 checkTime(startTime, "startProcess: bad proc running, killing"); 3002 Process.killProcessGroup(app.info.uid, app.pid); 3003 handleAppDiedLocked(app, true, true); 3004 checkTime(startTime, "startProcess: done killing old proc"); 3005 } 3006 3007 String hostingNameStr = hostingName != null 3008 ? hostingName.flattenToShortString() : null; 3009 3010 if (!isolated) { 3011 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3012 // If we are in the background, then check to see if this process 3013 // is bad. If so, we will just silently fail. 3014 if (mBadProcesses.get(info.processName, info.uid) != null) { 3015 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3016 + "/" + info.processName); 3017 return null; 3018 } 3019 } else { 3020 // When the user is explicitly starting a process, then clear its 3021 // crash count so that we won't make it bad until they see at 3022 // least one crash dialog again, and make the process good again 3023 // if it had been bad. 3024 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3025 + "/" + info.processName); 3026 mProcessCrashTimes.remove(info.processName, info.uid); 3027 if (mBadProcesses.get(info.processName, info.uid) != null) { 3028 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3029 UserHandle.getUserId(info.uid), info.uid, 3030 info.processName); 3031 mBadProcesses.remove(info.processName, info.uid); 3032 if (app != null) { 3033 app.bad = false; 3034 } 3035 } 3036 } 3037 } 3038 3039 if (app == null) { 3040 checkTime(startTime, "startProcess: creating new process record"); 3041 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3042 app.crashHandler = crashHandler; 3043 if (app == null) { 3044 Slog.w(TAG, "Failed making new process record for " 3045 + processName + "/" + info.uid + " isolated=" + isolated); 3046 return null; 3047 } 3048 mProcessNames.put(processName, app.uid, app); 3049 if (isolated) { 3050 mIsolatedProcesses.put(app.uid, app); 3051 } 3052 checkTime(startTime, "startProcess: done creating new process record"); 3053 } else { 3054 // If this is a new package in the process, add the package to the list 3055 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3056 checkTime(startTime, "startProcess: added package to existing proc"); 3057 } 3058 3059 // If the system is not ready yet, then hold off on starting this 3060 // process until it is. 3061 if (!mProcessesReady 3062 && !isAllowedWhileBooting(info) 3063 && !allowWhileBooting) { 3064 if (!mProcessesOnHold.contains(app)) { 3065 mProcessesOnHold.add(app); 3066 } 3067 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3068 checkTime(startTime, "startProcess: returning with proc on hold"); 3069 return app; 3070 } 3071 3072 checkTime(startTime, "startProcess: stepping in to startProcess"); 3073 startProcessLocked( 3074 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3075 checkTime(startTime, "startProcess: done starting proc!"); 3076 return (app.pid != 0) ? app : null; 3077 } 3078 3079 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3080 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3081 } 3082 3083 private final void startProcessLocked(ProcessRecord app, 3084 String hostingType, String hostingNameStr) { 3085 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3086 null /* entryPoint */, null /* entryPointArgs */); 3087 } 3088 3089 private final void startProcessLocked(ProcessRecord app, String hostingType, 3090 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3091 long startTime = SystemClock.elapsedRealtime(); 3092 if (app.pid > 0 && app.pid != MY_PID) { 3093 checkTime(startTime, "startProcess: removing from pids map"); 3094 synchronized (mPidsSelfLocked) { 3095 mPidsSelfLocked.remove(app.pid); 3096 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3097 } 3098 checkTime(startTime, "startProcess: done removing from pids map"); 3099 app.setPid(0); 3100 } 3101 3102 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3103 "startProcessLocked removing on hold: " + app); 3104 mProcessesOnHold.remove(app); 3105 3106 checkTime(startTime, "startProcess: starting to update cpu stats"); 3107 updateCpuStats(); 3108 checkTime(startTime, "startProcess: done updating cpu stats"); 3109 3110 try { 3111 int uid = app.uid; 3112 3113 int[] gids = null; 3114 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3115 if (!app.isolated) { 3116 int[] permGids = null; 3117 try { 3118 checkTime(startTime, "startProcess: getting gids from package manager"); 3119 final PackageManager pm = mContext.getPackageManager(); 3120 permGids = pm.getPackageGids(app.info.packageName); 3121 3122 if (Environment.isExternalStorageEmulated()) { 3123 checkTime(startTime, "startProcess: checking external storage perm"); 3124 if (pm.checkPermission( 3125 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3126 app.info.packageName) == PERMISSION_GRANTED) { 3127 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3128 } else { 3129 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3130 } 3131 } 3132 } catch (PackageManager.NameNotFoundException e) { 3133 Slog.w(TAG, "Unable to retrieve gids", e); 3134 } 3135 3136 /* 3137 * Add shared application and profile GIDs so applications can share some 3138 * resources like shared libraries and access user-wide resources 3139 */ 3140 if (permGids == null) { 3141 gids = new int[2]; 3142 } else { 3143 gids = new int[permGids.length + 2]; 3144 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3145 } 3146 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3147 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3148 } 3149 checkTime(startTime, "startProcess: building args"); 3150 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3151 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3152 && mTopComponent != null 3153 && app.processName.equals(mTopComponent.getPackageName())) { 3154 uid = 0; 3155 } 3156 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3157 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3158 uid = 0; 3159 } 3160 } 3161 int debugFlags = 0; 3162 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3163 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3164 // Also turn on CheckJNI for debuggable apps. It's quite 3165 // awkward to turn on otherwise. 3166 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3167 } 3168 // Run the app in safe mode if its manifest requests so or the 3169 // system is booted in safe mode. 3170 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3171 mSafeMode == true) { 3172 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3173 } 3174 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3175 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3176 } 3177 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3178 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3179 } 3180 if ("1".equals(SystemProperties.get("debug.assert"))) { 3181 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3182 } 3183 3184 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3185 if (requiredAbi == null) { 3186 requiredAbi = Build.SUPPORTED_ABIS[0]; 3187 } 3188 3189 String instructionSet = null; 3190 if (app.info.primaryCpuAbi != null) { 3191 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3192 } 3193 3194 // Start the process. It will either succeed and return a result containing 3195 // the PID of the new process, or else throw a RuntimeException. 3196 boolean isActivityProcess = (entryPoint == null); 3197 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3198 checkTime(startTime, "startProcess: asking zygote to start proc"); 3199 Process.ProcessStartResult startResult = Process.start(entryPoint, 3200 app.processName, uid, uid, gids, debugFlags, mountExternal, 3201 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3202 app.info.dataDir, entryPointArgs); 3203 checkTime(startTime, "startProcess: returned from zygote!"); 3204 3205 if (app.isolated) { 3206 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3207 } 3208 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3209 checkTime(startTime, "startProcess: done updating battery stats"); 3210 3211 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3212 UserHandle.getUserId(uid), startResult.pid, uid, 3213 app.processName, hostingType, 3214 hostingNameStr != null ? hostingNameStr : ""); 3215 3216 if (app.persistent) { 3217 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3218 } 3219 3220 checkTime(startTime, "startProcess: building log message"); 3221 StringBuilder buf = mStringBuilder; 3222 buf.setLength(0); 3223 buf.append("Start proc "); 3224 buf.append(app.processName); 3225 if (!isActivityProcess) { 3226 buf.append(" ["); 3227 buf.append(entryPoint); 3228 buf.append("]"); 3229 } 3230 buf.append(" for "); 3231 buf.append(hostingType); 3232 if (hostingNameStr != null) { 3233 buf.append(" "); 3234 buf.append(hostingNameStr); 3235 } 3236 buf.append(": pid="); 3237 buf.append(startResult.pid); 3238 buf.append(" uid="); 3239 buf.append(uid); 3240 buf.append(" gids={"); 3241 if (gids != null) { 3242 for (int gi=0; gi<gids.length; gi++) { 3243 if (gi != 0) buf.append(", "); 3244 buf.append(gids[gi]); 3245 3246 } 3247 } 3248 buf.append("}"); 3249 if (requiredAbi != null) { 3250 buf.append(" abi="); 3251 buf.append(requiredAbi); 3252 } 3253 Slog.i(TAG, buf.toString()); 3254 app.setPid(startResult.pid); 3255 app.usingWrapper = startResult.usingWrapper; 3256 app.removed = false; 3257 app.killed = false; 3258 app.killedByAm = false; 3259 checkTime(startTime, "startProcess: starting to update pids map"); 3260 synchronized (mPidsSelfLocked) { 3261 this.mPidsSelfLocked.put(startResult.pid, app); 3262 if (isActivityProcess) { 3263 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3264 msg.obj = app; 3265 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3266 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3267 } 3268 } 3269 checkTime(startTime, "startProcess: done updating pids map"); 3270 } catch (RuntimeException e) { 3271 // XXX do better error recovery. 3272 app.setPid(0); 3273 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3274 if (app.isolated) { 3275 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3276 } 3277 Slog.e(TAG, "Failure starting process " + app.processName, e); 3278 } 3279 } 3280 3281 void updateUsageStats(ActivityRecord component, boolean resumed) { 3282 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3283 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3284 if (resumed) { 3285 if (mUsageStatsService != null) { 3286 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3287 UsageEvents.Event.MOVE_TO_FOREGROUND); 3288 } 3289 synchronized (stats) { 3290 stats.noteActivityResumedLocked(component.app.uid); 3291 } 3292 } else { 3293 if (mUsageStatsService != null) { 3294 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3295 UsageEvents.Event.MOVE_TO_BACKGROUND); 3296 } 3297 synchronized (stats) { 3298 stats.noteActivityPausedLocked(component.app.uid); 3299 } 3300 } 3301 } 3302 3303 Intent getHomeIntent() { 3304 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3305 intent.setComponent(mTopComponent); 3306 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3307 intent.addCategory(Intent.CATEGORY_HOME); 3308 } 3309 return intent; 3310 } 3311 3312 boolean startHomeActivityLocked(int userId) { 3313 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3314 && mTopAction == null) { 3315 // We are running in factory test mode, but unable to find 3316 // the factory test app, so just sit around displaying the 3317 // error message and don't try to start anything. 3318 return false; 3319 } 3320 Intent intent = getHomeIntent(); 3321 ActivityInfo aInfo = 3322 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3323 if (aInfo != null) { 3324 intent.setComponent(new ComponentName( 3325 aInfo.applicationInfo.packageName, aInfo.name)); 3326 // Don't do this if the home app is currently being 3327 // instrumented. 3328 aInfo = new ActivityInfo(aInfo); 3329 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3330 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3331 aInfo.applicationInfo.uid, true); 3332 if (app == null || app.instrumentationClass == null) { 3333 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3334 mStackSupervisor.startHomeActivity(intent, aInfo); 3335 } 3336 } 3337 3338 return true; 3339 } 3340 3341 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3342 ActivityInfo ai = null; 3343 ComponentName comp = intent.getComponent(); 3344 try { 3345 if (comp != null) { 3346 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3347 } else { 3348 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3349 intent, 3350 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3351 flags, userId); 3352 3353 if (info != null) { 3354 ai = info.activityInfo; 3355 } 3356 } 3357 } catch (RemoteException e) { 3358 // ignore 3359 } 3360 3361 return ai; 3362 } 3363 3364 /** 3365 * Starts the "new version setup screen" if appropriate. 3366 */ 3367 void startSetupActivityLocked() { 3368 // Only do this once per boot. 3369 if (mCheckedForSetup) { 3370 return; 3371 } 3372 3373 // We will show this screen if the current one is a different 3374 // version than the last one shown, and we are not running in 3375 // low-level factory test mode. 3376 final ContentResolver resolver = mContext.getContentResolver(); 3377 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3378 Settings.Global.getInt(resolver, 3379 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3380 mCheckedForSetup = true; 3381 3382 // See if we should be showing the platform update setup UI. 3383 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3384 List<ResolveInfo> ris = mContext.getPackageManager() 3385 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3386 3387 // We don't allow third party apps to replace this. 3388 ResolveInfo ri = null; 3389 for (int i=0; ris != null && i<ris.size(); i++) { 3390 if ((ris.get(i).activityInfo.applicationInfo.flags 3391 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3392 ri = ris.get(i); 3393 break; 3394 } 3395 } 3396 3397 if (ri != null) { 3398 String vers = ri.activityInfo.metaData != null 3399 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3400 : null; 3401 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3402 vers = ri.activityInfo.applicationInfo.metaData.getString( 3403 Intent.METADATA_SETUP_VERSION); 3404 } 3405 String lastVers = Settings.Secure.getString( 3406 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3407 if (vers != null && !vers.equals(lastVers)) { 3408 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3409 intent.setComponent(new ComponentName( 3410 ri.activityInfo.packageName, ri.activityInfo.name)); 3411 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3412 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3413 null); 3414 } 3415 } 3416 } 3417 } 3418 3419 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3420 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3421 } 3422 3423 void enforceNotIsolatedCaller(String caller) { 3424 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3425 throw new SecurityException("Isolated process not allowed to call " + caller); 3426 } 3427 } 3428 3429 void enforceShellRestriction(String restriction, int userHandle) { 3430 if (Binder.getCallingUid() == Process.SHELL_UID) { 3431 if (userHandle < 0 3432 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3433 throw new SecurityException("Shell does not have permission to access user " 3434 + userHandle); 3435 } 3436 } 3437 } 3438 3439 @Override 3440 public int getFrontActivityScreenCompatMode() { 3441 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3442 synchronized (this) { 3443 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3444 } 3445 } 3446 3447 @Override 3448 public void setFrontActivityScreenCompatMode(int mode) { 3449 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3450 "setFrontActivityScreenCompatMode"); 3451 synchronized (this) { 3452 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3453 } 3454 } 3455 3456 @Override 3457 public int getPackageScreenCompatMode(String packageName) { 3458 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3459 synchronized (this) { 3460 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3461 } 3462 } 3463 3464 @Override 3465 public void setPackageScreenCompatMode(String packageName, int mode) { 3466 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3467 "setPackageScreenCompatMode"); 3468 synchronized (this) { 3469 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3470 } 3471 } 3472 3473 @Override 3474 public boolean getPackageAskScreenCompat(String packageName) { 3475 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3476 synchronized (this) { 3477 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3478 } 3479 } 3480 3481 @Override 3482 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3483 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3484 "setPackageAskScreenCompat"); 3485 synchronized (this) { 3486 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3487 } 3488 } 3489 3490 private void dispatchProcessesChanged() { 3491 int N; 3492 synchronized (this) { 3493 N = mPendingProcessChanges.size(); 3494 if (mActiveProcessChanges.length < N) { 3495 mActiveProcessChanges = new ProcessChangeItem[N]; 3496 } 3497 mPendingProcessChanges.toArray(mActiveProcessChanges); 3498 mAvailProcessChanges.addAll(mPendingProcessChanges); 3499 mPendingProcessChanges.clear(); 3500 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3501 } 3502 3503 int i = mProcessObservers.beginBroadcast(); 3504 while (i > 0) { 3505 i--; 3506 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3507 if (observer != null) { 3508 try { 3509 for (int j=0; j<N; j++) { 3510 ProcessChangeItem item = mActiveProcessChanges[j]; 3511 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3513 + item.pid + " uid=" + item.uid + ": " 3514 + item.foregroundActivities); 3515 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3516 item.foregroundActivities); 3517 } 3518 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3519 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3520 + item.pid + " uid=" + item.uid + ": " + item.processState); 3521 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3522 } 3523 } 3524 } catch (RemoteException e) { 3525 } 3526 } 3527 } 3528 mProcessObservers.finishBroadcast(); 3529 } 3530 3531 private void dispatchProcessDied(int pid, int uid) { 3532 int i = mProcessObservers.beginBroadcast(); 3533 while (i > 0) { 3534 i--; 3535 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3536 if (observer != null) { 3537 try { 3538 observer.onProcessDied(pid, uid); 3539 } catch (RemoteException e) { 3540 } 3541 } 3542 } 3543 mProcessObservers.finishBroadcast(); 3544 } 3545 3546 @Override 3547 public final int startActivity(IApplicationThread caller, String callingPackage, 3548 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3549 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3550 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3551 resultWho, requestCode, startFlags, profilerInfo, options, 3552 UserHandle.getCallingUserId()); 3553 } 3554 3555 @Override 3556 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3557 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3558 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3559 enforceNotIsolatedCaller("startActivity"); 3560 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3561 false, ALLOW_FULL_ONLY, "startActivity", null); 3562 // TODO: Switch to user app stacks here. 3563 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3564 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3565 profilerInfo, null, null, options, userId, null, null); 3566 } 3567 3568 @Override 3569 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3570 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3571 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3572 3573 // This is very dangerous -- it allows you to perform a start activity (including 3574 // permission grants) as any app that may launch one of your own activities. So 3575 // we will only allow this to be done from activities that are part of the core framework, 3576 // and then only when they are running as the system. 3577 final ActivityRecord sourceRecord; 3578 final int targetUid; 3579 final String targetPackage; 3580 synchronized (this) { 3581 if (resultTo == null) { 3582 throw new SecurityException("Must be called from an activity"); 3583 } 3584 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3585 if (sourceRecord == null) { 3586 throw new SecurityException("Called with bad activity token: " + resultTo); 3587 } 3588 if (!sourceRecord.info.packageName.equals("android")) { 3589 throw new SecurityException( 3590 "Must be called from an activity that is declared in the android package"); 3591 } 3592 if (sourceRecord.app == null) { 3593 throw new SecurityException("Called without a process attached to activity"); 3594 } 3595 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3596 // This is still okay, as long as this activity is running under the 3597 // uid of the original calling activity. 3598 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3599 throw new SecurityException( 3600 "Calling activity in uid " + sourceRecord.app.uid 3601 + " must be system uid or original calling uid " 3602 + sourceRecord.launchedFromUid); 3603 } 3604 } 3605 targetUid = sourceRecord.launchedFromUid; 3606 targetPackage = sourceRecord.launchedFromPackage; 3607 } 3608 3609 if (userId == UserHandle.USER_NULL) { 3610 userId = UserHandle.getUserId(sourceRecord.app.uid); 3611 } 3612 3613 // TODO: Switch to user app stacks here. 3614 try { 3615 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3616 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3617 null, null, options, userId, null, null); 3618 return ret; 3619 } catch (SecurityException e) { 3620 // XXX need to figure out how to propagate to original app. 3621 // A SecurityException here is generally actually a fault of the original 3622 // calling activity (such as a fairly granting permissions), so propagate it 3623 // back to them. 3624 /* 3625 StringBuilder msg = new StringBuilder(); 3626 msg.append("While launching"); 3627 msg.append(intent.toString()); 3628 msg.append(": "); 3629 msg.append(e.getMessage()); 3630 */ 3631 throw e; 3632 } 3633 } 3634 3635 @Override 3636 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3637 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3638 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3639 enforceNotIsolatedCaller("startActivityAndWait"); 3640 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3641 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3642 WaitResult res = new WaitResult(); 3643 // TODO: Switch to user app stacks here. 3644 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3645 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3646 options, userId, null, null); 3647 return res; 3648 } 3649 3650 @Override 3651 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3652 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3653 int startFlags, Configuration config, Bundle options, int userId) { 3654 enforceNotIsolatedCaller("startActivityWithConfig"); 3655 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3656 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3657 // TODO: Switch to user app stacks here. 3658 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3659 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3660 null, null, config, options, userId, null, null); 3661 return ret; 3662 } 3663 3664 @Override 3665 public int startActivityIntentSender(IApplicationThread caller, 3666 IntentSender intent, Intent fillInIntent, String resolvedType, 3667 IBinder resultTo, String resultWho, int requestCode, 3668 int flagsMask, int flagsValues, Bundle options) { 3669 enforceNotIsolatedCaller("startActivityIntentSender"); 3670 // Refuse possible leaked file descriptors 3671 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3672 throw new IllegalArgumentException("File descriptors passed in Intent"); 3673 } 3674 3675 IIntentSender sender = intent.getTarget(); 3676 if (!(sender instanceof PendingIntentRecord)) { 3677 throw new IllegalArgumentException("Bad PendingIntent object"); 3678 } 3679 3680 PendingIntentRecord pir = (PendingIntentRecord)sender; 3681 3682 synchronized (this) { 3683 // If this is coming from the currently resumed activity, it is 3684 // effectively saying that app switches are allowed at this point. 3685 final ActivityStack stack = getFocusedStack(); 3686 if (stack.mResumedActivity != null && 3687 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3688 mAppSwitchesAllowedTime = 0; 3689 } 3690 } 3691 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3692 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3693 return ret; 3694 } 3695 3696 @Override 3697 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3698 Intent intent, String resolvedType, IVoiceInteractionSession session, 3699 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3700 Bundle options, int userId) { 3701 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3702 != PackageManager.PERMISSION_GRANTED) { 3703 String msg = "Permission Denial: startVoiceActivity() from pid=" 3704 + Binder.getCallingPid() 3705 + ", uid=" + Binder.getCallingUid() 3706 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3707 Slog.w(TAG, msg); 3708 throw new SecurityException(msg); 3709 } 3710 if (session == null || interactor == null) { 3711 throw new NullPointerException("null session or interactor"); 3712 } 3713 userId = handleIncomingUser(callingPid, callingUid, userId, 3714 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3715 // TODO: Switch to user app stacks here. 3716 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3717 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3718 null, options, userId, null, null); 3719 } 3720 3721 @Override 3722 public boolean startNextMatchingActivity(IBinder callingActivity, 3723 Intent intent, Bundle options) { 3724 // Refuse possible leaked file descriptors 3725 if (intent != null && intent.hasFileDescriptors() == true) { 3726 throw new IllegalArgumentException("File descriptors passed in Intent"); 3727 } 3728 3729 synchronized (this) { 3730 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3731 if (r == null) { 3732 ActivityOptions.abort(options); 3733 return false; 3734 } 3735 if (r.app == null || r.app.thread == null) { 3736 // The caller is not running... d'oh! 3737 ActivityOptions.abort(options); 3738 return false; 3739 } 3740 intent = new Intent(intent); 3741 // The caller is not allowed to change the data. 3742 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3743 // And we are resetting to find the next component... 3744 intent.setComponent(null); 3745 3746 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3747 3748 ActivityInfo aInfo = null; 3749 try { 3750 List<ResolveInfo> resolves = 3751 AppGlobals.getPackageManager().queryIntentActivities( 3752 intent, r.resolvedType, 3753 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3754 UserHandle.getCallingUserId()); 3755 3756 // Look for the original activity in the list... 3757 final int N = resolves != null ? resolves.size() : 0; 3758 for (int i=0; i<N; i++) { 3759 ResolveInfo rInfo = resolves.get(i); 3760 if (rInfo.activityInfo.packageName.equals(r.packageName) 3761 && rInfo.activityInfo.name.equals(r.info.name)) { 3762 // We found the current one... the next matching is 3763 // after it. 3764 i++; 3765 if (i<N) { 3766 aInfo = resolves.get(i).activityInfo; 3767 } 3768 if (debug) { 3769 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3770 + "/" + r.info.name); 3771 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3772 + "/" + aInfo.name); 3773 } 3774 break; 3775 } 3776 } 3777 } catch (RemoteException e) { 3778 } 3779 3780 if (aInfo == null) { 3781 // Nobody who is next! 3782 ActivityOptions.abort(options); 3783 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3784 return false; 3785 } 3786 3787 intent.setComponent(new ComponentName( 3788 aInfo.applicationInfo.packageName, aInfo.name)); 3789 intent.setFlags(intent.getFlags()&~( 3790 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3791 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3792 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3793 Intent.FLAG_ACTIVITY_NEW_TASK)); 3794 3795 // Okay now we need to start the new activity, replacing the 3796 // currently running activity. This is a little tricky because 3797 // we want to start the new one as if the current one is finished, 3798 // but not finish the current one first so that there is no flicker. 3799 // And thus... 3800 final boolean wasFinishing = r.finishing; 3801 r.finishing = true; 3802 3803 // Propagate reply information over to the new activity. 3804 final ActivityRecord resultTo = r.resultTo; 3805 final String resultWho = r.resultWho; 3806 final int requestCode = r.requestCode; 3807 r.resultTo = null; 3808 if (resultTo != null) { 3809 resultTo.removeResultsLocked(r, resultWho, requestCode); 3810 } 3811 3812 final long origId = Binder.clearCallingIdentity(); 3813 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3814 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3815 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3816 -1, r.launchedFromUid, 0, options, false, null, null, null); 3817 Binder.restoreCallingIdentity(origId); 3818 3819 r.finishing = wasFinishing; 3820 if (res != ActivityManager.START_SUCCESS) { 3821 return false; 3822 } 3823 return true; 3824 } 3825 } 3826 3827 @Override 3828 public final int startActivityFromRecents(int taskId, Bundle options) { 3829 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3830 String msg = "Permission Denial: startActivityFromRecents called without " + 3831 START_TASKS_FROM_RECENTS; 3832 Slog.w(TAG, msg); 3833 throw new SecurityException(msg); 3834 } 3835 return startActivityFromRecentsInner(taskId, options); 3836 } 3837 3838 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3839 final TaskRecord task; 3840 final int callingUid; 3841 final String callingPackage; 3842 final Intent intent; 3843 final int userId; 3844 synchronized (this) { 3845 task = recentTaskForIdLocked(taskId); 3846 if (task == null) { 3847 throw new IllegalArgumentException("Task " + taskId + " not found."); 3848 } 3849 callingUid = task.mCallingUid; 3850 callingPackage = task.mCallingPackage; 3851 intent = task.intent; 3852 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3853 userId = task.userId; 3854 } 3855 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3856 options, userId, null, task); 3857 } 3858 3859 final int startActivityInPackage(int uid, String callingPackage, 3860 Intent intent, String resolvedType, IBinder resultTo, 3861 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3862 IActivityContainer container, TaskRecord inTask) { 3863 3864 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3865 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3866 3867 // TODO: Switch to user app stacks here. 3868 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3869 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3870 null, null, null, options, userId, container, inTask); 3871 return ret; 3872 } 3873 3874 @Override 3875 public final int startActivities(IApplicationThread caller, String callingPackage, 3876 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3877 int userId) { 3878 enforceNotIsolatedCaller("startActivities"); 3879 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3880 false, ALLOW_FULL_ONLY, "startActivity", null); 3881 // TODO: Switch to user app stacks here. 3882 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3883 resolvedTypes, resultTo, options, userId); 3884 return ret; 3885 } 3886 3887 final int startActivitiesInPackage(int uid, String callingPackage, 3888 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3889 Bundle options, int userId) { 3890 3891 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3892 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3893 // TODO: Switch to user app stacks here. 3894 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3895 resultTo, options, userId); 3896 return ret; 3897 } 3898 3899 //explicitly remove thd old information in mRecentTasks when removing existing user. 3900 private void removeRecentTasksForUserLocked(int userId) { 3901 if(userId <= 0) { 3902 Slog.i(TAG, "Can't remove recent task on user " + userId); 3903 return; 3904 } 3905 3906 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3907 TaskRecord tr = mRecentTasks.get(i); 3908 if (tr.userId == userId) { 3909 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3910 + " when finishing user" + userId); 3911 mRecentTasks.remove(i); 3912 tr.removedFromRecents(mTaskPersister); 3913 } 3914 } 3915 3916 // Remove tasks from persistent storage. 3917 mTaskPersister.wakeup(null, true); 3918 } 3919 3920 // Sort by taskId 3921 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3922 @Override 3923 public int compare(TaskRecord lhs, TaskRecord rhs) { 3924 return rhs.taskId - lhs.taskId; 3925 } 3926 }; 3927 3928 // Extract the affiliates of the chain containing mRecentTasks[start]. 3929 private int processNextAffiliateChain(int start) { 3930 final TaskRecord startTask = mRecentTasks.get(start); 3931 final int affiliateId = startTask.mAffiliatedTaskId; 3932 3933 // Quick identification of isolated tasks. I.e. those not launched behind. 3934 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3935 startTask.mNextAffiliate == null) { 3936 // There is still a slim chance that there are other tasks that point to this task 3937 // and that the chain is so messed up that this task no longer points to them but 3938 // the gain of this optimization outweighs the risk. 3939 startTask.inRecents = true; 3940 return start + 1; 3941 } 3942 3943 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3944 mTmpRecents.clear(); 3945 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3946 final TaskRecord task = mRecentTasks.get(i); 3947 if (task.mAffiliatedTaskId == affiliateId) { 3948 mRecentTasks.remove(i); 3949 mTmpRecents.add(task); 3950 } 3951 } 3952 3953 // Sort them all by taskId. That is the order they were create in and that order will 3954 // always be correct. 3955 Collections.sort(mTmpRecents, mTaskRecordComparator); 3956 3957 // Go through and fix up the linked list. 3958 // The first one is the end of the chain and has no next. 3959 final TaskRecord first = mTmpRecents.get(0); 3960 first.inRecents = true; 3961 if (first.mNextAffiliate != null) { 3962 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3963 first.setNextAffiliate(null); 3964 mTaskPersister.wakeup(first, false); 3965 } 3966 // Everything in the middle is doubly linked from next to prev. 3967 final int tmpSize = mTmpRecents.size(); 3968 for (int i = 0; i < tmpSize - 1; ++i) { 3969 final TaskRecord next = mTmpRecents.get(i); 3970 final TaskRecord prev = mTmpRecents.get(i + 1); 3971 if (next.mPrevAffiliate != prev) { 3972 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3973 " setting prev=" + prev); 3974 next.setPrevAffiliate(prev); 3975 mTaskPersister.wakeup(next, false); 3976 } 3977 if (prev.mNextAffiliate != next) { 3978 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3979 " setting next=" + next); 3980 prev.setNextAffiliate(next); 3981 mTaskPersister.wakeup(prev, false); 3982 } 3983 prev.inRecents = true; 3984 } 3985 // The last one is the beginning of the list and has no prev. 3986 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3987 if (last.mPrevAffiliate != null) { 3988 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3989 last.setPrevAffiliate(null); 3990 mTaskPersister.wakeup(last, false); 3991 } 3992 3993 // Insert the group back into mRecentTasks at start. 3994 mRecentTasks.addAll(start, mTmpRecents); 3995 3996 // Let the caller know where we left off. 3997 return start + tmpSize; 3998 } 3999 4000 /** 4001 * Update the recent tasks lists: make sure tasks should still be here (their 4002 * applications / activities still exist), update their availability, fixup ordering 4003 * of affiliations. 4004 */ 4005 void cleanupRecentTasksLocked(int userId) { 4006 if (mRecentTasks == null) { 4007 // Happens when called from the packagemanager broadcast before boot. 4008 return; 4009 } 4010 4011 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4012 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4013 final IPackageManager pm = AppGlobals.getPackageManager(); 4014 final ActivityInfo dummyAct = new ActivityInfo(); 4015 final ApplicationInfo dummyApp = new ApplicationInfo(); 4016 4017 int N = mRecentTasks.size(); 4018 4019 int[] users = userId == UserHandle.USER_ALL 4020 ? getUsersLocked() : new int[] { userId }; 4021 for (int user : users) { 4022 for (int i = 0; i < N; i++) { 4023 TaskRecord task = mRecentTasks.get(i); 4024 if (task.userId != user) { 4025 // Only look at tasks for the user ID of interest. 4026 continue; 4027 } 4028 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4029 // This situation is broken, and we should just get rid of it now. 4030 mRecentTasks.remove(i); 4031 task.removedFromRecents(mTaskPersister); 4032 i--; 4033 N--; 4034 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4035 continue; 4036 } 4037 // Check whether this activity is currently available. 4038 if (task.realActivity != null) { 4039 ActivityInfo ai = availActCache.get(task.realActivity); 4040 if (ai == null) { 4041 try { 4042 ai = pm.getActivityInfo(task.realActivity, 4043 PackageManager.GET_UNINSTALLED_PACKAGES 4044 | PackageManager.GET_DISABLED_COMPONENTS, user); 4045 } catch (RemoteException e) { 4046 // Will never happen. 4047 continue; 4048 } 4049 if (ai == null) { 4050 ai = dummyAct; 4051 } 4052 availActCache.put(task.realActivity, ai); 4053 } 4054 if (ai == dummyAct) { 4055 // This could be either because the activity no longer exists, or the 4056 // app is temporarily gone. For the former we want to remove the recents 4057 // entry; for the latter we want to mark it as unavailable. 4058 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4059 if (app == null) { 4060 try { 4061 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4062 PackageManager.GET_UNINSTALLED_PACKAGES 4063 | PackageManager.GET_DISABLED_COMPONENTS, user); 4064 } catch (RemoteException e) { 4065 // Will never happen. 4066 continue; 4067 } 4068 if (app == null) { 4069 app = dummyApp; 4070 } 4071 availAppCache.put(task.realActivity.getPackageName(), app); 4072 } 4073 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4074 // Doesn't exist any more! Good-bye. 4075 mRecentTasks.remove(i); 4076 task.removedFromRecents(mTaskPersister); 4077 i--; 4078 N--; 4079 Slog.w(TAG, "Removing no longer valid recent: " + task); 4080 continue; 4081 } else { 4082 // Otherwise just not available for now. 4083 if (task.isAvailable) { 4084 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4085 + task); 4086 } 4087 task.isAvailable = false; 4088 } 4089 } else { 4090 if (!ai.enabled || !ai.applicationInfo.enabled 4091 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4092 if (task.isAvailable) { 4093 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4094 + task + " (enabled=" + ai.enabled + "/" 4095 + ai.applicationInfo.enabled + " flags=" 4096 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4097 } 4098 task.isAvailable = false; 4099 } else { 4100 if (!task.isAvailable) { 4101 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4102 + task); 4103 } 4104 task.isAvailable = true; 4105 } 4106 } 4107 } 4108 } 4109 } 4110 4111 // Verify the affiliate chain for each task. 4112 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4113 } 4114 4115 mTmpRecents.clear(); 4116 // mRecentTasks is now in sorted, affiliated order. 4117 } 4118 4119 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4120 int N = mRecentTasks.size(); 4121 TaskRecord top = task; 4122 int topIndex = taskIndex; 4123 while (top.mNextAffiliate != null && topIndex > 0) { 4124 top = top.mNextAffiliate; 4125 topIndex--; 4126 } 4127 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4128 + topIndex + " from intial " + taskIndex); 4129 // Find the end of the chain, doing a sanity check along the way. 4130 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4131 int endIndex = topIndex; 4132 TaskRecord prev = top; 4133 while (endIndex < N) { 4134 TaskRecord cur = mRecentTasks.get(endIndex); 4135 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4136 + endIndex + " " + cur); 4137 if (cur == top) { 4138 // Verify start of the chain. 4139 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4140 Slog.wtf(TAG, "Bad chain @" + endIndex 4141 + ": first task has next affiliate: " + prev); 4142 sane = false; 4143 break; 4144 } 4145 } else { 4146 // Verify middle of the chain's next points back to the one before. 4147 if (cur.mNextAffiliate != prev 4148 || cur.mNextAffiliateTaskId != prev.taskId) { 4149 Slog.wtf(TAG, "Bad chain @" + endIndex 4150 + ": middle task " + cur + " @" + endIndex 4151 + " has bad next affiliate " 4152 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4153 + ", expected " + prev); 4154 sane = false; 4155 break; 4156 } 4157 } 4158 if (cur.mPrevAffiliateTaskId == -1) { 4159 // Chain ends here. 4160 if (cur.mPrevAffiliate != null) { 4161 Slog.wtf(TAG, "Bad chain @" + endIndex 4162 + ": last task " + cur + " has previous affiliate " 4163 + cur.mPrevAffiliate); 4164 sane = false; 4165 } 4166 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4167 break; 4168 } else { 4169 // Verify middle of the chain's prev points to a valid item. 4170 if (cur.mPrevAffiliate == null) { 4171 Slog.wtf(TAG, "Bad chain @" + endIndex 4172 + ": task " + cur + " has previous affiliate " 4173 + cur.mPrevAffiliate + " but should be id " 4174 + cur.mPrevAffiliate); 4175 sane = false; 4176 break; 4177 } 4178 } 4179 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4180 Slog.wtf(TAG, "Bad chain @" + endIndex 4181 + ": task " + cur + " has affiliated id " 4182 + cur.mAffiliatedTaskId + " but should be " 4183 + task.mAffiliatedTaskId); 4184 sane = false; 4185 break; 4186 } 4187 prev = cur; 4188 endIndex++; 4189 if (endIndex >= N) { 4190 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4191 + ": last task " + prev); 4192 sane = false; 4193 break; 4194 } 4195 } 4196 if (sane) { 4197 if (endIndex < taskIndex) { 4198 Slog.wtf(TAG, "Bad chain @" + endIndex 4199 + ": did not extend to task " + task + " @" + taskIndex); 4200 sane = false; 4201 } 4202 } 4203 if (sane) { 4204 // All looks good, we can just move all of the affiliated tasks 4205 // to the top. 4206 for (int i=topIndex; i<=endIndex; i++) { 4207 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4208 + " from " + i + " to " + (i-topIndex)); 4209 TaskRecord cur = mRecentTasks.remove(i); 4210 mRecentTasks.add(i-topIndex, cur); 4211 } 4212 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4213 + " to " + endIndex); 4214 return true; 4215 } 4216 4217 // Whoops, couldn't do it. 4218 return false; 4219 } 4220 4221 final void addRecentTaskLocked(TaskRecord task) { 4222 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4223 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4224 4225 int N = mRecentTasks.size(); 4226 // Quick case: check if the top-most recent task is the same. 4227 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4228 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4229 return; 4230 } 4231 // Another quick case: check if this is part of a set of affiliated 4232 // tasks that are at the top. 4233 if (isAffiliated && N > 0 && task.inRecents 4234 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4235 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4236 + " at top when adding " + task); 4237 return; 4238 } 4239 // Another quick case: never add voice sessions. 4240 if (task.voiceSession != null) { 4241 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4242 return; 4243 } 4244 4245 boolean needAffiliationFix = false; 4246 4247 // Slightly less quick case: the task is already in recents, so all we need 4248 // to do is move it. 4249 if (task.inRecents) { 4250 int taskIndex = mRecentTasks.indexOf(task); 4251 if (taskIndex >= 0) { 4252 if (!isAffiliated) { 4253 // Simple case: this is not an affiliated task, so we just move it to the front. 4254 mRecentTasks.remove(taskIndex); 4255 mRecentTasks.add(0, task); 4256 notifyTaskPersisterLocked(task, false); 4257 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4258 + " from " + taskIndex); 4259 return; 4260 } else { 4261 // More complicated: need to keep all affiliated tasks together. 4262 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4263 // All went well. 4264 return; 4265 } 4266 4267 // Uh oh... something bad in the affiliation chain, try to rebuild 4268 // everything and then go through our general path of adding a new task. 4269 needAffiliationFix = true; 4270 } 4271 } else { 4272 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4273 needAffiliationFix = true; 4274 } 4275 } 4276 4277 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4278 trimRecentsForTask(task, true); 4279 4280 N = mRecentTasks.size(); 4281 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4282 final TaskRecord tr = mRecentTasks.remove(N - 1); 4283 tr.removedFromRecents(mTaskPersister); 4284 N--; 4285 } 4286 task.inRecents = true; 4287 if (!isAffiliated || needAffiliationFix) { 4288 // If this is a simple non-affiliated task, or we had some failure trying to 4289 // handle it as part of an affilated task, then just place it at the top. 4290 mRecentTasks.add(0, task); 4291 } else if (isAffiliated) { 4292 // If this is a new affiliated task, then move all of the affiliated tasks 4293 // to the front and insert this new one. 4294 TaskRecord other = task.mNextAffiliate; 4295 if (other == null) { 4296 other = task.mPrevAffiliate; 4297 } 4298 if (other != null) { 4299 int otherIndex = mRecentTasks.indexOf(other); 4300 if (otherIndex >= 0) { 4301 // Insert new task at appropriate location. 4302 int taskIndex; 4303 if (other == task.mNextAffiliate) { 4304 // We found the index of our next affiliation, which is who is 4305 // before us in the list, so add after that point. 4306 taskIndex = otherIndex+1; 4307 } else { 4308 // We found the index of our previous affiliation, which is who is 4309 // after us in the list, so add at their position. 4310 taskIndex = otherIndex; 4311 } 4312 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4313 + taskIndex + ": " + task); 4314 mRecentTasks.add(taskIndex, task); 4315 4316 // Now move everything to the front. 4317 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4318 // All went well. 4319 return; 4320 } 4321 4322 // Uh oh... something bad in the affiliation chain, try to rebuild 4323 // everything and then go through our general path of adding a new task. 4324 needAffiliationFix = true; 4325 } else { 4326 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4327 + other); 4328 needAffiliationFix = true; 4329 } 4330 } else { 4331 if (DEBUG_RECENTS) Slog.d(TAG, 4332 "addRecent: adding affiliated task without next/prev:" + task); 4333 needAffiliationFix = true; 4334 } 4335 } 4336 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4337 4338 if (needAffiliationFix) { 4339 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4340 cleanupRecentTasksLocked(task.userId); 4341 } 4342 } 4343 4344 /** 4345 * If needed, remove oldest existing entries in recents that are for the same kind 4346 * of task as the given one. 4347 */ 4348 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4349 int N = mRecentTasks.size(); 4350 final Intent intent = task.intent; 4351 final boolean document = intent != null && intent.isDocument(); 4352 4353 int maxRecents = task.maxRecents - 1; 4354 for (int i=0; i<N; i++) { 4355 final TaskRecord tr = mRecentTasks.get(i); 4356 if (task != tr) { 4357 if (task.userId != tr.userId) { 4358 continue; 4359 } 4360 if (i > MAX_RECENT_BITMAPS) { 4361 tr.freeLastThumbnail(); 4362 } 4363 final Intent trIntent = tr.intent; 4364 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4365 (intent == null || !intent.filterEquals(trIntent))) { 4366 continue; 4367 } 4368 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4369 if (document && trIsDocument) { 4370 // These are the same document activity (not necessarily the same doc). 4371 if (maxRecents > 0) { 4372 --maxRecents; 4373 continue; 4374 } 4375 // Hit the maximum number of documents for this task. Fall through 4376 // and remove this document from recents. 4377 } else if (document || trIsDocument) { 4378 // Only one of these is a document. Not the droid we're looking for. 4379 continue; 4380 } 4381 } 4382 4383 if (!doTrim) { 4384 // If the caller is not actually asking for a trim, just tell them we reached 4385 // a point where the trim would happen. 4386 return i; 4387 } 4388 4389 // Either task and tr are the same or, their affinities match or their intents match 4390 // and neither of them is a document, or they are documents using the same activity 4391 // and their maxRecents has been reached. 4392 tr.disposeThumbnail(); 4393 mRecentTasks.remove(i); 4394 if (task != tr) { 4395 tr.removedFromRecents(mTaskPersister); 4396 } 4397 i--; 4398 N--; 4399 if (task.intent == null) { 4400 // If the new recent task we are adding is not fully 4401 // specified, then replace it with the existing recent task. 4402 task = tr; 4403 } 4404 notifyTaskPersisterLocked(tr, false); 4405 } 4406 4407 return -1; 4408 } 4409 4410 @Override 4411 public void reportActivityFullyDrawn(IBinder token) { 4412 synchronized (this) { 4413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4414 if (r == null) { 4415 return; 4416 } 4417 r.reportFullyDrawnLocked(); 4418 } 4419 } 4420 4421 @Override 4422 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4423 synchronized (this) { 4424 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4425 if (r == null) { 4426 return; 4427 } 4428 final long origId = Binder.clearCallingIdentity(); 4429 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4430 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4431 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4432 if (config != null) { 4433 r.frozenBeforeDestroy = true; 4434 if (!updateConfigurationLocked(config, r, false, false)) { 4435 mStackSupervisor.resumeTopActivitiesLocked(); 4436 } 4437 } 4438 Binder.restoreCallingIdentity(origId); 4439 } 4440 } 4441 4442 @Override 4443 public int getRequestedOrientation(IBinder token) { 4444 synchronized (this) { 4445 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4446 if (r == null) { 4447 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4448 } 4449 return mWindowManager.getAppOrientation(r.appToken); 4450 } 4451 } 4452 4453 /** 4454 * This is the internal entry point for handling Activity.finish(). 4455 * 4456 * @param token The Binder token referencing the Activity we want to finish. 4457 * @param resultCode Result code, if any, from this Activity. 4458 * @param resultData Result data (Intent), if any, from this Activity. 4459 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4460 * the root Activity in the task. 4461 * 4462 * @return Returns true if the activity successfully finished, or false if it is still running. 4463 */ 4464 @Override 4465 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4466 boolean finishTask) { 4467 // Refuse possible leaked file descriptors 4468 if (resultData != null && resultData.hasFileDescriptors() == true) { 4469 throw new IllegalArgumentException("File descriptors passed in Intent"); 4470 } 4471 4472 synchronized(this) { 4473 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4474 if (r == null) { 4475 return true; 4476 } 4477 // Keep track of the root activity of the task before we finish it 4478 TaskRecord tr = r.task; 4479 ActivityRecord rootR = tr.getRootActivity(); 4480 // Do not allow task to finish in Lock Task mode. 4481 if (tr == mStackSupervisor.mLockTaskModeTask) { 4482 if (rootR == r) { 4483 mStackSupervisor.showLockTaskToast(); 4484 return false; 4485 } 4486 } 4487 if (mController != null) { 4488 // Find the first activity that is not finishing. 4489 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4490 if (next != null) { 4491 // ask watcher if this is allowed 4492 boolean resumeOK = true; 4493 try { 4494 resumeOK = mController.activityResuming(next.packageName); 4495 } catch (RemoteException e) { 4496 mController = null; 4497 Watchdog.getInstance().setActivityController(null); 4498 } 4499 4500 if (!resumeOK) { 4501 return false; 4502 } 4503 } 4504 } 4505 final long origId = Binder.clearCallingIdentity(); 4506 try { 4507 boolean res; 4508 if (finishTask && r == rootR) { 4509 // If requested, remove the task that is associated to this activity only if it 4510 // was the root activity in the task. The result code and data is ignored because 4511 // we don't support returning them across task boundaries. 4512 res = removeTaskByIdLocked(tr.taskId, 0); 4513 } else { 4514 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4515 resultData, "app-request", true); 4516 } 4517 return res; 4518 } finally { 4519 Binder.restoreCallingIdentity(origId); 4520 } 4521 } 4522 } 4523 4524 @Override 4525 public final void finishHeavyWeightApp() { 4526 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4527 != PackageManager.PERMISSION_GRANTED) { 4528 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4529 + Binder.getCallingPid() 4530 + ", uid=" + Binder.getCallingUid() 4531 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4532 Slog.w(TAG, msg); 4533 throw new SecurityException(msg); 4534 } 4535 4536 synchronized(this) { 4537 if (mHeavyWeightProcess == null) { 4538 return; 4539 } 4540 4541 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4542 mHeavyWeightProcess.activities); 4543 for (int i=0; i<activities.size(); i++) { 4544 ActivityRecord r = activities.get(i); 4545 if (!r.finishing) { 4546 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4547 null, "finish-heavy", true); 4548 } 4549 } 4550 4551 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4552 mHeavyWeightProcess.userId, 0)); 4553 mHeavyWeightProcess = null; 4554 } 4555 } 4556 4557 @Override 4558 public void crashApplication(int uid, int initialPid, String packageName, 4559 String message) { 4560 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4561 != PackageManager.PERMISSION_GRANTED) { 4562 String msg = "Permission Denial: crashApplication() from pid=" 4563 + Binder.getCallingPid() 4564 + ", uid=" + Binder.getCallingUid() 4565 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4566 Slog.w(TAG, msg); 4567 throw new SecurityException(msg); 4568 } 4569 4570 synchronized(this) { 4571 ProcessRecord proc = null; 4572 4573 // Figure out which process to kill. We don't trust that initialPid 4574 // still has any relation to current pids, so must scan through the 4575 // list. 4576 synchronized (mPidsSelfLocked) { 4577 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4578 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4579 if (p.uid != uid) { 4580 continue; 4581 } 4582 if (p.pid == initialPid) { 4583 proc = p; 4584 break; 4585 } 4586 if (p.pkgList.containsKey(packageName)) { 4587 proc = p; 4588 } 4589 } 4590 } 4591 4592 if (proc == null) { 4593 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4594 + " initialPid=" + initialPid 4595 + " packageName=" + packageName); 4596 return; 4597 } 4598 4599 if (proc.thread != null) { 4600 if (proc.pid == Process.myPid()) { 4601 Log.w(TAG, "crashApplication: trying to crash self!"); 4602 return; 4603 } 4604 long ident = Binder.clearCallingIdentity(); 4605 try { 4606 proc.thread.scheduleCrash(message); 4607 } catch (RemoteException e) { 4608 } 4609 Binder.restoreCallingIdentity(ident); 4610 } 4611 } 4612 } 4613 4614 @Override 4615 public final void finishSubActivity(IBinder token, String resultWho, 4616 int requestCode) { 4617 synchronized(this) { 4618 final long origId = Binder.clearCallingIdentity(); 4619 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4620 if (r != null) { 4621 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4622 } 4623 Binder.restoreCallingIdentity(origId); 4624 } 4625 } 4626 4627 @Override 4628 public boolean finishActivityAffinity(IBinder token) { 4629 synchronized(this) { 4630 final long origId = Binder.clearCallingIdentity(); 4631 try { 4632 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4633 4634 ActivityRecord rootR = r.task.getRootActivity(); 4635 // Do not allow task to finish in Lock Task mode. 4636 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4637 if (rootR == r) { 4638 mStackSupervisor.showLockTaskToast(); 4639 return false; 4640 } 4641 } 4642 boolean res = false; 4643 if (r != null) { 4644 res = r.task.stack.finishActivityAffinityLocked(r); 4645 } 4646 return res; 4647 } finally { 4648 Binder.restoreCallingIdentity(origId); 4649 } 4650 } 4651 } 4652 4653 @Override 4654 public void finishVoiceTask(IVoiceInteractionSession session) { 4655 synchronized(this) { 4656 final long origId = Binder.clearCallingIdentity(); 4657 try { 4658 mStackSupervisor.finishVoiceTask(session); 4659 } finally { 4660 Binder.restoreCallingIdentity(origId); 4661 } 4662 } 4663 4664 } 4665 4666 @Override 4667 public boolean releaseActivityInstance(IBinder token) { 4668 synchronized(this) { 4669 final long origId = Binder.clearCallingIdentity(); 4670 try { 4671 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4672 if (r.task == null || r.task.stack == null) { 4673 return false; 4674 } 4675 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4676 } finally { 4677 Binder.restoreCallingIdentity(origId); 4678 } 4679 } 4680 } 4681 4682 @Override 4683 public void releaseSomeActivities(IApplicationThread appInt) { 4684 synchronized(this) { 4685 final long origId = Binder.clearCallingIdentity(); 4686 try { 4687 ProcessRecord app = getRecordForAppLocked(appInt); 4688 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4689 } finally { 4690 Binder.restoreCallingIdentity(origId); 4691 } 4692 } 4693 } 4694 4695 @Override 4696 public boolean willActivityBeVisible(IBinder token) { 4697 synchronized(this) { 4698 ActivityStack stack = ActivityRecord.getStackLocked(token); 4699 if (stack != null) { 4700 return stack.willActivityBeVisibleLocked(token); 4701 } 4702 return false; 4703 } 4704 } 4705 4706 @Override 4707 public void overridePendingTransition(IBinder token, String packageName, 4708 int enterAnim, int exitAnim) { 4709 synchronized(this) { 4710 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4711 if (self == null) { 4712 return; 4713 } 4714 4715 final long origId = Binder.clearCallingIdentity(); 4716 4717 if (self.state == ActivityState.RESUMED 4718 || self.state == ActivityState.PAUSING) { 4719 mWindowManager.overridePendingAppTransition(packageName, 4720 enterAnim, exitAnim, null); 4721 } 4722 4723 Binder.restoreCallingIdentity(origId); 4724 } 4725 } 4726 4727 /** 4728 * Main function for removing an existing process from the activity manager 4729 * as a result of that process going away. Clears out all connections 4730 * to the process. 4731 */ 4732 private final void handleAppDiedLocked(ProcessRecord app, 4733 boolean restarting, boolean allowRestart) { 4734 int pid = app.pid; 4735 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4736 if (!kept && !restarting) { 4737 removeLruProcessLocked(app); 4738 if (pid > 0) { 4739 ProcessList.remove(pid); 4740 } 4741 } 4742 4743 if (mProfileProc == app) { 4744 clearProfilerLocked(); 4745 } 4746 4747 // Remove this application's activities from active lists. 4748 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4749 4750 app.activities.clear(); 4751 4752 if (app.instrumentationClass != null) { 4753 Slog.w(TAG, "Crash of app " + app.processName 4754 + " running instrumentation " + app.instrumentationClass); 4755 Bundle info = new Bundle(); 4756 info.putString("shortMsg", "Process crashed."); 4757 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4758 } 4759 4760 if (!restarting) { 4761 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4762 // If there was nothing to resume, and we are not already 4763 // restarting this process, but there is a visible activity that 4764 // is hosted by the process... then make sure all visible 4765 // activities are running, taking care of restarting this 4766 // process. 4767 if (hasVisibleActivities) { 4768 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4769 } 4770 } 4771 } 4772 } 4773 4774 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4775 IBinder threadBinder = thread.asBinder(); 4776 // Find the application record. 4777 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4778 ProcessRecord rec = mLruProcesses.get(i); 4779 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4780 return i; 4781 } 4782 } 4783 return -1; 4784 } 4785 4786 final ProcessRecord getRecordForAppLocked( 4787 IApplicationThread thread) { 4788 if (thread == null) { 4789 return null; 4790 } 4791 4792 int appIndex = getLRURecordIndexForAppLocked(thread); 4793 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4794 } 4795 4796 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4797 // If there are no longer any background processes running, 4798 // and the app that died was not running instrumentation, 4799 // then tell everyone we are now low on memory. 4800 boolean haveBg = false; 4801 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4802 ProcessRecord rec = mLruProcesses.get(i); 4803 if (rec.thread != null 4804 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4805 haveBg = true; 4806 break; 4807 } 4808 } 4809 4810 if (!haveBg) { 4811 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4812 if (doReport) { 4813 long now = SystemClock.uptimeMillis(); 4814 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4815 doReport = false; 4816 } else { 4817 mLastMemUsageReportTime = now; 4818 } 4819 } 4820 final ArrayList<ProcessMemInfo> memInfos 4821 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4822 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4823 long now = SystemClock.uptimeMillis(); 4824 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4825 ProcessRecord rec = mLruProcesses.get(i); 4826 if (rec == dyingProc || rec.thread == null) { 4827 continue; 4828 } 4829 if (doReport) { 4830 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4831 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4832 } 4833 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4834 // The low memory report is overriding any current 4835 // state for a GC request. Make sure to do 4836 // heavy/important/visible/foreground processes first. 4837 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4838 rec.lastRequestedGc = 0; 4839 } else { 4840 rec.lastRequestedGc = rec.lastLowMemory; 4841 } 4842 rec.reportLowMemory = true; 4843 rec.lastLowMemory = now; 4844 mProcessesToGc.remove(rec); 4845 addProcessToGcListLocked(rec); 4846 } 4847 } 4848 if (doReport) { 4849 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4850 mHandler.sendMessage(msg); 4851 } 4852 scheduleAppGcsLocked(); 4853 } 4854 } 4855 4856 final void appDiedLocked(ProcessRecord app) { 4857 appDiedLocked(app, app.pid, app.thread); 4858 } 4859 4860 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4861 // First check if this ProcessRecord is actually active for the pid. 4862 synchronized (mPidsSelfLocked) { 4863 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4864 if (curProc != app) { 4865 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4866 return; 4867 } 4868 } 4869 4870 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4871 synchronized (stats) { 4872 stats.noteProcessDiedLocked(app.info.uid, pid); 4873 } 4874 4875 Process.killProcessQuiet(pid); 4876 Process.killProcessGroup(app.info.uid, pid); 4877 app.killed = true; 4878 4879 // Clean up already done if the process has been re-started. 4880 if (app.pid == pid && app.thread != null && 4881 app.thread.asBinder() == thread.asBinder()) { 4882 boolean doLowMem = app.instrumentationClass == null; 4883 boolean doOomAdj = doLowMem; 4884 if (!app.killedByAm) { 4885 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4886 + ") has died"); 4887 mAllowLowerMemLevel = true; 4888 } else { 4889 // Note that we always want to do oom adj to update our state with the 4890 // new number of procs. 4891 mAllowLowerMemLevel = false; 4892 doLowMem = false; 4893 } 4894 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4895 if (DEBUG_CLEANUP) Slog.v( 4896 TAG, "Dying app: " + app + ", pid: " + pid 4897 + ", thread: " + thread.asBinder()); 4898 handleAppDiedLocked(app, false, true); 4899 4900 if (doOomAdj) { 4901 updateOomAdjLocked(); 4902 } 4903 if (doLowMem) { 4904 doLowMemReportIfNeededLocked(app); 4905 } 4906 } else if (app.pid != pid) { 4907 // A new process has already been started. 4908 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4909 + ") has died and restarted (pid " + app.pid + ")."); 4910 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4911 } else if (DEBUG_PROCESSES) { 4912 Slog.d(TAG, "Received spurious death notification for thread " 4913 + thread.asBinder()); 4914 } 4915 } 4916 4917 /** 4918 * If a stack trace dump file is configured, dump process stack traces. 4919 * @param clearTraces causes the dump file to be erased prior to the new 4920 * traces being written, if true; when false, the new traces will be 4921 * appended to any existing file content. 4922 * @param firstPids of dalvik VM processes to dump stack traces for first 4923 * @param lastPids of dalvik VM processes to dump stack traces for last 4924 * @param nativeProcs optional list of native process names to dump stack crawls 4925 * @return file containing stack traces, or null if no dump file is configured 4926 */ 4927 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4928 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4929 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4930 if (tracesPath == null || tracesPath.length() == 0) { 4931 return null; 4932 } 4933 4934 File tracesFile = new File(tracesPath); 4935 try { 4936 File tracesDir = tracesFile.getParentFile(); 4937 if (!tracesDir.exists()) { 4938 tracesDir.mkdirs(); 4939 if (!SELinux.restorecon(tracesDir)) { 4940 return null; 4941 } 4942 } 4943 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4944 4945 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4946 tracesFile.createNewFile(); 4947 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4948 } catch (IOException e) { 4949 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4950 return null; 4951 } 4952 4953 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4954 return tracesFile; 4955 } 4956 4957 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4958 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4959 // Use a FileObserver to detect when traces finish writing. 4960 // The order of traces is considered important to maintain for legibility. 4961 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4962 @Override 4963 public synchronized void onEvent(int event, String path) { notify(); } 4964 }; 4965 4966 try { 4967 observer.startWatching(); 4968 4969 // First collect all of the stacks of the most important pids. 4970 if (firstPids != null) { 4971 try { 4972 int num = firstPids.size(); 4973 for (int i = 0; i < num; i++) { 4974 synchronized (observer) { 4975 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4976 observer.wait(200); // Wait for write-close, give up after 200msec 4977 } 4978 } 4979 } catch (InterruptedException e) { 4980 Slog.wtf(TAG, e); 4981 } 4982 } 4983 4984 // Next collect the stacks of the native pids 4985 if (nativeProcs != null) { 4986 int[] pids = Process.getPidsForCommands(nativeProcs); 4987 if (pids != null) { 4988 for (int pid : pids) { 4989 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4990 } 4991 } 4992 } 4993 4994 // Lastly, measure CPU usage. 4995 if (processCpuTracker != null) { 4996 processCpuTracker.init(); 4997 System.gc(); 4998 processCpuTracker.update(); 4999 try { 5000 synchronized (processCpuTracker) { 5001 processCpuTracker.wait(500); // measure over 1/2 second. 5002 } 5003 } catch (InterruptedException e) { 5004 } 5005 processCpuTracker.update(); 5006 5007 // We'll take the stack crawls of just the top apps using CPU. 5008 final int N = processCpuTracker.countWorkingStats(); 5009 int numProcs = 0; 5010 for (int i=0; i<N && numProcs<5; i++) { 5011 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5012 if (lastPids.indexOfKey(stats.pid) >= 0) { 5013 numProcs++; 5014 try { 5015 synchronized (observer) { 5016 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5017 observer.wait(200); // Wait for write-close, give up after 200msec 5018 } 5019 } catch (InterruptedException e) { 5020 Slog.wtf(TAG, e); 5021 } 5022 5023 } 5024 } 5025 } 5026 } finally { 5027 observer.stopWatching(); 5028 } 5029 } 5030 5031 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5032 if (true || IS_USER_BUILD) { 5033 return; 5034 } 5035 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5036 if (tracesPath == null || tracesPath.length() == 0) { 5037 return; 5038 } 5039 5040 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5041 StrictMode.allowThreadDiskWrites(); 5042 try { 5043 final File tracesFile = new File(tracesPath); 5044 final File tracesDir = tracesFile.getParentFile(); 5045 final File tracesTmp = new File(tracesDir, "__tmp__"); 5046 try { 5047 if (!tracesDir.exists()) { 5048 tracesDir.mkdirs(); 5049 if (!SELinux.restorecon(tracesDir.getPath())) { 5050 return; 5051 } 5052 } 5053 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5054 5055 if (tracesFile.exists()) { 5056 tracesTmp.delete(); 5057 tracesFile.renameTo(tracesTmp); 5058 } 5059 StringBuilder sb = new StringBuilder(); 5060 Time tobj = new Time(); 5061 tobj.set(System.currentTimeMillis()); 5062 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5063 sb.append(": "); 5064 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5065 sb.append(" since "); 5066 sb.append(msg); 5067 FileOutputStream fos = new FileOutputStream(tracesFile); 5068 fos.write(sb.toString().getBytes()); 5069 if (app == null) { 5070 fos.write("\n*** No application process!".getBytes()); 5071 } 5072 fos.close(); 5073 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5074 } catch (IOException e) { 5075 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5076 return; 5077 } 5078 5079 if (app != null) { 5080 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5081 firstPids.add(app.pid); 5082 dumpStackTraces(tracesPath, firstPids, null, null, null); 5083 } 5084 5085 File lastTracesFile = null; 5086 File curTracesFile = null; 5087 for (int i=9; i>=0; i--) { 5088 String name = String.format(Locale.US, "slow%02d.txt", i); 5089 curTracesFile = new File(tracesDir, name); 5090 if (curTracesFile.exists()) { 5091 if (lastTracesFile != null) { 5092 curTracesFile.renameTo(lastTracesFile); 5093 } else { 5094 curTracesFile.delete(); 5095 } 5096 } 5097 lastTracesFile = curTracesFile; 5098 } 5099 tracesFile.renameTo(curTracesFile); 5100 if (tracesTmp.exists()) { 5101 tracesTmp.renameTo(tracesFile); 5102 } 5103 } finally { 5104 StrictMode.setThreadPolicy(oldPolicy); 5105 } 5106 } 5107 5108 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5109 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5110 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5111 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5112 5113 if (mController != null) { 5114 try { 5115 // 0 == continue, -1 = kill process immediately 5116 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5117 if (res < 0 && app.pid != MY_PID) { 5118 app.kill("anr", true); 5119 } 5120 } catch (RemoteException e) { 5121 mController = null; 5122 Watchdog.getInstance().setActivityController(null); 5123 } 5124 } 5125 5126 long anrTime = SystemClock.uptimeMillis(); 5127 if (MONITOR_CPU_USAGE) { 5128 updateCpuStatsNow(); 5129 } 5130 5131 synchronized (this) { 5132 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5133 if (mShuttingDown) { 5134 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5135 return; 5136 } else if (app.notResponding) { 5137 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5138 return; 5139 } else if (app.crashing) { 5140 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5141 return; 5142 } 5143 5144 // In case we come through here for the same app before completing 5145 // this one, mark as anring now so we will bail out. 5146 app.notResponding = true; 5147 5148 // Log the ANR to the event log. 5149 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5150 app.processName, app.info.flags, annotation); 5151 5152 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5153 firstPids.add(app.pid); 5154 5155 int parentPid = app.pid; 5156 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5157 if (parentPid != app.pid) firstPids.add(parentPid); 5158 5159 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5160 5161 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5162 ProcessRecord r = mLruProcesses.get(i); 5163 if (r != null && r.thread != null) { 5164 int pid = r.pid; 5165 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5166 if (r.persistent) { 5167 firstPids.add(pid); 5168 } else { 5169 lastPids.put(pid, Boolean.TRUE); 5170 } 5171 } 5172 } 5173 } 5174 } 5175 5176 // Log the ANR to the main log. 5177 StringBuilder info = new StringBuilder(); 5178 info.setLength(0); 5179 info.append("ANR in ").append(app.processName); 5180 if (activity != null && activity.shortComponentName != null) { 5181 info.append(" (").append(activity.shortComponentName).append(")"); 5182 } 5183 info.append("\n"); 5184 info.append("PID: ").append(app.pid).append("\n"); 5185 if (annotation != null) { 5186 info.append("Reason: ").append(annotation).append("\n"); 5187 } 5188 if (parent != null && parent != activity) { 5189 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5190 } 5191 5192 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5193 5194 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5195 NATIVE_STACKS_OF_INTEREST); 5196 5197 String cpuInfo = null; 5198 if (MONITOR_CPU_USAGE) { 5199 updateCpuStatsNow(); 5200 synchronized (mProcessCpuTracker) { 5201 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5202 } 5203 info.append(processCpuTracker.printCurrentLoad()); 5204 info.append(cpuInfo); 5205 } 5206 5207 info.append(processCpuTracker.printCurrentState(anrTime)); 5208 5209 Slog.e(TAG, info.toString()); 5210 if (tracesFile == null) { 5211 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5212 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5213 } 5214 5215 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5216 cpuInfo, tracesFile, null); 5217 5218 if (mController != null) { 5219 try { 5220 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5221 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5222 if (res != 0) { 5223 if (res < 0 && app.pid != MY_PID) { 5224 app.kill("anr", true); 5225 } else { 5226 synchronized (this) { 5227 mServices.scheduleServiceTimeoutLocked(app); 5228 } 5229 } 5230 return; 5231 } 5232 } catch (RemoteException e) { 5233 mController = null; 5234 Watchdog.getInstance().setActivityController(null); 5235 } 5236 } 5237 5238 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5239 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5240 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5241 5242 synchronized (this) { 5243 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5244 app.kill("bg anr", true); 5245 return; 5246 } 5247 5248 // Set the app's notResponding state, and look up the errorReportReceiver 5249 makeAppNotRespondingLocked(app, 5250 activity != null ? activity.shortComponentName : null, 5251 annotation != null ? "ANR " + annotation : "ANR", 5252 info.toString()); 5253 5254 // Bring up the infamous App Not Responding dialog 5255 Message msg = Message.obtain(); 5256 HashMap<String, Object> map = new HashMap<String, Object>(); 5257 msg.what = SHOW_NOT_RESPONDING_MSG; 5258 msg.obj = map; 5259 msg.arg1 = aboveSystem ? 1 : 0; 5260 map.put("app", app); 5261 if (activity != null) { 5262 map.put("activity", activity); 5263 } 5264 5265 mHandler.sendMessage(msg); 5266 } 5267 } 5268 5269 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5270 if (!mLaunchWarningShown) { 5271 mLaunchWarningShown = true; 5272 mHandler.post(new Runnable() { 5273 @Override 5274 public void run() { 5275 synchronized (ActivityManagerService.this) { 5276 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5277 d.show(); 5278 mHandler.postDelayed(new Runnable() { 5279 @Override 5280 public void run() { 5281 synchronized (ActivityManagerService.this) { 5282 d.dismiss(); 5283 mLaunchWarningShown = false; 5284 } 5285 } 5286 }, 4000); 5287 } 5288 } 5289 }); 5290 } 5291 } 5292 5293 @Override 5294 public boolean clearApplicationUserData(final String packageName, 5295 final IPackageDataObserver observer, int userId) { 5296 enforceNotIsolatedCaller("clearApplicationUserData"); 5297 int uid = Binder.getCallingUid(); 5298 int pid = Binder.getCallingPid(); 5299 userId = handleIncomingUser(pid, uid, 5300 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5301 long callingId = Binder.clearCallingIdentity(); 5302 try { 5303 IPackageManager pm = AppGlobals.getPackageManager(); 5304 int pkgUid = -1; 5305 synchronized(this) { 5306 try { 5307 pkgUid = pm.getPackageUid(packageName, userId); 5308 } catch (RemoteException e) { 5309 } 5310 if (pkgUid == -1) { 5311 Slog.w(TAG, "Invalid packageName: " + packageName); 5312 if (observer != null) { 5313 try { 5314 observer.onRemoveCompleted(packageName, false); 5315 } catch (RemoteException e) { 5316 Slog.i(TAG, "Observer no longer exists."); 5317 } 5318 } 5319 return false; 5320 } 5321 if (uid == pkgUid || checkComponentPermission( 5322 android.Manifest.permission.CLEAR_APP_USER_DATA, 5323 pid, uid, -1, true) 5324 == PackageManager.PERMISSION_GRANTED) { 5325 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5326 } else { 5327 throw new SecurityException("PID " + pid + " does not have permission " 5328 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5329 + " of package " + packageName); 5330 } 5331 5332 // Remove all tasks match the cleared application package and user 5333 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5334 final TaskRecord tr = mRecentTasks.get(i); 5335 final String taskPackageName = 5336 tr.getBaseIntent().getComponent().getPackageName(); 5337 if (tr.userId != userId) continue; 5338 if (!taskPackageName.equals(packageName)) continue; 5339 removeTaskByIdLocked(tr.taskId, 0); 5340 } 5341 } 5342 5343 try { 5344 // Clear application user data 5345 pm.clearApplicationUserData(packageName, observer, userId); 5346 5347 synchronized(this) { 5348 // Remove all permissions granted from/to this package 5349 removeUriPermissionsForPackageLocked(packageName, userId, true); 5350 } 5351 5352 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5353 Uri.fromParts("package", packageName, null)); 5354 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5355 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5356 null, null, 0, null, null, null, false, false, userId); 5357 } catch (RemoteException e) { 5358 } 5359 } finally { 5360 Binder.restoreCallingIdentity(callingId); 5361 } 5362 return true; 5363 } 5364 5365 @Override 5366 public void killBackgroundProcesses(final String packageName, int userId) { 5367 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5368 != PackageManager.PERMISSION_GRANTED && 5369 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5370 != PackageManager.PERMISSION_GRANTED) { 5371 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5372 + Binder.getCallingPid() 5373 + ", uid=" + Binder.getCallingUid() 5374 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5375 Slog.w(TAG, msg); 5376 throw new SecurityException(msg); 5377 } 5378 5379 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5380 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5381 long callingId = Binder.clearCallingIdentity(); 5382 try { 5383 IPackageManager pm = AppGlobals.getPackageManager(); 5384 synchronized(this) { 5385 int appId = -1; 5386 try { 5387 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5388 } catch (RemoteException e) { 5389 } 5390 if (appId == -1) { 5391 Slog.w(TAG, "Invalid packageName: " + packageName); 5392 return; 5393 } 5394 killPackageProcessesLocked(packageName, appId, userId, 5395 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5396 } 5397 } finally { 5398 Binder.restoreCallingIdentity(callingId); 5399 } 5400 } 5401 5402 @Override 5403 public void killAllBackgroundProcesses() { 5404 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5405 != PackageManager.PERMISSION_GRANTED) { 5406 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5407 + Binder.getCallingPid() 5408 + ", uid=" + Binder.getCallingUid() 5409 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5410 Slog.w(TAG, msg); 5411 throw new SecurityException(msg); 5412 } 5413 5414 long callingId = Binder.clearCallingIdentity(); 5415 try { 5416 synchronized(this) { 5417 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5418 final int NP = mProcessNames.getMap().size(); 5419 for (int ip=0; ip<NP; ip++) { 5420 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5421 final int NA = apps.size(); 5422 for (int ia=0; ia<NA; ia++) { 5423 ProcessRecord app = apps.valueAt(ia); 5424 if (app.persistent) { 5425 // we don't kill persistent processes 5426 continue; 5427 } 5428 if (app.removed) { 5429 procs.add(app); 5430 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5431 app.removed = true; 5432 procs.add(app); 5433 } 5434 } 5435 } 5436 5437 int N = procs.size(); 5438 for (int i=0; i<N; i++) { 5439 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5440 } 5441 mAllowLowerMemLevel = true; 5442 updateOomAdjLocked(); 5443 doLowMemReportIfNeededLocked(null); 5444 } 5445 } finally { 5446 Binder.restoreCallingIdentity(callingId); 5447 } 5448 } 5449 5450 @Override 5451 public void forceStopPackage(final String packageName, int userId) { 5452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5453 != PackageManager.PERMISSION_GRANTED) { 5454 String msg = "Permission Denial: forceStopPackage() from pid=" 5455 + Binder.getCallingPid() 5456 + ", uid=" + Binder.getCallingUid() 5457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5458 Slog.w(TAG, msg); 5459 throw new SecurityException(msg); 5460 } 5461 final int callingPid = Binder.getCallingPid(); 5462 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5463 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5464 long callingId = Binder.clearCallingIdentity(); 5465 try { 5466 IPackageManager pm = AppGlobals.getPackageManager(); 5467 synchronized(this) { 5468 int[] users = userId == UserHandle.USER_ALL 5469 ? getUsersLocked() : new int[] { userId }; 5470 for (int user : users) { 5471 int pkgUid = -1; 5472 try { 5473 pkgUid = pm.getPackageUid(packageName, user); 5474 } catch (RemoteException e) { 5475 } 5476 if (pkgUid == -1) { 5477 Slog.w(TAG, "Invalid packageName: " + packageName); 5478 continue; 5479 } 5480 try { 5481 pm.setPackageStoppedState(packageName, true, user); 5482 } catch (RemoteException e) { 5483 } catch (IllegalArgumentException e) { 5484 Slog.w(TAG, "Failed trying to unstop package " 5485 + packageName + ": " + e); 5486 } 5487 if (isUserRunningLocked(user, false)) { 5488 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5489 } 5490 } 5491 } 5492 } finally { 5493 Binder.restoreCallingIdentity(callingId); 5494 } 5495 } 5496 5497 @Override 5498 public void addPackageDependency(String packageName) { 5499 synchronized (this) { 5500 int callingPid = Binder.getCallingPid(); 5501 if (callingPid == Process.myPid()) { 5502 // Yeah, um, no. 5503 Slog.w(TAG, "Can't addPackageDependency on system process"); 5504 return; 5505 } 5506 ProcessRecord proc; 5507 synchronized (mPidsSelfLocked) { 5508 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5509 } 5510 if (proc != null) { 5511 if (proc.pkgDeps == null) { 5512 proc.pkgDeps = new ArraySet<String>(1); 5513 } 5514 proc.pkgDeps.add(packageName); 5515 } 5516 } 5517 } 5518 5519 /* 5520 * The pkg name and app id have to be specified. 5521 */ 5522 @Override 5523 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5524 if (pkg == null) { 5525 return; 5526 } 5527 // Make sure the uid is valid. 5528 if (appid < 0) { 5529 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5530 return; 5531 } 5532 int callerUid = Binder.getCallingUid(); 5533 // Only the system server can kill an application 5534 if (callerUid == Process.SYSTEM_UID) { 5535 // Post an aysnc message to kill the application 5536 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5537 msg.arg1 = appid; 5538 msg.arg2 = 0; 5539 Bundle bundle = new Bundle(); 5540 bundle.putString("pkg", pkg); 5541 bundle.putString("reason", reason); 5542 msg.obj = bundle; 5543 mHandler.sendMessage(msg); 5544 } else { 5545 throw new SecurityException(callerUid + " cannot kill pkg: " + 5546 pkg); 5547 } 5548 } 5549 5550 @Override 5551 public void closeSystemDialogs(String reason) { 5552 enforceNotIsolatedCaller("closeSystemDialogs"); 5553 5554 final int pid = Binder.getCallingPid(); 5555 final int uid = Binder.getCallingUid(); 5556 final long origId = Binder.clearCallingIdentity(); 5557 try { 5558 synchronized (this) { 5559 // Only allow this from foreground processes, so that background 5560 // applications can't abuse it to prevent system UI from being shown. 5561 if (uid >= Process.FIRST_APPLICATION_UID) { 5562 ProcessRecord proc; 5563 synchronized (mPidsSelfLocked) { 5564 proc = mPidsSelfLocked.get(pid); 5565 } 5566 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5567 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5568 + " from background process " + proc); 5569 return; 5570 } 5571 } 5572 closeSystemDialogsLocked(reason); 5573 } 5574 } finally { 5575 Binder.restoreCallingIdentity(origId); 5576 } 5577 } 5578 5579 void closeSystemDialogsLocked(String reason) { 5580 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5581 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5582 | Intent.FLAG_RECEIVER_FOREGROUND); 5583 if (reason != null) { 5584 intent.putExtra("reason", reason); 5585 } 5586 mWindowManager.closeSystemDialogs(reason); 5587 5588 mStackSupervisor.closeSystemDialogsLocked(); 5589 5590 broadcastIntentLocked(null, null, intent, null, 5591 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5592 Process.SYSTEM_UID, UserHandle.USER_ALL); 5593 } 5594 5595 @Override 5596 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5597 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5598 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5599 for (int i=pids.length-1; i>=0; i--) { 5600 ProcessRecord proc; 5601 int oomAdj; 5602 synchronized (this) { 5603 synchronized (mPidsSelfLocked) { 5604 proc = mPidsSelfLocked.get(pids[i]); 5605 oomAdj = proc != null ? proc.setAdj : 0; 5606 } 5607 } 5608 infos[i] = new Debug.MemoryInfo(); 5609 Debug.getMemoryInfo(pids[i], infos[i]); 5610 if (proc != null) { 5611 synchronized (this) { 5612 if (proc.thread != null && proc.setAdj == oomAdj) { 5613 // Record this for posterity if the process has been stable. 5614 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5615 infos[i].getTotalUss(), false, proc.pkgList); 5616 } 5617 } 5618 } 5619 } 5620 return infos; 5621 } 5622 5623 @Override 5624 public long[] getProcessPss(int[] pids) { 5625 enforceNotIsolatedCaller("getProcessPss"); 5626 long[] pss = new long[pids.length]; 5627 for (int i=pids.length-1; i>=0; i--) { 5628 ProcessRecord proc; 5629 int oomAdj; 5630 synchronized (this) { 5631 synchronized (mPidsSelfLocked) { 5632 proc = mPidsSelfLocked.get(pids[i]); 5633 oomAdj = proc != null ? proc.setAdj : 0; 5634 } 5635 } 5636 long[] tmpUss = new long[1]; 5637 pss[i] = Debug.getPss(pids[i], tmpUss); 5638 if (proc != null) { 5639 synchronized (this) { 5640 if (proc.thread != null && proc.setAdj == oomAdj) { 5641 // Record this for posterity if the process has been stable. 5642 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5643 } 5644 } 5645 } 5646 } 5647 return pss; 5648 } 5649 5650 @Override 5651 public void killApplicationProcess(String processName, int uid) { 5652 if (processName == null) { 5653 return; 5654 } 5655 5656 int callerUid = Binder.getCallingUid(); 5657 // Only the system server can kill an application 5658 if (callerUid == Process.SYSTEM_UID) { 5659 synchronized (this) { 5660 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5661 if (app != null && app.thread != null) { 5662 try { 5663 app.thread.scheduleSuicide(); 5664 } catch (RemoteException e) { 5665 // If the other end already died, then our work here is done. 5666 } 5667 } else { 5668 Slog.w(TAG, "Process/uid not found attempting kill of " 5669 + processName + " / " + uid); 5670 } 5671 } 5672 } else { 5673 throw new SecurityException(callerUid + " cannot kill app process: " + 5674 processName); 5675 } 5676 } 5677 5678 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5679 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5680 false, true, false, false, UserHandle.getUserId(uid), reason); 5681 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5682 Uri.fromParts("package", packageName, null)); 5683 if (!mProcessesReady) { 5684 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5685 | Intent.FLAG_RECEIVER_FOREGROUND); 5686 } 5687 intent.putExtra(Intent.EXTRA_UID, uid); 5688 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5689 broadcastIntentLocked(null, null, intent, 5690 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5691 false, false, 5692 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5693 } 5694 5695 private void forceStopUserLocked(int userId, String reason) { 5696 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5697 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5698 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5699 | Intent.FLAG_RECEIVER_FOREGROUND); 5700 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5701 broadcastIntentLocked(null, null, intent, 5702 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5703 false, false, 5704 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5705 } 5706 5707 private final boolean killPackageProcessesLocked(String packageName, int appId, 5708 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5709 boolean doit, boolean evenPersistent, String reason) { 5710 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5711 5712 // Remove all processes this package may have touched: all with the 5713 // same UID (except for the system or root user), and all whose name 5714 // matches the package name. 5715 final int NP = mProcessNames.getMap().size(); 5716 for (int ip=0; ip<NP; ip++) { 5717 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5718 final int NA = apps.size(); 5719 for (int ia=0; ia<NA; ia++) { 5720 ProcessRecord app = apps.valueAt(ia); 5721 if (app.persistent && !evenPersistent) { 5722 // we don't kill persistent processes 5723 continue; 5724 } 5725 if (app.removed) { 5726 if (doit) { 5727 procs.add(app); 5728 } 5729 continue; 5730 } 5731 5732 // Skip process if it doesn't meet our oom adj requirement. 5733 if (app.setAdj < minOomAdj) { 5734 continue; 5735 } 5736 5737 // If no package is specified, we call all processes under the 5738 // give user id. 5739 if (packageName == null) { 5740 if (app.userId != userId) { 5741 continue; 5742 } 5743 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5744 continue; 5745 } 5746 // Package has been specified, we want to hit all processes 5747 // that match it. We need to qualify this by the processes 5748 // that are running under the specified app and user ID. 5749 } else { 5750 final boolean isDep = app.pkgDeps != null 5751 && app.pkgDeps.contains(packageName); 5752 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5753 continue; 5754 } 5755 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5756 continue; 5757 } 5758 if (!app.pkgList.containsKey(packageName) && !isDep) { 5759 continue; 5760 } 5761 } 5762 5763 // Process has passed all conditions, kill it! 5764 if (!doit) { 5765 return true; 5766 } 5767 app.removed = true; 5768 procs.add(app); 5769 } 5770 } 5771 5772 int N = procs.size(); 5773 for (int i=0; i<N; i++) { 5774 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5775 } 5776 updateOomAdjLocked(); 5777 return N > 0; 5778 } 5779 5780 private final boolean forceStopPackageLocked(String name, int appId, 5781 boolean callerWillRestart, boolean purgeCache, boolean doit, 5782 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5783 int i; 5784 int N; 5785 5786 if (userId == UserHandle.USER_ALL && name == null) { 5787 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5788 } 5789 5790 if (appId < 0 && name != null) { 5791 try { 5792 appId = UserHandle.getAppId( 5793 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5794 } catch (RemoteException e) { 5795 } 5796 } 5797 5798 if (doit) { 5799 if (name != null) { 5800 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5801 + " user=" + userId + ": " + reason); 5802 } else { 5803 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5804 } 5805 5806 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5807 for (int ip=pmap.size()-1; ip>=0; ip--) { 5808 SparseArray<Long> ba = pmap.valueAt(ip); 5809 for (i=ba.size()-1; i>=0; i--) { 5810 boolean remove = false; 5811 final int entUid = ba.keyAt(i); 5812 if (name != null) { 5813 if (userId == UserHandle.USER_ALL) { 5814 if (UserHandle.getAppId(entUid) == appId) { 5815 remove = true; 5816 } 5817 } else { 5818 if (entUid == UserHandle.getUid(userId, appId)) { 5819 remove = true; 5820 } 5821 } 5822 } else if (UserHandle.getUserId(entUid) == userId) { 5823 remove = true; 5824 } 5825 if (remove) { 5826 ba.removeAt(i); 5827 } 5828 } 5829 if (ba.size() == 0) { 5830 pmap.removeAt(ip); 5831 } 5832 } 5833 } 5834 5835 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5836 -100, callerWillRestart, true, doit, evenPersistent, 5837 name == null ? ("stop user " + userId) : ("stop " + name)); 5838 5839 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5840 if (!doit) { 5841 return true; 5842 } 5843 didSomething = true; 5844 } 5845 5846 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5847 if (!doit) { 5848 return true; 5849 } 5850 didSomething = true; 5851 } 5852 5853 if (name == null) { 5854 // Remove all sticky broadcasts from this user. 5855 mStickyBroadcasts.remove(userId); 5856 } 5857 5858 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5859 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5860 userId, providers)) { 5861 if (!doit) { 5862 return true; 5863 } 5864 didSomething = true; 5865 } 5866 N = providers.size(); 5867 for (i=0; i<N; i++) { 5868 removeDyingProviderLocked(null, providers.get(i), true); 5869 } 5870 5871 // Remove transient permissions granted from/to this package/user 5872 removeUriPermissionsForPackageLocked(name, userId, false); 5873 5874 if (name == null || uninstalling) { 5875 // Remove pending intents. For now we only do this when force 5876 // stopping users, because we have some problems when doing this 5877 // for packages -- app widgets are not currently cleaned up for 5878 // such packages, so they can be left with bad pending intents. 5879 if (mIntentSenderRecords.size() > 0) { 5880 Iterator<WeakReference<PendingIntentRecord>> it 5881 = mIntentSenderRecords.values().iterator(); 5882 while (it.hasNext()) { 5883 WeakReference<PendingIntentRecord> wpir = it.next(); 5884 if (wpir == null) { 5885 it.remove(); 5886 continue; 5887 } 5888 PendingIntentRecord pir = wpir.get(); 5889 if (pir == null) { 5890 it.remove(); 5891 continue; 5892 } 5893 if (name == null) { 5894 // Stopping user, remove all objects for the user. 5895 if (pir.key.userId != userId) { 5896 // Not the same user, skip it. 5897 continue; 5898 } 5899 } else { 5900 if (UserHandle.getAppId(pir.uid) != appId) { 5901 // Different app id, skip it. 5902 continue; 5903 } 5904 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5905 // Different user, skip it. 5906 continue; 5907 } 5908 if (!pir.key.packageName.equals(name)) { 5909 // Different package, skip it. 5910 continue; 5911 } 5912 } 5913 if (!doit) { 5914 return true; 5915 } 5916 didSomething = true; 5917 it.remove(); 5918 pir.canceled = true; 5919 if (pir.key.activity != null) { 5920 pir.key.activity.pendingResults.remove(pir.ref); 5921 } 5922 } 5923 } 5924 } 5925 5926 if (doit) { 5927 if (purgeCache && name != null) { 5928 AttributeCache ac = AttributeCache.instance(); 5929 if (ac != null) { 5930 ac.removePackage(name); 5931 } 5932 } 5933 if (mBooted) { 5934 mStackSupervisor.resumeTopActivitiesLocked(); 5935 mStackSupervisor.scheduleIdleLocked(); 5936 } 5937 } 5938 5939 return didSomething; 5940 } 5941 5942 private final boolean removeProcessLocked(ProcessRecord app, 5943 boolean callerWillRestart, boolean allowRestart, String reason) { 5944 final String name = app.processName; 5945 final int uid = app.uid; 5946 if (DEBUG_PROCESSES) Slog.d( 5947 TAG, "Force removing proc " + app.toShortString() + " (" + name 5948 + "/" + uid + ")"); 5949 5950 mProcessNames.remove(name, uid); 5951 mIsolatedProcesses.remove(app.uid); 5952 if (mHeavyWeightProcess == app) { 5953 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5954 mHeavyWeightProcess.userId, 0)); 5955 mHeavyWeightProcess = null; 5956 } 5957 boolean needRestart = false; 5958 if (app.pid > 0 && app.pid != MY_PID) { 5959 int pid = app.pid; 5960 synchronized (mPidsSelfLocked) { 5961 mPidsSelfLocked.remove(pid); 5962 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5963 } 5964 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5965 if (app.isolated) { 5966 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5967 } 5968 app.kill(reason, true); 5969 handleAppDiedLocked(app, true, allowRestart); 5970 removeLruProcessLocked(app); 5971 5972 if (app.persistent && !app.isolated) { 5973 if (!callerWillRestart) { 5974 addAppLocked(app.info, false, null /* ABI override */); 5975 } else { 5976 needRestart = true; 5977 } 5978 } 5979 } else { 5980 mRemovedProcesses.add(app); 5981 } 5982 5983 return needRestart; 5984 } 5985 5986 private final void processStartTimedOutLocked(ProcessRecord app) { 5987 final int pid = app.pid; 5988 boolean gone = false; 5989 synchronized (mPidsSelfLocked) { 5990 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5991 if (knownApp != null && knownApp.thread == null) { 5992 mPidsSelfLocked.remove(pid); 5993 gone = true; 5994 } 5995 } 5996 5997 if (gone) { 5998 Slog.w(TAG, "Process " + app + " failed to attach"); 5999 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 6000 pid, app.uid, app.processName); 6001 mProcessNames.remove(app.processName, app.uid); 6002 mIsolatedProcesses.remove(app.uid); 6003 if (mHeavyWeightProcess == app) { 6004 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6005 mHeavyWeightProcess.userId, 0)); 6006 mHeavyWeightProcess = null; 6007 } 6008 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6009 if (app.isolated) { 6010 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6011 } 6012 // Take care of any launching providers waiting for this process. 6013 checkAppInLaunchingProvidersLocked(app, true); 6014 // Take care of any services that are waiting for the process. 6015 mServices.processStartTimedOutLocked(app); 6016 app.kill("start timeout", true); 6017 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6018 Slog.w(TAG, "Unattached app died before backup, skipping"); 6019 try { 6020 IBackupManager bm = IBackupManager.Stub.asInterface( 6021 ServiceManager.getService(Context.BACKUP_SERVICE)); 6022 bm.agentDisconnected(app.info.packageName); 6023 } catch (RemoteException e) { 6024 // Can't happen; the backup manager is local 6025 } 6026 } 6027 if (isPendingBroadcastProcessLocked(pid)) { 6028 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6029 skipPendingBroadcastLocked(pid); 6030 } 6031 } else { 6032 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6033 } 6034 } 6035 6036 private final boolean attachApplicationLocked(IApplicationThread thread, 6037 int pid) { 6038 6039 // Find the application record that is being attached... either via 6040 // the pid if we are running in multiple processes, or just pull the 6041 // next app record if we are emulating process with anonymous threads. 6042 ProcessRecord app; 6043 if (pid != MY_PID && pid >= 0) { 6044 synchronized (mPidsSelfLocked) { 6045 app = mPidsSelfLocked.get(pid); 6046 } 6047 } else { 6048 app = null; 6049 } 6050 6051 if (app == null) { 6052 Slog.w(TAG, "No pending application record for pid " + pid 6053 + " (IApplicationThread " + thread + "); dropping process"); 6054 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6055 if (pid > 0 && pid != MY_PID) { 6056 Process.killProcessQuiet(pid); 6057 //TODO: Process.killProcessGroup(app.info.uid, pid); 6058 } else { 6059 try { 6060 thread.scheduleExit(); 6061 } catch (Exception e) { 6062 // Ignore exceptions. 6063 } 6064 } 6065 return false; 6066 } 6067 6068 // If this application record is still attached to a previous 6069 // process, clean it up now. 6070 if (app.thread != null) { 6071 handleAppDiedLocked(app, true, true); 6072 } 6073 6074 // Tell the process all about itself. 6075 6076 if (localLOGV) Slog.v( 6077 TAG, "Binding process pid " + pid + " to record " + app); 6078 6079 final String processName = app.processName; 6080 try { 6081 AppDeathRecipient adr = new AppDeathRecipient( 6082 app, pid, thread); 6083 thread.asBinder().linkToDeath(adr, 0); 6084 app.deathRecipient = adr; 6085 } catch (RemoteException e) { 6086 app.resetPackageList(mProcessStats); 6087 startProcessLocked(app, "link fail", processName); 6088 return false; 6089 } 6090 6091 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6092 6093 app.makeActive(thread, mProcessStats); 6094 app.curAdj = app.setAdj = -100; 6095 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6096 app.forcingToForeground = null; 6097 updateProcessForegroundLocked(app, false, false); 6098 app.hasShownUi = false; 6099 app.debugging = false; 6100 app.cached = false; 6101 6102 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6103 6104 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6105 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6106 6107 if (!normalMode) { 6108 Slog.i(TAG, "Launching preboot mode app: " + app); 6109 } 6110 6111 if (localLOGV) Slog.v( 6112 TAG, "New app record " + app 6113 + " thread=" + thread.asBinder() + " pid=" + pid); 6114 try { 6115 int testMode = IApplicationThread.DEBUG_OFF; 6116 if (mDebugApp != null && mDebugApp.equals(processName)) { 6117 testMode = mWaitForDebugger 6118 ? IApplicationThread.DEBUG_WAIT 6119 : IApplicationThread.DEBUG_ON; 6120 app.debugging = true; 6121 if (mDebugTransient) { 6122 mDebugApp = mOrigDebugApp; 6123 mWaitForDebugger = mOrigWaitForDebugger; 6124 } 6125 } 6126 String profileFile = app.instrumentationProfileFile; 6127 ParcelFileDescriptor profileFd = null; 6128 int samplingInterval = 0; 6129 boolean profileAutoStop = false; 6130 if (mProfileApp != null && mProfileApp.equals(processName)) { 6131 mProfileProc = app; 6132 profileFile = mProfileFile; 6133 profileFd = mProfileFd; 6134 samplingInterval = mSamplingInterval; 6135 profileAutoStop = mAutoStopProfiler; 6136 } 6137 boolean enableOpenGlTrace = false; 6138 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6139 enableOpenGlTrace = true; 6140 mOpenGlTraceApp = null; 6141 } 6142 6143 // If the app is being launched for restore or full backup, set it up specially 6144 boolean isRestrictedBackupMode = false; 6145 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6146 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6147 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6148 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6149 } 6150 6151 ensurePackageDexOpt(app.instrumentationInfo != null 6152 ? app.instrumentationInfo.packageName 6153 : app.info.packageName); 6154 if (app.instrumentationClass != null) { 6155 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6156 } 6157 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6158 + processName + " with config " + mConfiguration); 6159 ApplicationInfo appInfo = app.instrumentationInfo != null 6160 ? app.instrumentationInfo : app.info; 6161 app.compat = compatibilityInfoForPackageLocked(appInfo); 6162 if (profileFd != null) { 6163 profileFd = profileFd.dup(); 6164 } 6165 ProfilerInfo profilerInfo = profileFile == null ? null 6166 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6167 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6168 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6169 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6170 isRestrictedBackupMode || !normalMode, app.persistent, 6171 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6172 mCoreSettingsObserver.getCoreSettingsLocked()); 6173 updateLruProcessLocked(app, false, null); 6174 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6175 } catch (Exception e) { 6176 // todo: Yikes! What should we do? For now we will try to 6177 // start another process, but that could easily get us in 6178 // an infinite loop of restarting processes... 6179 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6180 6181 app.resetPackageList(mProcessStats); 6182 app.unlinkDeathRecipient(); 6183 startProcessLocked(app, "bind fail", processName); 6184 return false; 6185 } 6186 6187 // Remove this record from the list of starting applications. 6188 mPersistentStartingProcesses.remove(app); 6189 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6190 "Attach application locked removing on hold: " + app); 6191 mProcessesOnHold.remove(app); 6192 6193 boolean badApp = false; 6194 boolean didSomething = false; 6195 6196 // See if the top visible activity is waiting to run in this process... 6197 if (normalMode) { 6198 try { 6199 if (mStackSupervisor.attachApplicationLocked(app)) { 6200 didSomething = true; 6201 } 6202 } catch (Exception e) { 6203 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6204 badApp = true; 6205 } 6206 } 6207 6208 // Find any services that should be running in this process... 6209 if (!badApp) { 6210 try { 6211 didSomething |= mServices.attachApplicationLocked(app, processName); 6212 } catch (Exception e) { 6213 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6214 badApp = true; 6215 } 6216 } 6217 6218 // Check if a next-broadcast receiver is in this process... 6219 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6220 try { 6221 didSomething |= sendPendingBroadcastsLocked(app); 6222 } catch (Exception e) { 6223 // If the app died trying to launch the receiver we declare it 'bad' 6224 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6225 badApp = true; 6226 } 6227 } 6228 6229 // Check whether the next backup agent is in this process... 6230 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6231 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6232 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6233 try { 6234 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6235 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6236 mBackupTarget.backupMode); 6237 } catch (Exception e) { 6238 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6239 badApp = true; 6240 } 6241 } 6242 6243 if (badApp) { 6244 app.kill("error during init", true); 6245 handleAppDiedLocked(app, false, true); 6246 return false; 6247 } 6248 6249 if (!didSomething) { 6250 updateOomAdjLocked(); 6251 } 6252 6253 return true; 6254 } 6255 6256 @Override 6257 public final void attachApplication(IApplicationThread thread) { 6258 synchronized (this) { 6259 int callingPid = Binder.getCallingPid(); 6260 final long origId = Binder.clearCallingIdentity(); 6261 attachApplicationLocked(thread, callingPid); 6262 Binder.restoreCallingIdentity(origId); 6263 } 6264 } 6265 6266 @Override 6267 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6268 final long origId = Binder.clearCallingIdentity(); 6269 synchronized (this) { 6270 ActivityStack stack = ActivityRecord.getStackLocked(token); 6271 if (stack != null) { 6272 ActivityRecord r = 6273 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6274 if (stopProfiling) { 6275 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6276 try { 6277 mProfileFd.close(); 6278 } catch (IOException e) { 6279 } 6280 clearProfilerLocked(); 6281 } 6282 } 6283 } 6284 } 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6289 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6290 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6291 } 6292 6293 void enableScreenAfterBoot() { 6294 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6295 SystemClock.uptimeMillis()); 6296 mWindowManager.enableScreenAfterBoot(); 6297 6298 synchronized (this) { 6299 updateEventDispatchingLocked(); 6300 } 6301 } 6302 6303 @Override 6304 public void showBootMessage(final CharSequence msg, final boolean always) { 6305 enforceNotIsolatedCaller("showBootMessage"); 6306 mWindowManager.showBootMessage(msg, always); 6307 } 6308 6309 @Override 6310 public void keyguardWaitingForActivityDrawn() { 6311 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6312 final long token = Binder.clearCallingIdentity(); 6313 try { 6314 synchronized (this) { 6315 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6316 mWindowManager.keyguardWaitingForActivityDrawn(); 6317 if (mLockScreenShown) { 6318 mLockScreenShown = false; 6319 comeOutOfSleepIfNeededLocked(); 6320 } 6321 } 6322 } finally { 6323 Binder.restoreCallingIdentity(token); 6324 } 6325 } 6326 6327 final void finishBooting() { 6328 synchronized (this) { 6329 if (!mBootAnimationComplete) { 6330 mCallFinishBooting = true; 6331 return; 6332 } 6333 mCallFinishBooting = false; 6334 } 6335 6336 ArraySet<String> completedIsas = new ArraySet<String>(); 6337 for (String abi : Build.SUPPORTED_ABIS) { 6338 Process.establishZygoteConnectionForAbi(abi); 6339 final String instructionSet = VMRuntime.getInstructionSet(abi); 6340 if (!completedIsas.contains(instructionSet)) { 6341 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6342 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6343 } 6344 completedIsas.add(instructionSet); 6345 } 6346 } 6347 6348 // Register receivers to handle package update events 6349 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6350 6351 // Let system services know. 6352 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6353 6354 synchronized (this) { 6355 // Ensure that any processes we had put on hold are now started 6356 // up. 6357 final int NP = mProcessesOnHold.size(); 6358 if (NP > 0) { 6359 ArrayList<ProcessRecord> procs = 6360 new ArrayList<ProcessRecord>(mProcessesOnHold); 6361 for (int ip=0; ip<NP; ip++) { 6362 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6363 + procs.get(ip)); 6364 startProcessLocked(procs.get(ip), "on-hold", null); 6365 } 6366 } 6367 6368 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6369 // Start looking for apps that are abusing wake locks. 6370 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6371 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6372 // Tell anyone interested that we are done booting! 6373 SystemProperties.set("sys.boot_completed", "1"); 6374 6375 // And trigger dev.bootcomplete if we are not showing encryption progress 6376 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6377 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6378 SystemProperties.set("dev.bootcomplete", "1"); 6379 } 6380 for (int i=0; i<mStartedUsers.size(); i++) { 6381 UserStartedState uss = mStartedUsers.valueAt(i); 6382 if (uss.mState == UserStartedState.STATE_BOOTING) { 6383 uss.mState = UserStartedState.STATE_RUNNING; 6384 final int userId = mStartedUsers.keyAt(i); 6385 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6386 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6387 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6388 broadcastIntentLocked(null, null, intent, null, 6389 new IIntentReceiver.Stub() { 6390 @Override 6391 public void performReceive(Intent intent, int resultCode, 6392 String data, Bundle extras, boolean ordered, 6393 boolean sticky, int sendingUser) { 6394 synchronized (ActivityManagerService.this) { 6395 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6396 true, false); 6397 } 6398 } 6399 }, 6400 0, null, null, 6401 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6402 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6403 userId); 6404 } 6405 } 6406 scheduleStartProfilesLocked(); 6407 } 6408 } 6409 } 6410 6411 @Override 6412 public void bootAnimationComplete() { 6413 final boolean callFinishBooting; 6414 synchronized (this) { 6415 callFinishBooting = mCallFinishBooting; 6416 mBootAnimationComplete = true; 6417 } 6418 if (callFinishBooting) { 6419 finishBooting(); 6420 } 6421 } 6422 6423 final void ensureBootCompleted() { 6424 boolean booting; 6425 boolean enableScreen; 6426 synchronized (this) { 6427 booting = mBooting; 6428 mBooting = false; 6429 enableScreen = !mBooted; 6430 mBooted = true; 6431 } 6432 6433 if (booting) { 6434 finishBooting(); 6435 } 6436 6437 if (enableScreen) { 6438 enableScreenAfterBoot(); 6439 } 6440 } 6441 6442 @Override 6443 public final void activityResumed(IBinder token) { 6444 final long origId = Binder.clearCallingIdentity(); 6445 synchronized(this) { 6446 ActivityStack stack = ActivityRecord.getStackLocked(token); 6447 if (stack != null) { 6448 ActivityRecord.activityResumedLocked(token); 6449 } 6450 } 6451 Binder.restoreCallingIdentity(origId); 6452 } 6453 6454 @Override 6455 public final void activityPaused(IBinder token) { 6456 final long origId = Binder.clearCallingIdentity(); 6457 synchronized(this) { 6458 ActivityStack stack = ActivityRecord.getStackLocked(token); 6459 if (stack != null) { 6460 stack.activityPausedLocked(token, false); 6461 } 6462 } 6463 Binder.restoreCallingIdentity(origId); 6464 } 6465 6466 @Override 6467 public final void activityStopped(IBinder token, Bundle icicle, 6468 PersistableBundle persistentState, CharSequence description) { 6469 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6470 6471 // Refuse possible leaked file descriptors 6472 if (icicle != null && icicle.hasFileDescriptors()) { 6473 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6474 } 6475 6476 final long origId = Binder.clearCallingIdentity(); 6477 6478 synchronized (this) { 6479 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6480 if (r != null) { 6481 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6482 } 6483 } 6484 6485 trimApplications(); 6486 6487 Binder.restoreCallingIdentity(origId); 6488 } 6489 6490 @Override 6491 public final void activityDestroyed(IBinder token) { 6492 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6493 synchronized (this) { 6494 ActivityStack stack = ActivityRecord.getStackLocked(token); 6495 if (stack != null) { 6496 stack.activityDestroyedLocked(token); 6497 } 6498 } 6499 } 6500 6501 @Override 6502 public final void backgroundResourcesReleased(IBinder token) { 6503 final long origId = Binder.clearCallingIdentity(); 6504 try { 6505 synchronized (this) { 6506 ActivityStack stack = ActivityRecord.getStackLocked(token); 6507 if (stack != null) { 6508 stack.backgroundResourcesReleased(token); 6509 } 6510 } 6511 } finally { 6512 Binder.restoreCallingIdentity(origId); 6513 } 6514 } 6515 6516 @Override 6517 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6518 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6519 } 6520 6521 @Override 6522 public final void notifyEnterAnimationComplete(IBinder token) { 6523 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6524 } 6525 6526 @Override 6527 public String getCallingPackage(IBinder token) { 6528 synchronized (this) { 6529 ActivityRecord r = getCallingRecordLocked(token); 6530 return r != null ? r.info.packageName : null; 6531 } 6532 } 6533 6534 @Override 6535 public ComponentName getCallingActivity(IBinder token) { 6536 synchronized (this) { 6537 ActivityRecord r = getCallingRecordLocked(token); 6538 return r != null ? r.intent.getComponent() : null; 6539 } 6540 } 6541 6542 private ActivityRecord getCallingRecordLocked(IBinder token) { 6543 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6544 if (r == null) { 6545 return null; 6546 } 6547 return r.resultTo; 6548 } 6549 6550 @Override 6551 public ComponentName getActivityClassForToken(IBinder token) { 6552 synchronized(this) { 6553 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6554 if (r == null) { 6555 return null; 6556 } 6557 return r.intent.getComponent(); 6558 } 6559 } 6560 6561 @Override 6562 public String getPackageForToken(IBinder token) { 6563 synchronized(this) { 6564 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6565 if (r == null) { 6566 return null; 6567 } 6568 return r.packageName; 6569 } 6570 } 6571 6572 @Override 6573 public IIntentSender getIntentSender(int type, 6574 String packageName, IBinder token, String resultWho, 6575 int requestCode, Intent[] intents, String[] resolvedTypes, 6576 int flags, Bundle options, int userId) { 6577 enforceNotIsolatedCaller("getIntentSender"); 6578 // Refuse possible leaked file descriptors 6579 if (intents != null) { 6580 if (intents.length < 1) { 6581 throw new IllegalArgumentException("Intents array length must be >= 1"); 6582 } 6583 for (int i=0; i<intents.length; i++) { 6584 Intent intent = intents[i]; 6585 if (intent != null) { 6586 if (intent.hasFileDescriptors()) { 6587 throw new IllegalArgumentException("File descriptors passed in Intent"); 6588 } 6589 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6590 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6591 throw new IllegalArgumentException( 6592 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6593 } 6594 intents[i] = new Intent(intent); 6595 } 6596 } 6597 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6598 throw new IllegalArgumentException( 6599 "Intent array length does not match resolvedTypes length"); 6600 } 6601 } 6602 if (options != null) { 6603 if (options.hasFileDescriptors()) { 6604 throw new IllegalArgumentException("File descriptors passed in options"); 6605 } 6606 } 6607 6608 synchronized(this) { 6609 int callingUid = Binder.getCallingUid(); 6610 int origUserId = userId; 6611 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6612 type == ActivityManager.INTENT_SENDER_BROADCAST, 6613 ALLOW_NON_FULL, "getIntentSender", null); 6614 if (origUserId == UserHandle.USER_CURRENT) { 6615 // We don't want to evaluate this until the pending intent is 6616 // actually executed. However, we do want to always do the 6617 // security checking for it above. 6618 userId = UserHandle.USER_CURRENT; 6619 } 6620 try { 6621 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6622 int uid = AppGlobals.getPackageManager() 6623 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6624 if (!UserHandle.isSameApp(callingUid, uid)) { 6625 String msg = "Permission Denial: getIntentSender() from pid=" 6626 + Binder.getCallingPid() 6627 + ", uid=" + Binder.getCallingUid() 6628 + ", (need uid=" + uid + ")" 6629 + " is not allowed to send as package " + packageName; 6630 Slog.w(TAG, msg); 6631 throw new SecurityException(msg); 6632 } 6633 } 6634 6635 return getIntentSenderLocked(type, packageName, callingUid, userId, 6636 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6637 6638 } catch (RemoteException e) { 6639 throw new SecurityException(e); 6640 } 6641 } 6642 } 6643 6644 IIntentSender getIntentSenderLocked(int type, String packageName, 6645 int callingUid, int userId, IBinder token, String resultWho, 6646 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6647 Bundle options) { 6648 if (DEBUG_MU) 6649 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6650 ActivityRecord activity = null; 6651 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6652 activity = ActivityRecord.isInStackLocked(token); 6653 if (activity == null) { 6654 return null; 6655 } 6656 if (activity.finishing) { 6657 return null; 6658 } 6659 } 6660 6661 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6662 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6663 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6664 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6665 |PendingIntent.FLAG_UPDATE_CURRENT); 6666 6667 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6668 type, packageName, activity, resultWho, 6669 requestCode, intents, resolvedTypes, flags, options, userId); 6670 WeakReference<PendingIntentRecord> ref; 6671 ref = mIntentSenderRecords.get(key); 6672 PendingIntentRecord rec = ref != null ? ref.get() : null; 6673 if (rec != null) { 6674 if (!cancelCurrent) { 6675 if (updateCurrent) { 6676 if (rec.key.requestIntent != null) { 6677 rec.key.requestIntent.replaceExtras(intents != null ? 6678 intents[intents.length - 1] : null); 6679 } 6680 if (intents != null) { 6681 intents[intents.length-1] = rec.key.requestIntent; 6682 rec.key.allIntents = intents; 6683 rec.key.allResolvedTypes = resolvedTypes; 6684 } else { 6685 rec.key.allIntents = null; 6686 rec.key.allResolvedTypes = null; 6687 } 6688 } 6689 return rec; 6690 } 6691 rec.canceled = true; 6692 mIntentSenderRecords.remove(key); 6693 } 6694 if (noCreate) { 6695 return rec; 6696 } 6697 rec = new PendingIntentRecord(this, key, callingUid); 6698 mIntentSenderRecords.put(key, rec.ref); 6699 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6700 if (activity.pendingResults == null) { 6701 activity.pendingResults 6702 = new HashSet<WeakReference<PendingIntentRecord>>(); 6703 } 6704 activity.pendingResults.add(rec.ref); 6705 } 6706 return rec; 6707 } 6708 6709 @Override 6710 public void cancelIntentSender(IIntentSender sender) { 6711 if (!(sender instanceof PendingIntentRecord)) { 6712 return; 6713 } 6714 synchronized(this) { 6715 PendingIntentRecord rec = (PendingIntentRecord)sender; 6716 try { 6717 int uid = AppGlobals.getPackageManager() 6718 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6719 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6720 String msg = "Permission Denial: cancelIntentSender() from pid=" 6721 + Binder.getCallingPid() 6722 + ", uid=" + Binder.getCallingUid() 6723 + " is not allowed to cancel packges " 6724 + rec.key.packageName; 6725 Slog.w(TAG, msg); 6726 throw new SecurityException(msg); 6727 } 6728 } catch (RemoteException e) { 6729 throw new SecurityException(e); 6730 } 6731 cancelIntentSenderLocked(rec, true); 6732 } 6733 } 6734 6735 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6736 rec.canceled = true; 6737 mIntentSenderRecords.remove(rec.key); 6738 if (cleanActivity && rec.key.activity != null) { 6739 rec.key.activity.pendingResults.remove(rec.ref); 6740 } 6741 } 6742 6743 @Override 6744 public String getPackageForIntentSender(IIntentSender pendingResult) { 6745 if (!(pendingResult instanceof PendingIntentRecord)) { 6746 return null; 6747 } 6748 try { 6749 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6750 return res.key.packageName; 6751 } catch (ClassCastException e) { 6752 } 6753 return null; 6754 } 6755 6756 @Override 6757 public int getUidForIntentSender(IIntentSender sender) { 6758 if (sender instanceof PendingIntentRecord) { 6759 try { 6760 PendingIntentRecord res = (PendingIntentRecord)sender; 6761 return res.uid; 6762 } catch (ClassCastException e) { 6763 } 6764 } 6765 return -1; 6766 } 6767 6768 @Override 6769 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6770 if (!(pendingResult instanceof PendingIntentRecord)) { 6771 return false; 6772 } 6773 try { 6774 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6775 if (res.key.allIntents == null) { 6776 return false; 6777 } 6778 for (int i=0; i<res.key.allIntents.length; i++) { 6779 Intent intent = res.key.allIntents[i]; 6780 if (intent.getPackage() != null && intent.getComponent() != null) { 6781 return false; 6782 } 6783 } 6784 return true; 6785 } catch (ClassCastException e) { 6786 } 6787 return false; 6788 } 6789 6790 @Override 6791 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6792 if (!(pendingResult instanceof PendingIntentRecord)) { 6793 return false; 6794 } 6795 try { 6796 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6797 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6798 return true; 6799 } 6800 return false; 6801 } catch (ClassCastException e) { 6802 } 6803 return false; 6804 } 6805 6806 @Override 6807 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6808 if (!(pendingResult instanceof PendingIntentRecord)) { 6809 return null; 6810 } 6811 try { 6812 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6813 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6814 } catch (ClassCastException e) { 6815 } 6816 return null; 6817 } 6818 6819 @Override 6820 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6821 if (!(pendingResult instanceof PendingIntentRecord)) { 6822 return null; 6823 } 6824 try { 6825 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6826 Intent intent = res.key.requestIntent; 6827 if (intent != null) { 6828 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6829 || res.lastTagPrefix.equals(prefix))) { 6830 return res.lastTag; 6831 } 6832 res.lastTagPrefix = prefix; 6833 StringBuilder sb = new StringBuilder(128); 6834 if (prefix != null) { 6835 sb.append(prefix); 6836 } 6837 if (intent.getAction() != null) { 6838 sb.append(intent.getAction()); 6839 } else if (intent.getComponent() != null) { 6840 intent.getComponent().appendShortString(sb); 6841 } else { 6842 sb.append("?"); 6843 } 6844 return res.lastTag = sb.toString(); 6845 } 6846 } catch (ClassCastException e) { 6847 } 6848 return null; 6849 } 6850 6851 @Override 6852 public void setProcessLimit(int max) { 6853 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6854 "setProcessLimit()"); 6855 synchronized (this) { 6856 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6857 mProcessLimitOverride = max; 6858 } 6859 trimApplications(); 6860 } 6861 6862 @Override 6863 public int getProcessLimit() { 6864 synchronized (this) { 6865 return mProcessLimitOverride; 6866 } 6867 } 6868 6869 void foregroundTokenDied(ForegroundToken token) { 6870 synchronized (ActivityManagerService.this) { 6871 synchronized (mPidsSelfLocked) { 6872 ForegroundToken cur 6873 = mForegroundProcesses.get(token.pid); 6874 if (cur != token) { 6875 return; 6876 } 6877 mForegroundProcesses.remove(token.pid); 6878 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6879 if (pr == null) { 6880 return; 6881 } 6882 pr.forcingToForeground = null; 6883 updateProcessForegroundLocked(pr, false, false); 6884 } 6885 updateOomAdjLocked(); 6886 } 6887 } 6888 6889 @Override 6890 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6891 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6892 "setProcessForeground()"); 6893 synchronized(this) { 6894 boolean changed = false; 6895 6896 synchronized (mPidsSelfLocked) { 6897 ProcessRecord pr = mPidsSelfLocked.get(pid); 6898 if (pr == null && isForeground) { 6899 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6900 return; 6901 } 6902 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6903 if (oldToken != null) { 6904 oldToken.token.unlinkToDeath(oldToken, 0); 6905 mForegroundProcesses.remove(pid); 6906 if (pr != null) { 6907 pr.forcingToForeground = null; 6908 } 6909 changed = true; 6910 } 6911 if (isForeground && token != null) { 6912 ForegroundToken newToken = new ForegroundToken() { 6913 @Override 6914 public void binderDied() { 6915 foregroundTokenDied(this); 6916 } 6917 }; 6918 newToken.pid = pid; 6919 newToken.token = token; 6920 try { 6921 token.linkToDeath(newToken, 0); 6922 mForegroundProcesses.put(pid, newToken); 6923 pr.forcingToForeground = token; 6924 changed = true; 6925 } catch (RemoteException e) { 6926 // If the process died while doing this, we will later 6927 // do the cleanup with the process death link. 6928 } 6929 } 6930 } 6931 6932 if (changed) { 6933 updateOomAdjLocked(); 6934 } 6935 } 6936 } 6937 6938 // ========================================================= 6939 // PERMISSIONS 6940 // ========================================================= 6941 6942 static class PermissionController extends IPermissionController.Stub { 6943 ActivityManagerService mActivityManagerService; 6944 PermissionController(ActivityManagerService activityManagerService) { 6945 mActivityManagerService = activityManagerService; 6946 } 6947 6948 @Override 6949 public boolean checkPermission(String permission, int pid, int uid) { 6950 return mActivityManagerService.checkPermission(permission, pid, 6951 uid) == PackageManager.PERMISSION_GRANTED; 6952 } 6953 } 6954 6955 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6956 @Override 6957 public int checkComponentPermission(String permission, int pid, int uid, 6958 int owningUid, boolean exported) { 6959 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6960 owningUid, exported); 6961 } 6962 6963 @Override 6964 public Object getAMSLock() { 6965 return ActivityManagerService.this; 6966 } 6967 } 6968 6969 /** 6970 * This can be called with or without the global lock held. 6971 */ 6972 int checkComponentPermission(String permission, int pid, int uid, 6973 int owningUid, boolean exported) { 6974 // We might be performing an operation on behalf of an indirect binder 6975 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6976 // client identity accordingly before proceeding. 6977 Identity tlsIdentity = sCallerIdentity.get(); 6978 if (tlsIdentity != null) { 6979 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6980 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6981 uid = tlsIdentity.uid; 6982 pid = tlsIdentity.pid; 6983 } 6984 6985 if (pid == MY_PID) { 6986 return PackageManager.PERMISSION_GRANTED; 6987 } 6988 6989 return ActivityManager.checkComponentPermission(permission, uid, 6990 owningUid, exported); 6991 } 6992 6993 /** 6994 * As the only public entry point for permissions checking, this method 6995 * can enforce the semantic that requesting a check on a null global 6996 * permission is automatically denied. (Internally a null permission 6997 * string is used when calling {@link #checkComponentPermission} in cases 6998 * when only uid-based security is needed.) 6999 * 7000 * This can be called with or without the global lock held. 7001 */ 7002 @Override 7003 public int checkPermission(String permission, int pid, int uid) { 7004 if (permission == null) { 7005 return PackageManager.PERMISSION_DENIED; 7006 } 7007 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 7008 } 7009 7010 /** 7011 * Binder IPC calls go through the public entry point. 7012 * This can be called with or without the global lock held. 7013 */ 7014 int checkCallingPermission(String permission) { 7015 return checkPermission(permission, 7016 Binder.getCallingPid(), 7017 UserHandle.getAppId(Binder.getCallingUid())); 7018 } 7019 7020 /** 7021 * This can be called with or without the global lock held. 7022 */ 7023 void enforceCallingPermission(String permission, String func) { 7024 if (checkCallingPermission(permission) 7025 == PackageManager.PERMISSION_GRANTED) { 7026 return; 7027 } 7028 7029 String msg = "Permission Denial: " + func + " from pid=" 7030 + Binder.getCallingPid() 7031 + ", uid=" + Binder.getCallingUid() 7032 + " requires " + permission; 7033 Slog.w(TAG, msg); 7034 throw new SecurityException(msg); 7035 } 7036 7037 /** 7038 * Determine if UID is holding permissions required to access {@link Uri} in 7039 * the given {@link ProviderInfo}. Final permission checking is always done 7040 * in {@link ContentProvider}. 7041 */ 7042 private final boolean checkHoldingPermissionsLocked( 7043 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7044 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7045 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7046 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7047 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7048 != PERMISSION_GRANTED) { 7049 return false; 7050 } 7051 } 7052 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7053 } 7054 7055 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7056 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7057 if (pi.applicationInfo.uid == uid) { 7058 return true; 7059 } else if (!pi.exported) { 7060 return false; 7061 } 7062 7063 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7064 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7065 try { 7066 // check if target holds top-level <provider> permissions 7067 if (!readMet && pi.readPermission != null && considerUidPermissions 7068 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7069 readMet = true; 7070 } 7071 if (!writeMet && pi.writePermission != null && considerUidPermissions 7072 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7073 writeMet = true; 7074 } 7075 7076 // track if unprotected read/write is allowed; any denied 7077 // <path-permission> below removes this ability 7078 boolean allowDefaultRead = pi.readPermission == null; 7079 boolean allowDefaultWrite = pi.writePermission == null; 7080 7081 // check if target holds any <path-permission> that match uri 7082 final PathPermission[] pps = pi.pathPermissions; 7083 if (pps != null) { 7084 final String path = grantUri.uri.getPath(); 7085 int i = pps.length; 7086 while (i > 0 && (!readMet || !writeMet)) { 7087 i--; 7088 PathPermission pp = pps[i]; 7089 if (pp.match(path)) { 7090 if (!readMet) { 7091 final String pprperm = pp.getReadPermission(); 7092 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7093 + pprperm + " for " + pp.getPath() 7094 + ": match=" + pp.match(path) 7095 + " check=" + pm.checkUidPermission(pprperm, uid)); 7096 if (pprperm != null) { 7097 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7098 == PERMISSION_GRANTED) { 7099 readMet = true; 7100 } else { 7101 allowDefaultRead = false; 7102 } 7103 } 7104 } 7105 if (!writeMet) { 7106 final String ppwperm = pp.getWritePermission(); 7107 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7108 + ppwperm + " for " + pp.getPath() 7109 + ": match=" + pp.match(path) 7110 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7111 if (ppwperm != null) { 7112 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7113 == PERMISSION_GRANTED) { 7114 writeMet = true; 7115 } else { 7116 allowDefaultWrite = false; 7117 } 7118 } 7119 } 7120 } 7121 } 7122 } 7123 7124 // grant unprotected <provider> read/write, if not blocked by 7125 // <path-permission> above 7126 if (allowDefaultRead) readMet = true; 7127 if (allowDefaultWrite) writeMet = true; 7128 7129 } catch (RemoteException e) { 7130 return false; 7131 } 7132 7133 return readMet && writeMet; 7134 } 7135 7136 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7137 ProviderInfo pi = null; 7138 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7139 if (cpr != null) { 7140 pi = cpr.info; 7141 } else { 7142 try { 7143 pi = AppGlobals.getPackageManager().resolveContentProvider( 7144 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7145 } catch (RemoteException ex) { 7146 } 7147 } 7148 return pi; 7149 } 7150 7151 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7152 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7153 if (targetUris != null) { 7154 return targetUris.get(grantUri); 7155 } 7156 return null; 7157 } 7158 7159 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7160 String targetPkg, int targetUid, GrantUri grantUri) { 7161 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7162 if (targetUris == null) { 7163 targetUris = Maps.newArrayMap(); 7164 mGrantedUriPermissions.put(targetUid, targetUris); 7165 } 7166 7167 UriPermission perm = targetUris.get(grantUri); 7168 if (perm == null) { 7169 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7170 targetUris.put(grantUri, perm); 7171 } 7172 7173 return perm; 7174 } 7175 7176 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7177 final int modeFlags) { 7178 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7179 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7180 : UriPermission.STRENGTH_OWNED; 7181 7182 // Root gets to do everything. 7183 if (uid == 0) { 7184 return true; 7185 } 7186 7187 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7188 if (perms == null) return false; 7189 7190 // First look for exact match 7191 final UriPermission exactPerm = perms.get(grantUri); 7192 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7193 return true; 7194 } 7195 7196 // No exact match, look for prefixes 7197 final int N = perms.size(); 7198 for (int i = 0; i < N; i++) { 7199 final UriPermission perm = perms.valueAt(i); 7200 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7201 && perm.getStrength(modeFlags) >= minStrength) { 7202 return true; 7203 } 7204 } 7205 7206 return false; 7207 } 7208 7209 /** 7210 * @param uri This uri must NOT contain an embedded userId. 7211 * @param userId The userId in which the uri is to be resolved. 7212 */ 7213 @Override 7214 public int checkUriPermission(Uri uri, int pid, int uid, 7215 final int modeFlags, int userId) { 7216 enforceNotIsolatedCaller("checkUriPermission"); 7217 7218 // Another redirected-binder-call permissions check as in 7219 // {@link checkComponentPermission}. 7220 Identity tlsIdentity = sCallerIdentity.get(); 7221 if (tlsIdentity != null) { 7222 uid = tlsIdentity.uid; 7223 pid = tlsIdentity.pid; 7224 } 7225 7226 // Our own process gets to do everything. 7227 if (pid == MY_PID) { 7228 return PackageManager.PERMISSION_GRANTED; 7229 } 7230 synchronized (this) { 7231 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7232 ? PackageManager.PERMISSION_GRANTED 7233 : PackageManager.PERMISSION_DENIED; 7234 } 7235 } 7236 7237 /** 7238 * Check if the targetPkg can be granted permission to access uri by 7239 * the callingUid using the given modeFlags. Throws a security exception 7240 * if callingUid is not allowed to do this. Returns the uid of the target 7241 * if the URI permission grant should be performed; returns -1 if it is not 7242 * needed (for example targetPkg already has permission to access the URI). 7243 * If you already know the uid of the target, you can supply it in 7244 * lastTargetUid else set that to -1. 7245 */ 7246 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7247 final int modeFlags, int lastTargetUid) { 7248 if (!Intent.isAccessUriMode(modeFlags)) { 7249 return -1; 7250 } 7251 7252 if (targetPkg != null) { 7253 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7254 "Checking grant " + targetPkg + " permission to " + grantUri); 7255 } 7256 7257 final IPackageManager pm = AppGlobals.getPackageManager(); 7258 7259 // If this is not a content: uri, we can't do anything with it. 7260 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7261 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7262 "Can't grant URI permission for non-content URI: " + grantUri); 7263 return -1; 7264 } 7265 7266 final String authority = grantUri.uri.getAuthority(); 7267 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7268 if (pi == null) { 7269 Slog.w(TAG, "No content provider found for permission check: " + 7270 grantUri.uri.toSafeString()); 7271 return -1; 7272 } 7273 7274 int targetUid = lastTargetUid; 7275 if (targetUid < 0 && targetPkg != null) { 7276 try { 7277 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7278 if (targetUid < 0) { 7279 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7280 "Can't grant URI permission no uid for: " + targetPkg); 7281 return -1; 7282 } 7283 } catch (RemoteException ex) { 7284 return -1; 7285 } 7286 } 7287 7288 if (targetUid >= 0) { 7289 // First... does the target actually need this permission? 7290 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7291 // No need to grant the target this permission. 7292 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7293 "Target " + targetPkg + " already has full permission to " + grantUri); 7294 return -1; 7295 } 7296 } else { 7297 // First... there is no target package, so can anyone access it? 7298 boolean allowed = pi.exported; 7299 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7300 if (pi.readPermission != null) { 7301 allowed = false; 7302 } 7303 } 7304 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7305 if (pi.writePermission != null) { 7306 allowed = false; 7307 } 7308 } 7309 if (allowed) { 7310 return -1; 7311 } 7312 } 7313 7314 /* There is a special cross user grant if: 7315 * - The target is on another user. 7316 * - Apps on the current user can access the uri without any uid permissions. 7317 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7318 * grant uri permissions. 7319 */ 7320 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7321 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7322 modeFlags, false /*without considering the uid permissions*/); 7323 7324 // Second... is the provider allowing granting of URI permissions? 7325 if (!specialCrossUserGrant) { 7326 if (!pi.grantUriPermissions) { 7327 throw new SecurityException("Provider " + pi.packageName 7328 + "/" + pi.name 7329 + " does not allow granting of Uri permissions (uri " 7330 + grantUri + ")"); 7331 } 7332 if (pi.uriPermissionPatterns != null) { 7333 final int N = pi.uriPermissionPatterns.length; 7334 boolean allowed = false; 7335 for (int i=0; i<N; i++) { 7336 if (pi.uriPermissionPatterns[i] != null 7337 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7338 allowed = true; 7339 break; 7340 } 7341 } 7342 if (!allowed) { 7343 throw new SecurityException("Provider " + pi.packageName 7344 + "/" + pi.name 7345 + " does not allow granting of permission to path of Uri " 7346 + grantUri); 7347 } 7348 } 7349 } 7350 7351 // Third... does the caller itself have permission to access 7352 // this uri? 7353 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7354 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7355 // Require they hold a strong enough Uri permission 7356 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7357 throw new SecurityException("Uid " + callingUid 7358 + " does not have permission to uri " + grantUri); 7359 } 7360 } 7361 } 7362 return targetUid; 7363 } 7364 7365 /** 7366 * @param uri This uri must NOT contain an embedded userId. 7367 * @param userId The userId in which the uri is to be resolved. 7368 */ 7369 @Override 7370 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7371 final int modeFlags, int userId) { 7372 enforceNotIsolatedCaller("checkGrantUriPermission"); 7373 synchronized(this) { 7374 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7375 new GrantUri(userId, uri, false), modeFlags, -1); 7376 } 7377 } 7378 7379 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7380 final int modeFlags, UriPermissionOwner owner) { 7381 if (!Intent.isAccessUriMode(modeFlags)) { 7382 return; 7383 } 7384 7385 // So here we are: the caller has the assumed permission 7386 // to the uri, and the target doesn't. Let's now give this to 7387 // the target. 7388 7389 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7390 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7391 7392 final String authority = grantUri.uri.getAuthority(); 7393 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7394 if (pi == null) { 7395 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7396 return; 7397 } 7398 7399 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7400 grantUri.prefix = true; 7401 } 7402 final UriPermission perm = findOrCreateUriPermissionLocked( 7403 pi.packageName, targetPkg, targetUid, grantUri); 7404 perm.grantModes(modeFlags, owner); 7405 } 7406 7407 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7408 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7409 if (targetPkg == null) { 7410 throw new NullPointerException("targetPkg"); 7411 } 7412 int targetUid; 7413 final IPackageManager pm = AppGlobals.getPackageManager(); 7414 try { 7415 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7416 } catch (RemoteException ex) { 7417 return; 7418 } 7419 7420 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7421 targetUid); 7422 if (targetUid < 0) { 7423 return; 7424 } 7425 7426 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7427 owner); 7428 } 7429 7430 static class NeededUriGrants extends ArrayList<GrantUri> { 7431 final String targetPkg; 7432 final int targetUid; 7433 final int flags; 7434 7435 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7436 this.targetPkg = targetPkg; 7437 this.targetUid = targetUid; 7438 this.flags = flags; 7439 } 7440 } 7441 7442 /** 7443 * Like checkGrantUriPermissionLocked, but takes an Intent. 7444 */ 7445 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7446 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7447 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7448 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7449 + " clip=" + (intent != null ? intent.getClipData() : null) 7450 + " from " + intent + "; flags=0x" 7451 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7452 7453 if (targetPkg == null) { 7454 throw new NullPointerException("targetPkg"); 7455 } 7456 7457 if (intent == null) { 7458 return null; 7459 } 7460 Uri data = intent.getData(); 7461 ClipData clip = intent.getClipData(); 7462 if (data == null && clip == null) { 7463 return null; 7464 } 7465 // Default userId for uris in the intent (if they don't specify it themselves) 7466 int contentUserHint = intent.getContentUserHint(); 7467 if (contentUserHint == UserHandle.USER_CURRENT) { 7468 contentUserHint = UserHandle.getUserId(callingUid); 7469 } 7470 final IPackageManager pm = AppGlobals.getPackageManager(); 7471 int targetUid; 7472 if (needed != null) { 7473 targetUid = needed.targetUid; 7474 } else { 7475 try { 7476 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7477 } catch (RemoteException ex) { 7478 return null; 7479 } 7480 if (targetUid < 0) { 7481 if (DEBUG_URI_PERMISSION) { 7482 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7483 + " on user " + targetUserId); 7484 } 7485 return null; 7486 } 7487 } 7488 if (data != null) { 7489 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7490 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7491 targetUid); 7492 if (targetUid > 0) { 7493 if (needed == null) { 7494 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7495 } 7496 needed.add(grantUri); 7497 } 7498 } 7499 if (clip != null) { 7500 for (int i=0; i<clip.getItemCount(); i++) { 7501 Uri uri = clip.getItemAt(i).getUri(); 7502 if (uri != null) { 7503 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7504 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7505 targetUid); 7506 if (targetUid > 0) { 7507 if (needed == null) { 7508 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7509 } 7510 needed.add(grantUri); 7511 } 7512 } else { 7513 Intent clipIntent = clip.getItemAt(i).getIntent(); 7514 if (clipIntent != null) { 7515 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7516 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7517 if (newNeeded != null) { 7518 needed = newNeeded; 7519 } 7520 } 7521 } 7522 } 7523 } 7524 7525 return needed; 7526 } 7527 7528 /** 7529 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7530 */ 7531 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7532 UriPermissionOwner owner) { 7533 if (needed != null) { 7534 for (int i=0; i<needed.size(); i++) { 7535 GrantUri grantUri = needed.get(i); 7536 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7537 grantUri, needed.flags, owner); 7538 } 7539 } 7540 } 7541 7542 void grantUriPermissionFromIntentLocked(int callingUid, 7543 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7544 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7545 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7546 if (needed == null) { 7547 return; 7548 } 7549 7550 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7551 } 7552 7553 /** 7554 * @param uri This uri must NOT contain an embedded userId. 7555 * @param userId The userId in which the uri is to be resolved. 7556 */ 7557 @Override 7558 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7559 final int modeFlags, int userId) { 7560 enforceNotIsolatedCaller("grantUriPermission"); 7561 GrantUri grantUri = new GrantUri(userId, uri, false); 7562 synchronized(this) { 7563 final ProcessRecord r = getRecordForAppLocked(caller); 7564 if (r == null) { 7565 throw new SecurityException("Unable to find app for caller " 7566 + caller 7567 + " when granting permission to uri " + grantUri); 7568 } 7569 if (targetPkg == null) { 7570 throw new IllegalArgumentException("null target"); 7571 } 7572 if (grantUri == null) { 7573 throw new IllegalArgumentException("null uri"); 7574 } 7575 7576 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7577 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7578 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7579 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7580 7581 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7582 UserHandle.getUserId(r.uid)); 7583 } 7584 } 7585 7586 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7587 if (perm.modeFlags == 0) { 7588 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7589 perm.targetUid); 7590 if (perms != null) { 7591 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7592 "Removing " + perm.targetUid + " permission to " + perm.uri); 7593 7594 perms.remove(perm.uri); 7595 if (perms.isEmpty()) { 7596 mGrantedUriPermissions.remove(perm.targetUid); 7597 } 7598 } 7599 } 7600 } 7601 7602 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7603 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7604 7605 final IPackageManager pm = AppGlobals.getPackageManager(); 7606 final String authority = grantUri.uri.getAuthority(); 7607 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7608 if (pi == null) { 7609 Slog.w(TAG, "No content provider found for permission revoke: " 7610 + grantUri.toSafeString()); 7611 return; 7612 } 7613 7614 // Does the caller have this permission on the URI? 7615 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7616 // If they don't have direct access to the URI, then revoke any 7617 // ownerless URI permissions that have been granted to them. 7618 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7619 if (perms != null) { 7620 boolean persistChanged = false; 7621 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7622 final UriPermission perm = it.next(); 7623 if (perm.uri.sourceUserId == grantUri.sourceUserId 7624 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7625 if (DEBUG_URI_PERMISSION) 7626 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7627 " permission to " + perm.uri); 7628 persistChanged |= perm.revokeModes( 7629 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7630 if (perm.modeFlags == 0) { 7631 it.remove(); 7632 } 7633 } 7634 } 7635 if (perms.isEmpty()) { 7636 mGrantedUriPermissions.remove(callingUid); 7637 } 7638 if (persistChanged) { 7639 schedulePersistUriGrants(); 7640 } 7641 } 7642 return; 7643 } 7644 7645 boolean persistChanged = false; 7646 7647 // Go through all of the permissions and remove any that match. 7648 int N = mGrantedUriPermissions.size(); 7649 for (int i = 0; i < N; i++) { 7650 final int targetUid = mGrantedUriPermissions.keyAt(i); 7651 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7652 7653 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7654 final UriPermission perm = it.next(); 7655 if (perm.uri.sourceUserId == grantUri.sourceUserId 7656 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7657 if (DEBUG_URI_PERMISSION) 7658 Slog.v(TAG, 7659 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7660 persistChanged |= perm.revokeModes( 7661 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7662 if (perm.modeFlags == 0) { 7663 it.remove(); 7664 } 7665 } 7666 } 7667 7668 if (perms.isEmpty()) { 7669 mGrantedUriPermissions.remove(targetUid); 7670 N--; 7671 i--; 7672 } 7673 } 7674 7675 if (persistChanged) { 7676 schedulePersistUriGrants(); 7677 } 7678 } 7679 7680 /** 7681 * @param uri This uri must NOT contain an embedded userId. 7682 * @param userId The userId in which the uri is to be resolved. 7683 */ 7684 @Override 7685 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7686 int userId) { 7687 enforceNotIsolatedCaller("revokeUriPermission"); 7688 synchronized(this) { 7689 final ProcessRecord r = getRecordForAppLocked(caller); 7690 if (r == null) { 7691 throw new SecurityException("Unable to find app for caller " 7692 + caller 7693 + " when revoking permission to uri " + uri); 7694 } 7695 if (uri == null) { 7696 Slog.w(TAG, "revokeUriPermission: null uri"); 7697 return; 7698 } 7699 7700 if (!Intent.isAccessUriMode(modeFlags)) { 7701 return; 7702 } 7703 7704 final IPackageManager pm = AppGlobals.getPackageManager(); 7705 final String authority = uri.getAuthority(); 7706 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7707 if (pi == null) { 7708 Slog.w(TAG, "No content provider found for permission revoke: " 7709 + uri.toSafeString()); 7710 return; 7711 } 7712 7713 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7714 } 7715 } 7716 7717 /** 7718 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7719 * given package. 7720 * 7721 * @param packageName Package name to match, or {@code null} to apply to all 7722 * packages. 7723 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7724 * to all users. 7725 * @param persistable If persistable grants should be removed. 7726 */ 7727 private void removeUriPermissionsForPackageLocked( 7728 String packageName, int userHandle, boolean persistable) { 7729 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7730 throw new IllegalArgumentException("Must narrow by either package or user"); 7731 } 7732 7733 boolean persistChanged = false; 7734 7735 int N = mGrantedUriPermissions.size(); 7736 for (int i = 0; i < N; i++) { 7737 final int targetUid = mGrantedUriPermissions.keyAt(i); 7738 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7739 7740 // Only inspect grants matching user 7741 if (userHandle == UserHandle.USER_ALL 7742 || userHandle == UserHandle.getUserId(targetUid)) { 7743 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7744 final UriPermission perm = it.next(); 7745 7746 // Only inspect grants matching package 7747 if (packageName == null || perm.sourcePkg.equals(packageName) 7748 || perm.targetPkg.equals(packageName)) { 7749 persistChanged |= perm.revokeModes(persistable 7750 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7751 7752 // Only remove when no modes remain; any persisted grants 7753 // will keep this alive. 7754 if (perm.modeFlags == 0) { 7755 it.remove(); 7756 } 7757 } 7758 } 7759 7760 if (perms.isEmpty()) { 7761 mGrantedUriPermissions.remove(targetUid); 7762 N--; 7763 i--; 7764 } 7765 } 7766 } 7767 7768 if (persistChanged) { 7769 schedulePersistUriGrants(); 7770 } 7771 } 7772 7773 @Override 7774 public IBinder newUriPermissionOwner(String name) { 7775 enforceNotIsolatedCaller("newUriPermissionOwner"); 7776 synchronized(this) { 7777 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7778 return owner.getExternalTokenLocked(); 7779 } 7780 } 7781 7782 /** 7783 * @param uri This uri must NOT contain an embedded userId. 7784 * @param sourceUserId The userId in which the uri is to be resolved. 7785 * @param targetUserId The userId of the app that receives the grant. 7786 */ 7787 @Override 7788 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7789 final int modeFlags, int sourceUserId, int targetUserId) { 7790 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7791 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7792 synchronized(this) { 7793 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7794 if (owner == null) { 7795 throw new IllegalArgumentException("Unknown owner: " + token); 7796 } 7797 if (fromUid != Binder.getCallingUid()) { 7798 if (Binder.getCallingUid() != Process.myUid()) { 7799 // Only system code can grant URI permissions on behalf 7800 // of other users. 7801 throw new SecurityException("nice try"); 7802 } 7803 } 7804 if (targetPkg == null) { 7805 throw new IllegalArgumentException("null target"); 7806 } 7807 if (uri == null) { 7808 throw new IllegalArgumentException("null uri"); 7809 } 7810 7811 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7812 modeFlags, owner, targetUserId); 7813 } 7814 } 7815 7816 /** 7817 * @param uri This uri must NOT contain an embedded userId. 7818 * @param userId The userId in which the uri is to be resolved. 7819 */ 7820 @Override 7821 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7822 synchronized(this) { 7823 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7824 if (owner == null) { 7825 throw new IllegalArgumentException("Unknown owner: " + token); 7826 } 7827 7828 if (uri == null) { 7829 owner.removeUriPermissionsLocked(mode); 7830 } else { 7831 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7832 } 7833 } 7834 } 7835 7836 private void schedulePersistUriGrants() { 7837 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7838 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7839 10 * DateUtils.SECOND_IN_MILLIS); 7840 } 7841 } 7842 7843 private void writeGrantedUriPermissions() { 7844 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7845 7846 // Snapshot permissions so we can persist without lock 7847 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7848 synchronized (this) { 7849 final int size = mGrantedUriPermissions.size(); 7850 for (int i = 0; i < size; i++) { 7851 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7852 for (UriPermission perm : perms.values()) { 7853 if (perm.persistedModeFlags != 0) { 7854 persist.add(perm.snapshot()); 7855 } 7856 } 7857 } 7858 } 7859 7860 FileOutputStream fos = null; 7861 try { 7862 fos = mGrantFile.startWrite(); 7863 7864 XmlSerializer out = new FastXmlSerializer(); 7865 out.setOutput(fos, "utf-8"); 7866 out.startDocument(null, true); 7867 out.startTag(null, TAG_URI_GRANTS); 7868 for (UriPermission.Snapshot perm : persist) { 7869 out.startTag(null, TAG_URI_GRANT); 7870 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7871 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7872 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7873 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7874 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7875 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7876 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7877 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7878 out.endTag(null, TAG_URI_GRANT); 7879 } 7880 out.endTag(null, TAG_URI_GRANTS); 7881 out.endDocument(); 7882 7883 mGrantFile.finishWrite(fos); 7884 } catch (IOException e) { 7885 if (fos != null) { 7886 mGrantFile.failWrite(fos); 7887 } 7888 } 7889 } 7890 7891 private void readGrantedUriPermissionsLocked() { 7892 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7893 7894 final long now = System.currentTimeMillis(); 7895 7896 FileInputStream fis = null; 7897 try { 7898 fis = mGrantFile.openRead(); 7899 final XmlPullParser in = Xml.newPullParser(); 7900 in.setInput(fis, null); 7901 7902 int type; 7903 while ((type = in.next()) != END_DOCUMENT) { 7904 final String tag = in.getName(); 7905 if (type == START_TAG) { 7906 if (TAG_URI_GRANT.equals(tag)) { 7907 final int sourceUserId; 7908 final int targetUserId; 7909 final int userHandle = readIntAttribute(in, 7910 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7911 if (userHandle != UserHandle.USER_NULL) { 7912 // For backwards compatibility. 7913 sourceUserId = userHandle; 7914 targetUserId = userHandle; 7915 } else { 7916 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7917 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7918 } 7919 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7920 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7921 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7922 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7923 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7924 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7925 7926 // Sanity check that provider still belongs to source package 7927 final ProviderInfo pi = getProviderInfoLocked( 7928 uri.getAuthority(), sourceUserId); 7929 if (pi != null && sourcePkg.equals(pi.packageName)) { 7930 int targetUid = -1; 7931 try { 7932 targetUid = AppGlobals.getPackageManager() 7933 .getPackageUid(targetPkg, targetUserId); 7934 } catch (RemoteException e) { 7935 } 7936 if (targetUid != -1) { 7937 final UriPermission perm = findOrCreateUriPermissionLocked( 7938 sourcePkg, targetPkg, targetUid, 7939 new GrantUri(sourceUserId, uri, prefix)); 7940 perm.initPersistedModes(modeFlags, createdTime); 7941 } 7942 } else { 7943 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7944 + " but instead found " + pi); 7945 } 7946 } 7947 } 7948 } 7949 } catch (FileNotFoundException e) { 7950 // Missing grants is okay 7951 } catch (IOException e) { 7952 Slog.wtf(TAG, "Failed reading Uri grants", e); 7953 } catch (XmlPullParserException e) { 7954 Slog.wtf(TAG, "Failed reading Uri grants", e); 7955 } finally { 7956 IoUtils.closeQuietly(fis); 7957 } 7958 } 7959 7960 /** 7961 * @param uri This uri must NOT contain an embedded userId. 7962 * @param userId The userId in which the uri is to be resolved. 7963 */ 7964 @Override 7965 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7966 enforceNotIsolatedCaller("takePersistableUriPermission"); 7967 7968 Preconditions.checkFlagsArgument(modeFlags, 7969 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7970 7971 synchronized (this) { 7972 final int callingUid = Binder.getCallingUid(); 7973 boolean persistChanged = false; 7974 GrantUri grantUri = new GrantUri(userId, uri, false); 7975 7976 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7977 new GrantUri(userId, uri, false)); 7978 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7979 new GrantUri(userId, uri, true)); 7980 7981 final boolean exactValid = (exactPerm != null) 7982 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7983 final boolean prefixValid = (prefixPerm != null) 7984 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7985 7986 if (!(exactValid || prefixValid)) { 7987 throw new SecurityException("No persistable permission grants found for UID " 7988 + callingUid + " and Uri " + grantUri.toSafeString()); 7989 } 7990 7991 if (exactValid) { 7992 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7993 } 7994 if (prefixValid) { 7995 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7996 } 7997 7998 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7999 8000 if (persistChanged) { 8001 schedulePersistUriGrants(); 8002 } 8003 } 8004 } 8005 8006 /** 8007 * @param uri This uri must NOT contain an embedded userId. 8008 * @param userId The userId in which the uri is to be resolved. 8009 */ 8010 @Override 8011 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 8012 enforceNotIsolatedCaller("releasePersistableUriPermission"); 8013 8014 Preconditions.checkFlagsArgument(modeFlags, 8015 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 8016 8017 synchronized (this) { 8018 final int callingUid = Binder.getCallingUid(); 8019 boolean persistChanged = false; 8020 8021 UriPermission exactPerm = findUriPermissionLocked(callingUid, 8022 new GrantUri(userId, uri, false)); 8023 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8024 new GrantUri(userId, uri, true)); 8025 if (exactPerm == null && prefixPerm == null) { 8026 throw new SecurityException("No permission grants found for UID " + callingUid 8027 + " and Uri " + uri.toSafeString()); 8028 } 8029 8030 if (exactPerm != null) { 8031 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8032 removeUriPermissionIfNeededLocked(exactPerm); 8033 } 8034 if (prefixPerm != null) { 8035 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8036 removeUriPermissionIfNeededLocked(prefixPerm); 8037 } 8038 8039 if (persistChanged) { 8040 schedulePersistUriGrants(); 8041 } 8042 } 8043 } 8044 8045 /** 8046 * Prune any older {@link UriPermission} for the given UID until outstanding 8047 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8048 * 8049 * @return if any mutations occured that require persisting. 8050 */ 8051 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8052 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8053 if (perms == null) return false; 8054 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8055 8056 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8057 for (UriPermission perm : perms.values()) { 8058 if (perm.persistedModeFlags != 0) { 8059 persisted.add(perm); 8060 } 8061 } 8062 8063 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8064 if (trimCount <= 0) return false; 8065 8066 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8067 for (int i = 0; i < trimCount; i++) { 8068 final UriPermission perm = persisted.get(i); 8069 8070 if (DEBUG_URI_PERMISSION) { 8071 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8072 } 8073 8074 perm.releasePersistableModes(~0); 8075 removeUriPermissionIfNeededLocked(perm); 8076 } 8077 8078 return true; 8079 } 8080 8081 @Override 8082 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8083 String packageName, boolean incoming) { 8084 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8085 Preconditions.checkNotNull(packageName, "packageName"); 8086 8087 final int callingUid = Binder.getCallingUid(); 8088 final IPackageManager pm = AppGlobals.getPackageManager(); 8089 try { 8090 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8091 if (packageUid != callingUid) { 8092 throw new SecurityException( 8093 "Package " + packageName + " does not belong to calling UID " + callingUid); 8094 } 8095 } catch (RemoteException e) { 8096 throw new SecurityException("Failed to verify package name ownership"); 8097 } 8098 8099 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8100 synchronized (this) { 8101 if (incoming) { 8102 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8103 callingUid); 8104 if (perms == null) { 8105 Slog.w(TAG, "No permission grants found for " + packageName); 8106 } else { 8107 for (UriPermission perm : perms.values()) { 8108 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8109 result.add(perm.buildPersistedPublicApiObject()); 8110 } 8111 } 8112 } 8113 } else { 8114 final int size = mGrantedUriPermissions.size(); 8115 for (int i = 0; i < size; i++) { 8116 final ArrayMap<GrantUri, UriPermission> perms = 8117 mGrantedUriPermissions.valueAt(i); 8118 for (UriPermission perm : perms.values()) { 8119 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8120 result.add(perm.buildPersistedPublicApiObject()); 8121 } 8122 } 8123 } 8124 } 8125 } 8126 return new ParceledListSlice<android.content.UriPermission>(result); 8127 } 8128 8129 @Override 8130 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8131 synchronized (this) { 8132 ProcessRecord app = 8133 who != null ? getRecordForAppLocked(who) : null; 8134 if (app == null) return; 8135 8136 Message msg = Message.obtain(); 8137 msg.what = WAIT_FOR_DEBUGGER_MSG; 8138 msg.obj = app; 8139 msg.arg1 = waiting ? 1 : 0; 8140 mHandler.sendMessage(msg); 8141 } 8142 } 8143 8144 @Override 8145 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8146 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8147 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8148 outInfo.availMem = Process.getFreeMemory(); 8149 outInfo.totalMem = Process.getTotalMemory(); 8150 outInfo.threshold = homeAppMem; 8151 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8152 outInfo.hiddenAppThreshold = cachedAppMem; 8153 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8154 ProcessList.SERVICE_ADJ); 8155 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8156 ProcessList.VISIBLE_APP_ADJ); 8157 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8158 ProcessList.FOREGROUND_APP_ADJ); 8159 } 8160 8161 // ========================================================= 8162 // TASK MANAGEMENT 8163 // ========================================================= 8164 8165 @Override 8166 public List<IAppTask> getAppTasks(String callingPackage) { 8167 int callingUid = Binder.getCallingUid(); 8168 long ident = Binder.clearCallingIdentity(); 8169 8170 synchronized(this) { 8171 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8172 try { 8173 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8174 8175 final int N = mRecentTasks.size(); 8176 for (int i = 0; i < N; i++) { 8177 TaskRecord tr = mRecentTasks.get(i); 8178 // Skip tasks that do not match the caller. We don't need to verify 8179 // callingPackage, because we are also limiting to callingUid and know 8180 // that will limit to the correct security sandbox. 8181 if (tr.effectiveUid != callingUid) { 8182 continue; 8183 } 8184 Intent intent = tr.getBaseIntent(); 8185 if (intent == null || 8186 !callingPackage.equals(intent.getComponent().getPackageName())) { 8187 continue; 8188 } 8189 ActivityManager.RecentTaskInfo taskInfo = 8190 createRecentTaskInfoFromTaskRecord(tr); 8191 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8192 list.add(taskImpl); 8193 } 8194 } finally { 8195 Binder.restoreCallingIdentity(ident); 8196 } 8197 return list; 8198 } 8199 } 8200 8201 @Override 8202 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8203 final int callingUid = Binder.getCallingUid(); 8204 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8205 8206 synchronized(this) { 8207 if (localLOGV) Slog.v( 8208 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8209 8210 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8211 callingUid); 8212 8213 // TODO: Improve with MRU list from all ActivityStacks. 8214 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8215 } 8216 8217 return list; 8218 } 8219 8220 TaskRecord getMostRecentTask() { 8221 return mRecentTasks.get(0); 8222 } 8223 8224 /** 8225 * Creates a new RecentTaskInfo from a TaskRecord. 8226 */ 8227 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8228 // Update the task description to reflect any changes in the task stack 8229 tr.updateTaskDescription(); 8230 8231 // Compose the recent task info 8232 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8233 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8234 rti.persistentId = tr.taskId; 8235 rti.baseIntent = new Intent(tr.getBaseIntent()); 8236 rti.origActivity = tr.origActivity; 8237 rti.description = tr.lastDescription; 8238 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8239 rti.userId = tr.userId; 8240 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8241 rti.firstActiveTime = tr.firstActiveTime; 8242 rti.lastActiveTime = tr.lastActiveTime; 8243 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8244 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8245 return rti; 8246 } 8247 8248 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8249 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8250 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8251 if (!allowed) { 8252 if (checkPermission(android.Manifest.permission.GET_TASKS, 8253 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8254 // Temporary compatibility: some existing apps on the system image may 8255 // still be requesting the old permission and not switched to the new 8256 // one; if so, we'll still allow them full access. This means we need 8257 // to see if they are holding the old permission and are a system app. 8258 try { 8259 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8260 allowed = true; 8261 Slog.w(TAG, caller + ": caller " + callingUid 8262 + " is using old GET_TASKS but privileged; allowing"); 8263 } 8264 } catch (RemoteException e) { 8265 } 8266 } 8267 } 8268 if (!allowed) { 8269 Slog.w(TAG, caller + ": caller " + callingUid 8270 + " does not hold GET_TASKS; limiting output"); 8271 } 8272 return allowed; 8273 } 8274 8275 @Override 8276 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8277 final int callingUid = Binder.getCallingUid(); 8278 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8279 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8280 8281 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8282 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8283 synchronized (this) { 8284 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8285 callingUid); 8286 final boolean detailed = checkCallingPermission( 8287 android.Manifest.permission.GET_DETAILED_TASKS) 8288 == PackageManager.PERMISSION_GRANTED; 8289 8290 final int N = mRecentTasks.size(); 8291 ArrayList<ActivityManager.RecentTaskInfo> res 8292 = new ArrayList<ActivityManager.RecentTaskInfo>( 8293 maxNum < N ? maxNum : N); 8294 8295 final Set<Integer> includedUsers; 8296 if (includeProfiles) { 8297 includedUsers = getProfileIdsLocked(userId); 8298 } else { 8299 includedUsers = new HashSet<Integer>(); 8300 } 8301 includedUsers.add(Integer.valueOf(userId)); 8302 8303 for (int i=0; i<N && maxNum > 0; i++) { 8304 TaskRecord tr = mRecentTasks.get(i); 8305 // Only add calling user or related users recent tasks 8306 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8307 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8308 continue; 8309 } 8310 8311 // Return the entry if desired by the caller. We always return 8312 // the first entry, because callers always expect this to be the 8313 // foreground app. We may filter others if the caller has 8314 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8315 // we should exclude the entry. 8316 8317 if (i == 0 8318 || withExcluded 8319 || (tr.intent == null) 8320 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8321 == 0)) { 8322 if (!allowed) { 8323 // If the caller doesn't have the GET_TASKS permission, then only 8324 // allow them to see a small subset of tasks -- their own and home. 8325 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8326 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8327 continue; 8328 } 8329 } 8330 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8331 if (tr.stack != null && tr.stack.isHomeStack()) { 8332 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8333 continue; 8334 } 8335 } 8336 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8337 // Don't include auto remove tasks that are finished or finishing. 8338 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8339 + tr); 8340 continue; 8341 } 8342 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8343 && !tr.isAvailable) { 8344 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8345 continue; 8346 } 8347 8348 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8349 if (!detailed) { 8350 rti.baseIntent.replaceExtras((Bundle)null); 8351 } 8352 8353 res.add(rti); 8354 maxNum--; 8355 } 8356 } 8357 return res; 8358 } 8359 } 8360 8361 private TaskRecord recentTaskForIdLocked(int id) { 8362 final int N = mRecentTasks.size(); 8363 for (int i=0; i<N; i++) { 8364 TaskRecord tr = mRecentTasks.get(i); 8365 if (tr.taskId == id) { 8366 return tr; 8367 } 8368 } 8369 return null; 8370 } 8371 8372 @Override 8373 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8374 synchronized (this) { 8375 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8376 "getTaskThumbnail()"); 8377 TaskRecord tr = recentTaskForIdLocked(id); 8378 if (tr != null) { 8379 return tr.getTaskThumbnailLocked(); 8380 } 8381 } 8382 return null; 8383 } 8384 8385 @Override 8386 public int addAppTask(IBinder activityToken, Intent intent, 8387 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8388 final int callingUid = Binder.getCallingUid(); 8389 final long callingIdent = Binder.clearCallingIdentity(); 8390 8391 try { 8392 synchronized (this) { 8393 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8394 if (r == null) { 8395 throw new IllegalArgumentException("Activity does not exist; token=" 8396 + activityToken); 8397 } 8398 ComponentName comp = intent.getComponent(); 8399 if (comp == null) { 8400 throw new IllegalArgumentException("Intent " + intent 8401 + " must specify explicit component"); 8402 } 8403 if (thumbnail.getWidth() != mThumbnailWidth 8404 || thumbnail.getHeight() != mThumbnailHeight) { 8405 throw new IllegalArgumentException("Bad thumbnail size: got " 8406 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8407 + mThumbnailWidth + "x" + mThumbnailHeight); 8408 } 8409 if (intent.getSelector() != null) { 8410 intent.setSelector(null); 8411 } 8412 if (intent.getSourceBounds() != null) { 8413 intent.setSourceBounds(null); 8414 } 8415 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8416 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8417 // The caller has added this as an auto-remove task... that makes no 8418 // sense, so turn off auto-remove. 8419 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8420 } 8421 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8422 // Must be a new task. 8423 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8424 } 8425 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8426 mLastAddedTaskActivity = null; 8427 } 8428 ActivityInfo ainfo = mLastAddedTaskActivity; 8429 if (ainfo == null) { 8430 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8431 comp, 0, UserHandle.getUserId(callingUid)); 8432 if (ainfo.applicationInfo.uid != callingUid) { 8433 throw new SecurityException( 8434 "Can't add task for another application: target uid=" 8435 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8436 } 8437 } 8438 8439 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8440 intent, description); 8441 8442 int trimIdx = trimRecentsForTask(task, false); 8443 if (trimIdx >= 0) { 8444 // If this would have caused a trim, then we'll abort because that 8445 // means it would be added at the end of the list but then just removed. 8446 return -1; 8447 } 8448 8449 final int N = mRecentTasks.size(); 8450 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8451 final TaskRecord tr = mRecentTasks.remove(N - 1); 8452 tr.removedFromRecents(mTaskPersister); 8453 } 8454 8455 task.inRecents = true; 8456 mRecentTasks.add(task); 8457 r.task.stack.addTask(task, false, false); 8458 8459 task.setLastThumbnail(thumbnail); 8460 task.freeLastThumbnail(); 8461 8462 return task.taskId; 8463 } 8464 } finally { 8465 Binder.restoreCallingIdentity(callingIdent); 8466 } 8467 } 8468 8469 @Override 8470 public Point getAppTaskThumbnailSize() { 8471 synchronized (this) { 8472 return new Point(mThumbnailWidth, mThumbnailHeight); 8473 } 8474 } 8475 8476 @Override 8477 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8478 synchronized (this) { 8479 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8480 if (r != null) { 8481 r.setTaskDescription(td); 8482 r.task.updateTaskDescription(); 8483 } 8484 } 8485 } 8486 8487 @Override 8488 public Bitmap getTaskDescriptionIcon(String filename) { 8489 if (!FileUtils.isValidExtFilename(filename) 8490 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8491 throw new IllegalArgumentException("Bad filename: " + filename); 8492 } 8493 return mTaskPersister.getTaskDescriptionIcon(filename); 8494 } 8495 8496 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8497 mRecentTasks.remove(tr); 8498 tr.removedFromRecents(mTaskPersister); 8499 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8500 Intent baseIntent = new Intent( 8501 tr.intent != null ? tr.intent : tr.affinityIntent); 8502 ComponentName component = baseIntent.getComponent(); 8503 if (component == null) { 8504 Slog.w(TAG, "Now component for base intent of task: " + tr); 8505 return; 8506 } 8507 8508 // Find any running services associated with this app. 8509 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8510 8511 if (killProcesses) { 8512 // Find any running processes associated with this app. 8513 final String pkg = component.getPackageName(); 8514 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8515 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8516 for (int i=0; i<pmap.size(); i++) { 8517 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8518 for (int j=0; j<uids.size(); j++) { 8519 ProcessRecord proc = uids.valueAt(j); 8520 if (proc.userId != tr.userId) { 8521 continue; 8522 } 8523 if (!proc.pkgList.containsKey(pkg)) { 8524 continue; 8525 } 8526 procs.add(proc); 8527 } 8528 } 8529 8530 // Kill the running processes. 8531 for (int i=0; i<procs.size(); i++) { 8532 ProcessRecord pr = procs.get(i); 8533 if (pr == mHomeProcess) { 8534 // Don't kill the home process along with tasks from the same package. 8535 continue; 8536 } 8537 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8538 pr.kill("remove task", true); 8539 } else { 8540 pr.waitingToKill = "remove task"; 8541 } 8542 } 8543 } 8544 } 8545 8546 /** 8547 * Removes the task with the specified task id. 8548 * 8549 * @param taskId Identifier of the task to be removed. 8550 * @param flags Additional operational flags. May be 0 or 8551 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8552 * @return Returns true if the given task was found and removed. 8553 */ 8554 private boolean removeTaskByIdLocked(int taskId, int flags) { 8555 TaskRecord tr = recentTaskForIdLocked(taskId); 8556 if (tr != null) { 8557 tr.removeTaskActivitiesLocked(); 8558 cleanUpRemovedTaskLocked(tr, flags); 8559 if (tr.isPersistable) { 8560 notifyTaskPersisterLocked(null, true); 8561 } 8562 return true; 8563 } 8564 return false; 8565 } 8566 8567 @Override 8568 public boolean removeTask(int taskId, int flags) { 8569 synchronized (this) { 8570 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8571 "removeTask()"); 8572 long ident = Binder.clearCallingIdentity(); 8573 try { 8574 return removeTaskByIdLocked(taskId, flags); 8575 } finally { 8576 Binder.restoreCallingIdentity(ident); 8577 } 8578 } 8579 } 8580 8581 /** 8582 * TODO: Add mController hook 8583 */ 8584 @Override 8585 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8586 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8587 "moveTaskToFront()"); 8588 8589 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8590 synchronized(this) { 8591 moveTaskToFrontLocked(taskId, flags, options); 8592 } 8593 } 8594 8595 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8596 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8597 Binder.getCallingUid(), -1, -1, "Task to front")) { 8598 ActivityOptions.abort(options); 8599 return; 8600 } 8601 final long origId = Binder.clearCallingIdentity(); 8602 try { 8603 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8604 if (task == null) { 8605 return; 8606 } 8607 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8608 mStackSupervisor.showLockTaskToast(); 8609 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8610 return; 8611 } 8612 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8613 if (prev != null && prev.isRecentsActivity()) { 8614 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8615 } 8616 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8617 } finally { 8618 Binder.restoreCallingIdentity(origId); 8619 } 8620 ActivityOptions.abort(options); 8621 } 8622 8623 @Override 8624 public void moveTaskToBack(int taskId) { 8625 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8626 "moveTaskToBack()"); 8627 8628 synchronized(this) { 8629 TaskRecord tr = recentTaskForIdLocked(taskId); 8630 if (tr != null) { 8631 if (tr == mStackSupervisor.mLockTaskModeTask) { 8632 mStackSupervisor.showLockTaskToast(); 8633 return; 8634 } 8635 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8636 ActivityStack stack = tr.stack; 8637 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8638 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8639 Binder.getCallingUid(), -1, -1, "Task to back")) { 8640 return; 8641 } 8642 } 8643 final long origId = Binder.clearCallingIdentity(); 8644 try { 8645 stack.moveTaskToBackLocked(taskId, null); 8646 } finally { 8647 Binder.restoreCallingIdentity(origId); 8648 } 8649 } 8650 } 8651 } 8652 8653 /** 8654 * Moves an activity, and all of the other activities within the same task, to the bottom 8655 * of the history stack. The activity's order within the task is unchanged. 8656 * 8657 * @param token A reference to the activity we wish to move 8658 * @param nonRoot If false then this only works if the activity is the root 8659 * of a task; if true it will work for any activity in a task. 8660 * @return Returns true if the move completed, false if not. 8661 */ 8662 @Override 8663 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8664 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8665 synchronized(this) { 8666 final long origId = Binder.clearCallingIdentity(); 8667 try { 8668 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8669 if (taskId >= 0) { 8670 if ((mStackSupervisor.mLockTaskModeTask != null) 8671 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8672 mStackSupervisor.showLockTaskToast(); 8673 return false; 8674 } 8675 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8676 } 8677 } finally { 8678 Binder.restoreCallingIdentity(origId); 8679 } 8680 } 8681 return false; 8682 } 8683 8684 @Override 8685 public void moveTaskBackwards(int task) { 8686 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8687 "moveTaskBackwards()"); 8688 8689 synchronized(this) { 8690 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8691 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8692 return; 8693 } 8694 final long origId = Binder.clearCallingIdentity(); 8695 moveTaskBackwardsLocked(task); 8696 Binder.restoreCallingIdentity(origId); 8697 } 8698 } 8699 8700 private final void moveTaskBackwardsLocked(int task) { 8701 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8702 } 8703 8704 @Override 8705 public IBinder getHomeActivityToken() throws RemoteException { 8706 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8707 "getHomeActivityToken()"); 8708 synchronized (this) { 8709 return mStackSupervisor.getHomeActivityToken(); 8710 } 8711 } 8712 8713 @Override 8714 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8715 IActivityContainerCallback callback) throws RemoteException { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "createActivityContainer()"); 8718 synchronized (this) { 8719 if (parentActivityToken == null) { 8720 throw new IllegalArgumentException("parent token must not be null"); 8721 } 8722 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8723 if (r == null) { 8724 return null; 8725 } 8726 if (callback == null) { 8727 throw new IllegalArgumentException("callback must not be null"); 8728 } 8729 return mStackSupervisor.createActivityContainer(r, callback); 8730 } 8731 } 8732 8733 @Override 8734 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8735 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8736 "deleteActivityContainer()"); 8737 synchronized (this) { 8738 mStackSupervisor.deleteActivityContainer(container); 8739 } 8740 } 8741 8742 @Override 8743 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8744 throws RemoteException { 8745 synchronized (this) { 8746 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8747 if (stack != null) { 8748 return stack.mActivityContainer; 8749 } 8750 return null; 8751 } 8752 } 8753 8754 @Override 8755 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8756 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8757 "moveTaskToStack()"); 8758 if (stackId == HOME_STACK_ID) { 8759 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8760 new RuntimeException("here").fillInStackTrace()); 8761 } 8762 synchronized (this) { 8763 long ident = Binder.clearCallingIdentity(); 8764 try { 8765 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8766 + stackId + " toTop=" + toTop); 8767 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8768 } finally { 8769 Binder.restoreCallingIdentity(ident); 8770 } 8771 } 8772 } 8773 8774 @Override 8775 public void resizeStack(int stackBoxId, Rect bounds) { 8776 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8777 "resizeStackBox()"); 8778 long ident = Binder.clearCallingIdentity(); 8779 try { 8780 mWindowManager.resizeStack(stackBoxId, bounds); 8781 } finally { 8782 Binder.restoreCallingIdentity(ident); 8783 } 8784 } 8785 8786 @Override 8787 public List<StackInfo> getAllStackInfos() { 8788 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8789 "getAllStackInfos()"); 8790 long ident = Binder.clearCallingIdentity(); 8791 try { 8792 synchronized (this) { 8793 return mStackSupervisor.getAllStackInfosLocked(); 8794 } 8795 } finally { 8796 Binder.restoreCallingIdentity(ident); 8797 } 8798 } 8799 8800 @Override 8801 public StackInfo getStackInfo(int stackId) { 8802 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8803 "getStackInfo()"); 8804 long ident = Binder.clearCallingIdentity(); 8805 try { 8806 synchronized (this) { 8807 return mStackSupervisor.getStackInfoLocked(stackId); 8808 } 8809 } finally { 8810 Binder.restoreCallingIdentity(ident); 8811 } 8812 } 8813 8814 @Override 8815 public boolean isInHomeStack(int taskId) { 8816 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8817 "getStackInfo()"); 8818 long ident = Binder.clearCallingIdentity(); 8819 try { 8820 synchronized (this) { 8821 TaskRecord tr = recentTaskForIdLocked(taskId); 8822 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8823 } 8824 } finally { 8825 Binder.restoreCallingIdentity(ident); 8826 } 8827 } 8828 8829 @Override 8830 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8831 synchronized(this) { 8832 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8833 } 8834 } 8835 8836 private boolean isLockTaskAuthorized(String pkg) { 8837 final DevicePolicyManager dpm = (DevicePolicyManager) 8838 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8839 try { 8840 int uid = mContext.getPackageManager().getPackageUid(pkg, 8841 Binder.getCallingUserHandle().getIdentifier()); 8842 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8843 } catch (NameNotFoundException e) { 8844 return false; 8845 } 8846 } 8847 8848 void startLockTaskMode(TaskRecord task) { 8849 final String pkg; 8850 synchronized (this) { 8851 pkg = task.intent.getComponent().getPackageName(); 8852 } 8853 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8854 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8855 final TaskRecord taskRecord = task; 8856 mHandler.post(new Runnable() { 8857 @Override 8858 public void run() { 8859 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8860 } 8861 }); 8862 return; 8863 } 8864 long ident = Binder.clearCallingIdentity(); 8865 try { 8866 synchronized (this) { 8867 // Since we lost lock on task, make sure it is still there. 8868 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8869 if (task != null) { 8870 if (!isSystemInitiated 8871 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8872 throw new IllegalArgumentException("Invalid task, not in foreground"); 8873 } 8874 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8875 } 8876 } 8877 } finally { 8878 Binder.restoreCallingIdentity(ident); 8879 } 8880 } 8881 8882 @Override 8883 public void startLockTaskMode(int taskId) { 8884 final TaskRecord task; 8885 long ident = Binder.clearCallingIdentity(); 8886 try { 8887 synchronized (this) { 8888 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8889 } 8890 } finally { 8891 Binder.restoreCallingIdentity(ident); 8892 } 8893 if (task != null) { 8894 startLockTaskMode(task); 8895 } 8896 } 8897 8898 @Override 8899 public void startLockTaskMode(IBinder token) { 8900 final TaskRecord task; 8901 long ident = Binder.clearCallingIdentity(); 8902 try { 8903 synchronized (this) { 8904 final ActivityRecord r = ActivityRecord.forToken(token); 8905 if (r == null) { 8906 return; 8907 } 8908 task = r.task; 8909 } 8910 } finally { 8911 Binder.restoreCallingIdentity(ident); 8912 } 8913 if (task != null) { 8914 startLockTaskMode(task); 8915 } 8916 } 8917 8918 @Override 8919 public void startLockTaskModeOnCurrent() throws RemoteException { 8920 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8921 "startLockTaskModeOnCurrent"); 8922 ActivityRecord r = null; 8923 synchronized (this) { 8924 r = mStackSupervisor.topRunningActivityLocked(); 8925 } 8926 startLockTaskMode(r.task); 8927 } 8928 8929 @Override 8930 public void stopLockTaskMode() { 8931 // Verify that the user matches the package of the intent for the TaskRecord 8932 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8933 // and stopLockTaskMode. 8934 final int callingUid = Binder.getCallingUid(); 8935 if (callingUid != Process.SYSTEM_UID) { 8936 try { 8937 String pkg = 8938 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8939 int uid = mContext.getPackageManager().getPackageUid(pkg, 8940 Binder.getCallingUserHandle().getIdentifier()); 8941 if (uid != callingUid) { 8942 throw new SecurityException("Invalid uid, expected " + uid); 8943 } 8944 } catch (NameNotFoundException e) { 8945 Log.d(TAG, "stopLockTaskMode " + e); 8946 return; 8947 } 8948 } 8949 long ident = Binder.clearCallingIdentity(); 8950 try { 8951 Log.d(TAG, "stopLockTaskMode"); 8952 // Stop lock task 8953 synchronized (this) { 8954 mStackSupervisor.setLockTaskModeLocked(null, false); 8955 } 8956 } finally { 8957 Binder.restoreCallingIdentity(ident); 8958 } 8959 } 8960 8961 @Override 8962 public void stopLockTaskModeOnCurrent() throws RemoteException { 8963 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8964 "stopLockTaskModeOnCurrent"); 8965 long ident = Binder.clearCallingIdentity(); 8966 try { 8967 stopLockTaskMode(); 8968 } finally { 8969 Binder.restoreCallingIdentity(ident); 8970 } 8971 } 8972 8973 @Override 8974 public boolean isInLockTaskMode() { 8975 synchronized (this) { 8976 return mStackSupervisor.isInLockTaskMode(); 8977 } 8978 } 8979 8980 // ========================================================= 8981 // CONTENT PROVIDERS 8982 // ========================================================= 8983 8984 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8985 List<ProviderInfo> providers = null; 8986 try { 8987 providers = AppGlobals.getPackageManager(). 8988 queryContentProviders(app.processName, app.uid, 8989 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8990 } catch (RemoteException ex) { 8991 } 8992 if (DEBUG_MU) 8993 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8994 int userId = app.userId; 8995 if (providers != null) { 8996 int N = providers.size(); 8997 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8998 for (int i=0; i<N; i++) { 8999 ProviderInfo cpi = 9000 (ProviderInfo)providers.get(i); 9001 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9002 cpi.name, cpi.flags); 9003 if (singleton && UserHandle.getUserId(app.uid) != 0) { 9004 // This is a singleton provider, but a user besides the 9005 // default user is asking to initialize a process it runs 9006 // in... well, no, it doesn't actually run in this process, 9007 // it runs in the process of the default user. Get rid of it. 9008 providers.remove(i); 9009 N--; 9010 i--; 9011 continue; 9012 } 9013 9014 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9015 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 9016 if (cpr == null) { 9017 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 9018 mProviderMap.putProviderByClass(comp, cpr); 9019 } 9020 if (DEBUG_MU) 9021 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9022 app.pubProviders.put(cpi.name, cpr); 9023 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9024 // Don't add this if it is a platform component that is marked 9025 // to run in multiple processes, because this is actually 9026 // part of the framework so doesn't make sense to track as a 9027 // separate apk in the process. 9028 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9029 mProcessStats); 9030 } 9031 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9032 } 9033 } 9034 return providers; 9035 } 9036 9037 /** 9038 * Check if {@link ProcessRecord} has a possible chance at accessing the 9039 * given {@link ProviderInfo}. Final permission checking is always done 9040 * in {@link ContentProvider}. 9041 */ 9042 private final String checkContentProviderPermissionLocked( 9043 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9044 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9045 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9046 boolean checkedGrants = false; 9047 if (checkUser) { 9048 // Looking for cross-user grants before enforcing the typical cross-users permissions 9049 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9050 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9051 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9052 return null; 9053 } 9054 checkedGrants = true; 9055 } 9056 userId = handleIncomingUser(callingPid, callingUid, userId, 9057 false, ALLOW_NON_FULL, 9058 "checkContentProviderPermissionLocked " + cpi.authority, null); 9059 if (userId != tmpTargetUserId) { 9060 // When we actually went to determine the final targer user ID, this ended 9061 // up different than our initial check for the authority. This is because 9062 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9063 // SELF. So we need to re-check the grants again. 9064 checkedGrants = false; 9065 } 9066 } 9067 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9068 cpi.applicationInfo.uid, cpi.exported) 9069 == PackageManager.PERMISSION_GRANTED) { 9070 return null; 9071 } 9072 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9073 cpi.applicationInfo.uid, cpi.exported) 9074 == PackageManager.PERMISSION_GRANTED) { 9075 return null; 9076 } 9077 9078 PathPermission[] pps = cpi.pathPermissions; 9079 if (pps != null) { 9080 int i = pps.length; 9081 while (i > 0) { 9082 i--; 9083 PathPermission pp = pps[i]; 9084 String pprperm = pp.getReadPermission(); 9085 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9086 cpi.applicationInfo.uid, cpi.exported) 9087 == PackageManager.PERMISSION_GRANTED) { 9088 return null; 9089 } 9090 String ppwperm = pp.getWritePermission(); 9091 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9092 cpi.applicationInfo.uid, cpi.exported) 9093 == PackageManager.PERMISSION_GRANTED) { 9094 return null; 9095 } 9096 } 9097 } 9098 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9099 return null; 9100 } 9101 9102 String msg; 9103 if (!cpi.exported) { 9104 msg = "Permission Denial: opening provider " + cpi.name 9105 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9106 + ", uid=" + callingUid + ") that is not exported from uid " 9107 + cpi.applicationInfo.uid; 9108 } else { 9109 msg = "Permission Denial: opening provider " + cpi.name 9110 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9111 + ", uid=" + callingUid + ") requires " 9112 + cpi.readPermission + " or " + cpi.writePermission; 9113 } 9114 Slog.w(TAG, msg); 9115 return msg; 9116 } 9117 9118 /** 9119 * Returns if the ContentProvider has granted a uri to callingUid 9120 */ 9121 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9122 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9123 if (perms != null) { 9124 for (int i=perms.size()-1; i>=0; i--) { 9125 GrantUri grantUri = perms.keyAt(i); 9126 if (grantUri.sourceUserId == userId || !checkUser) { 9127 if (matchesProvider(grantUri.uri, cpi)) { 9128 return true; 9129 } 9130 } 9131 } 9132 } 9133 return false; 9134 } 9135 9136 /** 9137 * Returns true if the uri authority is one of the authorities specified in the provider. 9138 */ 9139 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9140 String uriAuth = uri.getAuthority(); 9141 String cpiAuth = cpi.authority; 9142 if (cpiAuth.indexOf(';') == -1) { 9143 return cpiAuth.equals(uriAuth); 9144 } 9145 String[] cpiAuths = cpiAuth.split(";"); 9146 int length = cpiAuths.length; 9147 for (int i = 0; i < length; i++) { 9148 if (cpiAuths[i].equals(uriAuth)) return true; 9149 } 9150 return false; 9151 } 9152 9153 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9154 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9155 if (r != null) { 9156 for (int i=0; i<r.conProviders.size(); i++) { 9157 ContentProviderConnection conn = r.conProviders.get(i); 9158 if (conn.provider == cpr) { 9159 if (DEBUG_PROVIDER) Slog.v(TAG, 9160 "Adding provider requested by " 9161 + r.processName + " from process " 9162 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9163 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9164 if (stable) { 9165 conn.stableCount++; 9166 conn.numStableIncs++; 9167 } else { 9168 conn.unstableCount++; 9169 conn.numUnstableIncs++; 9170 } 9171 return conn; 9172 } 9173 } 9174 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9175 if (stable) { 9176 conn.stableCount = 1; 9177 conn.numStableIncs = 1; 9178 } else { 9179 conn.unstableCount = 1; 9180 conn.numUnstableIncs = 1; 9181 } 9182 cpr.connections.add(conn); 9183 r.conProviders.add(conn); 9184 return conn; 9185 } 9186 cpr.addExternalProcessHandleLocked(externalProcessToken); 9187 return null; 9188 } 9189 9190 boolean decProviderCountLocked(ContentProviderConnection conn, 9191 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9192 if (conn != null) { 9193 cpr = conn.provider; 9194 if (DEBUG_PROVIDER) Slog.v(TAG, 9195 "Removing provider requested by " 9196 + conn.client.processName + " from process " 9197 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9198 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9199 if (stable) { 9200 conn.stableCount--; 9201 } else { 9202 conn.unstableCount--; 9203 } 9204 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9205 cpr.connections.remove(conn); 9206 conn.client.conProviders.remove(conn); 9207 return true; 9208 } 9209 return false; 9210 } 9211 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9212 return false; 9213 } 9214 9215 private void checkTime(long startTime, String where) { 9216 long now = SystemClock.elapsedRealtime(); 9217 if ((now-startTime) > 1000) { 9218 // If we are taking more than a second, log about it. 9219 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9220 } 9221 } 9222 9223 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9224 String name, IBinder token, boolean stable, int userId) { 9225 ContentProviderRecord cpr; 9226 ContentProviderConnection conn = null; 9227 ProviderInfo cpi = null; 9228 9229 synchronized(this) { 9230 long startTime = SystemClock.elapsedRealtime(); 9231 9232 ProcessRecord r = null; 9233 if (caller != null) { 9234 r = getRecordForAppLocked(caller); 9235 if (r == null) { 9236 throw new SecurityException( 9237 "Unable to find app for caller " + caller 9238 + " (pid=" + Binder.getCallingPid() 9239 + ") when getting content provider " + name); 9240 } 9241 } 9242 9243 boolean checkCrossUser = true; 9244 9245 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9246 9247 // First check if this content provider has been published... 9248 cpr = mProviderMap.getProviderByName(name, userId); 9249 // If that didn't work, check if it exists for user 0 and then 9250 // verify that it's a singleton provider before using it. 9251 if (cpr == null && userId != UserHandle.USER_OWNER) { 9252 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9253 if (cpr != null) { 9254 cpi = cpr.info; 9255 if (isSingleton(cpi.processName, cpi.applicationInfo, 9256 cpi.name, cpi.flags) 9257 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9258 userId = UserHandle.USER_OWNER; 9259 checkCrossUser = false; 9260 } else { 9261 cpr = null; 9262 cpi = null; 9263 } 9264 } 9265 } 9266 9267 boolean providerRunning = cpr != null; 9268 if (providerRunning) { 9269 cpi = cpr.info; 9270 String msg; 9271 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9272 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9273 != null) { 9274 throw new SecurityException(msg); 9275 } 9276 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9277 9278 if (r != null && cpr.canRunHere(r)) { 9279 // This provider has been published or is in the process 9280 // of being published... but it is also allowed to run 9281 // in the caller's process, so don't make a connection 9282 // and just let the caller instantiate its own instance. 9283 ContentProviderHolder holder = cpr.newHolder(null); 9284 // don't give caller the provider object, it needs 9285 // to make its own. 9286 holder.provider = null; 9287 return holder; 9288 } 9289 9290 final long origId = Binder.clearCallingIdentity(); 9291 9292 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9293 9294 // In this case the provider instance already exists, so we can 9295 // return it right away. 9296 conn = incProviderCountLocked(r, cpr, token, stable); 9297 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9298 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9299 // If this is a perceptible app accessing the provider, 9300 // make sure to count it as being accessed and thus 9301 // back up on the LRU list. This is good because 9302 // content providers are often expensive to start. 9303 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9304 updateLruProcessLocked(cpr.proc, false, null); 9305 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9306 } 9307 } 9308 9309 if (cpr.proc != null) { 9310 if (false) { 9311 if (cpr.name.flattenToShortString().equals( 9312 "com.android.providers.calendar/.CalendarProvider2")) { 9313 Slog.v(TAG, "****************** KILLING " 9314 + cpr.name.flattenToShortString()); 9315 Process.killProcess(cpr.proc.pid); 9316 } 9317 } 9318 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9319 boolean success = updateOomAdjLocked(cpr.proc); 9320 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9321 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9322 // NOTE: there is still a race here where a signal could be 9323 // pending on the process even though we managed to update its 9324 // adj level. Not sure what to do about this, but at least 9325 // the race is now smaller. 9326 if (!success) { 9327 // Uh oh... it looks like the provider's process 9328 // has been killed on us. We need to wait for a new 9329 // process to be started, and make sure its death 9330 // doesn't kill our process. 9331 Slog.i(TAG, 9332 "Existing provider " + cpr.name.flattenToShortString() 9333 + " is crashing; detaching " + r); 9334 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9335 checkTime(startTime, "getContentProviderImpl: before appDied"); 9336 appDiedLocked(cpr.proc); 9337 checkTime(startTime, "getContentProviderImpl: after appDied"); 9338 if (!lastRef) { 9339 // This wasn't the last ref our process had on 9340 // the provider... we have now been killed, bail. 9341 return null; 9342 } 9343 providerRunning = false; 9344 conn = null; 9345 } 9346 } 9347 9348 Binder.restoreCallingIdentity(origId); 9349 } 9350 9351 boolean singleton; 9352 if (!providerRunning) { 9353 try { 9354 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9355 cpi = AppGlobals.getPackageManager(). 9356 resolveContentProvider(name, 9357 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9358 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9359 } catch (RemoteException ex) { 9360 } 9361 if (cpi == null) { 9362 return null; 9363 } 9364 // If the provider is a singleton AND 9365 // (it's a call within the same user || the provider is a 9366 // privileged app) 9367 // Then allow connecting to the singleton provider 9368 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9369 cpi.name, cpi.flags) 9370 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9371 if (singleton) { 9372 userId = UserHandle.USER_OWNER; 9373 } 9374 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9375 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9376 9377 String msg; 9378 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9379 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9380 != null) { 9381 throw new SecurityException(msg); 9382 } 9383 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9384 9385 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9386 && !cpi.processName.equals("system")) { 9387 // If this content provider does not run in the system 9388 // process, and the system is not yet ready to run other 9389 // processes, then fail fast instead of hanging. 9390 throw new IllegalArgumentException( 9391 "Attempt to launch content provider before system ready"); 9392 } 9393 9394 // Make sure that the user who owns this provider is started. If not, 9395 // we don't want to allow it to run. 9396 if (mStartedUsers.get(userId) == null) { 9397 Slog.w(TAG, "Unable to launch app " 9398 + cpi.applicationInfo.packageName + "/" 9399 + cpi.applicationInfo.uid + " for provider " 9400 + name + ": user " + userId + " is stopped"); 9401 return null; 9402 } 9403 9404 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9405 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9406 cpr = mProviderMap.getProviderByClass(comp, userId); 9407 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9408 final boolean firstClass = cpr == null; 9409 if (firstClass) { 9410 final long ident = Binder.clearCallingIdentity(); 9411 try { 9412 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9413 ApplicationInfo ai = 9414 AppGlobals.getPackageManager(). 9415 getApplicationInfo( 9416 cpi.applicationInfo.packageName, 9417 STOCK_PM_FLAGS, userId); 9418 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9419 if (ai == null) { 9420 Slog.w(TAG, "No package info for content provider " 9421 + cpi.name); 9422 return null; 9423 } 9424 ai = getAppInfoForUser(ai, userId); 9425 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9426 } catch (RemoteException ex) { 9427 // pm is in same process, this will never happen. 9428 } finally { 9429 Binder.restoreCallingIdentity(ident); 9430 } 9431 } 9432 9433 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9434 9435 if (r != null && cpr.canRunHere(r)) { 9436 // If this is a multiprocess provider, then just return its 9437 // info and allow the caller to instantiate it. Only do 9438 // this if the provider is the same user as the caller's 9439 // process, or can run as root (so can be in any process). 9440 return cpr.newHolder(null); 9441 } 9442 9443 if (DEBUG_PROVIDER) { 9444 RuntimeException e = new RuntimeException("here"); 9445 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9446 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9447 } 9448 9449 // This is single process, and our app is now connecting to it. 9450 // See if we are already in the process of launching this 9451 // provider. 9452 final int N = mLaunchingProviders.size(); 9453 int i; 9454 for (i=0; i<N; i++) { 9455 if (mLaunchingProviders.get(i) == cpr) { 9456 break; 9457 } 9458 } 9459 9460 // If the provider is not already being launched, then get it 9461 // started. 9462 if (i >= N) { 9463 final long origId = Binder.clearCallingIdentity(); 9464 9465 try { 9466 // Content provider is now in use, its package can't be stopped. 9467 try { 9468 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9469 AppGlobals.getPackageManager().setPackageStoppedState( 9470 cpr.appInfo.packageName, false, userId); 9471 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9472 } catch (RemoteException e) { 9473 } catch (IllegalArgumentException e) { 9474 Slog.w(TAG, "Failed trying to unstop package " 9475 + cpr.appInfo.packageName + ": " + e); 9476 } 9477 9478 // Use existing process if already started 9479 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9480 ProcessRecord proc = getProcessRecordLocked( 9481 cpi.processName, cpr.appInfo.uid, false); 9482 if (proc != null && proc.thread != null) { 9483 if (DEBUG_PROVIDER) { 9484 Slog.d(TAG, "Installing in existing process " + proc); 9485 } 9486 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9487 proc.pubProviders.put(cpi.name, cpr); 9488 try { 9489 proc.thread.scheduleInstallProvider(cpi); 9490 } catch (RemoteException e) { 9491 } 9492 } else { 9493 checkTime(startTime, "getContentProviderImpl: before start process"); 9494 proc = startProcessLocked(cpi.processName, 9495 cpr.appInfo, false, 0, "content provider", 9496 new ComponentName(cpi.applicationInfo.packageName, 9497 cpi.name), false, false, false); 9498 checkTime(startTime, "getContentProviderImpl: after start process"); 9499 if (proc == null) { 9500 Slog.w(TAG, "Unable to launch app " 9501 + cpi.applicationInfo.packageName + "/" 9502 + cpi.applicationInfo.uid + " for provider " 9503 + name + ": process is bad"); 9504 return null; 9505 } 9506 } 9507 cpr.launchingApp = proc; 9508 mLaunchingProviders.add(cpr); 9509 } finally { 9510 Binder.restoreCallingIdentity(origId); 9511 } 9512 } 9513 9514 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9515 9516 // Make sure the provider is published (the same provider class 9517 // may be published under multiple names). 9518 if (firstClass) { 9519 mProviderMap.putProviderByClass(comp, cpr); 9520 } 9521 9522 mProviderMap.putProviderByName(name, cpr); 9523 conn = incProviderCountLocked(r, cpr, token, stable); 9524 if (conn != null) { 9525 conn.waiting = true; 9526 } 9527 } 9528 checkTime(startTime, "getContentProviderImpl: done!"); 9529 } 9530 9531 // Wait for the provider to be published... 9532 synchronized (cpr) { 9533 while (cpr.provider == null) { 9534 if (cpr.launchingApp == null) { 9535 Slog.w(TAG, "Unable to launch app " 9536 + cpi.applicationInfo.packageName + "/" 9537 + cpi.applicationInfo.uid + " for provider " 9538 + name + ": launching app became null"); 9539 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9540 UserHandle.getUserId(cpi.applicationInfo.uid), 9541 cpi.applicationInfo.packageName, 9542 cpi.applicationInfo.uid, name); 9543 return null; 9544 } 9545 try { 9546 if (DEBUG_MU) { 9547 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9548 + cpr.launchingApp); 9549 } 9550 if (conn != null) { 9551 conn.waiting = true; 9552 } 9553 cpr.wait(); 9554 } catch (InterruptedException ex) { 9555 } finally { 9556 if (conn != null) { 9557 conn.waiting = false; 9558 } 9559 } 9560 } 9561 } 9562 return cpr != null ? cpr.newHolder(conn) : null; 9563 } 9564 9565 @Override 9566 public final ContentProviderHolder getContentProvider( 9567 IApplicationThread caller, String name, int userId, boolean stable) { 9568 enforceNotIsolatedCaller("getContentProvider"); 9569 if (caller == null) { 9570 String msg = "null IApplicationThread when getting content provider " 9571 + name; 9572 Slog.w(TAG, msg); 9573 throw new SecurityException(msg); 9574 } 9575 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9576 // with cross-user grant. 9577 return getContentProviderImpl(caller, name, null, stable, userId); 9578 } 9579 9580 public ContentProviderHolder getContentProviderExternal( 9581 String name, int userId, IBinder token) { 9582 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9583 "Do not have permission in call getContentProviderExternal()"); 9584 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9585 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9586 return getContentProviderExternalUnchecked(name, token, userId); 9587 } 9588 9589 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9590 IBinder token, int userId) { 9591 return getContentProviderImpl(null, name, token, true, userId); 9592 } 9593 9594 /** 9595 * Drop a content provider from a ProcessRecord's bookkeeping 9596 */ 9597 public void removeContentProvider(IBinder connection, boolean stable) { 9598 enforceNotIsolatedCaller("removeContentProvider"); 9599 long ident = Binder.clearCallingIdentity(); 9600 try { 9601 synchronized (this) { 9602 ContentProviderConnection conn; 9603 try { 9604 conn = (ContentProviderConnection)connection; 9605 } catch (ClassCastException e) { 9606 String msg ="removeContentProvider: " + connection 9607 + " not a ContentProviderConnection"; 9608 Slog.w(TAG, msg); 9609 throw new IllegalArgumentException(msg); 9610 } 9611 if (conn == null) { 9612 throw new NullPointerException("connection is null"); 9613 } 9614 if (decProviderCountLocked(conn, null, null, stable)) { 9615 updateOomAdjLocked(); 9616 } 9617 } 9618 } finally { 9619 Binder.restoreCallingIdentity(ident); 9620 } 9621 } 9622 9623 public void removeContentProviderExternal(String name, IBinder token) { 9624 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9625 "Do not have permission in call removeContentProviderExternal()"); 9626 int userId = UserHandle.getCallingUserId(); 9627 long ident = Binder.clearCallingIdentity(); 9628 try { 9629 removeContentProviderExternalUnchecked(name, token, userId); 9630 } finally { 9631 Binder.restoreCallingIdentity(ident); 9632 } 9633 } 9634 9635 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9636 synchronized (this) { 9637 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9638 if(cpr == null) { 9639 //remove from mProvidersByClass 9640 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9641 return; 9642 } 9643 9644 //update content provider record entry info 9645 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9646 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9647 if (localCpr.hasExternalProcessHandles()) { 9648 if (localCpr.removeExternalProcessHandleLocked(token)) { 9649 updateOomAdjLocked(); 9650 } else { 9651 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9652 + " with no external reference for token: " 9653 + token + "."); 9654 } 9655 } else { 9656 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9657 + " with no external references."); 9658 } 9659 } 9660 } 9661 9662 public final void publishContentProviders(IApplicationThread caller, 9663 List<ContentProviderHolder> providers) { 9664 if (providers == null) { 9665 return; 9666 } 9667 9668 enforceNotIsolatedCaller("publishContentProviders"); 9669 synchronized (this) { 9670 final ProcessRecord r = getRecordForAppLocked(caller); 9671 if (DEBUG_MU) 9672 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9673 if (r == null) { 9674 throw new SecurityException( 9675 "Unable to find app for caller " + caller 9676 + " (pid=" + Binder.getCallingPid() 9677 + ") when publishing content providers"); 9678 } 9679 9680 final long origId = Binder.clearCallingIdentity(); 9681 9682 final int N = providers.size(); 9683 for (int i=0; i<N; i++) { 9684 ContentProviderHolder src = providers.get(i); 9685 if (src == null || src.info == null || src.provider == null) { 9686 continue; 9687 } 9688 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9689 if (DEBUG_MU) 9690 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9691 if (dst != null) { 9692 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9693 mProviderMap.putProviderByClass(comp, dst); 9694 String names[] = dst.info.authority.split(";"); 9695 for (int j = 0; j < names.length; j++) { 9696 mProviderMap.putProviderByName(names[j], dst); 9697 } 9698 9699 int NL = mLaunchingProviders.size(); 9700 int j; 9701 for (j=0; j<NL; j++) { 9702 if (mLaunchingProviders.get(j) == dst) { 9703 mLaunchingProviders.remove(j); 9704 j--; 9705 NL--; 9706 } 9707 } 9708 synchronized (dst) { 9709 dst.provider = src.provider; 9710 dst.proc = r; 9711 dst.notifyAll(); 9712 } 9713 updateOomAdjLocked(r); 9714 } 9715 } 9716 9717 Binder.restoreCallingIdentity(origId); 9718 } 9719 } 9720 9721 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9722 ContentProviderConnection conn; 9723 try { 9724 conn = (ContentProviderConnection)connection; 9725 } catch (ClassCastException e) { 9726 String msg ="refContentProvider: " + connection 9727 + " not a ContentProviderConnection"; 9728 Slog.w(TAG, msg); 9729 throw new IllegalArgumentException(msg); 9730 } 9731 if (conn == null) { 9732 throw new NullPointerException("connection is null"); 9733 } 9734 9735 synchronized (this) { 9736 if (stable > 0) { 9737 conn.numStableIncs += stable; 9738 } 9739 stable = conn.stableCount + stable; 9740 if (stable < 0) { 9741 throw new IllegalStateException("stableCount < 0: " + stable); 9742 } 9743 9744 if (unstable > 0) { 9745 conn.numUnstableIncs += unstable; 9746 } 9747 unstable = conn.unstableCount + unstable; 9748 if (unstable < 0) { 9749 throw new IllegalStateException("unstableCount < 0: " + unstable); 9750 } 9751 9752 if ((stable+unstable) <= 0) { 9753 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9754 + stable + " unstable=" + unstable); 9755 } 9756 conn.stableCount = stable; 9757 conn.unstableCount = unstable; 9758 return !conn.dead; 9759 } 9760 } 9761 9762 public void unstableProviderDied(IBinder connection) { 9763 ContentProviderConnection conn; 9764 try { 9765 conn = (ContentProviderConnection)connection; 9766 } catch (ClassCastException e) { 9767 String msg ="refContentProvider: " + connection 9768 + " not a ContentProviderConnection"; 9769 Slog.w(TAG, msg); 9770 throw new IllegalArgumentException(msg); 9771 } 9772 if (conn == null) { 9773 throw new NullPointerException("connection is null"); 9774 } 9775 9776 // Safely retrieve the content provider associated with the connection. 9777 IContentProvider provider; 9778 synchronized (this) { 9779 provider = conn.provider.provider; 9780 } 9781 9782 if (provider == null) { 9783 // Um, yeah, we're way ahead of you. 9784 return; 9785 } 9786 9787 // Make sure the caller is being honest with us. 9788 if (provider.asBinder().pingBinder()) { 9789 // Er, no, still looks good to us. 9790 synchronized (this) { 9791 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9792 + " says " + conn + " died, but we don't agree"); 9793 return; 9794 } 9795 } 9796 9797 // Well look at that! It's dead! 9798 synchronized (this) { 9799 if (conn.provider.provider != provider) { 9800 // But something changed... good enough. 9801 return; 9802 } 9803 9804 ProcessRecord proc = conn.provider.proc; 9805 if (proc == null || proc.thread == null) { 9806 // Seems like the process is already cleaned up. 9807 return; 9808 } 9809 9810 // As far as we're concerned, this is just like receiving a 9811 // death notification... just a bit prematurely. 9812 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9813 + ") early provider death"); 9814 final long ident = Binder.clearCallingIdentity(); 9815 try { 9816 appDiedLocked(proc); 9817 } finally { 9818 Binder.restoreCallingIdentity(ident); 9819 } 9820 } 9821 } 9822 9823 @Override 9824 public void appNotRespondingViaProvider(IBinder connection) { 9825 enforceCallingPermission( 9826 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9827 9828 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9829 if (conn == null) { 9830 Slog.w(TAG, "ContentProviderConnection is null"); 9831 return; 9832 } 9833 9834 final ProcessRecord host = conn.provider.proc; 9835 if (host == null) { 9836 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9837 return; 9838 } 9839 9840 final long token = Binder.clearCallingIdentity(); 9841 try { 9842 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9843 } finally { 9844 Binder.restoreCallingIdentity(token); 9845 } 9846 } 9847 9848 public final void installSystemProviders() { 9849 List<ProviderInfo> providers; 9850 synchronized (this) { 9851 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9852 providers = generateApplicationProvidersLocked(app); 9853 if (providers != null) { 9854 for (int i=providers.size()-1; i>=0; i--) { 9855 ProviderInfo pi = (ProviderInfo)providers.get(i); 9856 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9857 Slog.w(TAG, "Not installing system proc provider " + pi.name 9858 + ": not system .apk"); 9859 providers.remove(i); 9860 } 9861 } 9862 } 9863 } 9864 if (providers != null) { 9865 mSystemThread.installSystemProviders(providers); 9866 } 9867 9868 mCoreSettingsObserver = new CoreSettingsObserver(this); 9869 9870 //mUsageStatsService.monitorPackages(); 9871 } 9872 9873 /** 9874 * Allows apps to retrieve the MIME type of a URI. 9875 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9876 * users, then it does not need permission to access the ContentProvider. 9877 * Either, it needs cross-user uri grants. 9878 * 9879 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9880 * 9881 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9882 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9883 */ 9884 public String getProviderMimeType(Uri uri, int userId) { 9885 enforceNotIsolatedCaller("getProviderMimeType"); 9886 final String name = uri.getAuthority(); 9887 int callingUid = Binder.getCallingUid(); 9888 int callingPid = Binder.getCallingPid(); 9889 long ident = 0; 9890 boolean clearedIdentity = false; 9891 userId = unsafeConvertIncomingUser(userId); 9892 if (canClearIdentity(callingPid, callingUid, userId)) { 9893 clearedIdentity = true; 9894 ident = Binder.clearCallingIdentity(); 9895 } 9896 ContentProviderHolder holder = null; 9897 try { 9898 holder = getContentProviderExternalUnchecked(name, null, userId); 9899 if (holder != null) { 9900 return holder.provider.getType(uri); 9901 } 9902 } catch (RemoteException e) { 9903 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9904 return null; 9905 } finally { 9906 // We need to clear the identity to call removeContentProviderExternalUnchecked 9907 if (!clearedIdentity) { 9908 ident = Binder.clearCallingIdentity(); 9909 } 9910 try { 9911 if (holder != null) { 9912 removeContentProviderExternalUnchecked(name, null, userId); 9913 } 9914 } finally { 9915 Binder.restoreCallingIdentity(ident); 9916 } 9917 } 9918 9919 return null; 9920 } 9921 9922 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9923 if (UserHandle.getUserId(callingUid) == userId) { 9924 return true; 9925 } 9926 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9927 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9928 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9929 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9930 return true; 9931 } 9932 return false; 9933 } 9934 9935 // ========================================================= 9936 // GLOBAL MANAGEMENT 9937 // ========================================================= 9938 9939 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9940 boolean isolated, int isolatedUid) { 9941 String proc = customProcess != null ? customProcess : info.processName; 9942 BatteryStatsImpl.Uid.Proc ps = null; 9943 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9944 int uid = info.uid; 9945 if (isolated) { 9946 if (isolatedUid == 0) { 9947 int userId = UserHandle.getUserId(uid); 9948 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9949 while (true) { 9950 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9951 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9952 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9953 } 9954 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9955 mNextIsolatedProcessUid++; 9956 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9957 // No process for this uid, use it. 9958 break; 9959 } 9960 stepsLeft--; 9961 if (stepsLeft <= 0) { 9962 return null; 9963 } 9964 } 9965 } else { 9966 // Special case for startIsolatedProcess (internal only), where 9967 // the uid of the isolated process is specified by the caller. 9968 uid = isolatedUid; 9969 } 9970 } 9971 return new ProcessRecord(stats, info, proc, uid); 9972 } 9973 9974 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9975 String abiOverride) { 9976 ProcessRecord app; 9977 if (!isolated) { 9978 app = getProcessRecordLocked(info.processName, info.uid, true); 9979 } else { 9980 app = null; 9981 } 9982 9983 if (app == null) { 9984 app = newProcessRecordLocked(info, null, isolated, 0); 9985 mProcessNames.put(info.processName, app.uid, app); 9986 if (isolated) { 9987 mIsolatedProcesses.put(app.uid, app); 9988 } 9989 updateLruProcessLocked(app, false, null); 9990 updateOomAdjLocked(); 9991 } 9992 9993 // This package really, really can not be stopped. 9994 try { 9995 AppGlobals.getPackageManager().setPackageStoppedState( 9996 info.packageName, false, UserHandle.getUserId(app.uid)); 9997 } catch (RemoteException e) { 9998 } catch (IllegalArgumentException e) { 9999 Slog.w(TAG, "Failed trying to unstop package " 10000 + info.packageName + ": " + e); 10001 } 10002 10003 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 10004 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 10005 app.persistent = true; 10006 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 10007 } 10008 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 10009 mPersistentStartingProcesses.add(app); 10010 startProcessLocked(app, "added application", app.processName, abiOverride, 10011 null /* entryPoint */, null /* entryPointArgs */); 10012 } 10013 10014 return app; 10015 } 10016 10017 public void unhandledBack() { 10018 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10019 "unhandledBack()"); 10020 10021 synchronized(this) { 10022 final long origId = Binder.clearCallingIdentity(); 10023 try { 10024 getFocusedStack().unhandledBackLocked(); 10025 } finally { 10026 Binder.restoreCallingIdentity(origId); 10027 } 10028 } 10029 } 10030 10031 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10032 enforceNotIsolatedCaller("openContentUri"); 10033 final int userId = UserHandle.getCallingUserId(); 10034 String name = uri.getAuthority(); 10035 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10036 ParcelFileDescriptor pfd = null; 10037 if (cph != null) { 10038 // We record the binder invoker's uid in thread-local storage before 10039 // going to the content provider to open the file. Later, in the code 10040 // that handles all permissions checks, we look for this uid and use 10041 // that rather than the Activity Manager's own uid. The effect is that 10042 // we do the check against the caller's permissions even though it looks 10043 // to the content provider like the Activity Manager itself is making 10044 // the request. 10045 sCallerIdentity.set(new Identity( 10046 Binder.getCallingPid(), Binder.getCallingUid())); 10047 try { 10048 pfd = cph.provider.openFile(null, uri, "r", null); 10049 } catch (FileNotFoundException e) { 10050 // do nothing; pfd will be returned null 10051 } finally { 10052 // Ensure that whatever happens, we clean up the identity state 10053 sCallerIdentity.remove(); 10054 } 10055 10056 // We've got the fd now, so we're done with the provider. 10057 removeContentProviderExternalUnchecked(name, null, userId); 10058 } else { 10059 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10060 } 10061 return pfd; 10062 } 10063 10064 // Actually is sleeping or shutting down or whatever else in the future 10065 // is an inactive state. 10066 public boolean isSleepingOrShuttingDown() { 10067 return isSleeping() || mShuttingDown; 10068 } 10069 10070 public boolean isSleeping() { 10071 return mSleeping; 10072 } 10073 10074 void goingToSleep() { 10075 synchronized(this) { 10076 mWentToSleep = true; 10077 goToSleepIfNeededLocked(); 10078 } 10079 } 10080 10081 void finishRunningVoiceLocked() { 10082 if (mRunningVoice) { 10083 mRunningVoice = false; 10084 goToSleepIfNeededLocked(); 10085 } 10086 } 10087 10088 void goToSleepIfNeededLocked() { 10089 if (mWentToSleep && !mRunningVoice) { 10090 if (!mSleeping) { 10091 mSleeping = true; 10092 mStackSupervisor.goingToSleepLocked(); 10093 10094 // Initialize the wake times of all processes. 10095 checkExcessivePowerUsageLocked(false); 10096 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10097 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10098 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10099 } 10100 } 10101 } 10102 10103 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10104 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10105 // Never persist the home stack. 10106 return; 10107 } 10108 mTaskPersister.wakeup(task, flush); 10109 } 10110 10111 @Override 10112 public boolean shutdown(int timeout) { 10113 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10114 != PackageManager.PERMISSION_GRANTED) { 10115 throw new SecurityException("Requires permission " 10116 + android.Manifest.permission.SHUTDOWN); 10117 } 10118 10119 boolean timedout = false; 10120 10121 synchronized(this) { 10122 mShuttingDown = true; 10123 updateEventDispatchingLocked(); 10124 timedout = mStackSupervisor.shutdownLocked(timeout); 10125 } 10126 10127 mAppOpsService.shutdown(); 10128 if (mUsageStatsService != null) { 10129 mUsageStatsService.prepareShutdown(); 10130 } 10131 mBatteryStatsService.shutdown(); 10132 synchronized (this) { 10133 mProcessStats.shutdownLocked(); 10134 } 10135 notifyTaskPersisterLocked(null, true); 10136 10137 return timedout; 10138 } 10139 10140 public final void activitySlept(IBinder token) { 10141 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10142 10143 final long origId = Binder.clearCallingIdentity(); 10144 10145 synchronized (this) { 10146 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10147 if (r != null) { 10148 mStackSupervisor.activitySleptLocked(r); 10149 } 10150 } 10151 10152 Binder.restoreCallingIdentity(origId); 10153 } 10154 10155 void logLockScreen(String msg) { 10156 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10157 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10158 mWentToSleep + " mSleeping=" + mSleeping); 10159 } 10160 10161 private void comeOutOfSleepIfNeededLocked() { 10162 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10163 if (mSleeping) { 10164 mSleeping = false; 10165 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10166 } 10167 } 10168 } 10169 10170 void wakingUp() { 10171 synchronized(this) { 10172 mWentToSleep = false; 10173 comeOutOfSleepIfNeededLocked(); 10174 } 10175 } 10176 10177 void startRunningVoiceLocked() { 10178 if (!mRunningVoice) { 10179 mRunningVoice = true; 10180 comeOutOfSleepIfNeededLocked(); 10181 } 10182 } 10183 10184 private void updateEventDispatchingLocked() { 10185 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10186 } 10187 10188 public void setLockScreenShown(boolean shown) { 10189 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10190 != PackageManager.PERMISSION_GRANTED) { 10191 throw new SecurityException("Requires permission " 10192 + android.Manifest.permission.DEVICE_POWER); 10193 } 10194 10195 synchronized(this) { 10196 long ident = Binder.clearCallingIdentity(); 10197 try { 10198 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10199 mLockScreenShown = shown; 10200 comeOutOfSleepIfNeededLocked(); 10201 } finally { 10202 Binder.restoreCallingIdentity(ident); 10203 } 10204 } 10205 } 10206 10207 @Override 10208 public void stopAppSwitches() { 10209 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10210 != PackageManager.PERMISSION_GRANTED) { 10211 throw new SecurityException("Requires permission " 10212 + android.Manifest.permission.STOP_APP_SWITCHES); 10213 } 10214 10215 synchronized(this) { 10216 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10217 + APP_SWITCH_DELAY_TIME; 10218 mDidAppSwitch = false; 10219 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10220 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10221 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10222 } 10223 } 10224 10225 public void resumeAppSwitches() { 10226 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10227 != PackageManager.PERMISSION_GRANTED) { 10228 throw new SecurityException("Requires permission " 10229 + android.Manifest.permission.STOP_APP_SWITCHES); 10230 } 10231 10232 synchronized(this) { 10233 // Note that we don't execute any pending app switches... we will 10234 // let those wait until either the timeout, or the next start 10235 // activity request. 10236 mAppSwitchesAllowedTime = 0; 10237 } 10238 } 10239 10240 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10241 int callingPid, int callingUid, String name) { 10242 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10243 return true; 10244 } 10245 10246 int perm = checkComponentPermission( 10247 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10248 sourceUid, -1, true); 10249 if (perm == PackageManager.PERMISSION_GRANTED) { 10250 return true; 10251 } 10252 10253 // If the actual IPC caller is different from the logical source, then 10254 // also see if they are allowed to control app switches. 10255 if (callingUid != -1 && callingUid != sourceUid) { 10256 perm = checkComponentPermission( 10257 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10258 callingUid, -1, true); 10259 if (perm == PackageManager.PERMISSION_GRANTED) { 10260 return true; 10261 } 10262 } 10263 10264 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10265 return false; 10266 } 10267 10268 public void setDebugApp(String packageName, boolean waitForDebugger, 10269 boolean persistent) { 10270 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10271 "setDebugApp()"); 10272 10273 long ident = Binder.clearCallingIdentity(); 10274 try { 10275 // Note that this is not really thread safe if there are multiple 10276 // callers into it at the same time, but that's not a situation we 10277 // care about. 10278 if (persistent) { 10279 final ContentResolver resolver = mContext.getContentResolver(); 10280 Settings.Global.putString( 10281 resolver, Settings.Global.DEBUG_APP, 10282 packageName); 10283 Settings.Global.putInt( 10284 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10285 waitForDebugger ? 1 : 0); 10286 } 10287 10288 synchronized (this) { 10289 if (!persistent) { 10290 mOrigDebugApp = mDebugApp; 10291 mOrigWaitForDebugger = mWaitForDebugger; 10292 } 10293 mDebugApp = packageName; 10294 mWaitForDebugger = waitForDebugger; 10295 mDebugTransient = !persistent; 10296 if (packageName != null) { 10297 forceStopPackageLocked(packageName, -1, false, false, true, true, 10298 false, UserHandle.USER_ALL, "set debug app"); 10299 } 10300 } 10301 } finally { 10302 Binder.restoreCallingIdentity(ident); 10303 } 10304 } 10305 10306 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10307 synchronized (this) { 10308 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10309 if (!isDebuggable) { 10310 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10311 throw new SecurityException("Process not debuggable: " + app.packageName); 10312 } 10313 } 10314 10315 mOpenGlTraceApp = processName; 10316 } 10317 } 10318 10319 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10320 synchronized (this) { 10321 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10322 if (!isDebuggable) { 10323 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10324 throw new SecurityException("Process not debuggable: " + app.packageName); 10325 } 10326 } 10327 mProfileApp = processName; 10328 mProfileFile = profilerInfo.profileFile; 10329 if (mProfileFd != null) { 10330 try { 10331 mProfileFd.close(); 10332 } catch (IOException e) { 10333 } 10334 mProfileFd = null; 10335 } 10336 mProfileFd = profilerInfo.profileFd; 10337 mSamplingInterval = profilerInfo.samplingInterval; 10338 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10339 mProfileType = 0; 10340 } 10341 } 10342 10343 @Override 10344 public void setAlwaysFinish(boolean enabled) { 10345 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10346 "setAlwaysFinish()"); 10347 10348 Settings.Global.putInt( 10349 mContext.getContentResolver(), 10350 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10351 10352 synchronized (this) { 10353 mAlwaysFinishActivities = enabled; 10354 } 10355 } 10356 10357 @Override 10358 public void setActivityController(IActivityController controller) { 10359 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10360 "setActivityController()"); 10361 synchronized (this) { 10362 mController = controller; 10363 Watchdog.getInstance().setActivityController(controller); 10364 } 10365 } 10366 10367 @Override 10368 public void setUserIsMonkey(boolean userIsMonkey) { 10369 synchronized (this) { 10370 synchronized (mPidsSelfLocked) { 10371 final int callingPid = Binder.getCallingPid(); 10372 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10373 if (precessRecord == null) { 10374 throw new SecurityException("Unknown process: " + callingPid); 10375 } 10376 if (precessRecord.instrumentationUiAutomationConnection == null) { 10377 throw new SecurityException("Only an instrumentation process " 10378 + "with a UiAutomation can call setUserIsMonkey"); 10379 } 10380 } 10381 mUserIsMonkey = userIsMonkey; 10382 } 10383 } 10384 10385 @Override 10386 public boolean isUserAMonkey() { 10387 synchronized (this) { 10388 // If there is a controller also implies the user is a monkey. 10389 return (mUserIsMonkey || mController != null); 10390 } 10391 } 10392 10393 public void requestBugReport() { 10394 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10395 SystemProperties.set("ctl.start", "bugreport"); 10396 } 10397 10398 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10399 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10400 } 10401 10402 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10403 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10404 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10405 } 10406 return KEY_DISPATCHING_TIMEOUT; 10407 } 10408 10409 @Override 10410 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10411 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10412 != PackageManager.PERMISSION_GRANTED) { 10413 throw new SecurityException("Requires permission " 10414 + android.Manifest.permission.FILTER_EVENTS); 10415 } 10416 ProcessRecord proc; 10417 long timeout; 10418 synchronized (this) { 10419 synchronized (mPidsSelfLocked) { 10420 proc = mPidsSelfLocked.get(pid); 10421 } 10422 timeout = getInputDispatchingTimeoutLocked(proc); 10423 } 10424 10425 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10426 return -1; 10427 } 10428 10429 return timeout; 10430 } 10431 10432 /** 10433 * Handle input dispatching timeouts. 10434 * Returns whether input dispatching should be aborted or not. 10435 */ 10436 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10437 final ActivityRecord activity, final ActivityRecord parent, 10438 final boolean aboveSystem, String reason) { 10439 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10440 != PackageManager.PERMISSION_GRANTED) { 10441 throw new SecurityException("Requires permission " 10442 + android.Manifest.permission.FILTER_EVENTS); 10443 } 10444 10445 final String annotation; 10446 if (reason == null) { 10447 annotation = "Input dispatching timed out"; 10448 } else { 10449 annotation = "Input dispatching timed out (" + reason + ")"; 10450 } 10451 10452 if (proc != null) { 10453 synchronized (this) { 10454 if (proc.debugging) { 10455 return false; 10456 } 10457 10458 if (mDidDexOpt) { 10459 // Give more time since we were dexopting. 10460 mDidDexOpt = false; 10461 return false; 10462 } 10463 10464 if (proc.instrumentationClass != null) { 10465 Bundle info = new Bundle(); 10466 info.putString("shortMsg", "keyDispatchingTimedOut"); 10467 info.putString("longMsg", annotation); 10468 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10469 return true; 10470 } 10471 } 10472 mHandler.post(new Runnable() { 10473 @Override 10474 public void run() { 10475 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10476 } 10477 }); 10478 } 10479 10480 return true; 10481 } 10482 10483 public Bundle getAssistContextExtras(int requestType) { 10484 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10485 UserHandle.getCallingUserId()); 10486 if (pae == null) { 10487 return null; 10488 } 10489 synchronized (pae) { 10490 while (!pae.haveResult) { 10491 try { 10492 pae.wait(); 10493 } catch (InterruptedException e) { 10494 } 10495 } 10496 if (pae.result != null) { 10497 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10498 } 10499 } 10500 synchronized (this) { 10501 mPendingAssistExtras.remove(pae); 10502 mHandler.removeCallbacks(pae); 10503 } 10504 return pae.extras; 10505 } 10506 10507 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10508 int userHandle) { 10509 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10510 "getAssistContextExtras()"); 10511 PendingAssistExtras pae; 10512 Bundle extras = new Bundle(); 10513 synchronized (this) { 10514 ActivityRecord activity = getFocusedStack().mResumedActivity; 10515 if (activity == null) { 10516 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10517 return null; 10518 } 10519 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10520 if (activity.app == null || activity.app.thread == null) { 10521 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10522 return null; 10523 } 10524 if (activity.app.pid == Binder.getCallingPid()) { 10525 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10526 return null; 10527 } 10528 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10529 try { 10530 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10531 requestType); 10532 mPendingAssistExtras.add(pae); 10533 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10534 } catch (RemoteException e) { 10535 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10536 return null; 10537 } 10538 return pae; 10539 } 10540 } 10541 10542 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10543 PendingAssistExtras pae = (PendingAssistExtras)token; 10544 synchronized (pae) { 10545 pae.result = extras; 10546 pae.haveResult = true; 10547 pae.notifyAll(); 10548 if (pae.intent == null) { 10549 // Caller is just waiting for the result. 10550 return; 10551 } 10552 } 10553 10554 // We are now ready to launch the assist activity. 10555 synchronized (this) { 10556 boolean exists = mPendingAssistExtras.remove(pae); 10557 mHandler.removeCallbacks(pae); 10558 if (!exists) { 10559 // Timed out. 10560 return; 10561 } 10562 } 10563 pae.intent.replaceExtras(extras); 10564 if (pae.hint != null) { 10565 pae.intent.putExtra(pae.hint, true); 10566 } 10567 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10568 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10569 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10570 closeSystemDialogs("assist"); 10571 try { 10572 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10573 } catch (ActivityNotFoundException e) { 10574 Slog.w(TAG, "No activity to handle assist action.", e); 10575 } 10576 } 10577 10578 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10579 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10580 } 10581 10582 public void registerProcessObserver(IProcessObserver observer) { 10583 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10584 "registerProcessObserver()"); 10585 synchronized (this) { 10586 mProcessObservers.register(observer); 10587 } 10588 } 10589 10590 @Override 10591 public void unregisterProcessObserver(IProcessObserver observer) { 10592 synchronized (this) { 10593 mProcessObservers.unregister(observer); 10594 } 10595 } 10596 10597 @Override 10598 public boolean convertFromTranslucent(IBinder token) { 10599 final long origId = Binder.clearCallingIdentity(); 10600 try { 10601 synchronized (this) { 10602 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10603 if (r == null) { 10604 return false; 10605 } 10606 final boolean translucentChanged = r.changeWindowTranslucency(true); 10607 if (translucentChanged) { 10608 r.task.stack.releaseBackgroundResources(); 10609 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10610 } 10611 mWindowManager.setAppFullscreen(token, true); 10612 return translucentChanged; 10613 } 10614 } finally { 10615 Binder.restoreCallingIdentity(origId); 10616 } 10617 } 10618 10619 @Override 10620 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10621 final long origId = Binder.clearCallingIdentity(); 10622 try { 10623 synchronized (this) { 10624 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10625 if (r == null) { 10626 return false; 10627 } 10628 int index = r.task.mActivities.lastIndexOf(r); 10629 if (index > 0) { 10630 ActivityRecord under = r.task.mActivities.get(index - 1); 10631 under.returningOptions = options; 10632 } 10633 final boolean translucentChanged = r.changeWindowTranslucency(false); 10634 if (translucentChanged) { 10635 r.task.stack.convertToTranslucent(r); 10636 } 10637 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10638 mWindowManager.setAppFullscreen(token, false); 10639 return translucentChanged; 10640 } 10641 } finally { 10642 Binder.restoreCallingIdentity(origId); 10643 } 10644 } 10645 10646 @Override 10647 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10648 final long origId = Binder.clearCallingIdentity(); 10649 try { 10650 synchronized (this) { 10651 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10652 if (r != null) { 10653 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10654 } 10655 } 10656 return false; 10657 } finally { 10658 Binder.restoreCallingIdentity(origId); 10659 } 10660 } 10661 10662 @Override 10663 public boolean isBackgroundVisibleBehind(IBinder token) { 10664 final long origId = Binder.clearCallingIdentity(); 10665 try { 10666 synchronized (this) { 10667 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10668 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10669 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10670 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10671 return visible; 10672 } 10673 } finally { 10674 Binder.restoreCallingIdentity(origId); 10675 } 10676 } 10677 10678 @Override 10679 public ActivityOptions getActivityOptions(IBinder token) { 10680 final long origId = Binder.clearCallingIdentity(); 10681 try { 10682 synchronized (this) { 10683 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10684 if (r != null) { 10685 final ActivityOptions activityOptions = r.pendingOptions; 10686 r.pendingOptions = null; 10687 return activityOptions; 10688 } 10689 return null; 10690 } 10691 } finally { 10692 Binder.restoreCallingIdentity(origId); 10693 } 10694 } 10695 10696 @Override 10697 public void setImmersive(IBinder token, boolean immersive) { 10698 synchronized(this) { 10699 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10700 if (r == null) { 10701 throw new IllegalArgumentException(); 10702 } 10703 r.immersive = immersive; 10704 10705 // update associated state if we're frontmost 10706 if (r == mFocusedActivity) { 10707 if (DEBUG_IMMERSIVE) { 10708 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10709 } 10710 applyUpdateLockStateLocked(r); 10711 } 10712 } 10713 } 10714 10715 @Override 10716 public boolean isImmersive(IBinder token) { 10717 synchronized (this) { 10718 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10719 if (r == null) { 10720 throw new IllegalArgumentException(); 10721 } 10722 return r.immersive; 10723 } 10724 } 10725 10726 public boolean isTopActivityImmersive() { 10727 enforceNotIsolatedCaller("startActivity"); 10728 synchronized (this) { 10729 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10730 return (r != null) ? r.immersive : false; 10731 } 10732 } 10733 10734 @Override 10735 public boolean isTopOfTask(IBinder token) { 10736 synchronized (this) { 10737 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10738 if (r == null) { 10739 throw new IllegalArgumentException(); 10740 } 10741 return r.task.getTopActivity() == r; 10742 } 10743 } 10744 10745 public final void enterSafeMode() { 10746 synchronized(this) { 10747 // It only makes sense to do this before the system is ready 10748 // and started launching other packages. 10749 if (!mSystemReady) { 10750 try { 10751 AppGlobals.getPackageManager().enterSafeMode(); 10752 } catch (RemoteException e) { 10753 } 10754 } 10755 10756 mSafeMode = true; 10757 } 10758 } 10759 10760 public final void showSafeModeOverlay() { 10761 View v = LayoutInflater.from(mContext).inflate( 10762 com.android.internal.R.layout.safe_mode, null); 10763 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10764 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10765 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10766 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10767 lp.gravity = Gravity.BOTTOM | Gravity.START; 10768 lp.format = v.getBackground().getOpacity(); 10769 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10770 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10771 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10772 ((WindowManager)mContext.getSystemService( 10773 Context.WINDOW_SERVICE)).addView(v, lp); 10774 } 10775 10776 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10777 if (!(sender instanceof PendingIntentRecord)) { 10778 return; 10779 } 10780 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10781 synchronized (stats) { 10782 if (mBatteryStatsService.isOnBattery()) { 10783 mBatteryStatsService.enforceCallingPermission(); 10784 PendingIntentRecord rec = (PendingIntentRecord)sender; 10785 int MY_UID = Binder.getCallingUid(); 10786 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10787 BatteryStatsImpl.Uid.Pkg pkg = 10788 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10789 sourcePkg != null ? sourcePkg : rec.key.packageName); 10790 pkg.incWakeupsLocked(); 10791 } 10792 } 10793 } 10794 10795 public boolean killPids(int[] pids, String pReason, boolean secure) { 10796 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10797 throw new SecurityException("killPids only available to the system"); 10798 } 10799 String reason = (pReason == null) ? "Unknown" : pReason; 10800 // XXX Note: don't acquire main activity lock here, because the window 10801 // manager calls in with its locks held. 10802 10803 boolean killed = false; 10804 synchronized (mPidsSelfLocked) { 10805 int[] types = new int[pids.length]; 10806 int worstType = 0; 10807 for (int i=0; i<pids.length; i++) { 10808 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10809 if (proc != null) { 10810 int type = proc.setAdj; 10811 types[i] = type; 10812 if (type > worstType) { 10813 worstType = type; 10814 } 10815 } 10816 } 10817 10818 // If the worst oom_adj is somewhere in the cached proc LRU range, 10819 // then constrain it so we will kill all cached procs. 10820 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10821 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10822 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10823 } 10824 10825 // If this is not a secure call, don't let it kill processes that 10826 // are important. 10827 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10828 worstType = ProcessList.SERVICE_ADJ; 10829 } 10830 10831 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10832 for (int i=0; i<pids.length; i++) { 10833 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10834 if (proc == null) { 10835 continue; 10836 } 10837 int adj = proc.setAdj; 10838 if (adj >= worstType && !proc.killedByAm) { 10839 proc.kill(reason, true); 10840 killed = true; 10841 } 10842 } 10843 } 10844 return killed; 10845 } 10846 10847 @Override 10848 public void killUid(int uid, String reason) { 10849 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10850 throw new SecurityException("killUid only available to the system"); 10851 } 10852 synchronized (this) { 10853 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10854 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10855 reason != null ? reason : "kill uid"); 10856 } 10857 } 10858 10859 @Override 10860 public boolean killProcessesBelowForeground(String reason) { 10861 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10862 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10863 } 10864 10865 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10866 } 10867 10868 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10869 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10870 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10871 } 10872 10873 boolean killed = false; 10874 synchronized (mPidsSelfLocked) { 10875 final int size = mPidsSelfLocked.size(); 10876 for (int i = 0; i < size; i++) { 10877 final int pid = mPidsSelfLocked.keyAt(i); 10878 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10879 if (proc == null) continue; 10880 10881 final int adj = proc.setAdj; 10882 if (adj > belowAdj && !proc.killedByAm) { 10883 proc.kill(reason, true); 10884 killed = true; 10885 } 10886 } 10887 } 10888 return killed; 10889 } 10890 10891 @Override 10892 public void hang(final IBinder who, boolean allowRestart) { 10893 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10894 != PackageManager.PERMISSION_GRANTED) { 10895 throw new SecurityException("Requires permission " 10896 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10897 } 10898 10899 final IBinder.DeathRecipient death = new DeathRecipient() { 10900 @Override 10901 public void binderDied() { 10902 synchronized (this) { 10903 notifyAll(); 10904 } 10905 } 10906 }; 10907 10908 try { 10909 who.linkToDeath(death, 0); 10910 } catch (RemoteException e) { 10911 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10912 return; 10913 } 10914 10915 synchronized (this) { 10916 Watchdog.getInstance().setAllowRestart(allowRestart); 10917 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10918 synchronized (death) { 10919 while (who.isBinderAlive()) { 10920 try { 10921 death.wait(); 10922 } catch (InterruptedException e) { 10923 } 10924 } 10925 } 10926 Watchdog.getInstance().setAllowRestart(true); 10927 } 10928 } 10929 10930 @Override 10931 public void restart() { 10932 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10933 != PackageManager.PERMISSION_GRANTED) { 10934 throw new SecurityException("Requires permission " 10935 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10936 } 10937 10938 Log.i(TAG, "Sending shutdown broadcast..."); 10939 10940 BroadcastReceiver br = new BroadcastReceiver() { 10941 @Override public void onReceive(Context context, Intent intent) { 10942 // Now the broadcast is done, finish up the low-level shutdown. 10943 Log.i(TAG, "Shutting down activity manager..."); 10944 shutdown(10000); 10945 Log.i(TAG, "Shutdown complete, restarting!"); 10946 Process.killProcess(Process.myPid()); 10947 System.exit(10); 10948 } 10949 }; 10950 10951 // First send the high-level shut down broadcast. 10952 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10953 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10954 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10955 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10956 mContext.sendOrderedBroadcastAsUser(intent, 10957 UserHandle.ALL, null, br, mHandler, 0, null, null); 10958 */ 10959 br.onReceive(mContext, intent); 10960 } 10961 10962 private long getLowRamTimeSinceIdle(long now) { 10963 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10964 } 10965 10966 @Override 10967 public void performIdleMaintenance() { 10968 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10969 != PackageManager.PERMISSION_GRANTED) { 10970 throw new SecurityException("Requires permission " 10971 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10972 } 10973 10974 synchronized (this) { 10975 final long now = SystemClock.uptimeMillis(); 10976 final long timeSinceLastIdle = now - mLastIdleTime; 10977 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10978 mLastIdleTime = now; 10979 mLowRamTimeSinceLastIdle = 0; 10980 if (mLowRamStartTime != 0) { 10981 mLowRamStartTime = now; 10982 } 10983 10984 StringBuilder sb = new StringBuilder(128); 10985 sb.append("Idle maintenance over "); 10986 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10987 sb.append(" low RAM for "); 10988 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10989 Slog.i(TAG, sb.toString()); 10990 10991 // If at least 1/3 of our time since the last idle period has been spent 10992 // with RAM low, then we want to kill processes. 10993 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10994 10995 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10996 ProcessRecord proc = mLruProcesses.get(i); 10997 if (proc.notCachedSinceIdle) { 10998 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10999 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 11000 if (doKilling && proc.initialIdlePss != 0 11001 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 11002 proc.kill("idle maint (pss " + proc.lastPss 11003 + " from " + proc.initialIdlePss + ")", true); 11004 } 11005 } 11006 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 11007 proc.notCachedSinceIdle = true; 11008 proc.initialIdlePss = 0; 11009 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 11010 isSleeping(), now); 11011 } 11012 } 11013 11014 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 11015 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 11016 } 11017 } 11018 11019 private void retrieveSettings() { 11020 final ContentResolver resolver = mContext.getContentResolver(); 11021 String debugApp = Settings.Global.getString( 11022 resolver, Settings.Global.DEBUG_APP); 11023 boolean waitForDebugger = Settings.Global.getInt( 11024 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11025 boolean alwaysFinishActivities = Settings.Global.getInt( 11026 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11027 boolean forceRtl = Settings.Global.getInt( 11028 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11029 // Transfer any global setting for forcing RTL layout, into a System Property 11030 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11031 11032 Configuration configuration = new Configuration(); 11033 Settings.System.getConfiguration(resolver, configuration); 11034 if (forceRtl) { 11035 // This will take care of setting the correct layout direction flags 11036 configuration.setLayoutDirection(configuration.locale); 11037 } 11038 11039 synchronized (this) { 11040 mDebugApp = mOrigDebugApp = debugApp; 11041 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11042 mAlwaysFinishActivities = alwaysFinishActivities; 11043 // This happens before any activities are started, so we can 11044 // change mConfiguration in-place. 11045 updateConfigurationLocked(configuration, null, false, true); 11046 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11047 } 11048 } 11049 11050 /** Loads resources after the current configuration has been set. */ 11051 private void loadResourcesOnSystemReady() { 11052 final Resources res = mContext.getResources(); 11053 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11054 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11055 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11056 } 11057 11058 public boolean testIsSystemReady() { 11059 // no need to synchronize(this) just to read & return the value 11060 return mSystemReady; 11061 } 11062 11063 private static File getCalledPreBootReceiversFile() { 11064 File dataDir = Environment.getDataDirectory(); 11065 File systemDir = new File(dataDir, "system"); 11066 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11067 return fname; 11068 } 11069 11070 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11071 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11072 File file = getCalledPreBootReceiversFile(); 11073 FileInputStream fis = null; 11074 try { 11075 fis = new FileInputStream(file); 11076 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11077 int fvers = dis.readInt(); 11078 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11079 String vers = dis.readUTF(); 11080 String codename = dis.readUTF(); 11081 String build = dis.readUTF(); 11082 if (android.os.Build.VERSION.RELEASE.equals(vers) 11083 && android.os.Build.VERSION.CODENAME.equals(codename) 11084 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11085 int num = dis.readInt(); 11086 while (num > 0) { 11087 num--; 11088 String pkg = dis.readUTF(); 11089 String cls = dis.readUTF(); 11090 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11091 } 11092 } 11093 } 11094 } catch (FileNotFoundException e) { 11095 } catch (IOException e) { 11096 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11097 } finally { 11098 if (fis != null) { 11099 try { 11100 fis.close(); 11101 } catch (IOException e) { 11102 } 11103 } 11104 } 11105 return lastDoneReceivers; 11106 } 11107 11108 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11109 File file = getCalledPreBootReceiversFile(); 11110 FileOutputStream fos = null; 11111 DataOutputStream dos = null; 11112 try { 11113 fos = new FileOutputStream(file); 11114 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11115 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11116 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11117 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11118 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11119 dos.writeInt(list.size()); 11120 for (int i=0; i<list.size(); i++) { 11121 dos.writeUTF(list.get(i).getPackageName()); 11122 dos.writeUTF(list.get(i).getClassName()); 11123 } 11124 } catch (IOException e) { 11125 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11126 file.delete(); 11127 } finally { 11128 FileUtils.sync(fos); 11129 if (dos != null) { 11130 try { 11131 dos.close(); 11132 } catch (IOException e) { 11133 // TODO Auto-generated catch block 11134 e.printStackTrace(); 11135 } 11136 } 11137 } 11138 } 11139 11140 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11141 ArrayList<ComponentName> doneReceivers, int userId) { 11142 boolean waitingUpdate = false; 11143 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11144 List<ResolveInfo> ris = null; 11145 try { 11146 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11147 intent, null, 0, userId); 11148 } catch (RemoteException e) { 11149 } 11150 if (ris != null) { 11151 for (int i=ris.size()-1; i>=0; i--) { 11152 if ((ris.get(i).activityInfo.applicationInfo.flags 11153 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11154 ris.remove(i); 11155 } 11156 } 11157 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11158 11159 // For User 0, load the version number. When delivering to a new user, deliver 11160 // to all receivers. 11161 if (userId == UserHandle.USER_OWNER) { 11162 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11163 for (int i=0; i<ris.size(); i++) { 11164 ActivityInfo ai = ris.get(i).activityInfo; 11165 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11166 if (lastDoneReceivers.contains(comp)) { 11167 // We already did the pre boot receiver for this app with the current 11168 // platform version, so don't do it again... 11169 ris.remove(i); 11170 i--; 11171 // ...however, do keep it as one that has been done, so we don't 11172 // forget about it when rewriting the file of last done receivers. 11173 doneReceivers.add(comp); 11174 } 11175 } 11176 } 11177 11178 // If primary user, send broadcast to all available users, else just to userId 11179 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11180 : new int[] { userId }; 11181 for (int i = 0; i < ris.size(); i++) { 11182 ActivityInfo ai = ris.get(i).activityInfo; 11183 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11184 doneReceivers.add(comp); 11185 intent.setComponent(comp); 11186 for (int j=0; j<users.length; j++) { 11187 IIntentReceiver finisher = null; 11188 // On last receiver and user, set up a completion callback 11189 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11190 finisher = new IIntentReceiver.Stub() { 11191 public void performReceive(Intent intent, int resultCode, 11192 String data, Bundle extras, boolean ordered, 11193 boolean sticky, int sendingUser) { 11194 // The raw IIntentReceiver interface is called 11195 // with the AM lock held, so redispatch to 11196 // execute our code without the lock. 11197 mHandler.post(onFinishCallback); 11198 } 11199 }; 11200 } 11201 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11202 + " for user " + users[j]); 11203 broadcastIntentLocked(null, null, intent, null, finisher, 11204 0, null, null, null, AppOpsManager.OP_NONE, 11205 true, false, MY_PID, Process.SYSTEM_UID, 11206 users[j]); 11207 if (finisher != null) { 11208 waitingUpdate = true; 11209 } 11210 } 11211 } 11212 } 11213 11214 return waitingUpdate; 11215 } 11216 11217 public void systemReady(final Runnable goingCallback) { 11218 synchronized(this) { 11219 if (mSystemReady) { 11220 // If we're done calling all the receivers, run the next "boot phase" passed in 11221 // by the SystemServer 11222 if (goingCallback != null) { 11223 goingCallback.run(); 11224 } 11225 return; 11226 } 11227 11228 // Make sure we have the current profile info, since it is needed for 11229 // security checks. 11230 updateCurrentProfileIdsLocked(); 11231 11232 if (mRecentTasks == null) { 11233 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11234 if (!mRecentTasks.isEmpty()) { 11235 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11236 } 11237 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11238 mTaskPersister.startPersisting(); 11239 } 11240 11241 // Check to see if there are any update receivers to run. 11242 if (!mDidUpdate) { 11243 if (mWaitingUpdate) { 11244 return; 11245 } 11246 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11247 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11248 public void run() { 11249 synchronized (ActivityManagerService.this) { 11250 mDidUpdate = true; 11251 } 11252 writeLastDonePreBootReceivers(doneReceivers); 11253 showBootMessage(mContext.getText( 11254 R.string.android_upgrading_complete), 11255 false); 11256 systemReady(goingCallback); 11257 } 11258 }, doneReceivers, UserHandle.USER_OWNER); 11259 11260 if (mWaitingUpdate) { 11261 return; 11262 } 11263 mDidUpdate = true; 11264 } 11265 11266 mAppOpsService.systemReady(); 11267 mSystemReady = true; 11268 } 11269 11270 ArrayList<ProcessRecord> procsToKill = null; 11271 synchronized(mPidsSelfLocked) { 11272 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11273 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11274 if (!isAllowedWhileBooting(proc.info)){ 11275 if (procsToKill == null) { 11276 procsToKill = new ArrayList<ProcessRecord>(); 11277 } 11278 procsToKill.add(proc); 11279 } 11280 } 11281 } 11282 11283 synchronized(this) { 11284 if (procsToKill != null) { 11285 for (int i=procsToKill.size()-1; i>=0; i--) { 11286 ProcessRecord proc = procsToKill.get(i); 11287 Slog.i(TAG, "Removing system update proc: " + proc); 11288 removeProcessLocked(proc, true, false, "system update done"); 11289 } 11290 } 11291 11292 // Now that we have cleaned up any update processes, we 11293 // are ready to start launching real processes and know that 11294 // we won't trample on them any more. 11295 mProcessesReady = true; 11296 } 11297 11298 Slog.i(TAG, "System now ready"); 11299 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11300 SystemClock.uptimeMillis()); 11301 11302 synchronized(this) { 11303 // Make sure we have no pre-ready processes sitting around. 11304 11305 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11306 ResolveInfo ri = mContext.getPackageManager() 11307 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11308 STOCK_PM_FLAGS); 11309 CharSequence errorMsg = null; 11310 if (ri != null) { 11311 ActivityInfo ai = ri.activityInfo; 11312 ApplicationInfo app = ai.applicationInfo; 11313 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11314 mTopAction = Intent.ACTION_FACTORY_TEST; 11315 mTopData = null; 11316 mTopComponent = new ComponentName(app.packageName, 11317 ai.name); 11318 } else { 11319 errorMsg = mContext.getResources().getText( 11320 com.android.internal.R.string.factorytest_not_system); 11321 } 11322 } else { 11323 errorMsg = mContext.getResources().getText( 11324 com.android.internal.R.string.factorytest_no_action); 11325 } 11326 if (errorMsg != null) { 11327 mTopAction = null; 11328 mTopData = null; 11329 mTopComponent = null; 11330 Message msg = Message.obtain(); 11331 msg.what = SHOW_FACTORY_ERROR_MSG; 11332 msg.getData().putCharSequence("msg", errorMsg); 11333 mHandler.sendMessage(msg); 11334 } 11335 } 11336 } 11337 11338 retrieveSettings(); 11339 loadResourcesOnSystemReady(); 11340 11341 synchronized (this) { 11342 readGrantedUriPermissionsLocked(); 11343 } 11344 11345 if (goingCallback != null) goingCallback.run(); 11346 11347 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11348 Integer.toString(mCurrentUserId), mCurrentUserId); 11349 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11350 Integer.toString(mCurrentUserId), mCurrentUserId); 11351 mSystemServiceManager.startUser(mCurrentUserId); 11352 11353 synchronized (this) { 11354 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11355 try { 11356 List apps = AppGlobals.getPackageManager(). 11357 getPersistentApplications(STOCK_PM_FLAGS); 11358 if (apps != null) { 11359 int N = apps.size(); 11360 int i; 11361 for (i=0; i<N; i++) { 11362 ApplicationInfo info 11363 = (ApplicationInfo)apps.get(i); 11364 if (info != null && 11365 !info.packageName.equals("android")) { 11366 addAppLocked(info, false, null /* ABI override */); 11367 } 11368 } 11369 } 11370 } catch (RemoteException ex) { 11371 // pm is in same process, this will never happen. 11372 } 11373 } 11374 11375 // Start up initial activity. 11376 mBooting = true; 11377 startHomeActivityLocked(mCurrentUserId); 11378 11379 try { 11380 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11381 Message msg = Message.obtain(); 11382 msg.what = SHOW_UID_ERROR_MSG; 11383 mHandler.sendMessage(msg); 11384 } 11385 } catch (RemoteException e) { 11386 } 11387 11388 long ident = Binder.clearCallingIdentity(); 11389 try { 11390 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11391 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11392 | Intent.FLAG_RECEIVER_FOREGROUND); 11393 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11394 broadcastIntentLocked(null, null, intent, 11395 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11396 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11397 intent = new Intent(Intent.ACTION_USER_STARTING); 11398 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11399 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11400 broadcastIntentLocked(null, null, intent, 11401 null, new IIntentReceiver.Stub() { 11402 @Override 11403 public void performReceive(Intent intent, int resultCode, String data, 11404 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11405 throws RemoteException { 11406 } 11407 }, 0, null, null, 11408 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11409 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11410 } catch (Throwable t) { 11411 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11412 } finally { 11413 Binder.restoreCallingIdentity(ident); 11414 } 11415 mStackSupervisor.resumeTopActivitiesLocked(); 11416 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11417 } 11418 } 11419 11420 private boolean makeAppCrashingLocked(ProcessRecord app, 11421 String shortMsg, String longMsg, String stackTrace) { 11422 app.crashing = true; 11423 app.crashingReport = generateProcessError(app, 11424 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11425 startAppProblemLocked(app); 11426 app.stopFreezingAllLocked(); 11427 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11428 } 11429 11430 private void makeAppNotRespondingLocked(ProcessRecord app, 11431 String activity, String shortMsg, String longMsg) { 11432 app.notResponding = true; 11433 app.notRespondingReport = generateProcessError(app, 11434 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11435 activity, shortMsg, longMsg, null); 11436 startAppProblemLocked(app); 11437 app.stopFreezingAllLocked(); 11438 } 11439 11440 /** 11441 * Generate a process error record, suitable for attachment to a ProcessRecord. 11442 * 11443 * @param app The ProcessRecord in which the error occurred. 11444 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11445 * ActivityManager.AppErrorStateInfo 11446 * @param activity The activity associated with the crash, if known. 11447 * @param shortMsg Short message describing the crash. 11448 * @param longMsg Long message describing the crash. 11449 * @param stackTrace Full crash stack trace, may be null. 11450 * 11451 * @return Returns a fully-formed AppErrorStateInfo record. 11452 */ 11453 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11454 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11455 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11456 11457 report.condition = condition; 11458 report.processName = app.processName; 11459 report.pid = app.pid; 11460 report.uid = app.info.uid; 11461 report.tag = activity; 11462 report.shortMsg = shortMsg; 11463 report.longMsg = longMsg; 11464 report.stackTrace = stackTrace; 11465 11466 return report; 11467 } 11468 11469 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11470 synchronized (this) { 11471 app.crashing = false; 11472 app.crashingReport = null; 11473 app.notResponding = false; 11474 app.notRespondingReport = null; 11475 if (app.anrDialog == fromDialog) { 11476 app.anrDialog = null; 11477 } 11478 if (app.waitDialog == fromDialog) { 11479 app.waitDialog = null; 11480 } 11481 if (app.pid > 0 && app.pid != MY_PID) { 11482 handleAppCrashLocked(app, null, null, null); 11483 app.kill("user request after error", true); 11484 } 11485 } 11486 } 11487 11488 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11489 String stackTrace) { 11490 long now = SystemClock.uptimeMillis(); 11491 11492 Long crashTime; 11493 if (!app.isolated) { 11494 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11495 } else { 11496 crashTime = null; 11497 } 11498 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11499 // This process loses! 11500 Slog.w(TAG, "Process " + app.info.processName 11501 + " has crashed too many times: killing!"); 11502 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11503 app.userId, app.info.processName, app.uid); 11504 mStackSupervisor.handleAppCrashLocked(app); 11505 if (!app.persistent) { 11506 // We don't want to start this process again until the user 11507 // explicitly does so... but for persistent process, we really 11508 // need to keep it running. If a persistent process is actually 11509 // repeatedly crashing, then badness for everyone. 11510 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11511 app.info.processName); 11512 if (!app.isolated) { 11513 // XXX We don't have a way to mark isolated processes 11514 // as bad, since they don't have a peristent identity. 11515 mBadProcesses.put(app.info.processName, app.uid, 11516 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11517 mProcessCrashTimes.remove(app.info.processName, app.uid); 11518 } 11519 app.bad = true; 11520 app.removed = true; 11521 // Don't let services in this process be restarted and potentially 11522 // annoy the user repeatedly. Unless it is persistent, since those 11523 // processes run critical code. 11524 removeProcessLocked(app, false, false, "crash"); 11525 mStackSupervisor.resumeTopActivitiesLocked(); 11526 return false; 11527 } 11528 mStackSupervisor.resumeTopActivitiesLocked(); 11529 } else { 11530 mStackSupervisor.finishTopRunningActivityLocked(app); 11531 } 11532 11533 // Bump up the crash count of any services currently running in the proc. 11534 for (int i=app.services.size()-1; i>=0; i--) { 11535 // Any services running in the application need to be placed 11536 // back in the pending list. 11537 ServiceRecord sr = app.services.valueAt(i); 11538 sr.crashCount++; 11539 } 11540 11541 // If the crashing process is what we consider to be the "home process" and it has been 11542 // replaced by a third-party app, clear the package preferred activities from packages 11543 // with a home activity running in the process to prevent a repeatedly crashing app 11544 // from blocking the user to manually clear the list. 11545 final ArrayList<ActivityRecord> activities = app.activities; 11546 if (app == mHomeProcess && activities.size() > 0 11547 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11548 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11549 final ActivityRecord r = activities.get(activityNdx); 11550 if (r.isHomeActivity()) { 11551 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11552 try { 11553 ActivityThread.getPackageManager() 11554 .clearPackagePreferredActivities(r.packageName); 11555 } catch (RemoteException c) { 11556 // pm is in same process, this will never happen. 11557 } 11558 } 11559 } 11560 } 11561 11562 if (!app.isolated) { 11563 // XXX Can't keep track of crash times for isolated processes, 11564 // because they don't have a perisistent identity. 11565 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11566 } 11567 11568 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11569 return true; 11570 } 11571 11572 void startAppProblemLocked(ProcessRecord app) { 11573 // If this app is not running under the current user, then we 11574 // can't give it a report button because that would require 11575 // launching the report UI under a different user. 11576 app.errorReportReceiver = null; 11577 11578 for (int userId : mCurrentProfileIds) { 11579 if (app.userId == userId) { 11580 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11581 mContext, app.info.packageName, app.info.flags); 11582 } 11583 } 11584 skipCurrentReceiverLocked(app); 11585 } 11586 11587 void skipCurrentReceiverLocked(ProcessRecord app) { 11588 for (BroadcastQueue queue : mBroadcastQueues) { 11589 queue.skipCurrentReceiverLocked(app); 11590 } 11591 } 11592 11593 /** 11594 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11595 * The application process will exit immediately after this call returns. 11596 * @param app object of the crashing app, null for the system server 11597 * @param crashInfo describing the exception 11598 */ 11599 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11600 ProcessRecord r = findAppProcess(app, "Crash"); 11601 final String processName = app == null ? "system_server" 11602 : (r == null ? "unknown" : r.processName); 11603 11604 handleApplicationCrashInner("crash", r, processName, crashInfo); 11605 } 11606 11607 /* Native crash reporting uses this inner version because it needs to be somewhat 11608 * decoupled from the AM-managed cleanup lifecycle 11609 */ 11610 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11611 ApplicationErrorReport.CrashInfo crashInfo) { 11612 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11613 UserHandle.getUserId(Binder.getCallingUid()), processName, 11614 r == null ? -1 : r.info.flags, 11615 crashInfo.exceptionClassName, 11616 crashInfo.exceptionMessage, 11617 crashInfo.throwFileName, 11618 crashInfo.throwLineNumber); 11619 11620 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11621 11622 crashApplication(r, crashInfo); 11623 } 11624 11625 public void handleApplicationStrictModeViolation( 11626 IBinder app, 11627 int violationMask, 11628 StrictMode.ViolationInfo info) { 11629 ProcessRecord r = findAppProcess(app, "StrictMode"); 11630 if (r == null) { 11631 return; 11632 } 11633 11634 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11635 Integer stackFingerprint = info.hashCode(); 11636 boolean logIt = true; 11637 synchronized (mAlreadyLoggedViolatedStacks) { 11638 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11639 logIt = false; 11640 // TODO: sub-sample into EventLog for these, with 11641 // the info.durationMillis? Then we'd get 11642 // the relative pain numbers, without logging all 11643 // the stack traces repeatedly. We'd want to do 11644 // likewise in the client code, which also does 11645 // dup suppression, before the Binder call. 11646 } else { 11647 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11648 mAlreadyLoggedViolatedStacks.clear(); 11649 } 11650 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11651 } 11652 } 11653 if (logIt) { 11654 logStrictModeViolationToDropBox(r, info); 11655 } 11656 } 11657 11658 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11659 AppErrorResult result = new AppErrorResult(); 11660 synchronized (this) { 11661 final long origId = Binder.clearCallingIdentity(); 11662 11663 Message msg = Message.obtain(); 11664 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11665 HashMap<String, Object> data = new HashMap<String, Object>(); 11666 data.put("result", result); 11667 data.put("app", r); 11668 data.put("violationMask", violationMask); 11669 data.put("info", info); 11670 msg.obj = data; 11671 mHandler.sendMessage(msg); 11672 11673 Binder.restoreCallingIdentity(origId); 11674 } 11675 int res = result.get(); 11676 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11677 } 11678 } 11679 11680 // Depending on the policy in effect, there could be a bunch of 11681 // these in quick succession so we try to batch these together to 11682 // minimize disk writes, number of dropbox entries, and maximize 11683 // compression, by having more fewer, larger records. 11684 private void logStrictModeViolationToDropBox( 11685 ProcessRecord process, 11686 StrictMode.ViolationInfo info) { 11687 if (info == null) { 11688 return; 11689 } 11690 final boolean isSystemApp = process == null || 11691 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11692 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11693 final String processName = process == null ? "unknown" : process.processName; 11694 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11695 final DropBoxManager dbox = (DropBoxManager) 11696 mContext.getSystemService(Context.DROPBOX_SERVICE); 11697 11698 // Exit early if the dropbox isn't configured to accept this report type. 11699 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11700 11701 boolean bufferWasEmpty; 11702 boolean needsFlush; 11703 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11704 synchronized (sb) { 11705 bufferWasEmpty = sb.length() == 0; 11706 appendDropBoxProcessHeaders(process, processName, sb); 11707 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11708 sb.append("System-App: ").append(isSystemApp).append("\n"); 11709 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11710 if (info.violationNumThisLoop != 0) { 11711 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11712 } 11713 if (info.numAnimationsRunning != 0) { 11714 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11715 } 11716 if (info.broadcastIntentAction != null) { 11717 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11718 } 11719 if (info.durationMillis != -1) { 11720 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11721 } 11722 if (info.numInstances != -1) { 11723 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11724 } 11725 if (info.tags != null) { 11726 for (String tag : info.tags) { 11727 sb.append("Span-Tag: ").append(tag).append("\n"); 11728 } 11729 } 11730 sb.append("\n"); 11731 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11732 sb.append(info.crashInfo.stackTrace); 11733 } 11734 sb.append("\n"); 11735 11736 // Only buffer up to ~64k. Various logging bits truncate 11737 // things at 128k. 11738 needsFlush = (sb.length() > 64 * 1024); 11739 } 11740 11741 // Flush immediately if the buffer's grown too large, or this 11742 // is a non-system app. Non-system apps are isolated with a 11743 // different tag & policy and not batched. 11744 // 11745 // Batching is useful during internal testing with 11746 // StrictMode settings turned up high. Without batching, 11747 // thousands of separate files could be created on boot. 11748 if (!isSystemApp || needsFlush) { 11749 new Thread("Error dump: " + dropboxTag) { 11750 @Override 11751 public void run() { 11752 String report; 11753 synchronized (sb) { 11754 report = sb.toString(); 11755 sb.delete(0, sb.length()); 11756 sb.trimToSize(); 11757 } 11758 if (report.length() != 0) { 11759 dbox.addText(dropboxTag, report); 11760 } 11761 } 11762 }.start(); 11763 return; 11764 } 11765 11766 // System app batching: 11767 if (!bufferWasEmpty) { 11768 // An existing dropbox-writing thread is outstanding, so 11769 // we don't need to start it up. The existing thread will 11770 // catch the buffer appends we just did. 11771 return; 11772 } 11773 11774 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11775 // (After this point, we shouldn't access AMS internal data structures.) 11776 new Thread("Error dump: " + dropboxTag) { 11777 @Override 11778 public void run() { 11779 // 5 second sleep to let stacks arrive and be batched together 11780 try { 11781 Thread.sleep(5000); // 5 seconds 11782 } catch (InterruptedException e) {} 11783 11784 String errorReport; 11785 synchronized (mStrictModeBuffer) { 11786 errorReport = mStrictModeBuffer.toString(); 11787 if (errorReport.length() == 0) { 11788 return; 11789 } 11790 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11791 mStrictModeBuffer.trimToSize(); 11792 } 11793 dbox.addText(dropboxTag, errorReport); 11794 } 11795 }.start(); 11796 } 11797 11798 /** 11799 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11800 * @param app object of the crashing app, null for the system server 11801 * @param tag reported by the caller 11802 * @param system whether this wtf is coming from the system 11803 * @param crashInfo describing the context of the error 11804 * @return true if the process should exit immediately (WTF is fatal) 11805 */ 11806 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11807 final ApplicationErrorReport.CrashInfo crashInfo) { 11808 final int callingUid = Binder.getCallingUid(); 11809 final int callingPid = Binder.getCallingPid(); 11810 11811 if (system) { 11812 // If this is coming from the system, we could very well have low-level 11813 // system locks held, so we want to do this all asynchronously. And we 11814 // never want this to become fatal, so there is that too. 11815 mHandler.post(new Runnable() { 11816 @Override public void run() { 11817 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11818 } 11819 }); 11820 return false; 11821 } 11822 11823 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11824 crashInfo); 11825 11826 if (r != null && r.pid != Process.myPid() && 11827 Settings.Global.getInt(mContext.getContentResolver(), 11828 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11829 crashApplication(r, crashInfo); 11830 return true; 11831 } else { 11832 return false; 11833 } 11834 } 11835 11836 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11837 final ApplicationErrorReport.CrashInfo crashInfo) { 11838 final ProcessRecord r = findAppProcess(app, "WTF"); 11839 final String processName = app == null ? "system_server" 11840 : (r == null ? "unknown" : r.processName); 11841 11842 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11843 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11844 11845 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11846 11847 return r; 11848 } 11849 11850 /** 11851 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11852 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11853 */ 11854 private ProcessRecord findAppProcess(IBinder app, String reason) { 11855 if (app == null) { 11856 return null; 11857 } 11858 11859 synchronized (this) { 11860 final int NP = mProcessNames.getMap().size(); 11861 for (int ip=0; ip<NP; ip++) { 11862 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11863 final int NA = apps.size(); 11864 for (int ia=0; ia<NA; ia++) { 11865 ProcessRecord p = apps.valueAt(ia); 11866 if (p.thread != null && p.thread.asBinder() == app) { 11867 return p; 11868 } 11869 } 11870 } 11871 11872 Slog.w(TAG, "Can't find mystery application for " + reason 11873 + " from pid=" + Binder.getCallingPid() 11874 + " uid=" + Binder.getCallingUid() + ": " + app); 11875 return null; 11876 } 11877 } 11878 11879 /** 11880 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11881 * to append various headers to the dropbox log text. 11882 */ 11883 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11884 StringBuilder sb) { 11885 // Watchdog thread ends up invoking this function (with 11886 // a null ProcessRecord) to add the stack file to dropbox. 11887 // Do not acquire a lock on this (am) in such cases, as it 11888 // could cause a potential deadlock, if and when watchdog 11889 // is invoked due to unavailability of lock on am and it 11890 // would prevent watchdog from killing system_server. 11891 if (process == null) { 11892 sb.append("Process: ").append(processName).append("\n"); 11893 return; 11894 } 11895 // Note: ProcessRecord 'process' is guarded by the service 11896 // instance. (notably process.pkgList, which could otherwise change 11897 // concurrently during execution of this method) 11898 synchronized (this) { 11899 sb.append("Process: ").append(processName).append("\n"); 11900 int flags = process.info.flags; 11901 IPackageManager pm = AppGlobals.getPackageManager(); 11902 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11903 for (int ip=0; ip<process.pkgList.size(); ip++) { 11904 String pkg = process.pkgList.keyAt(ip); 11905 sb.append("Package: ").append(pkg); 11906 try { 11907 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11908 if (pi != null) { 11909 sb.append(" v").append(pi.versionCode); 11910 if (pi.versionName != null) { 11911 sb.append(" (").append(pi.versionName).append(")"); 11912 } 11913 } 11914 } catch (RemoteException e) { 11915 Slog.e(TAG, "Error getting package info: " + pkg, e); 11916 } 11917 sb.append("\n"); 11918 } 11919 } 11920 } 11921 11922 private static String processClass(ProcessRecord process) { 11923 if (process == null || process.pid == MY_PID) { 11924 return "system_server"; 11925 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11926 return "system_app"; 11927 } else { 11928 return "data_app"; 11929 } 11930 } 11931 11932 /** 11933 * Write a description of an error (crash, WTF, ANR) to the drop box. 11934 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11935 * @param process which caused the error, null means the system server 11936 * @param activity which triggered the error, null if unknown 11937 * @param parent activity related to the error, null if unknown 11938 * @param subject line related to the error, null if absent 11939 * @param report in long form describing the error, null if absent 11940 * @param logFile to include in the report, null if none 11941 * @param crashInfo giving an application stack trace, null if absent 11942 */ 11943 public void addErrorToDropBox(String eventType, 11944 ProcessRecord process, String processName, ActivityRecord activity, 11945 ActivityRecord parent, String subject, 11946 final String report, final File logFile, 11947 final ApplicationErrorReport.CrashInfo crashInfo) { 11948 // NOTE -- this must never acquire the ActivityManagerService lock, 11949 // otherwise the watchdog may be prevented from resetting the system. 11950 11951 final String dropboxTag = processClass(process) + "_" + eventType; 11952 final DropBoxManager dbox = (DropBoxManager) 11953 mContext.getSystemService(Context.DROPBOX_SERVICE); 11954 11955 // Exit early if the dropbox isn't configured to accept this report type. 11956 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11957 11958 final StringBuilder sb = new StringBuilder(1024); 11959 appendDropBoxProcessHeaders(process, processName, sb); 11960 if (activity != null) { 11961 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11962 } 11963 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11964 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11965 } 11966 if (parent != null && parent != activity) { 11967 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11968 } 11969 if (subject != null) { 11970 sb.append("Subject: ").append(subject).append("\n"); 11971 } 11972 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11973 if (Debug.isDebuggerConnected()) { 11974 sb.append("Debugger: Connected\n"); 11975 } 11976 sb.append("\n"); 11977 11978 // Do the rest in a worker thread to avoid blocking the caller on I/O 11979 // (After this point, we shouldn't access AMS internal data structures.) 11980 Thread worker = new Thread("Error dump: " + dropboxTag) { 11981 @Override 11982 public void run() { 11983 if (report != null) { 11984 sb.append(report); 11985 } 11986 if (logFile != null) { 11987 try { 11988 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11989 "\n\n[[TRUNCATED]]")); 11990 } catch (IOException e) { 11991 Slog.e(TAG, "Error reading " + logFile, e); 11992 } 11993 } 11994 if (crashInfo != null && crashInfo.stackTrace != null) { 11995 sb.append(crashInfo.stackTrace); 11996 } 11997 11998 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11999 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 12000 if (lines > 0) { 12001 sb.append("\n"); 12002 12003 // Merge several logcat streams, and take the last N lines 12004 InputStreamReader input = null; 12005 try { 12006 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 12007 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 12008 "-b", "crash", 12009 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 12010 12011 try { logcat.getOutputStream().close(); } catch (IOException e) {} 12012 try { logcat.getErrorStream().close(); } catch (IOException e) {} 12013 input = new InputStreamReader(logcat.getInputStream()); 12014 12015 int num; 12016 char[] buf = new char[8192]; 12017 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 12018 } catch (IOException e) { 12019 Slog.e(TAG, "Error running logcat", e); 12020 } finally { 12021 if (input != null) try { input.close(); } catch (IOException e) {} 12022 } 12023 } 12024 12025 dbox.addText(dropboxTag, sb.toString()); 12026 } 12027 }; 12028 12029 if (process == null) { 12030 // If process is null, we are being called from some internal code 12031 // and may be about to die -- run this synchronously. 12032 worker.run(); 12033 } else { 12034 worker.start(); 12035 } 12036 } 12037 12038 /** 12039 * Bring up the "unexpected error" dialog box for a crashing app. 12040 * Deal with edge cases (intercepts from instrumented applications, 12041 * ActivityController, error intent receivers, that sort of thing). 12042 * @param r the application crashing 12043 * @param crashInfo describing the failure 12044 */ 12045 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12046 long timeMillis = System.currentTimeMillis(); 12047 String shortMsg = crashInfo.exceptionClassName; 12048 String longMsg = crashInfo.exceptionMessage; 12049 String stackTrace = crashInfo.stackTrace; 12050 if (shortMsg != null && longMsg != null) { 12051 longMsg = shortMsg + ": " + longMsg; 12052 } else if (shortMsg != null) { 12053 longMsg = shortMsg; 12054 } 12055 12056 AppErrorResult result = new AppErrorResult(); 12057 synchronized (this) { 12058 if (mController != null) { 12059 try { 12060 String name = r != null ? r.processName : null; 12061 int pid = r != null ? r.pid : Binder.getCallingPid(); 12062 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12063 if (!mController.appCrashed(name, pid, 12064 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12065 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12066 && "Native crash".equals(crashInfo.exceptionClassName)) { 12067 Slog.w(TAG, "Skip killing native crashed app " + name 12068 + "(" + pid + ") during testing"); 12069 } else { 12070 Slog.w(TAG, "Force-killing crashed app " + name 12071 + " at watcher's request"); 12072 if (r != null) { 12073 r.kill("crash", true); 12074 } else { 12075 // Huh. 12076 Process.killProcess(pid); 12077 Process.killProcessGroup(uid, pid); 12078 } 12079 } 12080 return; 12081 } 12082 } catch (RemoteException e) { 12083 mController = null; 12084 Watchdog.getInstance().setActivityController(null); 12085 } 12086 } 12087 12088 final long origId = Binder.clearCallingIdentity(); 12089 12090 // If this process is running instrumentation, finish it. 12091 if (r != null && r.instrumentationClass != null) { 12092 Slog.w(TAG, "Error in app " + r.processName 12093 + " running instrumentation " + r.instrumentationClass + ":"); 12094 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12095 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12096 Bundle info = new Bundle(); 12097 info.putString("shortMsg", shortMsg); 12098 info.putString("longMsg", longMsg); 12099 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12100 Binder.restoreCallingIdentity(origId); 12101 return; 12102 } 12103 12104 // If we can't identify the process or it's already exceeded its crash quota, 12105 // quit right away without showing a crash dialog. 12106 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12107 Binder.restoreCallingIdentity(origId); 12108 return; 12109 } 12110 12111 Message msg = Message.obtain(); 12112 msg.what = SHOW_ERROR_MSG; 12113 HashMap data = new HashMap(); 12114 data.put("result", result); 12115 data.put("app", r); 12116 msg.obj = data; 12117 mHandler.sendMessage(msg); 12118 12119 Binder.restoreCallingIdentity(origId); 12120 } 12121 12122 int res = result.get(); 12123 12124 Intent appErrorIntent = null; 12125 synchronized (this) { 12126 if (r != null && !r.isolated) { 12127 // XXX Can't keep track of crash time for isolated processes, 12128 // since they don't have a persistent identity. 12129 mProcessCrashTimes.put(r.info.processName, r.uid, 12130 SystemClock.uptimeMillis()); 12131 } 12132 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12133 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12134 } 12135 } 12136 12137 if (appErrorIntent != null) { 12138 try { 12139 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12140 } catch (ActivityNotFoundException e) { 12141 Slog.w(TAG, "bug report receiver dissappeared", e); 12142 } 12143 } 12144 } 12145 12146 Intent createAppErrorIntentLocked(ProcessRecord r, 12147 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12148 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12149 if (report == null) { 12150 return null; 12151 } 12152 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12153 result.setComponent(r.errorReportReceiver); 12154 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12155 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12156 return result; 12157 } 12158 12159 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12160 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12161 if (r.errorReportReceiver == null) { 12162 return null; 12163 } 12164 12165 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12166 return null; 12167 } 12168 12169 ApplicationErrorReport report = new ApplicationErrorReport(); 12170 report.packageName = r.info.packageName; 12171 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12172 report.processName = r.processName; 12173 report.time = timeMillis; 12174 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12175 12176 if (r.crashing || r.forceCrashReport) { 12177 report.type = ApplicationErrorReport.TYPE_CRASH; 12178 report.crashInfo = crashInfo; 12179 } else if (r.notResponding) { 12180 report.type = ApplicationErrorReport.TYPE_ANR; 12181 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12182 12183 report.anrInfo.activity = r.notRespondingReport.tag; 12184 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12185 report.anrInfo.info = r.notRespondingReport.longMsg; 12186 } 12187 12188 return report; 12189 } 12190 12191 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12192 enforceNotIsolatedCaller("getProcessesInErrorState"); 12193 // assume our apps are happy - lazy create the list 12194 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12195 12196 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12197 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12198 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12199 12200 synchronized (this) { 12201 12202 // iterate across all processes 12203 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12204 ProcessRecord app = mLruProcesses.get(i); 12205 if (!allUsers && app.userId != userId) { 12206 continue; 12207 } 12208 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12209 // This one's in trouble, so we'll generate a report for it 12210 // crashes are higher priority (in case there's a crash *and* an anr) 12211 ActivityManager.ProcessErrorStateInfo report = null; 12212 if (app.crashing) { 12213 report = app.crashingReport; 12214 } else if (app.notResponding) { 12215 report = app.notRespondingReport; 12216 } 12217 12218 if (report != null) { 12219 if (errList == null) { 12220 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12221 } 12222 errList.add(report); 12223 } else { 12224 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12225 " crashing = " + app.crashing + 12226 " notResponding = " + app.notResponding); 12227 } 12228 } 12229 } 12230 } 12231 12232 return errList; 12233 } 12234 12235 static int procStateToImportance(int procState, int memAdj, 12236 ActivityManager.RunningAppProcessInfo currApp) { 12237 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12238 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12239 currApp.lru = memAdj; 12240 } else { 12241 currApp.lru = 0; 12242 } 12243 return imp; 12244 } 12245 12246 private void fillInProcMemInfo(ProcessRecord app, 12247 ActivityManager.RunningAppProcessInfo outInfo) { 12248 outInfo.pid = app.pid; 12249 outInfo.uid = app.info.uid; 12250 if (mHeavyWeightProcess == app) { 12251 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12252 } 12253 if (app.persistent) { 12254 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12255 } 12256 if (app.activities.size() > 0) { 12257 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12258 } 12259 outInfo.lastTrimLevel = app.trimMemoryLevel; 12260 int adj = app.curAdj; 12261 int procState = app.curProcState; 12262 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12263 outInfo.importanceReasonCode = app.adjTypeCode; 12264 outInfo.processState = app.curProcState; 12265 } 12266 12267 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12268 enforceNotIsolatedCaller("getRunningAppProcesses"); 12269 // Lazy instantiation of list 12270 List<ActivityManager.RunningAppProcessInfo> runList = null; 12271 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12272 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12273 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12274 synchronized (this) { 12275 // Iterate across all processes 12276 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12277 ProcessRecord app = mLruProcesses.get(i); 12278 if (!allUsers && app.userId != userId) { 12279 continue; 12280 } 12281 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12282 // Generate process state info for running application 12283 ActivityManager.RunningAppProcessInfo currApp = 12284 new ActivityManager.RunningAppProcessInfo(app.processName, 12285 app.pid, app.getPackageList()); 12286 fillInProcMemInfo(app, currApp); 12287 if (app.adjSource instanceof ProcessRecord) { 12288 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12289 currApp.importanceReasonImportance = 12290 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12291 app.adjSourceProcState); 12292 } else if (app.adjSource instanceof ActivityRecord) { 12293 ActivityRecord r = (ActivityRecord)app.adjSource; 12294 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12295 } 12296 if (app.adjTarget instanceof ComponentName) { 12297 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12298 } 12299 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12300 // + " lru=" + currApp.lru); 12301 if (runList == null) { 12302 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12303 } 12304 runList.add(currApp); 12305 } 12306 } 12307 } 12308 return runList; 12309 } 12310 12311 public List<ApplicationInfo> getRunningExternalApplications() { 12312 enforceNotIsolatedCaller("getRunningExternalApplications"); 12313 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12314 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12315 if (runningApps != null && runningApps.size() > 0) { 12316 Set<String> extList = new HashSet<String>(); 12317 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12318 if (app.pkgList != null) { 12319 for (String pkg : app.pkgList) { 12320 extList.add(pkg); 12321 } 12322 } 12323 } 12324 IPackageManager pm = AppGlobals.getPackageManager(); 12325 for (String pkg : extList) { 12326 try { 12327 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12328 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12329 retList.add(info); 12330 } 12331 } catch (RemoteException e) { 12332 } 12333 } 12334 } 12335 return retList; 12336 } 12337 12338 @Override 12339 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12340 enforceNotIsolatedCaller("getMyMemoryState"); 12341 synchronized (this) { 12342 ProcessRecord proc; 12343 synchronized (mPidsSelfLocked) { 12344 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12345 } 12346 fillInProcMemInfo(proc, outInfo); 12347 } 12348 } 12349 12350 @Override 12351 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12352 if (checkCallingPermission(android.Manifest.permission.DUMP) 12353 != PackageManager.PERMISSION_GRANTED) { 12354 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12355 + Binder.getCallingPid() 12356 + ", uid=" + Binder.getCallingUid() 12357 + " without permission " 12358 + android.Manifest.permission.DUMP); 12359 return; 12360 } 12361 12362 boolean dumpAll = false; 12363 boolean dumpClient = false; 12364 String dumpPackage = null; 12365 12366 int opti = 0; 12367 while (opti < args.length) { 12368 String opt = args[opti]; 12369 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12370 break; 12371 } 12372 opti++; 12373 if ("-a".equals(opt)) { 12374 dumpAll = true; 12375 } else if ("-c".equals(opt)) { 12376 dumpClient = true; 12377 } else if ("-h".equals(opt)) { 12378 pw.println("Activity manager dump options:"); 12379 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12380 pw.println(" cmd may be one of:"); 12381 pw.println(" a[ctivities]: activity stack state"); 12382 pw.println(" r[recents]: recent activities state"); 12383 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12384 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12385 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12386 pw.println(" o[om]: out of memory management"); 12387 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12388 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12389 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12390 pw.println(" service [COMP_SPEC]: service client-side state"); 12391 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12392 pw.println(" all: dump all activities"); 12393 pw.println(" top: dump the top activity"); 12394 pw.println(" write: write all pending state to storage"); 12395 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12396 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12397 pw.println(" a partial substring in a component name, a"); 12398 pw.println(" hex object identifier."); 12399 pw.println(" -a: include all available server state."); 12400 pw.println(" -c: include client state."); 12401 return; 12402 } else { 12403 pw.println("Unknown argument: " + opt + "; use -h for help"); 12404 } 12405 } 12406 12407 long origId = Binder.clearCallingIdentity(); 12408 boolean more = false; 12409 // Is the caller requesting to dump a particular piece of data? 12410 if (opti < args.length) { 12411 String cmd = args[opti]; 12412 opti++; 12413 if ("activities".equals(cmd) || "a".equals(cmd)) { 12414 synchronized (this) { 12415 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12416 } 12417 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12418 synchronized (this) { 12419 dumpRecentsLocked(fd, pw, args, opti, true, null); 12420 } 12421 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12422 String[] newArgs; 12423 String name; 12424 if (opti >= args.length) { 12425 name = null; 12426 newArgs = EMPTY_STRING_ARRAY; 12427 } else { 12428 name = args[opti]; 12429 opti++; 12430 newArgs = new String[args.length - opti]; 12431 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12432 args.length - opti); 12433 } 12434 synchronized (this) { 12435 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12436 } 12437 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12438 String[] newArgs; 12439 String name; 12440 if (opti >= args.length) { 12441 name = null; 12442 newArgs = EMPTY_STRING_ARRAY; 12443 } else { 12444 name = args[opti]; 12445 opti++; 12446 newArgs = new String[args.length - opti]; 12447 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12448 args.length - opti); 12449 } 12450 synchronized (this) { 12451 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12452 } 12453 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12454 String[] newArgs; 12455 String name; 12456 if (opti >= args.length) { 12457 name = null; 12458 newArgs = EMPTY_STRING_ARRAY; 12459 } else { 12460 name = args[opti]; 12461 opti++; 12462 newArgs = new String[args.length - opti]; 12463 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12464 args.length - opti); 12465 } 12466 synchronized (this) { 12467 dumpProcessesLocked(fd, pw, args, opti, true, name); 12468 } 12469 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12470 synchronized (this) { 12471 dumpOomLocked(fd, pw, args, opti, true); 12472 } 12473 } else if ("provider".equals(cmd)) { 12474 String[] newArgs; 12475 String name; 12476 if (opti >= args.length) { 12477 name = null; 12478 newArgs = EMPTY_STRING_ARRAY; 12479 } else { 12480 name = args[opti]; 12481 opti++; 12482 newArgs = new String[args.length - opti]; 12483 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12484 } 12485 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12486 pw.println("No providers match: " + name); 12487 pw.println("Use -h for help."); 12488 } 12489 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12490 synchronized (this) { 12491 dumpProvidersLocked(fd, pw, args, opti, true, null); 12492 } 12493 } else if ("service".equals(cmd)) { 12494 String[] newArgs; 12495 String name; 12496 if (opti >= args.length) { 12497 name = null; 12498 newArgs = EMPTY_STRING_ARRAY; 12499 } else { 12500 name = args[opti]; 12501 opti++; 12502 newArgs = new String[args.length - opti]; 12503 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12504 args.length - opti); 12505 } 12506 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12507 pw.println("No services match: " + name); 12508 pw.println("Use -h for help."); 12509 } 12510 } else if ("package".equals(cmd)) { 12511 String[] newArgs; 12512 if (opti >= args.length) { 12513 pw.println("package: no package name specified"); 12514 pw.println("Use -h for help."); 12515 } else { 12516 dumpPackage = args[opti]; 12517 opti++; 12518 newArgs = new String[args.length - opti]; 12519 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12520 args.length - opti); 12521 args = newArgs; 12522 opti = 0; 12523 more = true; 12524 } 12525 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12526 synchronized (this) { 12527 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12528 } 12529 } else if ("write".equals(cmd)) { 12530 mTaskPersister.flush(); 12531 pw.println("All tasks persisted."); 12532 return; 12533 } else { 12534 // Dumping a single activity? 12535 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12536 pw.println("Bad activity command, or no activities match: " + cmd); 12537 pw.println("Use -h for help."); 12538 } 12539 } 12540 if (!more) { 12541 Binder.restoreCallingIdentity(origId); 12542 return; 12543 } 12544 } 12545 12546 // No piece of data specified, dump everything. 12547 synchronized (this) { 12548 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12549 pw.println(); 12550 if (dumpAll) { 12551 pw.println("-------------------------------------------------------------------------------"); 12552 } 12553 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12554 pw.println(); 12555 if (dumpAll) { 12556 pw.println("-------------------------------------------------------------------------------"); 12557 } 12558 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12559 pw.println(); 12560 if (dumpAll) { 12561 pw.println("-------------------------------------------------------------------------------"); 12562 } 12563 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12564 pw.println(); 12565 if (dumpAll) { 12566 pw.println("-------------------------------------------------------------------------------"); 12567 } 12568 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12569 pw.println(); 12570 if (dumpAll) { 12571 pw.println("-------------------------------------------------------------------------------"); 12572 } 12573 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12574 pw.println(); 12575 if (dumpAll) { 12576 pw.println("-------------------------------------------------------------------------------"); 12577 } 12578 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12579 } 12580 Binder.restoreCallingIdentity(origId); 12581 } 12582 12583 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12584 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12585 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12586 12587 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12588 dumpPackage); 12589 boolean needSep = printedAnything; 12590 12591 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12592 dumpPackage, needSep, " mFocusedActivity: "); 12593 if (printed) { 12594 printedAnything = true; 12595 needSep = false; 12596 } 12597 12598 if (dumpPackage == null) { 12599 if (needSep) { 12600 pw.println(); 12601 } 12602 needSep = true; 12603 printedAnything = true; 12604 mStackSupervisor.dump(pw, " "); 12605 } 12606 12607 if (!printedAnything) { 12608 pw.println(" (nothing)"); 12609 } 12610 } 12611 12612 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12613 int opti, boolean dumpAll, String dumpPackage) { 12614 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12615 12616 boolean printedAnything = false; 12617 12618 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12619 boolean printedHeader = false; 12620 12621 final int N = mRecentTasks.size(); 12622 for (int i=0; i<N; i++) { 12623 TaskRecord tr = mRecentTasks.get(i); 12624 if (dumpPackage != null) { 12625 if (tr.realActivity == null || 12626 !dumpPackage.equals(tr.realActivity)) { 12627 continue; 12628 } 12629 } 12630 if (!printedHeader) { 12631 pw.println(" Recent tasks:"); 12632 printedHeader = true; 12633 printedAnything = true; 12634 } 12635 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12636 pw.println(tr); 12637 if (dumpAll) { 12638 mRecentTasks.get(i).dump(pw, " "); 12639 } 12640 } 12641 } 12642 12643 if (!printedAnything) { 12644 pw.println(" (nothing)"); 12645 } 12646 } 12647 12648 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12649 int opti, boolean dumpAll, String dumpPackage) { 12650 boolean needSep = false; 12651 boolean printedAnything = false; 12652 int numPers = 0; 12653 12654 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12655 12656 if (dumpAll) { 12657 final int NP = mProcessNames.getMap().size(); 12658 for (int ip=0; ip<NP; ip++) { 12659 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12660 final int NA = procs.size(); 12661 for (int ia=0; ia<NA; ia++) { 12662 ProcessRecord r = procs.valueAt(ia); 12663 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12664 continue; 12665 } 12666 if (!needSep) { 12667 pw.println(" All known processes:"); 12668 needSep = true; 12669 printedAnything = true; 12670 } 12671 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12672 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12673 pw.print(" "); pw.println(r); 12674 r.dump(pw, " "); 12675 if (r.persistent) { 12676 numPers++; 12677 } 12678 } 12679 } 12680 } 12681 12682 if (mIsolatedProcesses.size() > 0) { 12683 boolean printed = false; 12684 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12685 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12686 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12687 continue; 12688 } 12689 if (!printed) { 12690 if (needSep) { 12691 pw.println(); 12692 } 12693 pw.println(" Isolated process list (sorted by uid):"); 12694 printedAnything = true; 12695 printed = true; 12696 needSep = true; 12697 } 12698 pw.println(String.format("%sIsolated #%2d: %s", 12699 " ", i, r.toString())); 12700 } 12701 } 12702 12703 if (mLruProcesses.size() > 0) { 12704 if (needSep) { 12705 pw.println(); 12706 } 12707 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12708 pw.print(" total, non-act at "); 12709 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12710 pw.print(", non-svc at "); 12711 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12712 pw.println("):"); 12713 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12714 needSep = true; 12715 printedAnything = true; 12716 } 12717 12718 if (dumpAll || dumpPackage != null) { 12719 synchronized (mPidsSelfLocked) { 12720 boolean printed = false; 12721 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12722 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12723 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12724 continue; 12725 } 12726 if (!printed) { 12727 if (needSep) pw.println(); 12728 needSep = true; 12729 pw.println(" PID mappings:"); 12730 printed = true; 12731 printedAnything = true; 12732 } 12733 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12734 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12735 } 12736 } 12737 } 12738 12739 if (mForegroundProcesses.size() > 0) { 12740 synchronized (mPidsSelfLocked) { 12741 boolean printed = false; 12742 for (int i=0; i<mForegroundProcesses.size(); i++) { 12743 ProcessRecord r = mPidsSelfLocked.get( 12744 mForegroundProcesses.valueAt(i).pid); 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(" Foreground Processes:"); 12753 printed = true; 12754 printedAnything = true; 12755 } 12756 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12757 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12758 } 12759 } 12760 } 12761 12762 if (mPersistentStartingProcesses.size() > 0) { 12763 if (needSep) pw.println(); 12764 needSep = true; 12765 printedAnything = true; 12766 pw.println(" Persisent processes that are starting:"); 12767 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12768 "Starting Norm", "Restarting PERS", dumpPackage); 12769 } 12770 12771 if (mRemovedProcesses.size() > 0) { 12772 if (needSep) pw.println(); 12773 needSep = true; 12774 printedAnything = true; 12775 pw.println(" Processes that are being removed:"); 12776 dumpProcessList(pw, this, mRemovedProcesses, " ", 12777 "Removed Norm", "Removed PERS", dumpPackage); 12778 } 12779 12780 if (mProcessesOnHold.size() > 0) { 12781 if (needSep) pw.println(); 12782 needSep = true; 12783 printedAnything = true; 12784 pw.println(" Processes that are on old until the system is ready:"); 12785 dumpProcessList(pw, this, mProcessesOnHold, " ", 12786 "OnHold Norm", "OnHold PERS", dumpPackage); 12787 } 12788 12789 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12790 12791 if (mProcessCrashTimes.getMap().size() > 0) { 12792 boolean printed = false; 12793 long now = SystemClock.uptimeMillis(); 12794 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12795 final int NP = pmap.size(); 12796 for (int ip=0; ip<NP; ip++) { 12797 String pname = pmap.keyAt(ip); 12798 SparseArray<Long> uids = pmap.valueAt(ip); 12799 final int N = uids.size(); 12800 for (int i=0; i<N; i++) { 12801 int puid = uids.keyAt(i); 12802 ProcessRecord r = mProcessNames.get(pname, puid); 12803 if (dumpPackage != null && (r == null 12804 || !r.pkgList.containsKey(dumpPackage))) { 12805 continue; 12806 } 12807 if (!printed) { 12808 if (needSep) pw.println(); 12809 needSep = true; 12810 pw.println(" Time since processes crashed:"); 12811 printed = true; 12812 printedAnything = true; 12813 } 12814 pw.print(" Process "); pw.print(pname); 12815 pw.print(" uid "); pw.print(puid); 12816 pw.print(": last crashed "); 12817 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12818 pw.println(" ago"); 12819 } 12820 } 12821 } 12822 12823 if (mBadProcesses.getMap().size() > 0) { 12824 boolean printed = false; 12825 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12826 final int NP = pmap.size(); 12827 for (int ip=0; ip<NP; ip++) { 12828 String pname = pmap.keyAt(ip); 12829 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12830 final int N = uids.size(); 12831 for (int i=0; i<N; i++) { 12832 int puid = uids.keyAt(i); 12833 ProcessRecord r = mProcessNames.get(pname, puid); 12834 if (dumpPackage != null && (r == null 12835 || !r.pkgList.containsKey(dumpPackage))) { 12836 continue; 12837 } 12838 if (!printed) { 12839 if (needSep) pw.println(); 12840 needSep = true; 12841 pw.println(" Bad processes:"); 12842 printedAnything = true; 12843 } 12844 BadProcessInfo info = uids.valueAt(i); 12845 pw.print(" Bad process "); pw.print(pname); 12846 pw.print(" uid "); pw.print(puid); 12847 pw.print(": crashed at time "); pw.println(info.time); 12848 if (info.shortMsg != null) { 12849 pw.print(" Short msg: "); pw.println(info.shortMsg); 12850 } 12851 if (info.longMsg != null) { 12852 pw.print(" Long msg: "); pw.println(info.longMsg); 12853 } 12854 if (info.stack != null) { 12855 pw.println(" Stack:"); 12856 int lastPos = 0; 12857 for (int pos=0; pos<info.stack.length(); pos++) { 12858 if (info.stack.charAt(pos) == '\n') { 12859 pw.print(" "); 12860 pw.write(info.stack, lastPos, pos-lastPos); 12861 pw.println(); 12862 lastPos = pos+1; 12863 } 12864 } 12865 if (lastPos < info.stack.length()) { 12866 pw.print(" "); 12867 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12868 pw.println(); 12869 } 12870 } 12871 } 12872 } 12873 } 12874 12875 if (dumpPackage == null) { 12876 pw.println(); 12877 needSep = false; 12878 pw.println(" mStartedUsers:"); 12879 for (int i=0; i<mStartedUsers.size(); i++) { 12880 UserStartedState uss = mStartedUsers.valueAt(i); 12881 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12882 pw.print(": "); uss.dump("", pw); 12883 } 12884 pw.print(" mStartedUserArray: ["); 12885 for (int i=0; i<mStartedUserArray.length; i++) { 12886 if (i > 0) pw.print(", "); 12887 pw.print(mStartedUserArray[i]); 12888 } 12889 pw.println("]"); 12890 pw.print(" mUserLru: ["); 12891 for (int i=0; i<mUserLru.size(); i++) { 12892 if (i > 0) pw.print(", "); 12893 pw.print(mUserLru.get(i)); 12894 } 12895 pw.println("]"); 12896 if (dumpAll) { 12897 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12898 } 12899 synchronized (mUserProfileGroupIdsSelfLocked) { 12900 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12901 pw.println(" mUserProfileGroupIds:"); 12902 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12903 pw.print(" User #"); 12904 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12905 pw.print(" -> profile #"); 12906 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12907 } 12908 } 12909 } 12910 } 12911 if (mHomeProcess != null && (dumpPackage == null 12912 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12913 if (needSep) { 12914 pw.println(); 12915 needSep = false; 12916 } 12917 pw.println(" mHomeProcess: " + mHomeProcess); 12918 } 12919 if (mPreviousProcess != null && (dumpPackage == null 12920 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12921 if (needSep) { 12922 pw.println(); 12923 needSep = false; 12924 } 12925 pw.println(" mPreviousProcess: " + mPreviousProcess); 12926 } 12927 if (dumpAll) { 12928 StringBuilder sb = new StringBuilder(128); 12929 sb.append(" mPreviousProcessVisibleTime: "); 12930 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12931 pw.println(sb); 12932 } 12933 if (mHeavyWeightProcess != null && (dumpPackage == null 12934 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12935 if (needSep) { 12936 pw.println(); 12937 needSep = false; 12938 } 12939 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12940 } 12941 if (dumpPackage == null) { 12942 pw.println(" mConfiguration: " + mConfiguration); 12943 } 12944 if (dumpAll) { 12945 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12946 if (mCompatModePackages.getPackages().size() > 0) { 12947 boolean printed = false; 12948 for (Map.Entry<String, Integer> entry 12949 : mCompatModePackages.getPackages().entrySet()) { 12950 String pkg = entry.getKey(); 12951 int mode = entry.getValue(); 12952 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12953 continue; 12954 } 12955 if (!printed) { 12956 pw.println(" mScreenCompatPackages:"); 12957 printed = true; 12958 } 12959 pw.print(" "); pw.print(pkg); pw.print(": "); 12960 pw.print(mode); pw.println(); 12961 } 12962 } 12963 } 12964 if (dumpPackage == null) { 12965 if (mSleeping || mWentToSleep || mLockScreenShown) { 12966 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12967 + " mLockScreenShown " + mLockScreenShown); 12968 } 12969 if (mShuttingDown || mRunningVoice) { 12970 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12971 } 12972 } 12973 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12974 || mOrigWaitForDebugger) { 12975 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12976 || dumpPackage.equals(mOrigDebugApp)) { 12977 if (needSep) { 12978 pw.println(); 12979 needSep = false; 12980 } 12981 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12982 + " mDebugTransient=" + mDebugTransient 12983 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12984 } 12985 } 12986 if (mOpenGlTraceApp != null) { 12987 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12988 if (needSep) { 12989 pw.println(); 12990 needSep = false; 12991 } 12992 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12993 } 12994 } 12995 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12996 || mProfileFd != null) { 12997 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12998 if (needSep) { 12999 pw.println(); 13000 needSep = false; 13001 } 13002 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13003 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13004 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13005 + mAutoStopProfiler); 13006 pw.println(" mProfileType=" + mProfileType); 13007 } 13008 } 13009 if (dumpPackage == null) { 13010 if (mAlwaysFinishActivities || mController != null) { 13011 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13012 + " mController=" + mController); 13013 } 13014 if (dumpAll) { 13015 pw.println(" Total persistent processes: " + numPers); 13016 pw.println(" mProcessesReady=" + mProcessesReady 13017 + " mSystemReady=" + mSystemReady 13018 + " mBooted=" + mBooted 13019 + " mFactoryTest=" + mFactoryTest); 13020 pw.println(" mBooting=" + mBooting 13021 + " mCallFinishBooting=" + mCallFinishBooting 13022 + " mBootAnimationComplete=" + mBootAnimationComplete); 13023 pw.print(" mLastPowerCheckRealtime="); 13024 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13025 pw.println(""); 13026 pw.print(" mLastPowerCheckUptime="); 13027 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13028 pw.println(""); 13029 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13030 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13031 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13032 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13033 + " (" + mLruProcesses.size() + " total)" 13034 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13035 + " mNumServiceProcs=" + mNumServiceProcs 13036 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13037 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13038 + " mLastMemoryLevel" + mLastMemoryLevel 13039 + " mLastNumProcesses" + mLastNumProcesses); 13040 long now = SystemClock.uptimeMillis(); 13041 pw.print(" mLastIdleTime="); 13042 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13043 pw.print(" mLowRamSinceLastIdle="); 13044 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13045 pw.println(); 13046 } 13047 } 13048 13049 if (!printedAnything) { 13050 pw.println(" (nothing)"); 13051 } 13052 } 13053 13054 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13055 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13056 if (mProcessesToGc.size() > 0) { 13057 boolean printed = false; 13058 long now = SystemClock.uptimeMillis(); 13059 for (int i=0; i<mProcessesToGc.size(); i++) { 13060 ProcessRecord proc = mProcessesToGc.get(i); 13061 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13062 continue; 13063 } 13064 if (!printed) { 13065 if (needSep) pw.println(); 13066 needSep = true; 13067 pw.println(" Processes that are waiting to GC:"); 13068 printed = true; 13069 } 13070 pw.print(" Process "); pw.println(proc); 13071 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13072 pw.print(", last gced="); 13073 pw.print(now-proc.lastRequestedGc); 13074 pw.print(" ms ago, last lowMem="); 13075 pw.print(now-proc.lastLowMemory); 13076 pw.println(" ms ago"); 13077 13078 } 13079 } 13080 return needSep; 13081 } 13082 13083 void printOomLevel(PrintWriter pw, String name, int adj) { 13084 pw.print(" "); 13085 if (adj >= 0) { 13086 pw.print(' '); 13087 if (adj < 10) pw.print(' '); 13088 } else { 13089 if (adj > -10) pw.print(' '); 13090 } 13091 pw.print(adj); 13092 pw.print(": "); 13093 pw.print(name); 13094 pw.print(" ("); 13095 pw.print(mProcessList.getMemLevel(adj)/1024); 13096 pw.println(" kB)"); 13097 } 13098 13099 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13100 int opti, boolean dumpAll) { 13101 boolean needSep = false; 13102 13103 if (mLruProcesses.size() > 0) { 13104 if (needSep) pw.println(); 13105 needSep = true; 13106 pw.println(" OOM levels:"); 13107 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13108 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13109 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13110 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13111 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13112 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13113 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13114 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13115 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13116 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13117 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13118 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13119 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13120 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13121 13122 if (needSep) pw.println(); 13123 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13124 pw.print(" total, non-act at "); 13125 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13126 pw.print(", non-svc at "); 13127 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13128 pw.println("):"); 13129 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13130 needSep = true; 13131 } 13132 13133 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13134 13135 pw.println(); 13136 pw.println(" mHomeProcess: " + mHomeProcess); 13137 pw.println(" mPreviousProcess: " + mPreviousProcess); 13138 if (mHeavyWeightProcess != null) { 13139 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13140 } 13141 13142 return true; 13143 } 13144 13145 /** 13146 * There are three ways to call this: 13147 * - no provider specified: dump all the providers 13148 * - a flattened component name that matched an existing provider was specified as the 13149 * first arg: dump that one provider 13150 * - the first arg isn't the flattened component name of an existing provider: 13151 * dump all providers whose component contains the first arg as a substring 13152 */ 13153 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13154 int opti, boolean dumpAll) { 13155 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13156 } 13157 13158 static class ItemMatcher { 13159 ArrayList<ComponentName> components; 13160 ArrayList<String> strings; 13161 ArrayList<Integer> objects; 13162 boolean all; 13163 13164 ItemMatcher() { 13165 all = true; 13166 } 13167 13168 void build(String name) { 13169 ComponentName componentName = ComponentName.unflattenFromString(name); 13170 if (componentName != null) { 13171 if (components == null) { 13172 components = new ArrayList<ComponentName>(); 13173 } 13174 components.add(componentName); 13175 all = false; 13176 } else { 13177 int objectId = 0; 13178 // Not a '/' separated full component name; maybe an object ID? 13179 try { 13180 objectId = Integer.parseInt(name, 16); 13181 if (objects == null) { 13182 objects = new ArrayList<Integer>(); 13183 } 13184 objects.add(objectId); 13185 all = false; 13186 } catch (RuntimeException e) { 13187 // Not an integer; just do string match. 13188 if (strings == null) { 13189 strings = new ArrayList<String>(); 13190 } 13191 strings.add(name); 13192 all = false; 13193 } 13194 } 13195 } 13196 13197 int build(String[] args, int opti) { 13198 for (; opti<args.length; opti++) { 13199 String name = args[opti]; 13200 if ("--".equals(name)) { 13201 return opti+1; 13202 } 13203 build(name); 13204 } 13205 return opti; 13206 } 13207 13208 boolean match(Object object, ComponentName comp) { 13209 if (all) { 13210 return true; 13211 } 13212 if (components != null) { 13213 for (int i=0; i<components.size(); i++) { 13214 if (components.get(i).equals(comp)) { 13215 return true; 13216 } 13217 } 13218 } 13219 if (objects != null) { 13220 for (int i=0; i<objects.size(); i++) { 13221 if (System.identityHashCode(object) == objects.get(i)) { 13222 return true; 13223 } 13224 } 13225 } 13226 if (strings != null) { 13227 String flat = comp.flattenToString(); 13228 for (int i=0; i<strings.size(); i++) { 13229 if (flat.contains(strings.get(i))) { 13230 return true; 13231 } 13232 } 13233 } 13234 return false; 13235 } 13236 } 13237 13238 /** 13239 * There are three things that cmd can be: 13240 * - a flattened component name that matches an existing activity 13241 * - the cmd arg isn't the flattened component name of an existing activity: 13242 * dump all activity whose component contains the cmd as a substring 13243 * - A hex number of the ActivityRecord object instance. 13244 */ 13245 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13246 int opti, boolean dumpAll) { 13247 ArrayList<ActivityRecord> activities; 13248 13249 synchronized (this) { 13250 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13251 } 13252 13253 if (activities.size() <= 0) { 13254 return false; 13255 } 13256 13257 String[] newArgs = new String[args.length - opti]; 13258 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13259 13260 TaskRecord lastTask = null; 13261 boolean needSep = false; 13262 for (int i=activities.size()-1; i>=0; i--) { 13263 ActivityRecord r = activities.get(i); 13264 if (needSep) { 13265 pw.println(); 13266 } 13267 needSep = true; 13268 synchronized (this) { 13269 if (lastTask != r.task) { 13270 lastTask = r.task; 13271 pw.print("TASK "); pw.print(lastTask.affinity); 13272 pw.print(" id="); pw.println(lastTask.taskId); 13273 if (dumpAll) { 13274 lastTask.dump(pw, " "); 13275 } 13276 } 13277 } 13278 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13279 } 13280 return true; 13281 } 13282 13283 /** 13284 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13285 * there is a thread associated with the activity. 13286 */ 13287 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13288 final ActivityRecord r, String[] args, boolean dumpAll) { 13289 String innerPrefix = prefix + " "; 13290 synchronized (this) { 13291 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13292 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13293 pw.print(" pid="); 13294 if (r.app != null) pw.println(r.app.pid); 13295 else pw.println("(not running)"); 13296 if (dumpAll) { 13297 r.dump(pw, innerPrefix); 13298 } 13299 } 13300 if (r.app != null && r.app.thread != null) { 13301 // flush anything that is already in the PrintWriter since the thread is going 13302 // to write to the file descriptor directly 13303 pw.flush(); 13304 try { 13305 TransferPipe tp = new TransferPipe(); 13306 try { 13307 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13308 r.appToken, innerPrefix, args); 13309 tp.go(fd); 13310 } finally { 13311 tp.kill(); 13312 } 13313 } catch (IOException e) { 13314 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13315 } catch (RemoteException e) { 13316 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13317 } 13318 } 13319 } 13320 13321 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13322 int opti, boolean dumpAll, String dumpPackage) { 13323 boolean needSep = false; 13324 boolean onlyHistory = false; 13325 boolean printedAnything = false; 13326 13327 if ("history".equals(dumpPackage)) { 13328 if (opti < args.length && "-s".equals(args[opti])) { 13329 dumpAll = false; 13330 } 13331 onlyHistory = true; 13332 dumpPackage = null; 13333 } 13334 13335 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13336 if (!onlyHistory && dumpAll) { 13337 if (mRegisteredReceivers.size() > 0) { 13338 boolean printed = false; 13339 Iterator it = mRegisteredReceivers.values().iterator(); 13340 while (it.hasNext()) { 13341 ReceiverList r = (ReceiverList)it.next(); 13342 if (dumpPackage != null && (r.app == null || 13343 !dumpPackage.equals(r.app.info.packageName))) { 13344 continue; 13345 } 13346 if (!printed) { 13347 pw.println(" Registered Receivers:"); 13348 needSep = true; 13349 printed = true; 13350 printedAnything = true; 13351 } 13352 pw.print(" * "); pw.println(r); 13353 r.dump(pw, " "); 13354 } 13355 } 13356 13357 if (mReceiverResolver.dump(pw, needSep ? 13358 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13359 " ", dumpPackage, false)) { 13360 needSep = true; 13361 printedAnything = true; 13362 } 13363 } 13364 13365 for (BroadcastQueue q : mBroadcastQueues) { 13366 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13367 printedAnything |= needSep; 13368 } 13369 13370 needSep = true; 13371 13372 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13373 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13374 if (needSep) { 13375 pw.println(); 13376 } 13377 needSep = true; 13378 printedAnything = true; 13379 pw.print(" Sticky broadcasts for user "); 13380 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13381 StringBuilder sb = new StringBuilder(128); 13382 for (Map.Entry<String, ArrayList<Intent>> ent 13383 : mStickyBroadcasts.valueAt(user).entrySet()) { 13384 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13385 if (dumpAll) { 13386 pw.println(":"); 13387 ArrayList<Intent> intents = ent.getValue(); 13388 final int N = intents.size(); 13389 for (int i=0; i<N; i++) { 13390 sb.setLength(0); 13391 sb.append(" Intent: "); 13392 intents.get(i).toShortString(sb, false, true, false, false); 13393 pw.println(sb.toString()); 13394 Bundle bundle = intents.get(i).getExtras(); 13395 if (bundle != null) { 13396 pw.print(" "); 13397 pw.println(bundle.toString()); 13398 } 13399 } 13400 } else { 13401 pw.println(""); 13402 } 13403 } 13404 } 13405 } 13406 13407 if (!onlyHistory && dumpAll) { 13408 pw.println(); 13409 for (BroadcastQueue queue : mBroadcastQueues) { 13410 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13411 + queue.mBroadcastsScheduled); 13412 } 13413 pw.println(" mHandler:"); 13414 mHandler.dump(new PrintWriterPrinter(pw), " "); 13415 needSep = true; 13416 printedAnything = true; 13417 } 13418 13419 if (!printedAnything) { 13420 pw.println(" (nothing)"); 13421 } 13422 } 13423 13424 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13425 int opti, boolean dumpAll, String dumpPackage) { 13426 boolean needSep; 13427 boolean printedAnything = false; 13428 13429 ItemMatcher matcher = new ItemMatcher(); 13430 matcher.build(args, opti); 13431 13432 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13433 13434 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13435 printedAnything |= needSep; 13436 13437 if (mLaunchingProviders.size() > 0) { 13438 boolean printed = false; 13439 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13440 ContentProviderRecord r = mLaunchingProviders.get(i); 13441 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13442 continue; 13443 } 13444 if (!printed) { 13445 if (needSep) pw.println(); 13446 needSep = true; 13447 pw.println(" Launching content providers:"); 13448 printed = true; 13449 printedAnything = true; 13450 } 13451 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13452 pw.println(r); 13453 } 13454 } 13455 13456 if (mGrantedUriPermissions.size() > 0) { 13457 boolean printed = false; 13458 int dumpUid = -2; 13459 if (dumpPackage != null) { 13460 try { 13461 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13462 } catch (NameNotFoundException e) { 13463 dumpUid = -1; 13464 } 13465 } 13466 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13467 int uid = mGrantedUriPermissions.keyAt(i); 13468 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13469 continue; 13470 } 13471 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13472 if (!printed) { 13473 if (needSep) pw.println(); 13474 needSep = true; 13475 pw.println(" Granted Uri Permissions:"); 13476 printed = true; 13477 printedAnything = true; 13478 } 13479 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13480 for (UriPermission perm : perms.values()) { 13481 pw.print(" "); pw.println(perm); 13482 if (dumpAll) { 13483 perm.dump(pw, " "); 13484 } 13485 } 13486 } 13487 } 13488 13489 if (!printedAnything) { 13490 pw.println(" (nothing)"); 13491 } 13492 } 13493 13494 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13495 int opti, boolean dumpAll, String dumpPackage) { 13496 boolean printed = false; 13497 13498 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13499 13500 if (mIntentSenderRecords.size() > 0) { 13501 Iterator<WeakReference<PendingIntentRecord>> it 13502 = mIntentSenderRecords.values().iterator(); 13503 while (it.hasNext()) { 13504 WeakReference<PendingIntentRecord> ref = it.next(); 13505 PendingIntentRecord rec = ref != null ? ref.get(): null; 13506 if (dumpPackage != null && (rec == null 13507 || !dumpPackage.equals(rec.key.packageName))) { 13508 continue; 13509 } 13510 printed = true; 13511 if (rec != null) { 13512 pw.print(" * "); pw.println(rec); 13513 if (dumpAll) { 13514 rec.dump(pw, " "); 13515 } 13516 } else { 13517 pw.print(" * "); pw.println(ref); 13518 } 13519 } 13520 } 13521 13522 if (!printed) { 13523 pw.println(" (nothing)"); 13524 } 13525 } 13526 13527 private static final int dumpProcessList(PrintWriter pw, 13528 ActivityManagerService service, List list, 13529 String prefix, String normalLabel, String persistentLabel, 13530 String dumpPackage) { 13531 int numPers = 0; 13532 final int N = list.size()-1; 13533 for (int i=N; i>=0; i--) { 13534 ProcessRecord r = (ProcessRecord)list.get(i); 13535 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13536 continue; 13537 } 13538 pw.println(String.format("%s%s #%2d: %s", 13539 prefix, (r.persistent ? persistentLabel : normalLabel), 13540 i, r.toString())); 13541 if (r.persistent) { 13542 numPers++; 13543 } 13544 } 13545 return numPers; 13546 } 13547 13548 private static final boolean dumpProcessOomList(PrintWriter pw, 13549 ActivityManagerService service, List<ProcessRecord> origList, 13550 String prefix, String normalLabel, String persistentLabel, 13551 boolean inclDetails, String dumpPackage) { 13552 13553 ArrayList<Pair<ProcessRecord, Integer>> list 13554 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13555 for (int i=0; i<origList.size(); i++) { 13556 ProcessRecord r = origList.get(i); 13557 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13558 continue; 13559 } 13560 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13561 } 13562 13563 if (list.size() <= 0) { 13564 return false; 13565 } 13566 13567 Comparator<Pair<ProcessRecord, Integer>> comparator 13568 = new Comparator<Pair<ProcessRecord, Integer>>() { 13569 @Override 13570 public int compare(Pair<ProcessRecord, Integer> object1, 13571 Pair<ProcessRecord, Integer> object2) { 13572 if (object1.first.setAdj != object2.first.setAdj) { 13573 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13574 } 13575 if (object1.second.intValue() != object2.second.intValue()) { 13576 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13577 } 13578 return 0; 13579 } 13580 }; 13581 13582 Collections.sort(list, comparator); 13583 13584 final long curRealtime = SystemClock.elapsedRealtime(); 13585 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13586 final long curUptime = SystemClock.uptimeMillis(); 13587 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13588 13589 for (int i=list.size()-1; i>=0; i--) { 13590 ProcessRecord r = list.get(i).first; 13591 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13592 char schedGroup; 13593 switch (r.setSchedGroup) { 13594 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13595 schedGroup = 'B'; 13596 break; 13597 case Process.THREAD_GROUP_DEFAULT: 13598 schedGroup = 'F'; 13599 break; 13600 default: 13601 schedGroup = '?'; 13602 break; 13603 } 13604 char foreground; 13605 if (r.foregroundActivities) { 13606 foreground = 'A'; 13607 } else if (r.foregroundServices) { 13608 foreground = 'S'; 13609 } else { 13610 foreground = ' '; 13611 } 13612 String procState = ProcessList.makeProcStateString(r.curProcState); 13613 pw.print(prefix); 13614 pw.print(r.persistent ? persistentLabel : normalLabel); 13615 pw.print(" #"); 13616 int num = (origList.size()-1)-list.get(i).second; 13617 if (num < 10) pw.print(' '); 13618 pw.print(num); 13619 pw.print(": "); 13620 pw.print(oomAdj); 13621 pw.print(' '); 13622 pw.print(schedGroup); 13623 pw.print('/'); 13624 pw.print(foreground); 13625 pw.print('/'); 13626 pw.print(procState); 13627 pw.print(" trm:"); 13628 if (r.trimMemoryLevel < 10) pw.print(' '); 13629 pw.print(r.trimMemoryLevel); 13630 pw.print(' '); 13631 pw.print(r.toShortString()); 13632 pw.print(" ("); 13633 pw.print(r.adjType); 13634 pw.println(')'); 13635 if (r.adjSource != null || r.adjTarget != null) { 13636 pw.print(prefix); 13637 pw.print(" "); 13638 if (r.adjTarget instanceof ComponentName) { 13639 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13640 } else if (r.adjTarget != null) { 13641 pw.print(r.adjTarget.toString()); 13642 } else { 13643 pw.print("{null}"); 13644 } 13645 pw.print("<="); 13646 if (r.adjSource instanceof ProcessRecord) { 13647 pw.print("Proc{"); 13648 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13649 pw.println("}"); 13650 } else if (r.adjSource != null) { 13651 pw.println(r.adjSource.toString()); 13652 } else { 13653 pw.println("{null}"); 13654 } 13655 } 13656 if (inclDetails) { 13657 pw.print(prefix); 13658 pw.print(" "); 13659 pw.print("oom: max="); pw.print(r.maxAdj); 13660 pw.print(" curRaw="); pw.print(r.curRawAdj); 13661 pw.print(" setRaw="); pw.print(r.setRawAdj); 13662 pw.print(" cur="); pw.print(r.curAdj); 13663 pw.print(" set="); pw.println(r.setAdj); 13664 pw.print(prefix); 13665 pw.print(" "); 13666 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13667 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13668 pw.print(" lastPss="); pw.print(r.lastPss); 13669 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13670 pw.print(prefix); 13671 pw.print(" "); 13672 pw.print("cached="); pw.print(r.cached); 13673 pw.print(" empty="); pw.print(r.empty); 13674 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13675 13676 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13677 if (r.lastWakeTime != 0) { 13678 long wtime; 13679 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13680 synchronized (stats) { 13681 wtime = stats.getProcessWakeTime(r.info.uid, 13682 r.pid, curRealtime); 13683 } 13684 long timeUsed = wtime - r.lastWakeTime; 13685 pw.print(prefix); 13686 pw.print(" "); 13687 pw.print("keep awake over "); 13688 TimeUtils.formatDuration(realtimeSince, pw); 13689 pw.print(" used "); 13690 TimeUtils.formatDuration(timeUsed, pw); 13691 pw.print(" ("); 13692 pw.print((timeUsed*100)/realtimeSince); 13693 pw.println("%)"); 13694 } 13695 if (r.lastCpuTime != 0) { 13696 long timeUsed = r.curCpuTime - r.lastCpuTime; 13697 pw.print(prefix); 13698 pw.print(" "); 13699 pw.print("run cpu over "); 13700 TimeUtils.formatDuration(uptimeSince, pw); 13701 pw.print(" used "); 13702 TimeUtils.formatDuration(timeUsed, pw); 13703 pw.print(" ("); 13704 pw.print((timeUsed*100)/uptimeSince); 13705 pw.println("%)"); 13706 } 13707 } 13708 } 13709 } 13710 return true; 13711 } 13712 13713 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13714 String[] args) { 13715 ArrayList<ProcessRecord> procs; 13716 synchronized (this) { 13717 if (args != null && args.length > start 13718 && args[start].charAt(0) != '-') { 13719 procs = new ArrayList<ProcessRecord>(); 13720 int pid = -1; 13721 try { 13722 pid = Integer.parseInt(args[start]); 13723 } catch (NumberFormatException e) { 13724 } 13725 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13726 ProcessRecord proc = mLruProcesses.get(i); 13727 if (proc.pid == pid) { 13728 procs.add(proc); 13729 } else if (allPkgs && proc.pkgList != null 13730 && proc.pkgList.containsKey(args[start])) { 13731 procs.add(proc); 13732 } else if (proc.processName.equals(args[start])) { 13733 procs.add(proc); 13734 } 13735 } 13736 if (procs.size() <= 0) { 13737 return null; 13738 } 13739 } else { 13740 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13741 } 13742 } 13743 return procs; 13744 } 13745 13746 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13747 PrintWriter pw, String[] args) { 13748 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13749 if (procs == null) { 13750 pw.println("No process found for: " + args[0]); 13751 return; 13752 } 13753 13754 long uptime = SystemClock.uptimeMillis(); 13755 long realtime = SystemClock.elapsedRealtime(); 13756 pw.println("Applications Graphics Acceleration Info:"); 13757 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13758 13759 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13760 ProcessRecord r = procs.get(i); 13761 if (r.thread != null) { 13762 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13763 pw.flush(); 13764 try { 13765 TransferPipe tp = new TransferPipe(); 13766 try { 13767 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13768 tp.go(fd); 13769 } finally { 13770 tp.kill(); 13771 } 13772 } catch (IOException e) { 13773 pw.println("Failure while dumping the app: " + r); 13774 pw.flush(); 13775 } catch (RemoteException e) { 13776 pw.println("Got a RemoteException while dumping the app " + r); 13777 pw.flush(); 13778 } 13779 } 13780 } 13781 } 13782 13783 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13784 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13785 if (procs == null) { 13786 pw.println("No process found for: " + args[0]); 13787 return; 13788 } 13789 13790 pw.println("Applications Database Info:"); 13791 13792 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13793 ProcessRecord r = procs.get(i); 13794 if (r.thread != null) { 13795 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13796 pw.flush(); 13797 try { 13798 TransferPipe tp = new TransferPipe(); 13799 try { 13800 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13801 tp.go(fd); 13802 } finally { 13803 tp.kill(); 13804 } 13805 } catch (IOException e) { 13806 pw.println("Failure while dumping the app: " + r); 13807 pw.flush(); 13808 } catch (RemoteException e) { 13809 pw.println("Got a RemoteException while dumping the app " + r); 13810 pw.flush(); 13811 } 13812 } 13813 } 13814 } 13815 13816 final static class MemItem { 13817 final boolean isProc; 13818 final String label; 13819 final String shortLabel; 13820 final long pss; 13821 final int id; 13822 final boolean hasActivities; 13823 ArrayList<MemItem> subitems; 13824 13825 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13826 boolean _hasActivities) { 13827 isProc = true; 13828 label = _label; 13829 shortLabel = _shortLabel; 13830 pss = _pss; 13831 id = _id; 13832 hasActivities = _hasActivities; 13833 } 13834 13835 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13836 isProc = false; 13837 label = _label; 13838 shortLabel = _shortLabel; 13839 pss = _pss; 13840 id = _id; 13841 hasActivities = false; 13842 } 13843 } 13844 13845 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13846 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13847 if (sort && !isCompact) { 13848 Collections.sort(items, new Comparator<MemItem>() { 13849 @Override 13850 public int compare(MemItem lhs, MemItem rhs) { 13851 if (lhs.pss < rhs.pss) { 13852 return 1; 13853 } else if (lhs.pss > rhs.pss) { 13854 return -1; 13855 } 13856 return 0; 13857 } 13858 }); 13859 } 13860 13861 for (int i=0; i<items.size(); i++) { 13862 MemItem mi = items.get(i); 13863 if (!isCompact) { 13864 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13865 } else if (mi.isProc) { 13866 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13867 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13868 pw.println(mi.hasActivities ? ",a" : ",e"); 13869 } else { 13870 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13871 pw.println(mi.pss); 13872 } 13873 if (mi.subitems != null) { 13874 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13875 true, isCompact); 13876 } 13877 } 13878 } 13879 13880 // These are in KB. 13881 static final long[] DUMP_MEM_BUCKETS = new long[] { 13882 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13883 120*1024, 160*1024, 200*1024, 13884 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13885 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13886 }; 13887 13888 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13889 boolean stackLike) { 13890 int start = label.lastIndexOf('.'); 13891 if (start >= 0) start++; 13892 else start = 0; 13893 int end = label.length(); 13894 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13895 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13896 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13897 out.append(bucket); 13898 out.append(stackLike ? "MB." : "MB "); 13899 out.append(label, start, end); 13900 return; 13901 } 13902 } 13903 out.append(memKB/1024); 13904 out.append(stackLike ? "MB." : "MB "); 13905 out.append(label, start, end); 13906 } 13907 13908 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13909 ProcessList.NATIVE_ADJ, 13910 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13911 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13912 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13913 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13914 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13915 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13916 }; 13917 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13918 "Native", 13919 "System", "Persistent", "Persistent Service", "Foreground", 13920 "Visible", "Perceptible", 13921 "Heavy Weight", "Backup", 13922 "A Services", "Home", 13923 "Previous", "B Services", "Cached" 13924 }; 13925 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13926 "native", 13927 "sys", "pers", "persvc", "fore", 13928 "vis", "percept", 13929 "heavy", "backup", 13930 "servicea", "home", 13931 "prev", "serviceb", "cached" 13932 }; 13933 13934 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13935 long realtime, boolean isCheckinRequest, boolean isCompact) { 13936 if (isCheckinRequest || isCompact) { 13937 // short checkin version 13938 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13939 } else { 13940 pw.println("Applications Memory Usage (kB):"); 13941 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13942 } 13943 } 13944 13945 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13946 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13947 boolean dumpDetails = false; 13948 boolean dumpFullDetails = false; 13949 boolean dumpDalvik = false; 13950 boolean oomOnly = false; 13951 boolean isCompact = false; 13952 boolean localOnly = false; 13953 boolean packages = false; 13954 13955 int opti = 0; 13956 while (opti < args.length) { 13957 String opt = args[opti]; 13958 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13959 break; 13960 } 13961 opti++; 13962 if ("-a".equals(opt)) { 13963 dumpDetails = true; 13964 dumpFullDetails = true; 13965 dumpDalvik = true; 13966 } else if ("-d".equals(opt)) { 13967 dumpDalvik = true; 13968 } else if ("-c".equals(opt)) { 13969 isCompact = true; 13970 } else if ("--oom".equals(opt)) { 13971 oomOnly = true; 13972 } else if ("--local".equals(opt)) { 13973 localOnly = true; 13974 } else if ("--package".equals(opt)) { 13975 packages = true; 13976 } else if ("-h".equals(opt)) { 13977 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13978 pw.println(" -a: include all available information for each process."); 13979 pw.println(" -d: include dalvik details when dumping process details."); 13980 pw.println(" -c: dump in a compact machine-parseable representation."); 13981 pw.println(" --oom: only show processes organized by oom adj."); 13982 pw.println(" --local: only collect details locally, don't call process."); 13983 pw.println(" --package: interpret process arg as package, dumping all"); 13984 pw.println(" processes that have loaded that package."); 13985 pw.println("If [process] is specified it can be the name or "); 13986 pw.println("pid of a specific process to dump."); 13987 return; 13988 } else { 13989 pw.println("Unknown argument: " + opt + "; use -h for help"); 13990 } 13991 } 13992 13993 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13994 long uptime = SystemClock.uptimeMillis(); 13995 long realtime = SystemClock.elapsedRealtime(); 13996 final long[] tmpLong = new long[1]; 13997 13998 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13999 if (procs == null) { 14000 // No Java processes. Maybe they want to print a native process. 14001 if (args != null && args.length > opti 14002 && args[opti].charAt(0) != '-') { 14003 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14004 = new ArrayList<ProcessCpuTracker.Stats>(); 14005 updateCpuStatsNow(); 14006 int findPid = -1; 14007 try { 14008 findPid = Integer.parseInt(args[opti]); 14009 } catch (NumberFormatException e) { 14010 } 14011 synchronized (mProcessCpuTracker) { 14012 final int N = mProcessCpuTracker.countStats(); 14013 for (int i=0; i<N; i++) { 14014 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14015 if (st.pid == findPid || (st.baseName != null 14016 && st.baseName.equals(args[opti]))) { 14017 nativeProcs.add(st); 14018 } 14019 } 14020 } 14021 if (nativeProcs.size() > 0) { 14022 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14023 isCompact); 14024 Debug.MemoryInfo mi = null; 14025 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14026 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14027 final int pid = r.pid; 14028 if (!isCheckinRequest && dumpDetails) { 14029 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14030 } 14031 if (mi == null) { 14032 mi = new Debug.MemoryInfo(); 14033 } 14034 if (dumpDetails || (!brief && !oomOnly)) { 14035 Debug.getMemoryInfo(pid, mi); 14036 } else { 14037 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14038 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14039 } 14040 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14041 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14042 if (isCheckinRequest) { 14043 pw.println(); 14044 } 14045 } 14046 return; 14047 } 14048 } 14049 pw.println("No process found for: " + args[opti]); 14050 return; 14051 } 14052 14053 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14054 dumpDetails = true; 14055 } 14056 14057 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14058 14059 String[] innerArgs = new String[args.length-opti]; 14060 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14061 14062 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14063 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14064 long nativePss=0, dalvikPss=0, otherPss=0; 14065 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14066 14067 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14068 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14069 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14070 14071 long totalPss = 0; 14072 long cachedPss = 0; 14073 14074 Debug.MemoryInfo mi = null; 14075 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14076 final ProcessRecord r = procs.get(i); 14077 final IApplicationThread thread; 14078 final int pid; 14079 final int oomAdj; 14080 final boolean hasActivities; 14081 synchronized (this) { 14082 thread = r.thread; 14083 pid = r.pid; 14084 oomAdj = r.getSetAdjWithServices(); 14085 hasActivities = r.activities.size() > 0; 14086 } 14087 if (thread != null) { 14088 if (!isCheckinRequest && dumpDetails) { 14089 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14090 } 14091 if (mi == null) { 14092 mi = new Debug.MemoryInfo(); 14093 } 14094 if (dumpDetails || (!brief && !oomOnly)) { 14095 Debug.getMemoryInfo(pid, mi); 14096 } else { 14097 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14098 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14099 } 14100 if (dumpDetails) { 14101 if (localOnly) { 14102 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14103 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14104 if (isCheckinRequest) { 14105 pw.println(); 14106 } 14107 } else { 14108 try { 14109 pw.flush(); 14110 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14111 dumpDalvik, innerArgs); 14112 } catch (RemoteException e) { 14113 if (!isCheckinRequest) { 14114 pw.println("Got RemoteException!"); 14115 pw.flush(); 14116 } 14117 } 14118 } 14119 } 14120 14121 final long myTotalPss = mi.getTotalPss(); 14122 final long myTotalUss = mi.getTotalUss(); 14123 14124 synchronized (this) { 14125 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14126 // Record this for posterity if the process has been stable. 14127 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14128 } 14129 } 14130 14131 if (!isCheckinRequest && mi != null) { 14132 totalPss += myTotalPss; 14133 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14134 (hasActivities ? " / activities)" : ")"), 14135 r.processName, myTotalPss, pid, hasActivities); 14136 procMems.add(pssItem); 14137 procMemsMap.put(pid, pssItem); 14138 14139 nativePss += mi.nativePss; 14140 dalvikPss += mi.dalvikPss; 14141 otherPss += mi.otherPss; 14142 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14143 long mem = mi.getOtherPss(j); 14144 miscPss[j] += mem; 14145 otherPss -= mem; 14146 } 14147 14148 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14149 cachedPss += myTotalPss; 14150 } 14151 14152 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14153 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14154 || oomIndex == (oomPss.length-1)) { 14155 oomPss[oomIndex] += myTotalPss; 14156 if (oomProcs[oomIndex] == null) { 14157 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14158 } 14159 oomProcs[oomIndex].add(pssItem); 14160 break; 14161 } 14162 } 14163 } 14164 } 14165 } 14166 14167 long nativeProcTotalPss = 0; 14168 14169 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14170 // If we are showing aggregations, also look for native processes to 14171 // include so that our aggregations are more accurate. 14172 updateCpuStatsNow(); 14173 synchronized (mProcessCpuTracker) { 14174 final int N = mProcessCpuTracker.countStats(); 14175 for (int i=0; i<N; i++) { 14176 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14177 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14178 if (mi == null) { 14179 mi = new Debug.MemoryInfo(); 14180 } 14181 if (!brief && !oomOnly) { 14182 Debug.getMemoryInfo(st.pid, mi); 14183 } else { 14184 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14185 mi.nativePrivateDirty = (int)tmpLong[0]; 14186 } 14187 14188 final long myTotalPss = mi.getTotalPss(); 14189 totalPss += myTotalPss; 14190 nativeProcTotalPss += myTotalPss; 14191 14192 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14193 st.name, myTotalPss, st.pid, false); 14194 procMems.add(pssItem); 14195 14196 nativePss += mi.nativePss; 14197 dalvikPss += mi.dalvikPss; 14198 otherPss += mi.otherPss; 14199 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14200 long mem = mi.getOtherPss(j); 14201 miscPss[j] += mem; 14202 otherPss -= mem; 14203 } 14204 oomPss[0] += myTotalPss; 14205 if (oomProcs[0] == null) { 14206 oomProcs[0] = new ArrayList<MemItem>(); 14207 } 14208 oomProcs[0].add(pssItem); 14209 } 14210 } 14211 } 14212 14213 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14214 14215 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14216 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14217 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14218 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14219 String label = Debug.MemoryInfo.getOtherLabel(j); 14220 catMems.add(new MemItem(label, label, miscPss[j], j)); 14221 } 14222 14223 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14224 for (int j=0; j<oomPss.length; j++) { 14225 if (oomPss[j] != 0) { 14226 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14227 : DUMP_MEM_OOM_LABEL[j]; 14228 MemItem item = new MemItem(label, label, oomPss[j], 14229 DUMP_MEM_OOM_ADJ[j]); 14230 item.subitems = oomProcs[j]; 14231 oomMems.add(item); 14232 } 14233 } 14234 14235 if (!brief && !oomOnly && !isCompact) { 14236 pw.println(); 14237 pw.println("Total PSS by process:"); 14238 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14239 pw.println(); 14240 } 14241 if (!isCompact) { 14242 pw.println("Total PSS by OOM adjustment:"); 14243 } 14244 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14245 if (!brief && !oomOnly) { 14246 PrintWriter out = categoryPw != null ? categoryPw : pw; 14247 if (!isCompact) { 14248 out.println(); 14249 out.println("Total PSS by category:"); 14250 } 14251 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14252 } 14253 if (!isCompact) { 14254 pw.println(); 14255 } 14256 MemInfoReader memInfo = new MemInfoReader(); 14257 memInfo.readMemInfo(); 14258 if (nativeProcTotalPss > 0) { 14259 synchronized (this) { 14260 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14261 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14262 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14263 nativeProcTotalPss); 14264 } 14265 } 14266 if (!brief) { 14267 if (!isCompact) { 14268 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14269 pw.print(" kB (status "); 14270 switch (mLastMemoryLevel) { 14271 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14272 pw.println("normal)"); 14273 break; 14274 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14275 pw.println("moderate)"); 14276 break; 14277 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14278 pw.println("low)"); 14279 break; 14280 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14281 pw.println("critical)"); 14282 break; 14283 default: 14284 pw.print(mLastMemoryLevel); 14285 pw.println(")"); 14286 break; 14287 } 14288 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14289 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14290 pw.print(cachedPss); pw.print(" cached pss + "); 14291 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14292 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14293 } else { 14294 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14295 pw.print(cachedPss + memInfo.getCachedSizeKb() 14296 + memInfo.getFreeSizeKb()); pw.print(","); 14297 pw.println(totalPss - cachedPss); 14298 } 14299 } 14300 if (!isCompact) { 14301 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14302 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14303 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14304 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14305 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14306 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14307 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14308 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14309 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14310 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14311 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14312 } 14313 if (!brief) { 14314 if (memInfo.getZramTotalSizeKb() != 0) { 14315 if (!isCompact) { 14316 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14317 pw.print(" kB physical used for "); 14318 pw.print(memInfo.getSwapTotalSizeKb() 14319 - memInfo.getSwapFreeSizeKb()); 14320 pw.print(" kB in swap ("); 14321 pw.print(memInfo.getSwapTotalSizeKb()); 14322 pw.println(" kB total swap)"); 14323 } else { 14324 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14325 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14326 pw.println(memInfo.getSwapFreeSizeKb()); 14327 } 14328 } 14329 final int[] SINGLE_LONG_FORMAT = new int[] { 14330 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14331 }; 14332 long[] longOut = new long[1]; 14333 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14334 SINGLE_LONG_FORMAT, null, longOut, null); 14335 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14336 longOut[0] = 0; 14337 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14338 SINGLE_LONG_FORMAT, null, longOut, null); 14339 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14340 longOut[0] = 0; 14341 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14342 SINGLE_LONG_FORMAT, null, longOut, null); 14343 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14344 longOut[0] = 0; 14345 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14346 SINGLE_LONG_FORMAT, null, longOut, null); 14347 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14348 if (!isCompact) { 14349 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14350 pw.print(" KSM: "); pw.print(sharing); 14351 pw.print(" kB saved from shared "); 14352 pw.print(shared); pw.println(" kB"); 14353 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14354 pw.print(voltile); pw.println(" kB volatile"); 14355 } 14356 pw.print(" Tuning: "); 14357 pw.print(ActivityManager.staticGetMemoryClass()); 14358 pw.print(" (large "); 14359 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14360 pw.print("), oom "); 14361 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14362 pw.print(" kB"); 14363 pw.print(", restore limit "); 14364 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14365 pw.print(" kB"); 14366 if (ActivityManager.isLowRamDeviceStatic()) { 14367 pw.print(" (low-ram)"); 14368 } 14369 if (ActivityManager.isHighEndGfx()) { 14370 pw.print(" (high-end-gfx)"); 14371 } 14372 pw.println(); 14373 } else { 14374 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14375 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14376 pw.println(voltile); 14377 pw.print("tuning,"); 14378 pw.print(ActivityManager.staticGetMemoryClass()); 14379 pw.print(','); 14380 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14381 pw.print(','); 14382 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14383 if (ActivityManager.isLowRamDeviceStatic()) { 14384 pw.print(",low-ram"); 14385 } 14386 if (ActivityManager.isHighEndGfx()) { 14387 pw.print(",high-end-gfx"); 14388 } 14389 pw.println(); 14390 } 14391 } 14392 } 14393 } 14394 14395 /** 14396 * Searches array of arguments for the specified string 14397 * @param args array of argument strings 14398 * @param value value to search for 14399 * @return true if the value is contained in the array 14400 */ 14401 private static boolean scanArgs(String[] args, String value) { 14402 if (args != null) { 14403 for (String arg : args) { 14404 if (value.equals(arg)) { 14405 return true; 14406 } 14407 } 14408 } 14409 return false; 14410 } 14411 14412 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14413 ContentProviderRecord cpr, boolean always) { 14414 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14415 14416 if (!inLaunching || always) { 14417 synchronized (cpr) { 14418 cpr.launchingApp = null; 14419 cpr.notifyAll(); 14420 } 14421 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14422 String names[] = cpr.info.authority.split(";"); 14423 for (int j = 0; j < names.length; j++) { 14424 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14425 } 14426 } 14427 14428 for (int i=0; i<cpr.connections.size(); i++) { 14429 ContentProviderConnection conn = cpr.connections.get(i); 14430 if (conn.waiting) { 14431 // If this connection is waiting for the provider, then we don't 14432 // need to mess with its process unless we are always removing 14433 // or for some reason the provider is not currently launching. 14434 if (inLaunching && !always) { 14435 continue; 14436 } 14437 } 14438 ProcessRecord capp = conn.client; 14439 conn.dead = true; 14440 if (conn.stableCount > 0) { 14441 if (!capp.persistent && capp.thread != null 14442 && capp.pid != 0 14443 && capp.pid != MY_PID) { 14444 capp.kill("depends on provider " 14445 + cpr.name.flattenToShortString() 14446 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14447 } 14448 } else if (capp.thread != null && conn.provider.provider != null) { 14449 try { 14450 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14451 } catch (RemoteException e) { 14452 } 14453 // In the protocol here, we don't expect the client to correctly 14454 // clean up this connection, we'll just remove it. 14455 cpr.connections.remove(i); 14456 conn.client.conProviders.remove(conn); 14457 } 14458 } 14459 14460 if (inLaunching && always) { 14461 mLaunchingProviders.remove(cpr); 14462 } 14463 return inLaunching; 14464 } 14465 14466 /** 14467 * Main code for cleaning up a process when it has gone away. This is 14468 * called both as a result of the process dying, or directly when stopping 14469 * a process when running in single process mode. 14470 * 14471 * @return Returns true if the given process has been restarted, so the 14472 * app that was passed in must remain on the process lists. 14473 */ 14474 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14475 boolean restarting, boolean allowRestart, int index) { 14476 if (index >= 0) { 14477 removeLruProcessLocked(app); 14478 ProcessList.remove(app.pid); 14479 } 14480 14481 mProcessesToGc.remove(app); 14482 mPendingPssProcesses.remove(app); 14483 14484 // Dismiss any open dialogs. 14485 if (app.crashDialog != null && !app.forceCrashReport) { 14486 app.crashDialog.dismiss(); 14487 app.crashDialog = null; 14488 } 14489 if (app.anrDialog != null) { 14490 app.anrDialog.dismiss(); 14491 app.anrDialog = null; 14492 } 14493 if (app.waitDialog != null) { 14494 app.waitDialog.dismiss(); 14495 app.waitDialog = null; 14496 } 14497 14498 app.crashing = false; 14499 app.notResponding = false; 14500 14501 app.resetPackageList(mProcessStats); 14502 app.unlinkDeathRecipient(); 14503 app.makeInactive(mProcessStats); 14504 app.waitingToKill = null; 14505 app.forcingToForeground = null; 14506 updateProcessForegroundLocked(app, false, false); 14507 app.foregroundActivities = false; 14508 app.hasShownUi = false; 14509 app.treatLikeActivity = false; 14510 app.hasAboveClient = false; 14511 app.hasClientActivities = false; 14512 14513 mServices.killServicesLocked(app, allowRestart); 14514 14515 boolean restart = false; 14516 14517 // Remove published content providers. 14518 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14519 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14520 final boolean always = app.bad || !allowRestart; 14521 if (removeDyingProviderLocked(app, cpr, always) || always) { 14522 // We left the provider in the launching list, need to 14523 // restart it. 14524 restart = true; 14525 } 14526 14527 cpr.provider = null; 14528 cpr.proc = null; 14529 } 14530 app.pubProviders.clear(); 14531 14532 // Take care of any launching providers waiting for this process. 14533 if (checkAppInLaunchingProvidersLocked(app, false)) { 14534 restart = true; 14535 } 14536 14537 // Unregister from connected content providers. 14538 if (!app.conProviders.isEmpty()) { 14539 for (int i=0; i<app.conProviders.size(); i++) { 14540 ContentProviderConnection conn = app.conProviders.get(i); 14541 conn.provider.connections.remove(conn); 14542 } 14543 app.conProviders.clear(); 14544 } 14545 14546 // At this point there may be remaining entries in mLaunchingProviders 14547 // where we were the only one waiting, so they are no longer of use. 14548 // Look for these and clean up if found. 14549 // XXX Commented out for now. Trying to figure out a way to reproduce 14550 // the actual situation to identify what is actually going on. 14551 if (false) { 14552 for (int i=0; i<mLaunchingProviders.size(); i++) { 14553 ContentProviderRecord cpr = (ContentProviderRecord) 14554 mLaunchingProviders.get(i); 14555 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14556 synchronized (cpr) { 14557 cpr.launchingApp = null; 14558 cpr.notifyAll(); 14559 } 14560 } 14561 } 14562 } 14563 14564 skipCurrentReceiverLocked(app); 14565 14566 // Unregister any receivers. 14567 for (int i=app.receivers.size()-1; i>=0; i--) { 14568 removeReceiverLocked(app.receivers.valueAt(i)); 14569 } 14570 app.receivers.clear(); 14571 14572 // If the app is undergoing backup, tell the backup manager about it 14573 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14574 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14575 + mBackupTarget.appInfo + " died during backup"); 14576 try { 14577 IBackupManager bm = IBackupManager.Stub.asInterface( 14578 ServiceManager.getService(Context.BACKUP_SERVICE)); 14579 bm.agentDisconnected(app.info.packageName); 14580 } catch (RemoteException e) { 14581 // can't happen; backup manager is local 14582 } 14583 } 14584 14585 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14586 ProcessChangeItem item = mPendingProcessChanges.get(i); 14587 if (item.pid == app.pid) { 14588 mPendingProcessChanges.remove(i); 14589 mAvailProcessChanges.add(item); 14590 } 14591 } 14592 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14593 14594 // If the caller is restarting this app, then leave it in its 14595 // current lists and let the caller take care of it. 14596 if (restarting) { 14597 return false; 14598 } 14599 14600 if (!app.persistent || app.isolated) { 14601 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14602 "Removing non-persistent process during cleanup: " + app); 14603 mProcessNames.remove(app.processName, app.uid); 14604 mIsolatedProcesses.remove(app.uid); 14605 if (mHeavyWeightProcess == app) { 14606 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14607 mHeavyWeightProcess.userId, 0)); 14608 mHeavyWeightProcess = null; 14609 } 14610 } else if (!app.removed) { 14611 // This app is persistent, so we need to keep its record around. 14612 // If it is not already on the pending app list, add it there 14613 // and start a new process for it. 14614 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14615 mPersistentStartingProcesses.add(app); 14616 restart = true; 14617 } 14618 } 14619 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14620 "Clean-up removing on hold: " + app); 14621 mProcessesOnHold.remove(app); 14622 14623 if (app == mHomeProcess) { 14624 mHomeProcess = null; 14625 } 14626 if (app == mPreviousProcess) { 14627 mPreviousProcess = null; 14628 } 14629 14630 if (restart && !app.isolated) { 14631 // We have components that still need to be running in the 14632 // process, so re-launch it. 14633 if (index < 0) { 14634 ProcessList.remove(app.pid); 14635 } 14636 mProcessNames.put(app.processName, app.uid, app); 14637 startProcessLocked(app, "restart", app.processName); 14638 return true; 14639 } else if (app.pid > 0 && app.pid != MY_PID) { 14640 // Goodbye! 14641 boolean removed; 14642 synchronized (mPidsSelfLocked) { 14643 mPidsSelfLocked.remove(app.pid); 14644 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14645 } 14646 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14647 if (app.isolated) { 14648 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14649 } 14650 app.setPid(0); 14651 } 14652 return false; 14653 } 14654 14655 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14656 // Look through the content providers we are waiting to have launched, 14657 // and if any run in this process then either schedule a restart of 14658 // the process or kill the client waiting for it if this process has 14659 // gone bad. 14660 int NL = mLaunchingProviders.size(); 14661 boolean restart = false; 14662 for (int i=0; i<NL; i++) { 14663 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14664 if (cpr.launchingApp == app) { 14665 if (!alwaysBad && !app.bad) { 14666 restart = true; 14667 } else { 14668 removeDyingProviderLocked(app, cpr, true); 14669 // cpr should have been removed from mLaunchingProviders 14670 NL = mLaunchingProviders.size(); 14671 i--; 14672 } 14673 } 14674 } 14675 return restart; 14676 } 14677 14678 // ========================================================= 14679 // SERVICES 14680 // ========================================================= 14681 14682 @Override 14683 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14684 int flags) { 14685 enforceNotIsolatedCaller("getServices"); 14686 synchronized (this) { 14687 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14688 } 14689 } 14690 14691 @Override 14692 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14693 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14694 synchronized (this) { 14695 return mServices.getRunningServiceControlPanelLocked(name); 14696 } 14697 } 14698 14699 @Override 14700 public ComponentName startService(IApplicationThread caller, Intent service, 14701 String resolvedType, int userId) { 14702 enforceNotIsolatedCaller("startService"); 14703 // Refuse possible leaked file descriptors 14704 if (service != null && service.hasFileDescriptors() == true) { 14705 throw new IllegalArgumentException("File descriptors passed in Intent"); 14706 } 14707 14708 if (DEBUG_SERVICE) 14709 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14710 synchronized(this) { 14711 final int callingPid = Binder.getCallingPid(); 14712 final int callingUid = Binder.getCallingUid(); 14713 final long origId = Binder.clearCallingIdentity(); 14714 ComponentName res = mServices.startServiceLocked(caller, service, 14715 resolvedType, callingPid, callingUid, userId); 14716 Binder.restoreCallingIdentity(origId); 14717 return res; 14718 } 14719 } 14720 14721 ComponentName startServiceInPackage(int uid, 14722 Intent service, String resolvedType, int userId) { 14723 synchronized(this) { 14724 if (DEBUG_SERVICE) 14725 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14726 final long origId = Binder.clearCallingIdentity(); 14727 ComponentName res = mServices.startServiceLocked(null, service, 14728 resolvedType, -1, uid, userId); 14729 Binder.restoreCallingIdentity(origId); 14730 return res; 14731 } 14732 } 14733 14734 @Override 14735 public int stopService(IApplicationThread caller, Intent service, 14736 String resolvedType, int userId) { 14737 enforceNotIsolatedCaller("stopService"); 14738 // Refuse possible leaked file descriptors 14739 if (service != null && service.hasFileDescriptors() == true) { 14740 throw new IllegalArgumentException("File descriptors passed in Intent"); 14741 } 14742 14743 synchronized(this) { 14744 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14745 } 14746 } 14747 14748 @Override 14749 public IBinder peekService(Intent service, String resolvedType) { 14750 enforceNotIsolatedCaller("peekService"); 14751 // Refuse possible leaked file descriptors 14752 if (service != null && service.hasFileDescriptors() == true) { 14753 throw new IllegalArgumentException("File descriptors passed in Intent"); 14754 } 14755 synchronized(this) { 14756 return mServices.peekServiceLocked(service, resolvedType); 14757 } 14758 } 14759 14760 @Override 14761 public boolean stopServiceToken(ComponentName className, IBinder token, 14762 int startId) { 14763 synchronized(this) { 14764 return mServices.stopServiceTokenLocked(className, token, startId); 14765 } 14766 } 14767 14768 @Override 14769 public void setServiceForeground(ComponentName className, IBinder token, 14770 int id, Notification notification, boolean removeNotification) { 14771 synchronized(this) { 14772 mServices.setServiceForegroundLocked(className, token, id, notification, 14773 removeNotification); 14774 } 14775 } 14776 14777 @Override 14778 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14779 boolean requireFull, String name, String callerPackage) { 14780 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14781 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14782 } 14783 14784 int unsafeConvertIncomingUser(int userId) { 14785 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14786 ? mCurrentUserId : userId; 14787 } 14788 14789 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14790 int allowMode, String name, String callerPackage) { 14791 final int callingUserId = UserHandle.getUserId(callingUid); 14792 if (callingUserId == userId) { 14793 return userId; 14794 } 14795 14796 // Note that we may be accessing mCurrentUserId outside of a lock... 14797 // shouldn't be a big deal, if this is being called outside 14798 // of a locked context there is intrinsically a race with 14799 // the value the caller will receive and someone else changing it. 14800 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14801 // we will switch to the calling user if access to the current user fails. 14802 int targetUserId = unsafeConvertIncomingUser(userId); 14803 14804 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14805 final boolean allow; 14806 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14807 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14808 // If the caller has this permission, they always pass go. And collect $200. 14809 allow = true; 14810 } else if (allowMode == ALLOW_FULL_ONLY) { 14811 // We require full access, sucks to be you. 14812 allow = false; 14813 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14814 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14815 // If the caller does not have either permission, they are always doomed. 14816 allow = false; 14817 } else if (allowMode == ALLOW_NON_FULL) { 14818 // We are blanket allowing non-full access, you lucky caller! 14819 allow = true; 14820 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14821 // We may or may not allow this depending on whether the two users are 14822 // in the same profile. 14823 synchronized (mUserProfileGroupIdsSelfLocked) { 14824 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14825 UserInfo.NO_PROFILE_GROUP_ID); 14826 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14827 UserInfo.NO_PROFILE_GROUP_ID); 14828 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14829 && callingProfile == targetProfile; 14830 } 14831 } else { 14832 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14833 } 14834 if (!allow) { 14835 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14836 // In this case, they would like to just execute as their 14837 // owner user instead of failing. 14838 targetUserId = callingUserId; 14839 } else { 14840 StringBuilder builder = new StringBuilder(128); 14841 builder.append("Permission Denial: "); 14842 builder.append(name); 14843 if (callerPackage != null) { 14844 builder.append(" from "); 14845 builder.append(callerPackage); 14846 } 14847 builder.append(" asks to run as user "); 14848 builder.append(userId); 14849 builder.append(" but is calling from user "); 14850 builder.append(UserHandle.getUserId(callingUid)); 14851 builder.append("; this requires "); 14852 builder.append(INTERACT_ACROSS_USERS_FULL); 14853 if (allowMode != ALLOW_FULL_ONLY) { 14854 builder.append(" or "); 14855 builder.append(INTERACT_ACROSS_USERS); 14856 } 14857 String msg = builder.toString(); 14858 Slog.w(TAG, msg); 14859 throw new SecurityException(msg); 14860 } 14861 } 14862 } 14863 if (!allowAll && targetUserId < 0) { 14864 throw new IllegalArgumentException( 14865 "Call does not support special user #" + targetUserId); 14866 } 14867 // Check shell permission 14868 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14869 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14870 targetUserId)) { 14871 throw new SecurityException("Shell does not have permission to access user " 14872 + targetUserId + "\n " + Debug.getCallers(3)); 14873 } 14874 } 14875 return targetUserId; 14876 } 14877 14878 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14879 String className, int flags) { 14880 boolean result = false; 14881 // For apps that don't have pre-defined UIDs, check for permission 14882 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14883 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14884 if (ActivityManager.checkUidPermission( 14885 INTERACT_ACROSS_USERS, 14886 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14887 ComponentName comp = new ComponentName(aInfo.packageName, className); 14888 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14889 + " requests FLAG_SINGLE_USER, but app does not hold " 14890 + INTERACT_ACROSS_USERS; 14891 Slog.w(TAG, msg); 14892 throw new SecurityException(msg); 14893 } 14894 // Permission passed 14895 result = true; 14896 } 14897 } else if ("system".equals(componentProcessName)) { 14898 result = true; 14899 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14900 // Phone app and persistent apps are allowed to export singleuser providers. 14901 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14902 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14903 } 14904 if (DEBUG_MU) { 14905 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14906 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14907 } 14908 return result; 14909 } 14910 14911 /** 14912 * Checks to see if the caller is in the same app as the singleton 14913 * component, or the component is in a special app. It allows special apps 14914 * to export singleton components but prevents exporting singleton 14915 * components for regular apps. 14916 */ 14917 boolean isValidSingletonCall(int callingUid, int componentUid) { 14918 int componentAppId = UserHandle.getAppId(componentUid); 14919 return UserHandle.isSameApp(callingUid, componentUid) 14920 || componentAppId == Process.SYSTEM_UID 14921 || componentAppId == Process.PHONE_UID 14922 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14923 == PackageManager.PERMISSION_GRANTED; 14924 } 14925 14926 public int bindService(IApplicationThread caller, IBinder token, 14927 Intent service, String resolvedType, 14928 IServiceConnection connection, int flags, int userId) { 14929 enforceNotIsolatedCaller("bindService"); 14930 14931 // Refuse possible leaked file descriptors 14932 if (service != null && service.hasFileDescriptors() == true) { 14933 throw new IllegalArgumentException("File descriptors passed in Intent"); 14934 } 14935 14936 synchronized(this) { 14937 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14938 connection, flags, userId); 14939 } 14940 } 14941 14942 public boolean unbindService(IServiceConnection connection) { 14943 synchronized (this) { 14944 return mServices.unbindServiceLocked(connection); 14945 } 14946 } 14947 14948 public void publishService(IBinder token, Intent intent, IBinder service) { 14949 // Refuse possible leaked file descriptors 14950 if (intent != null && intent.hasFileDescriptors() == true) { 14951 throw new IllegalArgumentException("File descriptors passed in Intent"); 14952 } 14953 14954 synchronized(this) { 14955 if (!(token instanceof ServiceRecord)) { 14956 throw new IllegalArgumentException("Invalid service token"); 14957 } 14958 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14959 } 14960 } 14961 14962 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14963 // Refuse possible leaked file descriptors 14964 if (intent != null && intent.hasFileDescriptors() == true) { 14965 throw new IllegalArgumentException("File descriptors passed in Intent"); 14966 } 14967 14968 synchronized(this) { 14969 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14970 } 14971 } 14972 14973 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14974 synchronized(this) { 14975 if (!(token instanceof ServiceRecord)) { 14976 throw new IllegalArgumentException("Invalid service token"); 14977 } 14978 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14979 } 14980 } 14981 14982 // ========================================================= 14983 // BACKUP AND RESTORE 14984 // ========================================================= 14985 14986 // Cause the target app to be launched if necessary and its backup agent 14987 // instantiated. The backup agent will invoke backupAgentCreated() on the 14988 // activity manager to announce its creation. 14989 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14990 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14991 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14992 14993 synchronized(this) { 14994 // !!! TODO: currently no check here that we're already bound 14995 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14996 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14997 synchronized (stats) { 14998 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14999 } 15000 15001 // Backup agent is now in use, its package can't be stopped. 15002 try { 15003 AppGlobals.getPackageManager().setPackageStoppedState( 15004 app.packageName, false, UserHandle.getUserId(app.uid)); 15005 } catch (RemoteException e) { 15006 } catch (IllegalArgumentException e) { 15007 Slog.w(TAG, "Failed trying to unstop package " 15008 + app.packageName + ": " + e); 15009 } 15010 15011 BackupRecord r = new BackupRecord(ss, app, backupMode); 15012 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15013 ? new ComponentName(app.packageName, app.backupAgentName) 15014 : new ComponentName("android", "FullBackupAgent"); 15015 // startProcessLocked() returns existing proc's record if it's already running 15016 ProcessRecord proc = startProcessLocked(app.processName, app, 15017 false, 0, "backup", hostingName, false, false, false); 15018 if (proc == null) { 15019 Slog.e(TAG, "Unable to start backup agent process " + r); 15020 return false; 15021 } 15022 15023 r.app = proc; 15024 mBackupTarget = r; 15025 mBackupAppName = app.packageName; 15026 15027 // Try not to kill the process during backup 15028 updateOomAdjLocked(proc); 15029 15030 // If the process is already attached, schedule the creation of the backup agent now. 15031 // If it is not yet live, this will be done when it attaches to the framework. 15032 if (proc.thread != null) { 15033 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15034 try { 15035 proc.thread.scheduleCreateBackupAgent(app, 15036 compatibilityInfoForPackageLocked(app), backupMode); 15037 } catch (RemoteException e) { 15038 // Will time out on the backup manager side 15039 } 15040 } else { 15041 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15042 } 15043 // Invariants: at this point, the target app process exists and the application 15044 // is either already running or in the process of coming up. mBackupTarget and 15045 // mBackupAppName describe the app, so that when it binds back to the AM we 15046 // know that it's scheduled for a backup-agent operation. 15047 } 15048 15049 return true; 15050 } 15051 15052 @Override 15053 public void clearPendingBackup() { 15054 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15055 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15056 15057 synchronized (this) { 15058 mBackupTarget = null; 15059 mBackupAppName = null; 15060 } 15061 } 15062 15063 // A backup agent has just come up 15064 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15065 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15066 + " = " + agent); 15067 15068 synchronized(this) { 15069 if (!agentPackageName.equals(mBackupAppName)) { 15070 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15071 return; 15072 } 15073 } 15074 15075 long oldIdent = Binder.clearCallingIdentity(); 15076 try { 15077 IBackupManager bm = IBackupManager.Stub.asInterface( 15078 ServiceManager.getService(Context.BACKUP_SERVICE)); 15079 bm.agentConnected(agentPackageName, agent); 15080 } catch (RemoteException e) { 15081 // can't happen; the backup manager service is local 15082 } catch (Exception e) { 15083 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15084 e.printStackTrace(); 15085 } finally { 15086 Binder.restoreCallingIdentity(oldIdent); 15087 } 15088 } 15089 15090 // done with this agent 15091 public void unbindBackupAgent(ApplicationInfo appInfo) { 15092 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15093 if (appInfo == null) { 15094 Slog.w(TAG, "unbind backup agent for null app"); 15095 return; 15096 } 15097 15098 synchronized(this) { 15099 try { 15100 if (mBackupAppName == null) { 15101 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15102 return; 15103 } 15104 15105 if (!mBackupAppName.equals(appInfo.packageName)) { 15106 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15107 return; 15108 } 15109 15110 // Not backing this app up any more; reset its OOM adjustment 15111 final ProcessRecord proc = mBackupTarget.app; 15112 updateOomAdjLocked(proc); 15113 15114 // If the app crashed during backup, 'thread' will be null here 15115 if (proc.thread != null) { 15116 try { 15117 proc.thread.scheduleDestroyBackupAgent(appInfo, 15118 compatibilityInfoForPackageLocked(appInfo)); 15119 } catch (Exception e) { 15120 Slog.e(TAG, "Exception when unbinding backup agent:"); 15121 e.printStackTrace(); 15122 } 15123 } 15124 } finally { 15125 mBackupTarget = null; 15126 mBackupAppName = null; 15127 } 15128 } 15129 } 15130 // ========================================================= 15131 // BROADCASTS 15132 // ========================================================= 15133 15134 private final List getStickiesLocked(String action, IntentFilter filter, 15135 List cur, int userId) { 15136 final ContentResolver resolver = mContext.getContentResolver(); 15137 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15138 if (stickies == null) { 15139 return cur; 15140 } 15141 final ArrayList<Intent> list = stickies.get(action); 15142 if (list == null) { 15143 return cur; 15144 } 15145 int N = list.size(); 15146 for (int i=0; i<N; i++) { 15147 Intent intent = list.get(i); 15148 if (filter.match(resolver, intent, true, TAG) >= 0) { 15149 if (cur == null) { 15150 cur = new ArrayList<Intent>(); 15151 } 15152 cur.add(intent); 15153 } 15154 } 15155 return cur; 15156 } 15157 15158 boolean isPendingBroadcastProcessLocked(int pid) { 15159 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15160 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15161 } 15162 15163 void skipPendingBroadcastLocked(int pid) { 15164 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15165 for (BroadcastQueue queue : mBroadcastQueues) { 15166 queue.skipPendingBroadcastLocked(pid); 15167 } 15168 } 15169 15170 // The app just attached; send any pending broadcasts that it should receive 15171 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15172 boolean didSomething = false; 15173 for (BroadcastQueue queue : mBroadcastQueues) { 15174 didSomething |= queue.sendPendingBroadcastsLocked(app); 15175 } 15176 return didSomething; 15177 } 15178 15179 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15180 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15181 enforceNotIsolatedCaller("registerReceiver"); 15182 int callingUid; 15183 int callingPid; 15184 synchronized(this) { 15185 ProcessRecord callerApp = null; 15186 if (caller != null) { 15187 callerApp = getRecordForAppLocked(caller); 15188 if (callerApp == null) { 15189 throw new SecurityException( 15190 "Unable to find app for caller " + caller 15191 + " (pid=" + Binder.getCallingPid() 15192 + ") when registering receiver " + receiver); 15193 } 15194 if (callerApp.info.uid != Process.SYSTEM_UID && 15195 !callerApp.pkgList.containsKey(callerPackage) && 15196 !"android".equals(callerPackage)) { 15197 throw new SecurityException("Given caller package " + callerPackage 15198 + " is not running in process " + callerApp); 15199 } 15200 callingUid = callerApp.info.uid; 15201 callingPid = callerApp.pid; 15202 } else { 15203 callerPackage = null; 15204 callingUid = Binder.getCallingUid(); 15205 callingPid = Binder.getCallingPid(); 15206 } 15207 15208 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15209 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15210 15211 List allSticky = null; 15212 15213 // Look for any matching sticky broadcasts... 15214 Iterator actions = filter.actionsIterator(); 15215 if (actions != null) { 15216 while (actions.hasNext()) { 15217 String action = (String)actions.next(); 15218 allSticky = getStickiesLocked(action, filter, allSticky, 15219 UserHandle.USER_ALL); 15220 allSticky = getStickiesLocked(action, filter, allSticky, 15221 UserHandle.getUserId(callingUid)); 15222 } 15223 } else { 15224 allSticky = getStickiesLocked(null, filter, allSticky, 15225 UserHandle.USER_ALL); 15226 allSticky = getStickiesLocked(null, filter, allSticky, 15227 UserHandle.getUserId(callingUid)); 15228 } 15229 15230 // The first sticky in the list is returned directly back to 15231 // the client. 15232 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15233 15234 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15235 + ": " + sticky); 15236 15237 if (receiver == null) { 15238 return sticky; 15239 } 15240 15241 ReceiverList rl 15242 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15243 if (rl == null) { 15244 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15245 userId, receiver); 15246 if (rl.app != null) { 15247 rl.app.receivers.add(rl); 15248 } else { 15249 try { 15250 receiver.asBinder().linkToDeath(rl, 0); 15251 } catch (RemoteException e) { 15252 return sticky; 15253 } 15254 rl.linkedToDeath = true; 15255 } 15256 mRegisteredReceivers.put(receiver.asBinder(), rl); 15257 } else if (rl.uid != callingUid) { 15258 throw new IllegalArgumentException( 15259 "Receiver requested to register for uid " + callingUid 15260 + " was previously registered for uid " + rl.uid); 15261 } else if (rl.pid != callingPid) { 15262 throw new IllegalArgumentException( 15263 "Receiver requested to register for pid " + callingPid 15264 + " was previously registered for pid " + rl.pid); 15265 } else if (rl.userId != userId) { 15266 throw new IllegalArgumentException( 15267 "Receiver requested to register for user " + userId 15268 + " was previously registered for user " + rl.userId); 15269 } 15270 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15271 permission, callingUid, userId); 15272 rl.add(bf); 15273 if (!bf.debugCheck()) { 15274 Slog.w(TAG, "==> For Dynamic broadast"); 15275 } 15276 mReceiverResolver.addFilter(bf); 15277 15278 // Enqueue broadcasts for all existing stickies that match 15279 // this filter. 15280 if (allSticky != null) { 15281 ArrayList receivers = new ArrayList(); 15282 receivers.add(bf); 15283 15284 int N = allSticky.size(); 15285 for (int i=0; i<N; i++) { 15286 Intent intent = (Intent)allSticky.get(i); 15287 BroadcastQueue queue = broadcastQueueForIntent(intent); 15288 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15289 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15290 null, null, false, true, true, -1); 15291 queue.enqueueParallelBroadcastLocked(r); 15292 queue.scheduleBroadcastsLocked(); 15293 } 15294 } 15295 15296 return sticky; 15297 } 15298 } 15299 15300 public void unregisterReceiver(IIntentReceiver receiver) { 15301 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15302 15303 final long origId = Binder.clearCallingIdentity(); 15304 try { 15305 boolean doTrim = false; 15306 15307 synchronized(this) { 15308 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15309 if (rl != null) { 15310 if (rl.curBroadcast != null) { 15311 BroadcastRecord r = rl.curBroadcast; 15312 final boolean doNext = finishReceiverLocked( 15313 receiver.asBinder(), r.resultCode, r.resultData, 15314 r.resultExtras, r.resultAbort); 15315 if (doNext) { 15316 doTrim = true; 15317 r.queue.processNextBroadcast(false); 15318 } 15319 } 15320 15321 if (rl.app != null) { 15322 rl.app.receivers.remove(rl); 15323 } 15324 removeReceiverLocked(rl); 15325 if (rl.linkedToDeath) { 15326 rl.linkedToDeath = false; 15327 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15328 } 15329 } 15330 } 15331 15332 // If we actually concluded any broadcasts, we might now be able 15333 // to trim the recipients' apps from our working set 15334 if (doTrim) { 15335 trimApplications(); 15336 return; 15337 } 15338 15339 } finally { 15340 Binder.restoreCallingIdentity(origId); 15341 } 15342 } 15343 15344 void removeReceiverLocked(ReceiverList rl) { 15345 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15346 int N = rl.size(); 15347 for (int i=0; i<N; i++) { 15348 mReceiverResolver.removeFilter(rl.get(i)); 15349 } 15350 } 15351 15352 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15353 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15354 ProcessRecord r = mLruProcesses.get(i); 15355 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15356 try { 15357 r.thread.dispatchPackageBroadcast(cmd, packages); 15358 } catch (RemoteException ex) { 15359 } 15360 } 15361 } 15362 } 15363 15364 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15365 int callingUid, int[] users) { 15366 List<ResolveInfo> receivers = null; 15367 try { 15368 HashSet<ComponentName> singleUserReceivers = null; 15369 boolean scannedFirstReceivers = false; 15370 for (int user : users) { 15371 // Skip users that have Shell restrictions 15372 if (callingUid == Process.SHELL_UID 15373 && getUserManagerLocked().hasUserRestriction( 15374 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15375 continue; 15376 } 15377 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15378 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15379 if (user != 0 && newReceivers != null) { 15380 // If this is not the primary user, we need to check for 15381 // any receivers that should be filtered out. 15382 for (int i=0; i<newReceivers.size(); i++) { 15383 ResolveInfo ri = newReceivers.get(i); 15384 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15385 newReceivers.remove(i); 15386 i--; 15387 } 15388 } 15389 } 15390 if (newReceivers != null && newReceivers.size() == 0) { 15391 newReceivers = null; 15392 } 15393 if (receivers == null) { 15394 receivers = newReceivers; 15395 } else if (newReceivers != null) { 15396 // We need to concatenate the additional receivers 15397 // found with what we have do far. This would be easy, 15398 // but we also need to de-dup any receivers that are 15399 // singleUser. 15400 if (!scannedFirstReceivers) { 15401 // Collect any single user receivers we had already retrieved. 15402 scannedFirstReceivers = true; 15403 for (int i=0; i<receivers.size(); i++) { 15404 ResolveInfo ri = receivers.get(i); 15405 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15406 ComponentName cn = new ComponentName( 15407 ri.activityInfo.packageName, ri.activityInfo.name); 15408 if (singleUserReceivers == null) { 15409 singleUserReceivers = new HashSet<ComponentName>(); 15410 } 15411 singleUserReceivers.add(cn); 15412 } 15413 } 15414 } 15415 // Add the new results to the existing results, tracking 15416 // and de-dupping single user receivers. 15417 for (int i=0; i<newReceivers.size(); i++) { 15418 ResolveInfo ri = newReceivers.get(i); 15419 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15420 ComponentName cn = new ComponentName( 15421 ri.activityInfo.packageName, ri.activityInfo.name); 15422 if (singleUserReceivers == null) { 15423 singleUserReceivers = new HashSet<ComponentName>(); 15424 } 15425 if (!singleUserReceivers.contains(cn)) { 15426 singleUserReceivers.add(cn); 15427 receivers.add(ri); 15428 } 15429 } else { 15430 receivers.add(ri); 15431 } 15432 } 15433 } 15434 } 15435 } catch (RemoteException ex) { 15436 // pm is in same process, this will never happen. 15437 } 15438 return receivers; 15439 } 15440 15441 private final int broadcastIntentLocked(ProcessRecord callerApp, 15442 String callerPackage, Intent intent, String resolvedType, 15443 IIntentReceiver resultTo, int resultCode, String resultData, 15444 Bundle map, String requiredPermission, int appOp, 15445 boolean ordered, boolean sticky, int callingPid, int callingUid, 15446 int userId) { 15447 intent = new Intent(intent); 15448 15449 // By default broadcasts do not go to stopped apps. 15450 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15451 15452 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15453 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15454 + " ordered=" + ordered + " userid=" + userId); 15455 if ((resultTo != null) && !ordered) { 15456 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15457 } 15458 15459 userId = handleIncomingUser(callingPid, callingUid, userId, 15460 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15461 15462 // Make sure that the user who is receiving this broadcast is started. 15463 // If not, we will just skip it. 15464 15465 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15466 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15467 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15468 Slog.w(TAG, "Skipping broadcast of " + intent 15469 + ": user " + userId + " is stopped"); 15470 return ActivityManager.BROADCAST_SUCCESS; 15471 } 15472 } 15473 15474 /* 15475 * Prevent non-system code (defined here to be non-persistent 15476 * processes) from sending protected broadcasts. 15477 */ 15478 int callingAppId = UserHandle.getAppId(callingUid); 15479 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15480 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15481 || callingAppId == Process.NFC_UID || callingUid == 0) { 15482 // Always okay. 15483 } else if (callerApp == null || !callerApp.persistent) { 15484 try { 15485 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15486 intent.getAction())) { 15487 String msg = "Permission Denial: not allowed to send broadcast " 15488 + intent.getAction() + " from pid=" 15489 + callingPid + ", uid=" + callingUid; 15490 Slog.w(TAG, msg); 15491 throw new SecurityException(msg); 15492 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15493 // Special case for compatibility: we don't want apps to send this, 15494 // but historically it has not been protected and apps may be using it 15495 // to poke their own app widget. So, instead of making it protected, 15496 // just limit it to the caller. 15497 if (callerApp == null) { 15498 String msg = "Permission Denial: not allowed to send broadcast " 15499 + intent.getAction() + " from unknown caller."; 15500 Slog.w(TAG, msg); 15501 throw new SecurityException(msg); 15502 } else if (intent.getComponent() != null) { 15503 // They are good enough to send to an explicit component... verify 15504 // it is being sent to the calling app. 15505 if (!intent.getComponent().getPackageName().equals( 15506 callerApp.info.packageName)) { 15507 String msg = "Permission Denial: not allowed to send broadcast " 15508 + intent.getAction() + " to " 15509 + intent.getComponent().getPackageName() + " from " 15510 + callerApp.info.packageName; 15511 Slog.w(TAG, msg); 15512 throw new SecurityException(msg); 15513 } 15514 } else { 15515 // Limit broadcast to their own package. 15516 intent.setPackage(callerApp.info.packageName); 15517 } 15518 } 15519 } catch (RemoteException e) { 15520 Slog.w(TAG, "Remote exception", e); 15521 return ActivityManager.BROADCAST_SUCCESS; 15522 } 15523 } 15524 15525 // Handle special intents: if this broadcast is from the package 15526 // manager about a package being removed, we need to remove all of 15527 // its activities from the history stack. 15528 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15529 intent.getAction()); 15530 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15531 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15532 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15533 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15534 || uidRemoved) { 15535 if (checkComponentPermission( 15536 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15537 callingPid, callingUid, -1, true) 15538 == PackageManager.PERMISSION_GRANTED) { 15539 if (uidRemoved) { 15540 final Bundle intentExtras = intent.getExtras(); 15541 final int uid = intentExtras != null 15542 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15543 if (uid >= 0) { 15544 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15545 synchronized (bs) { 15546 bs.removeUidStatsLocked(uid); 15547 } 15548 mAppOpsService.uidRemoved(uid); 15549 } 15550 } else { 15551 // If resources are unavailable just force stop all 15552 // those packages and flush the attribute cache as well. 15553 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15554 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15555 if (list != null && (list.length > 0)) { 15556 for (String pkg : list) { 15557 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15558 "storage unmount"); 15559 } 15560 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15561 sendPackageBroadcastLocked( 15562 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15563 } 15564 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15565 intent.getAction())) { 15566 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15567 } else { 15568 Uri data = intent.getData(); 15569 String ssp; 15570 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15571 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15572 intent.getAction()); 15573 boolean fullUninstall = removed && 15574 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15575 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15576 forceStopPackageLocked(ssp, UserHandle.getAppId( 15577 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15578 false, fullUninstall, userId, 15579 removed ? "pkg removed" : "pkg changed"); 15580 } 15581 if (removed) { 15582 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15583 new String[] {ssp}, userId); 15584 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15585 mAppOpsService.packageRemoved( 15586 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15587 15588 // Remove all permissions granted from/to this package 15589 removeUriPermissionsForPackageLocked(ssp, userId, true); 15590 } 15591 } 15592 } 15593 } 15594 } 15595 } else { 15596 String msg = "Permission Denial: " + intent.getAction() 15597 + " broadcast from " + callerPackage + " (pid=" + callingPid 15598 + ", uid=" + callingUid + ")" 15599 + " requires " 15600 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15601 Slog.w(TAG, msg); 15602 throw new SecurityException(msg); 15603 } 15604 15605 // Special case for adding a package: by default turn on compatibility 15606 // mode. 15607 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15608 Uri data = intent.getData(); 15609 String ssp; 15610 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15611 mCompatModePackages.handlePackageAddedLocked(ssp, 15612 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15613 } 15614 } 15615 15616 /* 15617 * If this is the time zone changed action, queue up a message that will reset the timezone 15618 * of all currently running processes. This message will get queued up before the broadcast 15619 * happens. 15620 */ 15621 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15622 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15623 } 15624 15625 /* 15626 * If the user set the time, let all running processes know. 15627 */ 15628 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15629 final int is24Hour = intent.getBooleanExtra( 15630 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15631 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15632 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15633 synchronized (stats) { 15634 stats.noteCurrentTimeChangedLocked(); 15635 } 15636 } 15637 15638 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15639 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15640 } 15641 15642 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15643 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15644 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15645 } 15646 15647 // Add to the sticky list if requested. 15648 if (sticky) { 15649 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15650 callingPid, callingUid) 15651 != PackageManager.PERMISSION_GRANTED) { 15652 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15653 + callingPid + ", uid=" + callingUid 15654 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15655 Slog.w(TAG, msg); 15656 throw new SecurityException(msg); 15657 } 15658 if (requiredPermission != null) { 15659 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15660 + " and enforce permission " + requiredPermission); 15661 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15662 } 15663 if (intent.getComponent() != null) { 15664 throw new SecurityException( 15665 "Sticky broadcasts can't target a specific component"); 15666 } 15667 // We use userId directly here, since the "all" target is maintained 15668 // as a separate set of sticky broadcasts. 15669 if (userId != UserHandle.USER_ALL) { 15670 // But first, if this is not a broadcast to all users, then 15671 // make sure it doesn't conflict with an existing broadcast to 15672 // all users. 15673 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15674 UserHandle.USER_ALL); 15675 if (stickies != null) { 15676 ArrayList<Intent> list = stickies.get(intent.getAction()); 15677 if (list != null) { 15678 int N = list.size(); 15679 int i; 15680 for (i=0; i<N; i++) { 15681 if (intent.filterEquals(list.get(i))) { 15682 throw new IllegalArgumentException( 15683 "Sticky broadcast " + intent + " for user " 15684 + userId + " conflicts with existing global broadcast"); 15685 } 15686 } 15687 } 15688 } 15689 } 15690 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15691 if (stickies == null) { 15692 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15693 mStickyBroadcasts.put(userId, stickies); 15694 } 15695 ArrayList<Intent> list = stickies.get(intent.getAction()); 15696 if (list == null) { 15697 list = new ArrayList<Intent>(); 15698 stickies.put(intent.getAction(), list); 15699 } 15700 int N = list.size(); 15701 int i; 15702 for (i=0; i<N; i++) { 15703 if (intent.filterEquals(list.get(i))) { 15704 // This sticky already exists, replace it. 15705 list.set(i, new Intent(intent)); 15706 break; 15707 } 15708 } 15709 if (i >= N) { 15710 list.add(new Intent(intent)); 15711 } 15712 } 15713 15714 int[] users; 15715 if (userId == UserHandle.USER_ALL) { 15716 // Caller wants broadcast to go to all started users. 15717 users = mStartedUserArray; 15718 } else { 15719 // Caller wants broadcast to go to one specific user. 15720 users = new int[] {userId}; 15721 } 15722 15723 // Figure out who all will receive this broadcast. 15724 List receivers = null; 15725 List<BroadcastFilter> registeredReceivers = null; 15726 // Need to resolve the intent to interested receivers... 15727 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15728 == 0) { 15729 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15730 } 15731 if (intent.getComponent() == null) { 15732 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15733 // Query one target user at a time, excluding shell-restricted users 15734 UserManagerService ums = getUserManagerLocked(); 15735 for (int i = 0; i < users.length; i++) { 15736 if (ums.hasUserRestriction( 15737 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15738 continue; 15739 } 15740 List<BroadcastFilter> registeredReceiversForUser = 15741 mReceiverResolver.queryIntent(intent, 15742 resolvedType, false, users[i]); 15743 if (registeredReceivers == null) { 15744 registeredReceivers = registeredReceiversForUser; 15745 } else if (registeredReceiversForUser != null) { 15746 registeredReceivers.addAll(registeredReceiversForUser); 15747 } 15748 } 15749 } else { 15750 registeredReceivers = mReceiverResolver.queryIntent(intent, 15751 resolvedType, false, userId); 15752 } 15753 } 15754 15755 final boolean replacePending = 15756 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15757 15758 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15759 + " replacePending=" + replacePending); 15760 15761 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15762 if (!ordered && NR > 0) { 15763 // If we are not serializing this broadcast, then send the 15764 // registered receivers separately so they don't wait for the 15765 // components to be launched. 15766 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15767 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15768 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15769 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15770 ordered, sticky, false, userId); 15771 if (DEBUG_BROADCAST) Slog.v( 15772 TAG, "Enqueueing parallel broadcast " + r); 15773 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15774 if (!replaced) { 15775 queue.enqueueParallelBroadcastLocked(r); 15776 queue.scheduleBroadcastsLocked(); 15777 } 15778 registeredReceivers = null; 15779 NR = 0; 15780 } 15781 15782 // Merge into one list. 15783 int ir = 0; 15784 if (receivers != null) { 15785 // A special case for PACKAGE_ADDED: do not allow the package 15786 // being added to see this broadcast. This prevents them from 15787 // using this as a back door to get run as soon as they are 15788 // installed. Maybe in the future we want to have a special install 15789 // broadcast or such for apps, but we'd like to deliberately make 15790 // this decision. 15791 String skipPackages[] = null; 15792 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15793 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15794 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15795 Uri data = intent.getData(); 15796 if (data != null) { 15797 String pkgName = data.getSchemeSpecificPart(); 15798 if (pkgName != null) { 15799 skipPackages = new String[] { pkgName }; 15800 } 15801 } 15802 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15803 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15804 } 15805 if (skipPackages != null && (skipPackages.length > 0)) { 15806 for (String skipPackage : skipPackages) { 15807 if (skipPackage != null) { 15808 int NT = receivers.size(); 15809 for (int it=0; it<NT; it++) { 15810 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15811 if (curt.activityInfo.packageName.equals(skipPackage)) { 15812 receivers.remove(it); 15813 it--; 15814 NT--; 15815 } 15816 } 15817 } 15818 } 15819 } 15820 15821 int NT = receivers != null ? receivers.size() : 0; 15822 int it = 0; 15823 ResolveInfo curt = null; 15824 BroadcastFilter curr = null; 15825 while (it < NT && ir < NR) { 15826 if (curt == null) { 15827 curt = (ResolveInfo)receivers.get(it); 15828 } 15829 if (curr == null) { 15830 curr = registeredReceivers.get(ir); 15831 } 15832 if (curr.getPriority() >= curt.priority) { 15833 // Insert this broadcast record into the final list. 15834 receivers.add(it, curr); 15835 ir++; 15836 curr = null; 15837 it++; 15838 NT++; 15839 } else { 15840 // Skip to the next ResolveInfo in the final list. 15841 it++; 15842 curt = null; 15843 } 15844 } 15845 } 15846 while (ir < NR) { 15847 if (receivers == null) { 15848 receivers = new ArrayList(); 15849 } 15850 receivers.add(registeredReceivers.get(ir)); 15851 ir++; 15852 } 15853 15854 if ((receivers != null && receivers.size() > 0) 15855 || resultTo != null) { 15856 BroadcastQueue queue = broadcastQueueForIntent(intent); 15857 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15858 callerPackage, callingPid, callingUid, resolvedType, 15859 requiredPermission, appOp, receivers, resultTo, resultCode, 15860 resultData, map, ordered, sticky, false, userId); 15861 if (DEBUG_BROADCAST) Slog.v( 15862 TAG, "Enqueueing ordered broadcast " + r 15863 + ": prev had " + queue.mOrderedBroadcasts.size()); 15864 if (DEBUG_BROADCAST) { 15865 int seq = r.intent.getIntExtra("seq", -1); 15866 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15867 } 15868 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15869 if (!replaced) { 15870 queue.enqueueOrderedBroadcastLocked(r); 15871 queue.scheduleBroadcastsLocked(); 15872 } 15873 } 15874 15875 return ActivityManager.BROADCAST_SUCCESS; 15876 } 15877 15878 final Intent verifyBroadcastLocked(Intent intent) { 15879 // Refuse possible leaked file descriptors 15880 if (intent != null && intent.hasFileDescriptors() == true) { 15881 throw new IllegalArgumentException("File descriptors passed in Intent"); 15882 } 15883 15884 int flags = intent.getFlags(); 15885 15886 if (!mProcessesReady) { 15887 // if the caller really truly claims to know what they're doing, go 15888 // ahead and allow the broadcast without launching any receivers 15889 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15890 intent = new Intent(intent); 15891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15892 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15893 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15894 + " before boot completion"); 15895 throw new IllegalStateException("Cannot broadcast before boot completed"); 15896 } 15897 } 15898 15899 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15900 throw new IllegalArgumentException( 15901 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15902 } 15903 15904 return intent; 15905 } 15906 15907 public final int broadcastIntent(IApplicationThread caller, 15908 Intent intent, String resolvedType, IIntentReceiver resultTo, 15909 int resultCode, String resultData, Bundle map, 15910 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15911 enforceNotIsolatedCaller("broadcastIntent"); 15912 synchronized(this) { 15913 intent = verifyBroadcastLocked(intent); 15914 15915 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15916 final int callingPid = Binder.getCallingPid(); 15917 final int callingUid = Binder.getCallingUid(); 15918 final long origId = Binder.clearCallingIdentity(); 15919 int res = broadcastIntentLocked(callerApp, 15920 callerApp != null ? callerApp.info.packageName : null, 15921 intent, resolvedType, resultTo, 15922 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15923 callingPid, callingUid, userId); 15924 Binder.restoreCallingIdentity(origId); 15925 return res; 15926 } 15927 } 15928 15929 int broadcastIntentInPackage(String packageName, int uid, 15930 Intent intent, String resolvedType, IIntentReceiver resultTo, 15931 int resultCode, String resultData, Bundle map, 15932 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15933 synchronized(this) { 15934 intent = verifyBroadcastLocked(intent); 15935 15936 final long origId = Binder.clearCallingIdentity(); 15937 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15938 resultTo, resultCode, resultData, map, requiredPermission, 15939 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15940 Binder.restoreCallingIdentity(origId); 15941 return res; 15942 } 15943 } 15944 15945 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15946 // Refuse possible leaked file descriptors 15947 if (intent != null && intent.hasFileDescriptors() == true) { 15948 throw new IllegalArgumentException("File descriptors passed in Intent"); 15949 } 15950 15951 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15952 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15953 15954 synchronized(this) { 15955 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15956 != PackageManager.PERMISSION_GRANTED) { 15957 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15958 + Binder.getCallingPid() 15959 + ", uid=" + Binder.getCallingUid() 15960 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15961 Slog.w(TAG, msg); 15962 throw new SecurityException(msg); 15963 } 15964 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15965 if (stickies != null) { 15966 ArrayList<Intent> list = stickies.get(intent.getAction()); 15967 if (list != null) { 15968 int N = list.size(); 15969 int i; 15970 for (i=0; i<N; i++) { 15971 if (intent.filterEquals(list.get(i))) { 15972 list.remove(i); 15973 break; 15974 } 15975 } 15976 if (list.size() <= 0) { 15977 stickies.remove(intent.getAction()); 15978 } 15979 } 15980 if (stickies.size() <= 0) { 15981 mStickyBroadcasts.remove(userId); 15982 } 15983 } 15984 } 15985 } 15986 15987 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15988 String resultData, Bundle resultExtras, boolean resultAbort) { 15989 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15990 if (r == null) { 15991 Slog.w(TAG, "finishReceiver called but not found on queue"); 15992 return false; 15993 } 15994 15995 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15996 } 15997 15998 void backgroundServicesFinishedLocked(int userId) { 15999 for (BroadcastQueue queue : mBroadcastQueues) { 16000 queue.backgroundServicesFinishedLocked(userId); 16001 } 16002 } 16003 16004 public void finishReceiver(IBinder who, int resultCode, String resultData, 16005 Bundle resultExtras, boolean resultAbort) { 16006 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16007 16008 // Refuse possible leaked file descriptors 16009 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16010 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16011 } 16012 16013 final long origId = Binder.clearCallingIdentity(); 16014 try { 16015 boolean doNext = false; 16016 BroadcastRecord r; 16017 16018 synchronized(this) { 16019 r = broadcastRecordForReceiverLocked(who); 16020 if (r != null) { 16021 doNext = r.queue.finishReceiverLocked(r, resultCode, 16022 resultData, resultExtras, resultAbort, true); 16023 } 16024 } 16025 16026 if (doNext) { 16027 r.queue.processNextBroadcast(false); 16028 } 16029 trimApplications(); 16030 } finally { 16031 Binder.restoreCallingIdentity(origId); 16032 } 16033 } 16034 16035 // ========================================================= 16036 // INSTRUMENTATION 16037 // ========================================================= 16038 16039 public boolean startInstrumentation(ComponentName className, 16040 String profileFile, int flags, Bundle arguments, 16041 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16042 int userId, String abiOverride) { 16043 enforceNotIsolatedCaller("startInstrumentation"); 16044 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16045 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16046 // Refuse possible leaked file descriptors 16047 if (arguments != null && arguments.hasFileDescriptors()) { 16048 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16049 } 16050 16051 synchronized(this) { 16052 InstrumentationInfo ii = null; 16053 ApplicationInfo ai = null; 16054 try { 16055 ii = mContext.getPackageManager().getInstrumentationInfo( 16056 className, STOCK_PM_FLAGS); 16057 ai = AppGlobals.getPackageManager().getApplicationInfo( 16058 ii.targetPackage, STOCK_PM_FLAGS, userId); 16059 } catch (PackageManager.NameNotFoundException e) { 16060 } catch (RemoteException e) { 16061 } 16062 if (ii == null) { 16063 reportStartInstrumentationFailure(watcher, className, 16064 "Unable to find instrumentation info for: " + className); 16065 return false; 16066 } 16067 if (ai == null) { 16068 reportStartInstrumentationFailure(watcher, className, 16069 "Unable to find instrumentation target package: " + ii.targetPackage); 16070 return false; 16071 } 16072 16073 int match = mContext.getPackageManager().checkSignatures( 16074 ii.targetPackage, ii.packageName); 16075 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16076 String msg = "Permission Denial: starting instrumentation " 16077 + className + " from pid=" 16078 + Binder.getCallingPid() 16079 + ", uid=" + Binder.getCallingPid() 16080 + " not allowed because package " + ii.packageName 16081 + " does not have a signature matching the target " 16082 + ii.targetPackage; 16083 reportStartInstrumentationFailure(watcher, className, msg); 16084 throw new SecurityException(msg); 16085 } 16086 16087 final long origId = Binder.clearCallingIdentity(); 16088 // Instrumentation can kill and relaunch even persistent processes 16089 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16090 "start instr"); 16091 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16092 app.instrumentationClass = className; 16093 app.instrumentationInfo = ai; 16094 app.instrumentationProfileFile = profileFile; 16095 app.instrumentationArguments = arguments; 16096 app.instrumentationWatcher = watcher; 16097 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16098 app.instrumentationResultClass = className; 16099 Binder.restoreCallingIdentity(origId); 16100 } 16101 16102 return true; 16103 } 16104 16105 /** 16106 * Report errors that occur while attempting to start Instrumentation. Always writes the 16107 * error to the logs, but if somebody is watching, send the report there too. This enables 16108 * the "am" command to report errors with more information. 16109 * 16110 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16111 * @param cn The component name of the instrumentation. 16112 * @param report The error report. 16113 */ 16114 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16115 ComponentName cn, String report) { 16116 Slog.w(TAG, report); 16117 try { 16118 if (watcher != null) { 16119 Bundle results = new Bundle(); 16120 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16121 results.putString("Error", report); 16122 watcher.instrumentationStatus(cn, -1, results); 16123 } 16124 } catch (RemoteException e) { 16125 Slog.w(TAG, e); 16126 } 16127 } 16128 16129 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16130 if (app.instrumentationWatcher != null) { 16131 try { 16132 // NOTE: IInstrumentationWatcher *must* be oneway here 16133 app.instrumentationWatcher.instrumentationFinished( 16134 app.instrumentationClass, 16135 resultCode, 16136 results); 16137 } catch (RemoteException e) { 16138 } 16139 } 16140 if (app.instrumentationUiAutomationConnection != null) { 16141 try { 16142 app.instrumentationUiAutomationConnection.shutdown(); 16143 } catch (RemoteException re) { 16144 /* ignore */ 16145 } 16146 // Only a UiAutomation can set this flag and now that 16147 // it is finished we make sure it is reset to its default. 16148 mUserIsMonkey = false; 16149 } 16150 app.instrumentationWatcher = null; 16151 app.instrumentationUiAutomationConnection = null; 16152 app.instrumentationClass = null; 16153 app.instrumentationInfo = null; 16154 app.instrumentationProfileFile = null; 16155 app.instrumentationArguments = null; 16156 16157 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16158 "finished inst"); 16159 } 16160 16161 public void finishInstrumentation(IApplicationThread target, 16162 int resultCode, Bundle results) { 16163 int userId = UserHandle.getCallingUserId(); 16164 // Refuse possible leaked file descriptors 16165 if (results != null && results.hasFileDescriptors()) { 16166 throw new IllegalArgumentException("File descriptors passed in Intent"); 16167 } 16168 16169 synchronized(this) { 16170 ProcessRecord app = getRecordForAppLocked(target); 16171 if (app == null) { 16172 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16173 return; 16174 } 16175 final long origId = Binder.clearCallingIdentity(); 16176 finishInstrumentationLocked(app, resultCode, results); 16177 Binder.restoreCallingIdentity(origId); 16178 } 16179 } 16180 16181 // ========================================================= 16182 // CONFIGURATION 16183 // ========================================================= 16184 16185 public ConfigurationInfo getDeviceConfigurationInfo() { 16186 ConfigurationInfo config = new ConfigurationInfo(); 16187 synchronized (this) { 16188 config.reqTouchScreen = mConfiguration.touchscreen; 16189 config.reqKeyboardType = mConfiguration.keyboard; 16190 config.reqNavigation = mConfiguration.navigation; 16191 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16192 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16193 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16194 } 16195 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16196 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16197 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16198 } 16199 config.reqGlEsVersion = GL_ES_VERSION; 16200 } 16201 return config; 16202 } 16203 16204 ActivityStack getFocusedStack() { 16205 return mStackSupervisor.getFocusedStack(); 16206 } 16207 16208 public Configuration getConfiguration() { 16209 Configuration ci; 16210 synchronized(this) { 16211 ci = new Configuration(mConfiguration); 16212 } 16213 return ci; 16214 } 16215 16216 public void updatePersistentConfiguration(Configuration values) { 16217 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16218 "updateConfiguration()"); 16219 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16220 "updateConfiguration()"); 16221 if (values == null) { 16222 throw new NullPointerException("Configuration must not be null"); 16223 } 16224 16225 synchronized(this) { 16226 final long origId = Binder.clearCallingIdentity(); 16227 updateConfigurationLocked(values, null, true, false); 16228 Binder.restoreCallingIdentity(origId); 16229 } 16230 } 16231 16232 public void updateConfiguration(Configuration values) { 16233 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16234 "updateConfiguration()"); 16235 16236 synchronized(this) { 16237 if (values == null && mWindowManager != null) { 16238 // sentinel: fetch the current configuration from the window manager 16239 values = mWindowManager.computeNewConfiguration(); 16240 } 16241 16242 if (mWindowManager != null) { 16243 mProcessList.applyDisplaySize(mWindowManager); 16244 } 16245 16246 final long origId = Binder.clearCallingIdentity(); 16247 if (values != null) { 16248 Settings.System.clearConfiguration(values); 16249 } 16250 updateConfigurationLocked(values, null, false, false); 16251 Binder.restoreCallingIdentity(origId); 16252 } 16253 } 16254 16255 /** 16256 * Do either or both things: (1) change the current configuration, and (2) 16257 * make sure the given activity is running with the (now) current 16258 * configuration. Returns true if the activity has been left running, or 16259 * false if <var>starting</var> is being destroyed to match the new 16260 * configuration. 16261 * @param persistent TODO 16262 */ 16263 boolean updateConfigurationLocked(Configuration values, 16264 ActivityRecord starting, boolean persistent, boolean initLocale) { 16265 int changes = 0; 16266 16267 if (values != null) { 16268 Configuration newConfig = new Configuration(mConfiguration); 16269 changes = newConfig.updateFrom(values); 16270 if (changes != 0) { 16271 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16272 Slog.i(TAG, "Updating configuration to: " + values); 16273 } 16274 16275 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16276 16277 if (values.locale != null && !initLocale) { 16278 saveLocaleLocked(values.locale, 16279 !values.locale.equals(mConfiguration.locale), 16280 values.userSetLocale); 16281 } 16282 16283 mConfigurationSeq++; 16284 if (mConfigurationSeq <= 0) { 16285 mConfigurationSeq = 1; 16286 } 16287 newConfig.seq = mConfigurationSeq; 16288 mConfiguration = newConfig; 16289 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16290 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16291 //mUsageStatsService.noteStartConfig(newConfig); 16292 16293 final Configuration configCopy = new Configuration(mConfiguration); 16294 16295 // TODO: If our config changes, should we auto dismiss any currently 16296 // showing dialogs? 16297 mShowDialogs = shouldShowDialogs(newConfig); 16298 16299 AttributeCache ac = AttributeCache.instance(); 16300 if (ac != null) { 16301 ac.updateConfiguration(configCopy); 16302 } 16303 16304 // Make sure all resources in our process are updated 16305 // right now, so that anyone who is going to retrieve 16306 // resource values after we return will be sure to get 16307 // the new ones. This is especially important during 16308 // boot, where the first config change needs to guarantee 16309 // all resources have that config before following boot 16310 // code is executed. 16311 mSystemThread.applyConfigurationToResources(configCopy); 16312 16313 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16314 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16315 msg.obj = new Configuration(configCopy); 16316 mHandler.sendMessage(msg); 16317 } 16318 16319 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16320 ProcessRecord app = mLruProcesses.get(i); 16321 try { 16322 if (app.thread != null) { 16323 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16324 + app.processName + " new config " + mConfiguration); 16325 app.thread.scheduleConfigurationChanged(configCopy); 16326 } 16327 } catch (Exception e) { 16328 } 16329 } 16330 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16331 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16332 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16333 | Intent.FLAG_RECEIVER_FOREGROUND); 16334 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16335 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16336 Process.SYSTEM_UID, UserHandle.USER_ALL); 16337 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16338 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16339 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16340 broadcastIntentLocked(null, null, intent, 16341 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16342 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16343 } 16344 } 16345 } 16346 16347 boolean kept = true; 16348 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16349 // mainStack is null during startup. 16350 if (mainStack != null) { 16351 if (changes != 0 && starting == null) { 16352 // If the configuration changed, and the caller is not already 16353 // in the process of starting an activity, then find the top 16354 // activity to check if its configuration needs to change. 16355 starting = mainStack.topRunningActivityLocked(null); 16356 } 16357 16358 if (starting != null) { 16359 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16360 // And we need to make sure at this point that all other activities 16361 // are made visible with the correct configuration. 16362 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16363 } 16364 } 16365 16366 if (values != null && mWindowManager != null) { 16367 mWindowManager.setNewConfiguration(mConfiguration); 16368 } 16369 16370 return kept; 16371 } 16372 16373 /** 16374 * Decide based on the configuration whether we should shouw the ANR, 16375 * crash, etc dialogs. The idea is that if there is no affordnace to 16376 * press the on-screen buttons, we shouldn't show the dialog. 16377 * 16378 * A thought: SystemUI might also want to get told about this, the Power 16379 * dialog / global actions also might want different behaviors. 16380 */ 16381 private static final boolean shouldShowDialogs(Configuration config) { 16382 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16383 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16384 } 16385 16386 /** 16387 * Save the locale. You must be inside a synchronized (this) block. 16388 */ 16389 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16390 if(isDiff) { 16391 SystemProperties.set("user.language", l.getLanguage()); 16392 SystemProperties.set("user.region", l.getCountry()); 16393 } 16394 16395 if(isPersist) { 16396 SystemProperties.set("persist.sys.language", l.getLanguage()); 16397 SystemProperties.set("persist.sys.country", l.getCountry()); 16398 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16399 16400 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16401 } 16402 } 16403 16404 @Override 16405 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16406 synchronized (this) { 16407 ActivityRecord srec = ActivityRecord.forToken(token); 16408 if (srec.task != null && srec.task.stack != null) { 16409 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16410 } 16411 } 16412 return false; 16413 } 16414 16415 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16416 Intent resultData) { 16417 16418 synchronized (this) { 16419 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16420 if (stack != null) { 16421 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16422 } 16423 return false; 16424 } 16425 } 16426 16427 public int getLaunchedFromUid(IBinder activityToken) { 16428 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16429 if (srec == null) { 16430 return -1; 16431 } 16432 return srec.launchedFromUid; 16433 } 16434 16435 public String getLaunchedFromPackage(IBinder activityToken) { 16436 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16437 if (srec == null) { 16438 return null; 16439 } 16440 return srec.launchedFromPackage; 16441 } 16442 16443 // ========================================================= 16444 // LIFETIME MANAGEMENT 16445 // ========================================================= 16446 16447 // Returns which broadcast queue the app is the current [or imminent] receiver 16448 // on, or 'null' if the app is not an active broadcast recipient. 16449 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16450 BroadcastRecord r = app.curReceiver; 16451 if (r != null) { 16452 return r.queue; 16453 } 16454 16455 // It's not the current receiver, but it might be starting up to become one 16456 synchronized (this) { 16457 for (BroadcastQueue queue : mBroadcastQueues) { 16458 r = queue.mPendingBroadcast; 16459 if (r != null && r.curApp == app) { 16460 // found it; report which queue it's in 16461 return queue; 16462 } 16463 } 16464 } 16465 16466 return null; 16467 } 16468 16469 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16470 boolean doingAll, long now) { 16471 if (mAdjSeq == app.adjSeq) { 16472 // This adjustment has already been computed. 16473 return app.curRawAdj; 16474 } 16475 16476 if (app.thread == null) { 16477 app.adjSeq = mAdjSeq; 16478 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16479 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16480 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16481 } 16482 16483 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16484 app.adjSource = null; 16485 app.adjTarget = null; 16486 app.empty = false; 16487 app.cached = false; 16488 16489 final int activitiesSize = app.activities.size(); 16490 16491 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16492 // The max adjustment doesn't allow this app to be anything 16493 // below foreground, so it is not worth doing work for it. 16494 app.adjType = "fixed"; 16495 app.adjSeq = mAdjSeq; 16496 app.curRawAdj = app.maxAdj; 16497 app.foregroundActivities = false; 16498 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16499 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16500 // System processes can do UI, and when they do we want to have 16501 // them trim their memory after the user leaves the UI. To 16502 // facilitate this, here we need to determine whether or not it 16503 // is currently showing UI. 16504 app.systemNoUi = true; 16505 if (app == TOP_APP) { 16506 app.systemNoUi = false; 16507 } else if (activitiesSize > 0) { 16508 for (int j = 0; j < activitiesSize; j++) { 16509 final ActivityRecord r = app.activities.get(j); 16510 if (r.visible) { 16511 app.systemNoUi = false; 16512 } 16513 } 16514 } 16515 if (!app.systemNoUi) { 16516 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16517 } 16518 return (app.curAdj=app.maxAdj); 16519 } 16520 16521 app.systemNoUi = false; 16522 16523 // Determine the importance of the process, starting with most 16524 // important to least, and assign an appropriate OOM adjustment. 16525 int adj; 16526 int schedGroup; 16527 int procState; 16528 boolean foregroundActivities = false; 16529 BroadcastQueue queue; 16530 if (app == TOP_APP) { 16531 // The last app on the list is the foreground app. 16532 adj = ProcessList.FOREGROUND_APP_ADJ; 16533 schedGroup = Process.THREAD_GROUP_DEFAULT; 16534 app.adjType = "top-activity"; 16535 foregroundActivities = true; 16536 procState = ActivityManager.PROCESS_STATE_TOP; 16537 } else if (app.instrumentationClass != null) { 16538 // Don't want to kill running instrumentation. 16539 adj = ProcessList.FOREGROUND_APP_ADJ; 16540 schedGroup = Process.THREAD_GROUP_DEFAULT; 16541 app.adjType = "instrumentation"; 16542 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16543 } else if ((queue = isReceivingBroadcast(app)) != null) { 16544 // An app that is currently receiving a broadcast also 16545 // counts as being in the foreground for OOM killer purposes. 16546 // It's placed in a sched group based on the nature of the 16547 // broadcast as reflected by which queue it's active in. 16548 adj = ProcessList.FOREGROUND_APP_ADJ; 16549 schedGroup = (queue == mFgBroadcastQueue) 16550 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16551 app.adjType = "broadcast"; 16552 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16553 } else if (app.executingServices.size() > 0) { 16554 // An app that is currently executing a service callback also 16555 // counts as being in the foreground. 16556 adj = ProcessList.FOREGROUND_APP_ADJ; 16557 schedGroup = app.execServicesFg ? 16558 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16559 app.adjType = "exec-service"; 16560 procState = ActivityManager.PROCESS_STATE_SERVICE; 16561 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16562 } else { 16563 // As far as we know the process is empty. We may change our mind later. 16564 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16565 // At this point we don't actually know the adjustment. Use the cached adj 16566 // value that the caller wants us to. 16567 adj = cachedAdj; 16568 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16569 app.cached = true; 16570 app.empty = true; 16571 app.adjType = "cch-empty"; 16572 } 16573 16574 // Examine all activities if not already foreground. 16575 if (!foregroundActivities && activitiesSize > 0) { 16576 for (int j = 0; j < activitiesSize; j++) { 16577 final ActivityRecord r = app.activities.get(j); 16578 if (r.app != app) { 16579 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16580 + app + "?!?"); 16581 continue; 16582 } 16583 if (r.visible) { 16584 // App has a visible activity; only upgrade adjustment. 16585 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16586 adj = ProcessList.VISIBLE_APP_ADJ; 16587 app.adjType = "visible"; 16588 } 16589 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16590 procState = ActivityManager.PROCESS_STATE_TOP; 16591 } 16592 schedGroup = Process.THREAD_GROUP_DEFAULT; 16593 app.cached = false; 16594 app.empty = false; 16595 foregroundActivities = true; 16596 break; 16597 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16598 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16599 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16600 app.adjType = "pausing"; 16601 } 16602 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16603 procState = ActivityManager.PROCESS_STATE_TOP; 16604 } 16605 schedGroup = Process.THREAD_GROUP_DEFAULT; 16606 app.cached = false; 16607 app.empty = false; 16608 foregroundActivities = true; 16609 } else if (r.state == ActivityState.STOPPING) { 16610 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16611 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16612 app.adjType = "stopping"; 16613 } 16614 // For the process state, we will at this point consider the 16615 // process to be cached. It will be cached either as an activity 16616 // or empty depending on whether the activity is finishing. We do 16617 // this so that we can treat the process as cached for purposes of 16618 // memory trimming (determing current memory level, trim command to 16619 // send to process) since there can be an arbitrary number of stopping 16620 // processes and they should soon all go into the cached state. 16621 if (!r.finishing) { 16622 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16623 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16624 } 16625 } 16626 app.cached = false; 16627 app.empty = false; 16628 foregroundActivities = true; 16629 } else { 16630 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16631 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16632 app.adjType = "cch-act"; 16633 } 16634 } 16635 } 16636 } 16637 16638 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16639 if (app.foregroundServices) { 16640 // The user is aware of this app, so make it visible. 16641 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16642 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16643 app.cached = false; 16644 app.adjType = "fg-service"; 16645 schedGroup = Process.THREAD_GROUP_DEFAULT; 16646 } else if (app.forcingToForeground != null) { 16647 // The user is aware of this app, so make it visible. 16648 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16649 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16650 app.cached = false; 16651 app.adjType = "force-fg"; 16652 app.adjSource = app.forcingToForeground; 16653 schedGroup = Process.THREAD_GROUP_DEFAULT; 16654 } 16655 } 16656 16657 if (app == mHeavyWeightProcess) { 16658 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16659 // We don't want to kill the current heavy-weight process. 16660 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16661 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16662 app.cached = false; 16663 app.adjType = "heavy"; 16664 } 16665 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16666 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16667 } 16668 } 16669 16670 if (app == mHomeProcess) { 16671 if (adj > ProcessList.HOME_APP_ADJ) { 16672 // This process is hosting what we currently consider to be the 16673 // home app, so we don't want to let it go into the background. 16674 adj = ProcessList.HOME_APP_ADJ; 16675 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16676 app.cached = false; 16677 app.adjType = "home"; 16678 } 16679 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16680 procState = ActivityManager.PROCESS_STATE_HOME; 16681 } 16682 } 16683 16684 if (app == mPreviousProcess && app.activities.size() > 0) { 16685 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16686 // This was the previous process that showed UI to the user. 16687 // We want to try to keep it around more aggressively, to give 16688 // a good experience around switching between two apps. 16689 adj = ProcessList.PREVIOUS_APP_ADJ; 16690 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16691 app.cached = false; 16692 app.adjType = "previous"; 16693 } 16694 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16695 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16696 } 16697 } 16698 16699 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16700 + " reason=" + app.adjType); 16701 16702 // By default, we use the computed adjustment. It may be changed if 16703 // there are applications dependent on our services or providers, but 16704 // this gives us a baseline and makes sure we don't get into an 16705 // infinite recursion. 16706 app.adjSeq = mAdjSeq; 16707 app.curRawAdj = adj; 16708 app.hasStartedServices = false; 16709 16710 if (mBackupTarget != null && app == mBackupTarget.app) { 16711 // If possible we want to avoid killing apps while they're being backed up 16712 if (adj > ProcessList.BACKUP_APP_ADJ) { 16713 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16714 adj = ProcessList.BACKUP_APP_ADJ; 16715 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16716 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16717 } 16718 app.adjType = "backup"; 16719 app.cached = false; 16720 } 16721 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16722 procState = ActivityManager.PROCESS_STATE_BACKUP; 16723 } 16724 } 16725 16726 boolean mayBeTop = false; 16727 16728 for (int is = app.services.size()-1; 16729 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16730 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16731 || procState > ActivityManager.PROCESS_STATE_TOP); 16732 is--) { 16733 ServiceRecord s = app.services.valueAt(is); 16734 if (s.startRequested) { 16735 app.hasStartedServices = true; 16736 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16737 procState = ActivityManager.PROCESS_STATE_SERVICE; 16738 } 16739 if (app.hasShownUi && app != mHomeProcess) { 16740 // If this process has shown some UI, let it immediately 16741 // go to the LRU list because it may be pretty heavy with 16742 // UI stuff. We'll tag it with a label just to help 16743 // debug and understand what is going on. 16744 if (adj > ProcessList.SERVICE_ADJ) { 16745 app.adjType = "cch-started-ui-services"; 16746 } 16747 } else { 16748 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16749 // This service has seen some activity within 16750 // recent memory, so we will keep its process ahead 16751 // of the background processes. 16752 if (adj > ProcessList.SERVICE_ADJ) { 16753 adj = ProcessList.SERVICE_ADJ; 16754 app.adjType = "started-services"; 16755 app.cached = false; 16756 } 16757 } 16758 // If we have let the service slide into the background 16759 // state, still have some text describing what it is doing 16760 // even though the service no longer has an impact. 16761 if (adj > ProcessList.SERVICE_ADJ) { 16762 app.adjType = "cch-started-services"; 16763 } 16764 } 16765 } 16766 for (int conni = s.connections.size()-1; 16767 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16768 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16769 || procState > ActivityManager.PROCESS_STATE_TOP); 16770 conni--) { 16771 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16772 for (int i = 0; 16773 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16774 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16775 || procState > ActivityManager.PROCESS_STATE_TOP); 16776 i++) { 16777 // XXX should compute this based on the max of 16778 // all connected clients. 16779 ConnectionRecord cr = clist.get(i); 16780 if (cr.binding.client == app) { 16781 // Binding to ourself is not interesting. 16782 continue; 16783 } 16784 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16785 ProcessRecord client = cr.binding.client; 16786 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16787 TOP_APP, doingAll, now); 16788 int clientProcState = client.curProcState; 16789 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16790 // If the other app is cached for any reason, for purposes here 16791 // we are going to consider it empty. The specific cached state 16792 // doesn't propagate except under certain conditions. 16793 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16794 } 16795 String adjType = null; 16796 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16797 // Not doing bind OOM management, so treat 16798 // this guy more like a started service. 16799 if (app.hasShownUi && app != mHomeProcess) { 16800 // If this process has shown some UI, let it immediately 16801 // go to the LRU list because it may be pretty heavy with 16802 // UI stuff. We'll tag it with a label just to help 16803 // debug and understand what is going on. 16804 if (adj > clientAdj) { 16805 adjType = "cch-bound-ui-services"; 16806 } 16807 app.cached = false; 16808 clientAdj = adj; 16809 clientProcState = procState; 16810 } else { 16811 if (now >= (s.lastActivity 16812 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16813 // This service has not seen activity within 16814 // recent memory, so allow it to drop to the 16815 // LRU list if there is no other reason to keep 16816 // it around. We'll also tag it with a label just 16817 // to help debug and undertand what is going on. 16818 if (adj > clientAdj) { 16819 adjType = "cch-bound-services"; 16820 } 16821 clientAdj = adj; 16822 } 16823 } 16824 } 16825 if (adj > clientAdj) { 16826 // If this process has recently shown UI, and 16827 // the process that is binding to it is less 16828 // important than being visible, then we don't 16829 // care about the binding as much as we care 16830 // about letting this process get into the LRU 16831 // list to be killed and restarted if needed for 16832 // memory. 16833 if (app.hasShownUi && app != mHomeProcess 16834 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16835 adjType = "cch-bound-ui-services"; 16836 } else { 16837 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16838 |Context.BIND_IMPORTANT)) != 0) { 16839 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16840 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16841 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16842 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16843 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16844 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16845 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16846 adj = clientAdj; 16847 } else { 16848 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16849 adj = ProcessList.VISIBLE_APP_ADJ; 16850 } 16851 } 16852 if (!client.cached) { 16853 app.cached = false; 16854 } 16855 adjType = "service"; 16856 } 16857 } 16858 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16859 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16860 schedGroup = Process.THREAD_GROUP_DEFAULT; 16861 } 16862 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16863 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16864 // Special handling of clients who are in the top state. 16865 // We *may* want to consider this process to be in the 16866 // top state as well, but only if there is not another 16867 // reason for it to be running. Being on the top is a 16868 // special state, meaning you are specifically running 16869 // for the current top app. If the process is already 16870 // running in the background for some other reason, it 16871 // is more important to continue considering it to be 16872 // in the background state. 16873 mayBeTop = true; 16874 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16875 } else { 16876 // Special handling for above-top states (persistent 16877 // processes). These should not bring the current process 16878 // into the top state, since they are not on top. Instead 16879 // give them the best state after that. 16880 clientProcState = 16881 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16882 } 16883 } 16884 } else { 16885 if (clientProcState < 16886 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16887 clientProcState = 16888 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16889 } 16890 } 16891 if (procState > clientProcState) { 16892 procState = clientProcState; 16893 } 16894 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16895 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16896 app.pendingUiClean = true; 16897 } 16898 if (adjType != null) { 16899 app.adjType = adjType; 16900 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16901 .REASON_SERVICE_IN_USE; 16902 app.adjSource = cr.binding.client; 16903 app.adjSourceProcState = clientProcState; 16904 app.adjTarget = s.name; 16905 } 16906 } 16907 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16908 app.treatLikeActivity = true; 16909 } 16910 final ActivityRecord a = cr.activity; 16911 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16912 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16913 (a.visible || a.state == ActivityState.RESUMED 16914 || a.state == ActivityState.PAUSING)) { 16915 adj = ProcessList.FOREGROUND_APP_ADJ; 16916 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16917 schedGroup = Process.THREAD_GROUP_DEFAULT; 16918 } 16919 app.cached = false; 16920 app.adjType = "service"; 16921 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16922 .REASON_SERVICE_IN_USE; 16923 app.adjSource = a; 16924 app.adjSourceProcState = procState; 16925 app.adjTarget = s.name; 16926 } 16927 } 16928 } 16929 } 16930 } 16931 16932 for (int provi = app.pubProviders.size()-1; 16933 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16934 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16935 || procState > ActivityManager.PROCESS_STATE_TOP); 16936 provi--) { 16937 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16938 for (int i = cpr.connections.size()-1; 16939 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16940 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16941 || procState > ActivityManager.PROCESS_STATE_TOP); 16942 i--) { 16943 ContentProviderConnection conn = cpr.connections.get(i); 16944 ProcessRecord client = conn.client; 16945 if (client == app) { 16946 // Being our own client is not interesting. 16947 continue; 16948 } 16949 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16950 int clientProcState = client.curProcState; 16951 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16952 // If the other app is cached for any reason, for purposes here 16953 // we are going to consider it empty. 16954 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16955 } 16956 if (adj > clientAdj) { 16957 if (app.hasShownUi && app != mHomeProcess 16958 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16959 app.adjType = "cch-ui-provider"; 16960 } else { 16961 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16962 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16963 app.adjType = "provider"; 16964 } 16965 app.cached &= client.cached; 16966 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16967 .REASON_PROVIDER_IN_USE; 16968 app.adjSource = client; 16969 app.adjSourceProcState = clientProcState; 16970 app.adjTarget = cpr.name; 16971 } 16972 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16973 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16974 // Special handling of clients who are in the top state. 16975 // We *may* want to consider this process to be in the 16976 // top state as well, but only if there is not another 16977 // reason for it to be running. Being on the top is a 16978 // special state, meaning you are specifically running 16979 // for the current top app. If the process is already 16980 // running in the background for some other reason, it 16981 // is more important to continue considering it to be 16982 // in the background state. 16983 mayBeTop = true; 16984 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16985 } else { 16986 // Special handling for above-top states (persistent 16987 // processes). These should not bring the current process 16988 // into the top state, since they are not on top. Instead 16989 // give them the best state after that. 16990 clientProcState = 16991 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16992 } 16993 } 16994 if (procState > clientProcState) { 16995 procState = clientProcState; 16996 } 16997 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16998 schedGroup = Process.THREAD_GROUP_DEFAULT; 16999 } 17000 } 17001 // If the provider has external (non-framework) process 17002 // dependencies, ensure that its adjustment is at least 17003 // FOREGROUND_APP_ADJ. 17004 if (cpr.hasExternalProcessHandles()) { 17005 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17006 adj = ProcessList.FOREGROUND_APP_ADJ; 17007 schedGroup = Process.THREAD_GROUP_DEFAULT; 17008 app.cached = false; 17009 app.adjType = "provider"; 17010 app.adjTarget = cpr.name; 17011 } 17012 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17013 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17014 } 17015 } 17016 } 17017 17018 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17019 // A client of one of our services or providers is in the top state. We 17020 // *may* want to be in the top state, but not if we are already running in 17021 // the background for some other reason. For the decision here, we are going 17022 // to pick out a few specific states that we want to remain in when a client 17023 // is top (states that tend to be longer-term) and otherwise allow it to go 17024 // to the top state. 17025 switch (procState) { 17026 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17027 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17028 case ActivityManager.PROCESS_STATE_SERVICE: 17029 // These all are longer-term states, so pull them up to the top 17030 // of the background states, but not all the way to the top state. 17031 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17032 break; 17033 default: 17034 // Otherwise, top is a better choice, so take it. 17035 procState = ActivityManager.PROCESS_STATE_TOP; 17036 break; 17037 } 17038 } 17039 17040 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17041 if (app.hasClientActivities) { 17042 // This is a cached process, but with client activities. Mark it so. 17043 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17044 app.adjType = "cch-client-act"; 17045 } else if (app.treatLikeActivity) { 17046 // This is a cached process, but somebody wants us to treat it like it has 17047 // an activity, okay! 17048 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17049 app.adjType = "cch-as-act"; 17050 } 17051 } 17052 17053 if (adj == ProcessList.SERVICE_ADJ) { 17054 if (doingAll) { 17055 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17056 mNewNumServiceProcs++; 17057 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17058 if (!app.serviceb) { 17059 // This service isn't far enough down on the LRU list to 17060 // normally be a B service, but if we are low on RAM and it 17061 // is large we want to force it down since we would prefer to 17062 // keep launcher over it. 17063 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17064 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17065 app.serviceHighRam = true; 17066 app.serviceb = true; 17067 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17068 } else { 17069 mNewNumAServiceProcs++; 17070 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17071 } 17072 } else { 17073 app.serviceHighRam = false; 17074 } 17075 } 17076 if (app.serviceb) { 17077 adj = ProcessList.SERVICE_B_ADJ; 17078 } 17079 } 17080 17081 app.curRawAdj = adj; 17082 17083 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17084 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17085 if (adj > app.maxAdj) { 17086 adj = app.maxAdj; 17087 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17088 schedGroup = Process.THREAD_GROUP_DEFAULT; 17089 } 17090 } 17091 17092 // Do final modification to adj. Everything we do between here and applying 17093 // the final setAdj must be done in this function, because we will also use 17094 // it when computing the final cached adj later. Note that we don't need to 17095 // worry about this for max adj above, since max adj will always be used to 17096 // keep it out of the cached vaues. 17097 app.curAdj = app.modifyRawOomAdj(adj); 17098 app.curSchedGroup = schedGroup; 17099 app.curProcState = procState; 17100 app.foregroundActivities = foregroundActivities; 17101 17102 return app.curRawAdj; 17103 } 17104 17105 /** 17106 * Schedule PSS collection of a process. 17107 */ 17108 void requestPssLocked(ProcessRecord proc, int procState) { 17109 if (mPendingPssProcesses.contains(proc)) { 17110 return; 17111 } 17112 if (mPendingPssProcesses.size() == 0) { 17113 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17114 } 17115 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17116 proc.pssProcState = procState; 17117 mPendingPssProcesses.add(proc); 17118 } 17119 17120 /** 17121 * Schedule PSS collection of all processes. 17122 */ 17123 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17124 if (!always) { 17125 if (now < (mLastFullPssTime + 17126 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17127 return; 17128 } 17129 } 17130 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17131 mLastFullPssTime = now; 17132 mFullPssPending = true; 17133 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17134 mPendingPssProcesses.clear(); 17135 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17136 ProcessRecord app = mLruProcesses.get(i); 17137 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17138 app.pssProcState = app.setProcState; 17139 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17140 isSleeping(), now); 17141 mPendingPssProcesses.add(app); 17142 } 17143 } 17144 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17145 } 17146 17147 /** 17148 * Ask a given process to GC right now. 17149 */ 17150 final void performAppGcLocked(ProcessRecord app) { 17151 try { 17152 app.lastRequestedGc = SystemClock.uptimeMillis(); 17153 if (app.thread != null) { 17154 if (app.reportLowMemory) { 17155 app.reportLowMemory = false; 17156 app.thread.scheduleLowMemory(); 17157 } else { 17158 app.thread.processInBackground(); 17159 } 17160 } 17161 } catch (Exception e) { 17162 // whatever. 17163 } 17164 } 17165 17166 /** 17167 * Returns true if things are idle enough to perform GCs. 17168 */ 17169 private final boolean canGcNowLocked() { 17170 boolean processingBroadcasts = false; 17171 for (BroadcastQueue q : mBroadcastQueues) { 17172 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17173 processingBroadcasts = true; 17174 } 17175 } 17176 return !processingBroadcasts 17177 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17178 } 17179 17180 /** 17181 * Perform GCs on all processes that are waiting for it, but only 17182 * if things are idle. 17183 */ 17184 final void performAppGcsLocked() { 17185 final int N = mProcessesToGc.size(); 17186 if (N <= 0) { 17187 return; 17188 } 17189 if (canGcNowLocked()) { 17190 while (mProcessesToGc.size() > 0) { 17191 ProcessRecord proc = mProcessesToGc.remove(0); 17192 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17193 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17194 <= SystemClock.uptimeMillis()) { 17195 // To avoid spamming the system, we will GC processes one 17196 // at a time, waiting a few seconds between each. 17197 performAppGcLocked(proc); 17198 scheduleAppGcsLocked(); 17199 return; 17200 } else { 17201 // It hasn't been long enough since we last GCed this 17202 // process... put it in the list to wait for its time. 17203 addProcessToGcListLocked(proc); 17204 break; 17205 } 17206 } 17207 } 17208 17209 scheduleAppGcsLocked(); 17210 } 17211 } 17212 17213 /** 17214 * If all looks good, perform GCs on all processes waiting for them. 17215 */ 17216 final void performAppGcsIfAppropriateLocked() { 17217 if (canGcNowLocked()) { 17218 performAppGcsLocked(); 17219 return; 17220 } 17221 // Still not idle, wait some more. 17222 scheduleAppGcsLocked(); 17223 } 17224 17225 /** 17226 * Schedule the execution of all pending app GCs. 17227 */ 17228 final void scheduleAppGcsLocked() { 17229 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17230 17231 if (mProcessesToGc.size() > 0) { 17232 // Schedule a GC for the time to the next process. 17233 ProcessRecord proc = mProcessesToGc.get(0); 17234 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17235 17236 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17237 long now = SystemClock.uptimeMillis(); 17238 if (when < (now+GC_TIMEOUT)) { 17239 when = now + GC_TIMEOUT; 17240 } 17241 mHandler.sendMessageAtTime(msg, when); 17242 } 17243 } 17244 17245 /** 17246 * Add a process to the array of processes waiting to be GCed. Keeps the 17247 * list in sorted order by the last GC time. The process can't already be 17248 * on the list. 17249 */ 17250 final void addProcessToGcListLocked(ProcessRecord proc) { 17251 boolean added = false; 17252 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17253 if (mProcessesToGc.get(i).lastRequestedGc < 17254 proc.lastRequestedGc) { 17255 added = true; 17256 mProcessesToGc.add(i+1, proc); 17257 break; 17258 } 17259 } 17260 if (!added) { 17261 mProcessesToGc.add(0, proc); 17262 } 17263 } 17264 17265 /** 17266 * Set up to ask a process to GC itself. This will either do it 17267 * immediately, or put it on the list of processes to gc the next 17268 * time things are idle. 17269 */ 17270 final void scheduleAppGcLocked(ProcessRecord app) { 17271 long now = SystemClock.uptimeMillis(); 17272 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17273 return; 17274 } 17275 if (!mProcessesToGc.contains(app)) { 17276 addProcessToGcListLocked(app); 17277 scheduleAppGcsLocked(); 17278 } 17279 } 17280 17281 final void checkExcessivePowerUsageLocked(boolean doKills) { 17282 updateCpuStatsNow(); 17283 17284 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17285 boolean doWakeKills = doKills; 17286 boolean doCpuKills = doKills; 17287 if (mLastPowerCheckRealtime == 0) { 17288 doWakeKills = false; 17289 } 17290 if (mLastPowerCheckUptime == 0) { 17291 doCpuKills = false; 17292 } 17293 if (stats.isScreenOn()) { 17294 doWakeKills = false; 17295 } 17296 final long curRealtime = SystemClock.elapsedRealtime(); 17297 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17298 final long curUptime = SystemClock.uptimeMillis(); 17299 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17300 mLastPowerCheckRealtime = curRealtime; 17301 mLastPowerCheckUptime = curUptime; 17302 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17303 doWakeKills = false; 17304 } 17305 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17306 doCpuKills = false; 17307 } 17308 int i = mLruProcesses.size(); 17309 while (i > 0) { 17310 i--; 17311 ProcessRecord app = mLruProcesses.get(i); 17312 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17313 long wtime; 17314 synchronized (stats) { 17315 wtime = stats.getProcessWakeTime(app.info.uid, 17316 app.pid, curRealtime); 17317 } 17318 long wtimeUsed = wtime - app.lastWakeTime; 17319 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17320 if (DEBUG_POWER) { 17321 StringBuilder sb = new StringBuilder(128); 17322 sb.append("Wake for "); 17323 app.toShortString(sb); 17324 sb.append(": over "); 17325 TimeUtils.formatDuration(realtimeSince, sb); 17326 sb.append(" used "); 17327 TimeUtils.formatDuration(wtimeUsed, sb); 17328 sb.append(" ("); 17329 sb.append((wtimeUsed*100)/realtimeSince); 17330 sb.append("%)"); 17331 Slog.i(TAG, sb.toString()); 17332 sb.setLength(0); 17333 sb.append("CPU for "); 17334 app.toShortString(sb); 17335 sb.append(": over "); 17336 TimeUtils.formatDuration(uptimeSince, sb); 17337 sb.append(" used "); 17338 TimeUtils.formatDuration(cputimeUsed, sb); 17339 sb.append(" ("); 17340 sb.append((cputimeUsed*100)/uptimeSince); 17341 sb.append("%)"); 17342 Slog.i(TAG, sb.toString()); 17343 } 17344 // If a process has held a wake lock for more 17345 // than 50% of the time during this period, 17346 // that sounds bad. Kill! 17347 if (doWakeKills && realtimeSince > 0 17348 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17349 synchronized (stats) { 17350 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17351 realtimeSince, wtimeUsed); 17352 } 17353 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17354 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17355 } else if (doCpuKills && uptimeSince > 0 17356 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17357 synchronized (stats) { 17358 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17359 uptimeSince, cputimeUsed); 17360 } 17361 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17362 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17363 } else { 17364 app.lastWakeTime = wtime; 17365 app.lastCpuTime = app.curCpuTime; 17366 } 17367 } 17368 } 17369 } 17370 17371 private final boolean applyOomAdjLocked(ProcessRecord app, 17372 ProcessRecord TOP_APP, boolean doingAll, long now) { 17373 boolean success = true; 17374 17375 if (app.curRawAdj != app.setRawAdj) { 17376 app.setRawAdj = app.curRawAdj; 17377 } 17378 17379 int changes = 0; 17380 17381 if (app.curAdj != app.setAdj) { 17382 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17383 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17384 TAG, "Set " + app.pid + " " + app.processName + 17385 " adj " + app.curAdj + ": " + app.adjType); 17386 app.setAdj = app.curAdj; 17387 } 17388 17389 if (app.setSchedGroup != app.curSchedGroup) { 17390 app.setSchedGroup = app.curSchedGroup; 17391 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17392 "Setting process group of " + app.processName 17393 + " to " + app.curSchedGroup); 17394 if (app.waitingToKill != null && 17395 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17396 app.kill(app.waitingToKill, true); 17397 success = false; 17398 } else { 17399 if (true) { 17400 long oldId = Binder.clearCallingIdentity(); 17401 try { 17402 Process.setProcessGroup(app.pid, app.curSchedGroup); 17403 } catch (Exception e) { 17404 Slog.w(TAG, "Failed setting process group of " + app.pid 17405 + " to " + app.curSchedGroup); 17406 e.printStackTrace(); 17407 } finally { 17408 Binder.restoreCallingIdentity(oldId); 17409 } 17410 } else { 17411 if (app.thread != null) { 17412 try { 17413 app.thread.setSchedulingGroup(app.curSchedGroup); 17414 } catch (RemoteException e) { 17415 } 17416 } 17417 } 17418 Process.setSwappiness(app.pid, 17419 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17420 } 17421 } 17422 if (app.repForegroundActivities != app.foregroundActivities) { 17423 app.repForegroundActivities = app.foregroundActivities; 17424 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17425 } 17426 if (app.repProcState != app.curProcState) { 17427 app.repProcState = app.curProcState; 17428 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17429 if (app.thread != null) { 17430 try { 17431 if (false) { 17432 //RuntimeException h = new RuntimeException("here"); 17433 Slog.i(TAG, "Sending new process state " + app.repProcState 17434 + " to " + app /*, h*/); 17435 } 17436 app.thread.setProcessState(app.repProcState); 17437 } catch (RemoteException e) { 17438 } 17439 } 17440 } 17441 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17442 app.setProcState)) { 17443 app.lastStateTime = now; 17444 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17445 isSleeping(), now); 17446 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17447 + ProcessList.makeProcStateString(app.setProcState) + " to " 17448 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17449 + (app.nextPssTime-now) + ": " + app); 17450 } else { 17451 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17452 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17453 requestPssLocked(app, app.setProcState); 17454 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17455 isSleeping(), now); 17456 } else if (false && DEBUG_PSS) { 17457 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17458 } 17459 } 17460 if (app.setProcState != app.curProcState) { 17461 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17462 "Proc state change of " + app.processName 17463 + " to " + app.curProcState); 17464 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17465 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17466 if (setImportant && !curImportant) { 17467 // This app is no longer something we consider important enough to allow to 17468 // use arbitrary amounts of battery power. Note 17469 // its current wake lock time to later know to kill it if 17470 // it is not behaving well. 17471 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17472 synchronized (stats) { 17473 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17474 app.pid, SystemClock.elapsedRealtime()); 17475 } 17476 app.lastCpuTime = app.curCpuTime; 17477 17478 } 17479 app.setProcState = app.curProcState; 17480 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17481 app.notCachedSinceIdle = false; 17482 } 17483 if (!doingAll) { 17484 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17485 } else { 17486 app.procStateChanged = true; 17487 } 17488 } 17489 17490 if (changes != 0) { 17491 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17492 int i = mPendingProcessChanges.size()-1; 17493 ProcessChangeItem item = null; 17494 while (i >= 0) { 17495 item = mPendingProcessChanges.get(i); 17496 if (item.pid == app.pid) { 17497 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17498 break; 17499 } 17500 i--; 17501 } 17502 if (i < 0) { 17503 // No existing item in pending changes; need a new one. 17504 final int NA = mAvailProcessChanges.size(); 17505 if (NA > 0) { 17506 item = mAvailProcessChanges.remove(NA-1); 17507 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17508 } else { 17509 item = new ProcessChangeItem(); 17510 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17511 } 17512 item.changes = 0; 17513 item.pid = app.pid; 17514 item.uid = app.info.uid; 17515 if (mPendingProcessChanges.size() == 0) { 17516 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17517 "*** Enqueueing dispatch processes changed!"); 17518 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17519 } 17520 mPendingProcessChanges.add(item); 17521 } 17522 item.changes |= changes; 17523 item.processState = app.repProcState; 17524 item.foregroundActivities = app.repForegroundActivities; 17525 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17526 + Integer.toHexString(System.identityHashCode(item)) 17527 + " " + app.toShortString() + ": changes=" + item.changes 17528 + " procState=" + item.processState 17529 + " foreground=" + item.foregroundActivities 17530 + " type=" + app.adjType + " source=" + app.adjSource 17531 + " target=" + app.adjTarget); 17532 } 17533 17534 return success; 17535 } 17536 17537 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17538 if (proc.thread != null) { 17539 if (proc.baseProcessTracker != null) { 17540 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17541 } 17542 if (proc.repProcState >= 0) { 17543 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17544 proc.repProcState); 17545 } 17546 } 17547 } 17548 17549 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17550 ProcessRecord TOP_APP, boolean doingAll, long now) { 17551 if (app.thread == null) { 17552 return false; 17553 } 17554 17555 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17556 17557 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17558 } 17559 17560 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17561 boolean oomAdj) { 17562 if (isForeground != proc.foregroundServices) { 17563 proc.foregroundServices = isForeground; 17564 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17565 proc.info.uid); 17566 if (isForeground) { 17567 if (curProcs == null) { 17568 curProcs = new ArrayList<ProcessRecord>(); 17569 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17570 } 17571 if (!curProcs.contains(proc)) { 17572 curProcs.add(proc); 17573 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17574 proc.info.packageName, proc.info.uid); 17575 } 17576 } else { 17577 if (curProcs != null) { 17578 if (curProcs.remove(proc)) { 17579 mBatteryStatsService.noteEvent( 17580 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17581 proc.info.packageName, proc.info.uid); 17582 if (curProcs.size() <= 0) { 17583 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17584 } 17585 } 17586 } 17587 } 17588 if (oomAdj) { 17589 updateOomAdjLocked(); 17590 } 17591 } 17592 } 17593 17594 private final ActivityRecord resumedAppLocked() { 17595 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17596 String pkg; 17597 int uid; 17598 if (act != null) { 17599 pkg = act.packageName; 17600 uid = act.info.applicationInfo.uid; 17601 } else { 17602 pkg = null; 17603 uid = -1; 17604 } 17605 // Has the UID or resumed package name changed? 17606 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17607 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17608 if (mCurResumedPackage != null) { 17609 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17610 mCurResumedPackage, mCurResumedUid); 17611 } 17612 mCurResumedPackage = pkg; 17613 mCurResumedUid = uid; 17614 if (mCurResumedPackage != null) { 17615 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17616 mCurResumedPackage, mCurResumedUid); 17617 } 17618 } 17619 return act; 17620 } 17621 17622 final boolean updateOomAdjLocked(ProcessRecord app) { 17623 final ActivityRecord TOP_ACT = resumedAppLocked(); 17624 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17625 final boolean wasCached = app.cached; 17626 17627 mAdjSeq++; 17628 17629 // This is the desired cached adjusment we want to tell it to use. 17630 // If our app is currently cached, we know it, and that is it. Otherwise, 17631 // we don't know it yet, and it needs to now be cached we will then 17632 // need to do a complete oom adj. 17633 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17634 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17635 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17636 SystemClock.uptimeMillis()); 17637 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17638 // Changed to/from cached state, so apps after it in the LRU 17639 // list may also be changed. 17640 updateOomAdjLocked(); 17641 } 17642 return success; 17643 } 17644 17645 final void updateOomAdjLocked() { 17646 final ActivityRecord TOP_ACT = resumedAppLocked(); 17647 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17648 final long now = SystemClock.uptimeMillis(); 17649 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17650 final int N = mLruProcesses.size(); 17651 17652 if (false) { 17653 RuntimeException e = new RuntimeException(); 17654 e.fillInStackTrace(); 17655 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17656 } 17657 17658 mAdjSeq++; 17659 mNewNumServiceProcs = 0; 17660 mNewNumAServiceProcs = 0; 17661 17662 final int emptyProcessLimit; 17663 final int cachedProcessLimit; 17664 if (mProcessLimit <= 0) { 17665 emptyProcessLimit = cachedProcessLimit = 0; 17666 } else if (mProcessLimit == 1) { 17667 emptyProcessLimit = 1; 17668 cachedProcessLimit = 0; 17669 } else { 17670 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17671 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17672 } 17673 17674 // Let's determine how many processes we have running vs. 17675 // how many slots we have for background processes; we may want 17676 // to put multiple processes in a slot of there are enough of 17677 // them. 17678 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17679 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17680 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17681 if (numEmptyProcs > cachedProcessLimit) { 17682 // If there are more empty processes than our limit on cached 17683 // processes, then use the cached process limit for the factor. 17684 // This ensures that the really old empty processes get pushed 17685 // down to the bottom, so if we are running low on memory we will 17686 // have a better chance at keeping around more cached processes 17687 // instead of a gazillion empty processes. 17688 numEmptyProcs = cachedProcessLimit; 17689 } 17690 int emptyFactor = numEmptyProcs/numSlots; 17691 if (emptyFactor < 1) emptyFactor = 1; 17692 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17693 if (cachedFactor < 1) cachedFactor = 1; 17694 int stepCached = 0; 17695 int stepEmpty = 0; 17696 int numCached = 0; 17697 int numEmpty = 0; 17698 int numTrimming = 0; 17699 17700 mNumNonCachedProcs = 0; 17701 mNumCachedHiddenProcs = 0; 17702 17703 // First update the OOM adjustment for each of the 17704 // application processes based on their current state. 17705 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17706 int nextCachedAdj = curCachedAdj+1; 17707 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17708 int nextEmptyAdj = curEmptyAdj+2; 17709 for (int i=N-1; i>=0; i--) { 17710 ProcessRecord app = mLruProcesses.get(i); 17711 if (!app.killedByAm && app.thread != null) { 17712 app.procStateChanged = false; 17713 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17714 17715 // If we haven't yet assigned the final cached adj 17716 // to the process, do that now. 17717 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17718 switch (app.curProcState) { 17719 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17720 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17721 // This process is a cached process holding activities... 17722 // assign it the next cached value for that type, and then 17723 // step that cached level. 17724 app.curRawAdj = curCachedAdj; 17725 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17726 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17727 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17728 + ")"); 17729 if (curCachedAdj != nextCachedAdj) { 17730 stepCached++; 17731 if (stepCached >= cachedFactor) { 17732 stepCached = 0; 17733 curCachedAdj = nextCachedAdj; 17734 nextCachedAdj += 2; 17735 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17736 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17737 } 17738 } 17739 } 17740 break; 17741 default: 17742 // For everything else, assign next empty cached process 17743 // level and bump that up. Note that this means that 17744 // long-running services that have dropped down to the 17745 // cached level will be treated as empty (since their process 17746 // state is still as a service), which is what we want. 17747 app.curRawAdj = curEmptyAdj; 17748 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17749 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17750 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17751 + ")"); 17752 if (curEmptyAdj != nextEmptyAdj) { 17753 stepEmpty++; 17754 if (stepEmpty >= emptyFactor) { 17755 stepEmpty = 0; 17756 curEmptyAdj = nextEmptyAdj; 17757 nextEmptyAdj += 2; 17758 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17759 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17760 } 17761 } 17762 } 17763 break; 17764 } 17765 } 17766 17767 applyOomAdjLocked(app, TOP_APP, true, now); 17768 17769 // Count the number of process types. 17770 switch (app.curProcState) { 17771 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17772 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17773 mNumCachedHiddenProcs++; 17774 numCached++; 17775 if (numCached > cachedProcessLimit) { 17776 app.kill("cached #" + numCached, true); 17777 } 17778 break; 17779 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17780 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17781 && app.lastActivityTime < oldTime) { 17782 app.kill("empty for " 17783 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17784 / 1000) + "s", true); 17785 } else { 17786 numEmpty++; 17787 if (numEmpty > emptyProcessLimit) { 17788 app.kill("empty #" + numEmpty, true); 17789 } 17790 } 17791 break; 17792 default: 17793 mNumNonCachedProcs++; 17794 break; 17795 } 17796 17797 if (app.isolated && app.services.size() <= 0) { 17798 // If this is an isolated process, and there are no 17799 // services running in it, then the process is no longer 17800 // needed. We agressively kill these because we can by 17801 // definition not re-use the same process again, and it is 17802 // good to avoid having whatever code was running in them 17803 // left sitting around after no longer needed. 17804 app.kill("isolated not needed", true); 17805 } 17806 17807 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17808 && !app.killedByAm) { 17809 numTrimming++; 17810 } 17811 } 17812 } 17813 17814 mNumServiceProcs = mNewNumServiceProcs; 17815 17816 // Now determine the memory trimming level of background processes. 17817 // Unfortunately we need to start at the back of the list to do this 17818 // properly. We only do this if the number of background apps we 17819 // are managing to keep around is less than half the maximum we desire; 17820 // if we are keeping a good number around, we'll let them use whatever 17821 // memory they want. 17822 final int numCachedAndEmpty = numCached + numEmpty; 17823 int memFactor; 17824 if (numCached <= ProcessList.TRIM_CACHED_APPS 17825 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17826 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17827 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17828 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17829 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17830 } else { 17831 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17832 } 17833 } else { 17834 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17835 } 17836 // We always allow the memory level to go up (better). We only allow it to go 17837 // down if we are in a state where that is allowed, *and* the total number of processes 17838 // has gone down since last time. 17839 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17840 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17841 + " last=" + mLastNumProcesses); 17842 if (memFactor > mLastMemoryLevel) { 17843 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17844 memFactor = mLastMemoryLevel; 17845 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17846 } 17847 } 17848 mLastMemoryLevel = memFactor; 17849 mLastNumProcesses = mLruProcesses.size(); 17850 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17851 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17852 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17853 if (mLowRamStartTime == 0) { 17854 mLowRamStartTime = now; 17855 } 17856 int step = 0; 17857 int fgTrimLevel; 17858 switch (memFactor) { 17859 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17860 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17861 break; 17862 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17863 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17864 break; 17865 default: 17866 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17867 break; 17868 } 17869 int factor = numTrimming/3; 17870 int minFactor = 2; 17871 if (mHomeProcess != null) minFactor++; 17872 if (mPreviousProcess != null) minFactor++; 17873 if (factor < minFactor) factor = minFactor; 17874 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17875 for (int i=N-1; i>=0; i--) { 17876 ProcessRecord app = mLruProcesses.get(i); 17877 if (allChanged || app.procStateChanged) { 17878 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17879 app.procStateChanged = false; 17880 } 17881 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17882 && !app.killedByAm) { 17883 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17884 try { 17885 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17886 "Trimming memory of " + app.processName 17887 + " to " + curLevel); 17888 app.thread.scheduleTrimMemory(curLevel); 17889 } catch (RemoteException e) { 17890 } 17891 if (false) { 17892 // For now we won't do this; our memory trimming seems 17893 // to be good enough at this point that destroying 17894 // activities causes more harm than good. 17895 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17896 && app != mHomeProcess && app != mPreviousProcess) { 17897 // Need to do this on its own message because the stack may not 17898 // be in a consistent state at this point. 17899 // For these apps we will also finish their activities 17900 // to help them free memory. 17901 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17902 } 17903 } 17904 } 17905 app.trimMemoryLevel = curLevel; 17906 step++; 17907 if (step >= factor) { 17908 step = 0; 17909 switch (curLevel) { 17910 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17911 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17912 break; 17913 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17914 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17915 break; 17916 } 17917 } 17918 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17919 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17920 && app.thread != null) { 17921 try { 17922 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17923 "Trimming memory of heavy-weight " + app.processName 17924 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17925 app.thread.scheduleTrimMemory( 17926 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17927 } catch (RemoteException e) { 17928 } 17929 } 17930 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17931 } else { 17932 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17933 || app.systemNoUi) && app.pendingUiClean) { 17934 // If this application is now in the background and it 17935 // had done UI, then give it the special trim level to 17936 // have it free UI resources. 17937 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17938 if (app.trimMemoryLevel < level && app.thread != null) { 17939 try { 17940 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17941 "Trimming memory of bg-ui " + app.processName 17942 + " to " + level); 17943 app.thread.scheduleTrimMemory(level); 17944 } catch (RemoteException e) { 17945 } 17946 } 17947 app.pendingUiClean = false; 17948 } 17949 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17950 try { 17951 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17952 "Trimming memory of fg " + app.processName 17953 + " to " + fgTrimLevel); 17954 app.thread.scheduleTrimMemory(fgTrimLevel); 17955 } catch (RemoteException e) { 17956 } 17957 } 17958 app.trimMemoryLevel = fgTrimLevel; 17959 } 17960 } 17961 } else { 17962 if (mLowRamStartTime != 0) { 17963 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17964 mLowRamStartTime = 0; 17965 } 17966 for (int i=N-1; i>=0; i--) { 17967 ProcessRecord app = mLruProcesses.get(i); 17968 if (allChanged || app.procStateChanged) { 17969 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17970 app.procStateChanged = false; 17971 } 17972 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17973 || app.systemNoUi) && app.pendingUiClean) { 17974 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17975 && app.thread != null) { 17976 try { 17977 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17978 "Trimming memory of ui hidden " + app.processName 17979 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17980 app.thread.scheduleTrimMemory( 17981 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17982 } catch (RemoteException e) { 17983 } 17984 } 17985 app.pendingUiClean = false; 17986 } 17987 app.trimMemoryLevel = 0; 17988 } 17989 } 17990 17991 if (mAlwaysFinishActivities) { 17992 // Need to do this on its own message because the stack may not 17993 // be in a consistent state at this point. 17994 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17995 } 17996 17997 if (allChanged) { 17998 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17999 } 18000 18001 if (mProcessStats.shouldWriteNowLocked(now)) { 18002 mHandler.post(new Runnable() { 18003 @Override public void run() { 18004 synchronized (ActivityManagerService.this) { 18005 mProcessStats.writeStateAsyncLocked(); 18006 } 18007 } 18008 }); 18009 } 18010 18011 if (DEBUG_OOM_ADJ) { 18012 if (false) { 18013 RuntimeException here = new RuntimeException("here"); 18014 here.fillInStackTrace(); 18015 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18016 } else { 18017 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18018 } 18019 } 18020 } 18021 18022 final void trimApplications() { 18023 synchronized (this) { 18024 int i; 18025 18026 // First remove any unused application processes whose package 18027 // has been removed. 18028 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18029 final ProcessRecord app = mRemovedProcesses.get(i); 18030 if (app.activities.size() == 0 18031 && app.curReceiver == null && app.services.size() == 0) { 18032 Slog.i( 18033 TAG, "Exiting empty application process " 18034 + app.processName + " (" 18035 + (app.thread != null ? app.thread.asBinder() : null) 18036 + ")\n"); 18037 if (app.pid > 0 && app.pid != MY_PID) { 18038 app.kill("empty", false); 18039 } else { 18040 try { 18041 app.thread.scheduleExit(); 18042 } catch (Exception e) { 18043 // Ignore exceptions. 18044 } 18045 } 18046 cleanUpApplicationRecordLocked(app, false, true, -1); 18047 mRemovedProcesses.remove(i); 18048 18049 if (app.persistent) { 18050 addAppLocked(app.info, false, null /* ABI override */); 18051 } 18052 } 18053 } 18054 18055 // Now update the oom adj for all processes. 18056 updateOomAdjLocked(); 18057 } 18058 } 18059 18060 /** This method sends the specified signal to each of the persistent apps */ 18061 public void signalPersistentProcesses(int sig) throws RemoteException { 18062 if (sig != Process.SIGNAL_USR1) { 18063 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18064 } 18065 18066 synchronized (this) { 18067 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18068 != PackageManager.PERMISSION_GRANTED) { 18069 throw new SecurityException("Requires permission " 18070 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18071 } 18072 18073 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18074 ProcessRecord r = mLruProcesses.get(i); 18075 if (r.thread != null && r.persistent) { 18076 Process.sendSignal(r.pid, sig); 18077 } 18078 } 18079 } 18080 } 18081 18082 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18083 if (proc == null || proc == mProfileProc) { 18084 proc = mProfileProc; 18085 profileType = mProfileType; 18086 clearProfilerLocked(); 18087 } 18088 if (proc == null) { 18089 return; 18090 } 18091 try { 18092 proc.thread.profilerControl(false, null, profileType); 18093 } catch (RemoteException e) { 18094 throw new IllegalStateException("Process disappeared"); 18095 } 18096 } 18097 18098 private void clearProfilerLocked() { 18099 if (mProfileFd != null) { 18100 try { 18101 mProfileFd.close(); 18102 } catch (IOException e) { 18103 } 18104 } 18105 mProfileApp = null; 18106 mProfileProc = null; 18107 mProfileFile = null; 18108 mProfileType = 0; 18109 mAutoStopProfiler = false; 18110 mSamplingInterval = 0; 18111 } 18112 18113 public boolean profileControl(String process, int userId, boolean start, 18114 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18115 18116 try { 18117 synchronized (this) { 18118 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18119 // its own permission. 18120 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18121 != PackageManager.PERMISSION_GRANTED) { 18122 throw new SecurityException("Requires permission " 18123 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18124 } 18125 18126 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18127 throw new IllegalArgumentException("null profile info or fd"); 18128 } 18129 18130 ProcessRecord proc = null; 18131 if (process != null) { 18132 proc = findProcessLocked(process, userId, "profileControl"); 18133 } 18134 18135 if (start && (proc == null || proc.thread == null)) { 18136 throw new IllegalArgumentException("Unknown process: " + process); 18137 } 18138 18139 if (start) { 18140 stopProfilerLocked(null, 0); 18141 setProfileApp(proc.info, proc.processName, profilerInfo); 18142 mProfileProc = proc; 18143 mProfileType = profileType; 18144 ParcelFileDescriptor fd = profilerInfo.profileFd; 18145 try { 18146 fd = fd.dup(); 18147 } catch (IOException e) { 18148 fd = null; 18149 } 18150 profilerInfo.profileFd = fd; 18151 proc.thread.profilerControl(start, profilerInfo, profileType); 18152 fd = null; 18153 mProfileFd = null; 18154 } else { 18155 stopProfilerLocked(proc, profileType); 18156 if (profilerInfo != null && profilerInfo.profileFd != null) { 18157 try { 18158 profilerInfo.profileFd.close(); 18159 } catch (IOException e) { 18160 } 18161 } 18162 } 18163 18164 return true; 18165 } 18166 } catch (RemoteException e) { 18167 throw new IllegalStateException("Process disappeared"); 18168 } finally { 18169 if (profilerInfo != null && profilerInfo.profileFd != null) { 18170 try { 18171 profilerInfo.profileFd.close(); 18172 } catch (IOException e) { 18173 } 18174 } 18175 } 18176 } 18177 18178 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18179 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18180 userId, true, ALLOW_FULL_ONLY, callName, null); 18181 ProcessRecord proc = null; 18182 try { 18183 int pid = Integer.parseInt(process); 18184 synchronized (mPidsSelfLocked) { 18185 proc = mPidsSelfLocked.get(pid); 18186 } 18187 } catch (NumberFormatException e) { 18188 } 18189 18190 if (proc == null) { 18191 ArrayMap<String, SparseArray<ProcessRecord>> all 18192 = mProcessNames.getMap(); 18193 SparseArray<ProcessRecord> procs = all.get(process); 18194 if (procs != null && procs.size() > 0) { 18195 proc = procs.valueAt(0); 18196 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18197 for (int i=1; i<procs.size(); i++) { 18198 ProcessRecord thisProc = procs.valueAt(i); 18199 if (thisProc.userId == userId) { 18200 proc = thisProc; 18201 break; 18202 } 18203 } 18204 } 18205 } 18206 } 18207 18208 return proc; 18209 } 18210 18211 public boolean dumpHeap(String process, int userId, boolean managed, 18212 String path, ParcelFileDescriptor fd) throws RemoteException { 18213 18214 try { 18215 synchronized (this) { 18216 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18217 // its own permission (same as profileControl). 18218 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18219 != PackageManager.PERMISSION_GRANTED) { 18220 throw new SecurityException("Requires permission " 18221 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18222 } 18223 18224 if (fd == null) { 18225 throw new IllegalArgumentException("null fd"); 18226 } 18227 18228 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18229 if (proc == null || proc.thread == null) { 18230 throw new IllegalArgumentException("Unknown process: " + process); 18231 } 18232 18233 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18234 if (!isDebuggable) { 18235 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18236 throw new SecurityException("Process not debuggable: " + proc); 18237 } 18238 } 18239 18240 proc.thread.dumpHeap(managed, path, fd); 18241 fd = null; 18242 return true; 18243 } 18244 } catch (RemoteException e) { 18245 throw new IllegalStateException("Process disappeared"); 18246 } finally { 18247 if (fd != null) { 18248 try { 18249 fd.close(); 18250 } catch (IOException e) { 18251 } 18252 } 18253 } 18254 } 18255 18256 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18257 public void monitor() { 18258 synchronized (this) { } 18259 } 18260 18261 void onCoreSettingsChange(Bundle settings) { 18262 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18263 ProcessRecord processRecord = mLruProcesses.get(i); 18264 try { 18265 if (processRecord.thread != null) { 18266 processRecord.thread.setCoreSettings(settings); 18267 } 18268 } catch (RemoteException re) { 18269 /* ignore */ 18270 } 18271 } 18272 } 18273 18274 // Multi-user methods 18275 18276 /** 18277 * Start user, if its not already running, but don't bring it to foreground. 18278 */ 18279 @Override 18280 public boolean startUserInBackground(final int userId) { 18281 return startUser(userId, /* foreground */ false); 18282 } 18283 18284 /** 18285 * Start user, if its not already running, and bring it to foreground. 18286 */ 18287 boolean startUserInForeground(final int userId, Dialog dlg) { 18288 boolean result = startUser(userId, /* foreground */ true); 18289 dlg.dismiss(); 18290 return result; 18291 } 18292 18293 /** 18294 * Refreshes the list of users related to the current user when either a 18295 * user switch happens or when a new related user is started in the 18296 * background. 18297 */ 18298 private void updateCurrentProfileIdsLocked() { 18299 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18300 mCurrentUserId, false /* enabledOnly */); 18301 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18302 for (int i = 0; i < currentProfileIds.length; i++) { 18303 currentProfileIds[i] = profiles.get(i).id; 18304 } 18305 mCurrentProfileIds = currentProfileIds; 18306 18307 synchronized (mUserProfileGroupIdsSelfLocked) { 18308 mUserProfileGroupIdsSelfLocked.clear(); 18309 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18310 for (int i = 0; i < users.size(); i++) { 18311 UserInfo user = users.get(i); 18312 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18313 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18314 } 18315 } 18316 } 18317 } 18318 18319 private Set getProfileIdsLocked(int userId) { 18320 Set userIds = new HashSet<Integer>(); 18321 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18322 userId, false /* enabledOnly */); 18323 for (UserInfo user : profiles) { 18324 userIds.add(Integer.valueOf(user.id)); 18325 } 18326 return userIds; 18327 } 18328 18329 @Override 18330 public boolean switchUser(final int userId) { 18331 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18332 String userName; 18333 synchronized (this) { 18334 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18335 if (userInfo == null) { 18336 Slog.w(TAG, "No user info for user #" + userId); 18337 return false; 18338 } 18339 if (userInfo.isManagedProfile()) { 18340 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18341 return false; 18342 } 18343 userName = userInfo.name; 18344 mTargetUserId = userId; 18345 } 18346 mHandler.removeMessages(START_USER_SWITCH_MSG); 18347 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18348 return true; 18349 } 18350 18351 private void showUserSwitchDialog(int userId, String userName) { 18352 // The dialog will show and then initiate the user switch by calling startUserInForeground 18353 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18354 true /* above system */); 18355 d.show(); 18356 } 18357 18358 private boolean startUser(final int userId, final boolean foreground) { 18359 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18360 != PackageManager.PERMISSION_GRANTED) { 18361 String msg = "Permission Denial: switchUser() from pid=" 18362 + Binder.getCallingPid() 18363 + ", uid=" + Binder.getCallingUid() 18364 + " requires " + INTERACT_ACROSS_USERS_FULL; 18365 Slog.w(TAG, msg); 18366 throw new SecurityException(msg); 18367 } 18368 18369 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18370 18371 final long ident = Binder.clearCallingIdentity(); 18372 try { 18373 synchronized (this) { 18374 final int oldUserId = mCurrentUserId; 18375 if (oldUserId == userId) { 18376 return true; 18377 } 18378 18379 mStackSupervisor.setLockTaskModeLocked(null, false); 18380 18381 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18382 if (userInfo == null) { 18383 Slog.w(TAG, "No user info for user #" + userId); 18384 return false; 18385 } 18386 if (foreground && userInfo.isManagedProfile()) { 18387 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18388 return false; 18389 } 18390 18391 if (foreground) { 18392 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18393 R.anim.screen_user_enter); 18394 } 18395 18396 boolean needStart = false; 18397 18398 // If the user we are switching to is not currently started, then 18399 // we need to start it now. 18400 if (mStartedUsers.get(userId) == null) { 18401 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18402 updateStartedUserArrayLocked(); 18403 needStart = true; 18404 } 18405 18406 final Integer userIdInt = Integer.valueOf(userId); 18407 mUserLru.remove(userIdInt); 18408 mUserLru.add(userIdInt); 18409 18410 if (foreground) { 18411 mCurrentUserId = userId; 18412 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18413 updateCurrentProfileIdsLocked(); 18414 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18415 // Once the internal notion of the active user has switched, we lock the device 18416 // with the option to show the user switcher on the keyguard. 18417 mWindowManager.lockNow(null); 18418 } else { 18419 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18420 updateCurrentProfileIdsLocked(); 18421 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18422 mUserLru.remove(currentUserIdInt); 18423 mUserLru.add(currentUserIdInt); 18424 } 18425 18426 final UserStartedState uss = mStartedUsers.get(userId); 18427 18428 // Make sure user is in the started state. If it is currently 18429 // stopping, we need to knock that off. 18430 if (uss.mState == UserStartedState.STATE_STOPPING) { 18431 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18432 // so we can just fairly silently bring the user back from 18433 // the almost-dead. 18434 uss.mState = UserStartedState.STATE_RUNNING; 18435 updateStartedUserArrayLocked(); 18436 needStart = true; 18437 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18438 // This means ACTION_SHUTDOWN has been sent, so we will 18439 // need to treat this as a new boot of the user. 18440 uss.mState = UserStartedState.STATE_BOOTING; 18441 updateStartedUserArrayLocked(); 18442 needStart = true; 18443 } 18444 18445 if (uss.mState == UserStartedState.STATE_BOOTING) { 18446 // Booting up a new user, need to tell system services about it. 18447 // Note that this is on the same handler as scheduling of broadcasts, 18448 // which is important because it needs to go first. 18449 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18450 } 18451 18452 if (foreground) { 18453 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18454 oldUserId)); 18455 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18456 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18457 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18458 oldUserId, userId, uss)); 18459 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18460 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18461 } 18462 18463 if (needStart) { 18464 // Send USER_STARTED broadcast 18465 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18466 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18467 | Intent.FLAG_RECEIVER_FOREGROUND); 18468 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18469 broadcastIntentLocked(null, null, intent, 18470 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18471 false, false, MY_PID, Process.SYSTEM_UID, userId); 18472 } 18473 18474 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18475 if (userId != UserHandle.USER_OWNER) { 18476 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18477 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18478 broadcastIntentLocked(null, null, intent, null, 18479 new IIntentReceiver.Stub() { 18480 public void performReceive(Intent intent, int resultCode, 18481 String data, Bundle extras, boolean ordered, 18482 boolean sticky, int sendingUser) { 18483 onUserInitialized(uss, foreground, oldUserId, userId); 18484 } 18485 }, 0, null, null, null, AppOpsManager.OP_NONE, 18486 true, false, MY_PID, Process.SYSTEM_UID, 18487 userId); 18488 uss.initializing = true; 18489 } else { 18490 getUserManagerLocked().makeInitialized(userInfo.id); 18491 } 18492 } 18493 18494 if (foreground) { 18495 if (!uss.initializing) { 18496 moveUserToForeground(uss, oldUserId, userId); 18497 } 18498 } else { 18499 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18500 } 18501 18502 if (needStart) { 18503 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18505 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18506 broadcastIntentLocked(null, null, intent, 18507 null, new IIntentReceiver.Stub() { 18508 @Override 18509 public void performReceive(Intent intent, int resultCode, String data, 18510 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18511 throws RemoteException { 18512 } 18513 }, 0, null, null, 18514 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18515 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18516 } 18517 } 18518 } finally { 18519 Binder.restoreCallingIdentity(ident); 18520 } 18521 18522 return true; 18523 } 18524 18525 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18526 long ident = Binder.clearCallingIdentity(); 18527 try { 18528 Intent intent; 18529 if (oldUserId >= 0) { 18530 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18531 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18532 int count = profiles.size(); 18533 for (int i = 0; i < count; i++) { 18534 int profileUserId = profiles.get(i).id; 18535 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18536 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18537 | Intent.FLAG_RECEIVER_FOREGROUND); 18538 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18539 broadcastIntentLocked(null, null, intent, 18540 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18541 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18542 } 18543 } 18544 if (newUserId >= 0) { 18545 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18546 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18547 int count = profiles.size(); 18548 for (int i = 0; i < count; i++) { 18549 int profileUserId = profiles.get(i).id; 18550 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18551 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18552 | Intent.FLAG_RECEIVER_FOREGROUND); 18553 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18554 broadcastIntentLocked(null, null, intent, 18555 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18556 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18557 } 18558 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18559 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18560 | Intent.FLAG_RECEIVER_FOREGROUND); 18561 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18562 broadcastIntentLocked(null, null, intent, 18563 null, null, 0, null, null, 18564 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18565 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18566 } 18567 } finally { 18568 Binder.restoreCallingIdentity(ident); 18569 } 18570 } 18571 18572 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18573 final int newUserId) { 18574 final int N = mUserSwitchObservers.beginBroadcast(); 18575 if (N > 0) { 18576 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18577 int mCount = 0; 18578 @Override 18579 public void sendResult(Bundle data) throws RemoteException { 18580 synchronized (ActivityManagerService.this) { 18581 if (mCurUserSwitchCallback == this) { 18582 mCount++; 18583 if (mCount == N) { 18584 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18585 } 18586 } 18587 } 18588 } 18589 }; 18590 synchronized (this) { 18591 uss.switching = true; 18592 mCurUserSwitchCallback = callback; 18593 } 18594 for (int i=0; i<N; i++) { 18595 try { 18596 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18597 newUserId, callback); 18598 } catch (RemoteException e) { 18599 } 18600 } 18601 } else { 18602 synchronized (this) { 18603 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18604 } 18605 } 18606 mUserSwitchObservers.finishBroadcast(); 18607 } 18608 18609 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18610 synchronized (this) { 18611 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18612 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18613 } 18614 } 18615 18616 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18617 mCurUserSwitchCallback = null; 18618 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18619 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18620 oldUserId, newUserId, uss)); 18621 } 18622 18623 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18624 synchronized (this) { 18625 if (foreground) { 18626 moveUserToForeground(uss, oldUserId, newUserId); 18627 } 18628 } 18629 18630 completeSwitchAndInitalize(uss, newUserId, true, false); 18631 } 18632 18633 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18634 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18635 if (homeInFront) { 18636 startHomeActivityLocked(newUserId); 18637 } else { 18638 mStackSupervisor.resumeTopActivitiesLocked(); 18639 } 18640 EventLogTags.writeAmSwitchUser(newUserId); 18641 getUserManagerLocked().userForeground(newUserId); 18642 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18643 } 18644 18645 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18646 completeSwitchAndInitalize(uss, newUserId, false, true); 18647 } 18648 18649 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18650 boolean clearInitializing, boolean clearSwitching) { 18651 boolean unfrozen = false; 18652 synchronized (this) { 18653 if (clearInitializing) { 18654 uss.initializing = false; 18655 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18656 } 18657 if (clearSwitching) { 18658 uss.switching = false; 18659 } 18660 if (!uss.switching && !uss.initializing) { 18661 mWindowManager.stopFreezingScreen(); 18662 unfrozen = true; 18663 } 18664 } 18665 if (unfrozen) { 18666 final int N = mUserSwitchObservers.beginBroadcast(); 18667 for (int i=0; i<N; i++) { 18668 try { 18669 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18670 } catch (RemoteException e) { 18671 } 18672 } 18673 mUserSwitchObservers.finishBroadcast(); 18674 } 18675 } 18676 18677 void scheduleStartProfilesLocked() { 18678 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18679 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18680 DateUtils.SECOND_IN_MILLIS); 18681 } 18682 } 18683 18684 void startProfilesLocked() { 18685 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18686 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18687 mCurrentUserId, false /* enabledOnly */); 18688 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18689 for (UserInfo user : profiles) { 18690 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18691 && user.id != mCurrentUserId) { 18692 toStart.add(user); 18693 } 18694 } 18695 final int n = toStart.size(); 18696 int i = 0; 18697 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18698 startUserInBackground(toStart.get(i).id); 18699 } 18700 if (i < n) { 18701 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18702 } 18703 } 18704 18705 void finishUserBoot(UserStartedState uss) { 18706 synchronized (this) { 18707 if (uss.mState == UserStartedState.STATE_BOOTING 18708 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18709 uss.mState = UserStartedState.STATE_RUNNING; 18710 final int userId = uss.mHandle.getIdentifier(); 18711 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18712 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18713 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18714 broadcastIntentLocked(null, null, intent, 18715 null, null, 0, null, null, 18716 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18717 true, false, MY_PID, Process.SYSTEM_UID, userId); 18718 } 18719 } 18720 } 18721 18722 void finishUserSwitch(UserStartedState uss) { 18723 synchronized (this) { 18724 finishUserBoot(uss); 18725 18726 startProfilesLocked(); 18727 18728 int num = mUserLru.size(); 18729 int i = 0; 18730 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18731 Integer oldUserId = mUserLru.get(i); 18732 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18733 if (oldUss == null) { 18734 // Shouldn't happen, but be sane if it does. 18735 mUserLru.remove(i); 18736 num--; 18737 continue; 18738 } 18739 if (oldUss.mState == UserStartedState.STATE_STOPPING 18740 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18741 // This user is already stopping, doesn't count. 18742 num--; 18743 i++; 18744 continue; 18745 } 18746 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18747 // Owner and current can't be stopped, but count as running. 18748 i++; 18749 continue; 18750 } 18751 // This is a user to be stopped. 18752 stopUserLocked(oldUserId, null); 18753 num--; 18754 i++; 18755 } 18756 } 18757 } 18758 18759 @Override 18760 public int stopUser(final int userId, final IStopUserCallback callback) { 18761 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18762 != PackageManager.PERMISSION_GRANTED) { 18763 String msg = "Permission Denial: switchUser() from pid=" 18764 + Binder.getCallingPid() 18765 + ", uid=" + Binder.getCallingUid() 18766 + " requires " + INTERACT_ACROSS_USERS_FULL; 18767 Slog.w(TAG, msg); 18768 throw new SecurityException(msg); 18769 } 18770 if (userId <= 0) { 18771 throw new IllegalArgumentException("Can't stop primary user " + userId); 18772 } 18773 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18774 synchronized (this) { 18775 return stopUserLocked(userId, callback); 18776 } 18777 } 18778 18779 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18780 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18781 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18782 return ActivityManager.USER_OP_IS_CURRENT; 18783 } 18784 18785 final UserStartedState uss = mStartedUsers.get(userId); 18786 if (uss == null) { 18787 // User is not started, nothing to do... but we do need to 18788 // callback if requested. 18789 if (callback != null) { 18790 mHandler.post(new Runnable() { 18791 @Override 18792 public void run() { 18793 try { 18794 callback.userStopped(userId); 18795 } catch (RemoteException e) { 18796 } 18797 } 18798 }); 18799 } 18800 return ActivityManager.USER_OP_SUCCESS; 18801 } 18802 18803 if (callback != null) { 18804 uss.mStopCallbacks.add(callback); 18805 } 18806 18807 if (uss.mState != UserStartedState.STATE_STOPPING 18808 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18809 uss.mState = UserStartedState.STATE_STOPPING; 18810 updateStartedUserArrayLocked(); 18811 18812 long ident = Binder.clearCallingIdentity(); 18813 try { 18814 // We are going to broadcast ACTION_USER_STOPPING and then 18815 // once that is done send a final ACTION_SHUTDOWN and then 18816 // stop the user. 18817 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18818 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18819 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18820 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18821 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18822 // This is the result receiver for the final shutdown broadcast. 18823 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18824 @Override 18825 public void performReceive(Intent intent, int resultCode, String data, 18826 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18827 finishUserStop(uss); 18828 } 18829 }; 18830 // This is the result receiver for the initial stopping broadcast. 18831 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18832 @Override 18833 public void performReceive(Intent intent, int resultCode, String data, 18834 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18835 // On to the next. 18836 synchronized (ActivityManagerService.this) { 18837 if (uss.mState != UserStartedState.STATE_STOPPING) { 18838 // Whoops, we are being started back up. Abort, abort! 18839 return; 18840 } 18841 uss.mState = UserStartedState.STATE_SHUTDOWN; 18842 } 18843 mBatteryStatsService.noteEvent( 18844 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18845 Integer.toString(userId), userId); 18846 mSystemServiceManager.stopUser(userId); 18847 broadcastIntentLocked(null, null, shutdownIntent, 18848 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18849 true, false, MY_PID, Process.SYSTEM_UID, userId); 18850 } 18851 }; 18852 // Kick things off. 18853 broadcastIntentLocked(null, null, stoppingIntent, 18854 null, stoppingReceiver, 0, null, null, 18855 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18856 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18857 } finally { 18858 Binder.restoreCallingIdentity(ident); 18859 } 18860 } 18861 18862 return ActivityManager.USER_OP_SUCCESS; 18863 } 18864 18865 void finishUserStop(UserStartedState uss) { 18866 final int userId = uss.mHandle.getIdentifier(); 18867 boolean stopped; 18868 ArrayList<IStopUserCallback> callbacks; 18869 synchronized (this) { 18870 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18871 if (mStartedUsers.get(userId) != uss) { 18872 stopped = false; 18873 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18874 stopped = false; 18875 } else { 18876 stopped = true; 18877 // User can no longer run. 18878 mStartedUsers.remove(userId); 18879 mUserLru.remove(Integer.valueOf(userId)); 18880 updateStartedUserArrayLocked(); 18881 18882 // Clean up all state and processes associated with the user. 18883 // Kill all the processes for the user. 18884 forceStopUserLocked(userId, "finish user"); 18885 } 18886 18887 // Explicitly remove the old information in mRecentTasks. 18888 removeRecentTasksForUserLocked(userId); 18889 } 18890 18891 for (int i=0; i<callbacks.size(); i++) { 18892 try { 18893 if (stopped) callbacks.get(i).userStopped(userId); 18894 else callbacks.get(i).userStopAborted(userId); 18895 } catch (RemoteException e) { 18896 } 18897 } 18898 18899 if (stopped) { 18900 mSystemServiceManager.cleanupUser(userId); 18901 synchronized (this) { 18902 mStackSupervisor.removeUserLocked(userId); 18903 } 18904 } 18905 } 18906 18907 @Override 18908 public UserInfo getCurrentUser() { 18909 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18910 != PackageManager.PERMISSION_GRANTED) && ( 18911 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18912 != PackageManager.PERMISSION_GRANTED)) { 18913 String msg = "Permission Denial: getCurrentUser() from pid=" 18914 + Binder.getCallingPid() 18915 + ", uid=" + Binder.getCallingUid() 18916 + " requires " + INTERACT_ACROSS_USERS; 18917 Slog.w(TAG, msg); 18918 throw new SecurityException(msg); 18919 } 18920 synchronized (this) { 18921 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18922 return getUserManagerLocked().getUserInfo(userId); 18923 } 18924 } 18925 18926 int getCurrentUserIdLocked() { 18927 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18928 } 18929 18930 @Override 18931 public boolean isUserRunning(int userId, boolean orStopped) { 18932 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18933 != PackageManager.PERMISSION_GRANTED) { 18934 String msg = "Permission Denial: isUserRunning() from pid=" 18935 + Binder.getCallingPid() 18936 + ", uid=" + Binder.getCallingUid() 18937 + " requires " + INTERACT_ACROSS_USERS; 18938 Slog.w(TAG, msg); 18939 throw new SecurityException(msg); 18940 } 18941 synchronized (this) { 18942 return isUserRunningLocked(userId, orStopped); 18943 } 18944 } 18945 18946 boolean isUserRunningLocked(int userId, boolean orStopped) { 18947 UserStartedState state = mStartedUsers.get(userId); 18948 if (state == null) { 18949 return false; 18950 } 18951 if (orStopped) { 18952 return true; 18953 } 18954 return state.mState != UserStartedState.STATE_STOPPING 18955 && state.mState != UserStartedState.STATE_SHUTDOWN; 18956 } 18957 18958 @Override 18959 public int[] getRunningUserIds() { 18960 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18961 != PackageManager.PERMISSION_GRANTED) { 18962 String msg = "Permission Denial: isUserRunning() from pid=" 18963 + Binder.getCallingPid() 18964 + ", uid=" + Binder.getCallingUid() 18965 + " requires " + INTERACT_ACROSS_USERS; 18966 Slog.w(TAG, msg); 18967 throw new SecurityException(msg); 18968 } 18969 synchronized (this) { 18970 return mStartedUserArray; 18971 } 18972 } 18973 18974 private void updateStartedUserArrayLocked() { 18975 int num = 0; 18976 for (int i=0; i<mStartedUsers.size(); i++) { 18977 UserStartedState uss = mStartedUsers.valueAt(i); 18978 // This list does not include stopping users. 18979 if (uss.mState != UserStartedState.STATE_STOPPING 18980 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18981 num++; 18982 } 18983 } 18984 mStartedUserArray = new int[num]; 18985 num = 0; 18986 for (int i=0; i<mStartedUsers.size(); i++) { 18987 UserStartedState uss = mStartedUsers.valueAt(i); 18988 if (uss.mState != UserStartedState.STATE_STOPPING 18989 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18990 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18991 num++; 18992 } 18993 } 18994 } 18995 18996 @Override 18997 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18998 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18999 != PackageManager.PERMISSION_GRANTED) { 19000 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19001 + Binder.getCallingPid() 19002 + ", uid=" + Binder.getCallingUid() 19003 + " requires " + INTERACT_ACROSS_USERS_FULL; 19004 Slog.w(TAG, msg); 19005 throw new SecurityException(msg); 19006 } 19007 19008 mUserSwitchObservers.register(observer); 19009 } 19010 19011 @Override 19012 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19013 mUserSwitchObservers.unregister(observer); 19014 } 19015 19016 private boolean userExists(int userId) { 19017 if (userId == 0) { 19018 return true; 19019 } 19020 UserManagerService ums = getUserManagerLocked(); 19021 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19022 } 19023 19024 int[] getUsersLocked() { 19025 UserManagerService ums = getUserManagerLocked(); 19026 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19027 } 19028 19029 UserManagerService getUserManagerLocked() { 19030 if (mUserManager == null) { 19031 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19032 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19033 } 19034 return mUserManager; 19035 } 19036 19037 private int applyUserId(int uid, int userId) { 19038 return UserHandle.getUid(userId, uid); 19039 } 19040 19041 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19042 if (info == null) return null; 19043 ApplicationInfo newInfo = new ApplicationInfo(info); 19044 newInfo.uid = applyUserId(info.uid, userId); 19045 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19046 + info.packageName; 19047 return newInfo; 19048 } 19049 19050 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19051 if (aInfo == null 19052 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19053 return aInfo; 19054 } 19055 19056 ActivityInfo info = new ActivityInfo(aInfo); 19057 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19058 return info; 19059 } 19060 19061 private final class LocalService extends ActivityManagerInternal { 19062 @Override 19063 public void goingToSleep() { 19064 ActivityManagerService.this.goingToSleep(); 19065 } 19066 19067 @Override 19068 public void wakingUp() { 19069 ActivityManagerService.this.wakingUp(); 19070 } 19071 19072 @Override 19073 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19074 String processName, String abiOverride, int uid, Runnable crashHandler) { 19075 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19076 processName, abiOverride, uid, crashHandler); 19077 } 19078 } 19079 19080 /** 19081 * An implementation of IAppTask, that allows an app to manage its own tasks via 19082 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19083 * only the process that calls getAppTasks() can call the AppTask methods. 19084 */ 19085 class AppTaskImpl extends IAppTask.Stub { 19086 private int mTaskId; 19087 private int mCallingUid; 19088 19089 public AppTaskImpl(int taskId, int callingUid) { 19090 mTaskId = taskId; 19091 mCallingUid = callingUid; 19092 } 19093 19094 private void checkCaller() { 19095 if (mCallingUid != Binder.getCallingUid()) { 19096 throw new SecurityException("Caller " + mCallingUid 19097 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19098 } 19099 } 19100 19101 @Override 19102 public void finishAndRemoveTask() { 19103 checkCaller(); 19104 19105 synchronized (ActivityManagerService.this) { 19106 long origId = Binder.clearCallingIdentity(); 19107 try { 19108 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19109 if (tr == null) { 19110 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19111 } 19112 // Only kill the process if we are not a new document 19113 int flags = tr.getBaseIntent().getFlags(); 19114 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19115 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19116 removeTaskByIdLocked(mTaskId, 19117 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19118 } finally { 19119 Binder.restoreCallingIdentity(origId); 19120 } 19121 } 19122 } 19123 19124 @Override 19125 public ActivityManager.RecentTaskInfo getTaskInfo() { 19126 checkCaller(); 19127 19128 synchronized (ActivityManagerService.this) { 19129 long origId = Binder.clearCallingIdentity(); 19130 try { 19131 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19132 if (tr == null) { 19133 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19134 } 19135 return createRecentTaskInfoFromTaskRecord(tr); 19136 } finally { 19137 Binder.restoreCallingIdentity(origId); 19138 } 19139 } 19140 } 19141 19142 @Override 19143 public void moveToFront() { 19144 checkCaller(); 19145 19146 final TaskRecord tr; 19147 synchronized (ActivityManagerService.this) { 19148 tr = recentTaskForIdLocked(mTaskId); 19149 if (tr == null) { 19150 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19151 } 19152 if (tr.getRootActivity() != null) { 19153 moveTaskToFrontLocked(tr.taskId, 0, null); 19154 return; 19155 } 19156 } 19157 19158 startActivityFromRecentsInner(tr.taskId, null); 19159 } 19160 19161 @Override 19162 public int startActivity(IBinder whoThread, String callingPackage, 19163 Intent intent, String resolvedType, Bundle options) { 19164 checkCaller(); 19165 19166 int callingUser = UserHandle.getCallingUserId(); 19167 TaskRecord tr; 19168 IApplicationThread appThread; 19169 synchronized (ActivityManagerService.this) { 19170 tr = recentTaskForIdLocked(mTaskId); 19171 if (tr == null) { 19172 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19173 } 19174 appThread = ApplicationThreadNative.asInterface(whoThread); 19175 if (appThread == null) { 19176 throw new IllegalArgumentException("Bad app thread " + appThread); 19177 } 19178 } 19179 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19180 resolvedType, null, null, null, null, 0, 0, null, null, 19181 null, options, callingUser, null, tr); 19182 } 19183 19184 @Override 19185 public void setExcludeFromRecents(boolean exclude) { 19186 checkCaller(); 19187 19188 synchronized (ActivityManagerService.this) { 19189 long origId = Binder.clearCallingIdentity(); 19190 try { 19191 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19192 if (tr == null) { 19193 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19194 } 19195 Intent intent = tr.getBaseIntent(); 19196 if (exclude) { 19197 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19198 } else { 19199 intent.setFlags(intent.getFlags() 19200 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19201 } 19202 } finally { 19203 Binder.restoreCallingIdentity(origId); 19204 } 19205 } 19206 } 19207 } 19208} 19209