ActivityManagerService.java revision 3597b55d12f77d2fb3019b2bbc3496673c78be7d
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.statusbar.StatusBarManagerInternal; 87import com.android.server.wm.AppTransition; 88import com.android.server.wm.WindowManagerService; 89import com.google.android.collect.Lists; 90import com.google.android.collect.Maps; 91 92import libcore.io.IoUtils; 93 94import org.xmlpull.v1.XmlPullParser; 95import org.xmlpull.v1.XmlPullParserException; 96import org.xmlpull.v1.XmlSerializer; 97 98import android.app.Activity; 99import android.app.ActivityManager; 100import android.app.ActivityManager.RunningTaskInfo; 101import android.app.ActivityManager.StackInfo; 102import android.app.ActivityManagerInternal; 103import android.app.ActivityManagerNative; 104import android.app.ActivityOptions; 105import android.app.ActivityThread; 106import android.app.AlertDialog; 107import android.app.AppGlobals; 108import android.app.ApplicationErrorReport; 109import android.app.Dialog; 110import android.app.IActivityController; 111import android.app.IApplicationThread; 112import android.app.IInstrumentationWatcher; 113import android.app.INotificationManager; 114import android.app.IProcessObserver; 115import android.app.IServiceConnection; 116import android.app.IStopUserCallback; 117import android.app.IUiAutomationConnection; 118import android.app.IUserSwitchObserver; 119import android.app.Instrumentation; 120import android.app.Notification; 121import android.app.NotificationManager; 122import android.app.PendingIntent; 123import android.app.backup.IBackupManager; 124import android.content.ActivityNotFoundException; 125import android.content.BroadcastReceiver; 126import android.content.ClipData; 127import android.content.ComponentCallbacks2; 128import android.content.ComponentName; 129import android.content.ContentProvider; 130import android.content.ContentResolver; 131import android.content.Context; 132import android.content.DialogInterface; 133import android.content.IContentProvider; 134import android.content.IIntentReceiver; 135import android.content.IIntentSender; 136import android.content.Intent; 137import android.content.IntentFilter; 138import android.content.IntentSender; 139import android.content.pm.ActivityInfo; 140import android.content.pm.ApplicationInfo; 141import android.content.pm.ConfigurationInfo; 142import android.content.pm.IPackageDataObserver; 143import android.content.pm.IPackageManager; 144import android.content.pm.InstrumentationInfo; 145import android.content.pm.PackageInfo; 146import android.content.pm.PackageManager; 147import android.content.pm.ParceledListSlice; 148import android.content.pm.UserInfo; 149import android.content.pm.PackageManager.NameNotFoundException; 150import android.content.pm.PathPermission; 151import android.content.pm.ProviderInfo; 152import android.content.pm.ResolveInfo; 153import android.content.pm.ServiceInfo; 154import android.content.res.CompatibilityInfo; 155import android.content.res.Configuration; 156import android.net.Proxy; 157import android.net.ProxyInfo; 158import android.net.Uri; 159import android.os.Binder; 160import android.os.Build; 161import android.os.Bundle; 162import android.os.Debug; 163import android.os.DropBoxManager; 164import android.os.Environment; 165import android.os.FactoryTest; 166import android.os.FileObserver; 167import android.os.FileUtils; 168import android.os.Handler; 169import android.os.IBinder; 170import android.os.IPermissionController; 171import android.os.IRemoteCallback; 172import android.os.IUserManager; 173import android.os.Looper; 174import android.os.Message; 175import android.os.Parcel; 176import android.os.ParcelFileDescriptor; 177import android.os.Process; 178import android.os.RemoteCallbackList; 179import android.os.RemoteException; 180import android.os.SELinux; 181import android.os.ServiceManager; 182import android.os.StrictMode; 183import android.os.SystemClock; 184import android.os.SystemProperties; 185import android.os.UpdateLock; 186import android.os.UserHandle; 187import android.os.UserManager; 188import android.provider.Settings; 189import android.text.format.DateUtils; 190import android.text.format.Time; 191import android.util.AtomicFile; 192import android.util.EventLog; 193import android.util.Log; 194import android.util.Pair; 195import android.util.PrintWriterPrinter; 196import android.util.Slog; 197import android.util.SparseArray; 198import android.util.TimeUtils; 199import android.util.Xml; 200import android.view.Gravity; 201import android.view.LayoutInflater; 202import android.view.View; 203import android.view.WindowManager; 204 205import dalvik.system.VMRuntime; 206 207import java.io.BufferedInputStream; 208import java.io.BufferedOutputStream; 209import java.io.DataInputStream; 210import java.io.DataOutputStream; 211import java.io.File; 212import java.io.FileDescriptor; 213import java.io.FileInputStream; 214import java.io.FileNotFoundException; 215import java.io.FileOutputStream; 216import java.io.IOException; 217import java.io.InputStreamReader; 218import java.io.PrintWriter; 219import java.io.StringWriter; 220import java.lang.ref.WeakReference; 221import java.util.ArrayList; 222import java.util.Arrays; 223import java.util.Collections; 224import java.util.Comparator; 225import java.util.HashMap; 226import java.util.HashSet; 227import java.util.Iterator; 228import java.util.List; 229import java.util.Locale; 230import java.util.Map; 231import java.util.Set; 232import java.util.concurrent.atomic.AtomicBoolean; 233import java.util.concurrent.atomic.AtomicLong; 234 235public final class ActivityManagerService extends ActivityManagerNative 236 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 237 238 private static final String USER_DATA_DIR = "/data/user/"; 239 // File that stores last updated system version and called preboot receivers 240 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 241 242 static final String TAG = "ActivityManager"; 243 static final String TAG_MU = "ActivityManagerServiceMU"; 244 static final boolean DEBUG = false; 245 static final boolean localLOGV = DEBUG; 246 static final boolean DEBUG_BACKUP = localLOGV || false; 247 static final boolean DEBUG_BROADCAST = localLOGV || false; 248 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 249 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 250 static final boolean DEBUG_CLEANUP = localLOGV || false; 251 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 252 static final boolean DEBUG_FOCUS = false; 253 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 254 static final boolean DEBUG_MU = localLOGV || false; 255 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 256 static final boolean DEBUG_LRU = localLOGV || false; 257 static final boolean DEBUG_PAUSE = localLOGV || false; 258 static final boolean DEBUG_POWER = localLOGV || false; 259 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 260 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 261 static final boolean DEBUG_PROCESSES = localLOGV || false; 262 static final boolean DEBUG_PROVIDER = localLOGV || false; 263 static final boolean DEBUG_RESULTS = localLOGV || false; 264 static final boolean DEBUG_SERVICE = localLOGV || false; 265 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 266 static final boolean DEBUG_STACK = localLOGV || false; 267 static final boolean DEBUG_SWITCH = localLOGV || false; 268 static final boolean DEBUG_TASKS = localLOGV || false; 269 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 270 static final boolean DEBUG_TRANSITION = localLOGV || false; 271 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 272 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 273 static final boolean DEBUG_VISBILITY = localLOGV || false; 274 static final boolean DEBUG_PSS = localLOGV || false; 275 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 276 static final boolean DEBUG_RECENTS = localLOGV || false; 277 static final boolean VALIDATE_TOKENS = false; 278 static final boolean SHOW_ACTIVITY_START_TIME = true; 279 280 // Control over CPU and battery monitoring. 281 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 282 static final boolean MONITOR_CPU_USAGE = true; 283 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 284 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 285 static final boolean MONITOR_THREAD_CPU_USAGE = false; 286 287 // The flags that are set for all calls we make to the package manager. 288 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 289 290 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 291 292 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 293 294 // Maximum number recent bitmaps to keep in memory. 295 static final int MAX_RECENT_BITMAPS = 5; 296 297 // Amount of time after a call to stopAppSwitches() during which we will 298 // prevent further untrusted switches from happening. 299 static final long APP_SWITCH_DELAY_TIME = 5*1000; 300 301 // How long we wait for a launched process to attach to the activity manager 302 // before we decide it's never going to come up for real. 303 static final int PROC_START_TIMEOUT = 10*1000; 304 305 // How long we wait for a launched process to attach to the activity manager 306 // before we decide it's never going to come up for real, when the process was 307 // started with a wrapper for instrumentation (such as Valgrind) because it 308 // could take much longer than usual. 309 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 310 311 // How long to wait after going idle before forcing apps to GC. 312 static final int GC_TIMEOUT = 5*1000; 313 314 // The minimum amount of time between successive GC requests for a process. 315 static final int GC_MIN_INTERVAL = 60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process. 318 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 319 320 // The minimum amount of time between successive PSS requests for a process 321 // when the request is due to the memory state being lowered. 322 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 323 324 // The rate at which we check for apps using excessive power -- 15 mins. 325 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 326 327 // The minimum sample duration we will allow before deciding we have 328 // enough data on wake locks to start killing things. 329 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 330 331 // The minimum sample duration we will allow before deciding we have 332 // enough data on CPU usage to start killing things. 333 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 334 335 // How long we allow a receiver to run before giving up on it. 336 static final int BROADCAST_FG_TIMEOUT = 10*1000; 337 static final int BROADCAST_BG_TIMEOUT = 60*1000; 338 339 // How long we wait until we timeout on key dispatching. 340 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 341 342 // How long we wait until we timeout on key dispatching during instrumentation. 343 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 344 345 // Amount of time we wait for observers to handle a user switch before 346 // giving up on them and unfreezing the screen. 347 static final int USER_SWITCH_TIMEOUT = 2*1000; 348 349 // Maximum number of users we allow to be running at a time. 350 static final int MAX_RUNNING_USERS = 3; 351 352 // How long to wait in getAssistContextExtras for the activity and foreground services 353 // to respond with the result. 354 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 355 356 // Maximum number of persisted Uri grants a package is allowed 357 static final int MAX_PERSISTED_URI_GRANTS = 128; 358 359 static final int MY_PID = Process.myPid(); 360 361 static final String[] EMPTY_STRING_ARRAY = new String[0]; 362 363 // How many bytes to write into the dropbox log before truncating 364 static final int DROPBOX_MAX_SIZE = 256 * 1024; 365 366 // Access modes for handleIncomingUser. 367 static final int ALLOW_NON_FULL = 0; 368 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 369 static final int ALLOW_FULL_ONLY = 2; 370 371 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 372 373 /** All system services */ 374 SystemServiceManager mSystemServiceManager; 375 376 private Installer mInstaller; 377 378 /** Run all ActivityStacks through this */ 379 ActivityStackSupervisor mStackSupervisor; 380 381 public IntentFirewall mIntentFirewall; 382 383 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 384 // default actuion automatically. Important for devices without direct input 385 // devices. 386 private boolean mShowDialogs = true; 387 388 BroadcastQueue mFgBroadcastQueue; 389 BroadcastQueue mBgBroadcastQueue; 390 // Convenient for easy iteration over the queues. Foreground is first 391 // so that dispatch of foreground broadcasts gets precedence. 392 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 393 394 BroadcastQueue broadcastQueueForIntent(Intent intent) { 395 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 396 if (DEBUG_BACKGROUND_BROADCAST) { 397 Slog.i(TAG, "Broadcast intent " + intent + " on " 398 + (isFg ? "foreground" : "background") 399 + " queue"); 400 } 401 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 402 } 403 404 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 405 for (BroadcastQueue queue : mBroadcastQueues) { 406 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 407 if (r != null) { 408 return r; 409 } 410 } 411 return null; 412 } 413 414 /** 415 * Activity we have told the window manager to have key focus. 416 */ 417 ActivityRecord mFocusedActivity = null; 418 419 /** 420 * List of intents that were used to start the most recent tasks. 421 */ 422 ArrayList<TaskRecord> mRecentTasks; 423 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 424 425 /** 426 * For addAppTask: cached of the last activity component that was added. 427 */ 428 ComponentName mLastAddedTaskComponent; 429 430 /** 431 * For addAppTask: cached of the last activity uid that was added. 432 */ 433 int mLastAddedTaskUid; 434 435 /** 436 * For addAppTask: cached of the last ActivityInfo that was added. 437 */ 438 ActivityInfo mLastAddedTaskActivity; 439 440 public class PendingAssistExtras extends Binder implements Runnable { 441 public final ActivityRecord activity; 442 public final Bundle extras; 443 public final Intent intent; 444 public final String hint; 445 public final int userHandle; 446 public boolean haveResult = false; 447 public Bundle result = null; 448 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 449 String _hint, int _userHandle) { 450 activity = _activity; 451 extras = _extras; 452 intent = _intent; 453 hint = _hint; 454 userHandle = _userHandle; 455 } 456 @Override 457 public void run() { 458 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 459 synchronized (this) { 460 haveResult = true; 461 notifyAll(); 462 } 463 } 464 } 465 466 final ArrayList<PendingAssistExtras> mPendingAssistExtras 467 = new ArrayList<PendingAssistExtras>(); 468 469 /** 470 * Process management. 471 */ 472 final ProcessList mProcessList = new ProcessList(); 473 474 /** 475 * All of the applications we currently have running organized by name. 476 * The keys are strings of the application package name (as 477 * returned by the package manager), and the keys are ApplicationRecord 478 * objects. 479 */ 480 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 481 482 /** 483 * Tracking long-term execution of processes to look for abuse and other 484 * bad app behavior. 485 */ 486 final ProcessStatsService mProcessStats; 487 488 /** 489 * The currently running isolated processes. 490 */ 491 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 492 493 /** 494 * Counter for assigning isolated process uids, to avoid frequently reusing the 495 * same ones. 496 */ 497 int mNextIsolatedProcessUid = 0; 498 499 /** 500 * The currently running heavy-weight process, if any. 501 */ 502 ProcessRecord mHeavyWeightProcess = null; 503 504 /** 505 * The last time that various processes have crashed. 506 */ 507 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 508 509 /** 510 * Information about a process that is currently marked as bad. 511 */ 512 static final class BadProcessInfo { 513 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 514 this.time = time; 515 this.shortMsg = shortMsg; 516 this.longMsg = longMsg; 517 this.stack = stack; 518 } 519 520 final long time; 521 final String shortMsg; 522 final String longMsg; 523 final String stack; 524 } 525 526 /** 527 * Set of applications that we consider to be bad, and will reject 528 * incoming broadcasts from (which the user has no control over). 529 * Processes are added to this set when they have crashed twice within 530 * a minimum amount of time; they are removed from it when they are 531 * later restarted (hopefully due to some user action). The value is the 532 * time it was added to the list. 533 */ 534 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 535 536 /** 537 * All of the processes we currently have running organized by pid. 538 * The keys are the pid running the application. 539 * 540 * <p>NOTE: This object is protected by its own lock, NOT the global 541 * activity manager lock! 542 */ 543 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 544 545 /** 546 * All of the processes that have been forced to be foreground. The key 547 * is the pid of the caller who requested it (we hold a death 548 * link on it). 549 */ 550 abstract class ForegroundToken implements IBinder.DeathRecipient { 551 int pid; 552 IBinder token; 553 } 554 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 555 556 /** 557 * List of records for processes that someone had tried to start before the 558 * system was ready. We don't start them at that point, but ensure they 559 * are started by the time booting is complete. 560 */ 561 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 562 563 /** 564 * List of persistent applications that are in the process 565 * of being started. 566 */ 567 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * Processes that are being forcibly torn down. 571 */ 572 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 573 574 /** 575 * List of running applications, sorted by recent usage. 576 * The first entry in the list is the least recently used. 577 */ 578 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Where in mLruProcesses that the processes hosting activities start. 582 */ 583 int mLruProcessActivityStart = 0; 584 585 /** 586 * Where in mLruProcesses that the processes hosting services start. 587 * This is after (lower index) than mLruProcessesActivityStart. 588 */ 589 int mLruProcessServiceStart = 0; 590 591 /** 592 * List of processes that should gc as soon as things are idle. 593 */ 594 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Processes we want to collect PSS data from. 598 */ 599 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 600 601 /** 602 * Last time we requested PSS data of all processes. 603 */ 604 long mLastFullPssTime = SystemClock.uptimeMillis(); 605 606 /** 607 * If set, the next time we collect PSS data we should do a full collection 608 * with data from native processes and the kernel. 609 */ 610 boolean mFullPssPending = false; 611 612 /** 613 * This is the process holding what we currently consider to be 614 * the "home" activity. 615 */ 616 ProcessRecord mHomeProcess; 617 618 /** 619 * This is the process holding the activity the user last visited that 620 * is in a different process from the one they are currently in. 621 */ 622 ProcessRecord mPreviousProcess; 623 624 /** 625 * The time at which the previous process was last visible. 626 */ 627 long mPreviousProcessVisibleTime; 628 629 /** 630 * Which uses have been started, so are allowed to run code. 631 */ 632 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 633 634 /** 635 * LRU list of history of current users. Most recently current is at the end. 636 */ 637 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 638 639 /** 640 * Constant array of the users that are currently started. 641 */ 642 int[] mStartedUserArray = new int[] { 0 }; 643 644 /** 645 * Registered observers of the user switching mechanics. 646 */ 647 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 648 = new RemoteCallbackList<IUserSwitchObserver>(); 649 650 /** 651 * Currently active user switch. 652 */ 653 Object mCurUserSwitchCallback; 654 655 /** 656 * Packages that the user has asked to have run in screen size 657 * compatibility mode instead of filling the screen. 658 */ 659 final CompatModePackages mCompatModePackages; 660 661 /** 662 * Set of IntentSenderRecord objects that are currently active. 663 */ 664 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 665 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 666 667 /** 668 * Fingerprints (hashCode()) of stack traces that we've 669 * already logged DropBox entries for. Guarded by itself. If 670 * something (rogue user app) forces this over 671 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 672 */ 673 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 674 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 675 676 /** 677 * Strict Mode background batched logging state. 678 * 679 * The string buffer is guarded by itself, and its lock is also 680 * used to determine if another batched write is already 681 * in-flight. 682 */ 683 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 684 685 /** 686 * Keeps track of all IIntentReceivers that have been registered for 687 * broadcasts. Hash keys are the receiver IBinder, hash value is 688 * a ReceiverList. 689 */ 690 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 691 new HashMap<IBinder, ReceiverList>(); 692 693 /** 694 * Resolver for broadcast intents to registered receivers. 695 * Holds BroadcastFilter (subclass of IntentFilter). 696 */ 697 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 698 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 699 @Override 700 protected boolean allowFilterResult( 701 BroadcastFilter filter, List<BroadcastFilter> dest) { 702 IBinder target = filter.receiverList.receiver.asBinder(); 703 for (int i=dest.size()-1; i>=0; i--) { 704 if (dest.get(i).receiverList.receiver.asBinder() == target) { 705 return false; 706 } 707 } 708 return true; 709 } 710 711 @Override 712 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 713 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 714 || userId == filter.owningUserId) { 715 return super.newResult(filter, match, userId); 716 } 717 return null; 718 } 719 720 @Override 721 protected BroadcastFilter[] newArray(int size) { 722 return new BroadcastFilter[size]; 723 } 724 725 @Override 726 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 727 return packageName.equals(filter.packageName); 728 } 729 }; 730 731 /** 732 * State of all active sticky broadcasts per user. Keys are the action of the 733 * sticky Intent, values are an ArrayList of all broadcasted intents with 734 * that action (which should usually be one). The SparseArray is keyed 735 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 736 * for stickies that are sent to all users. 737 */ 738 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 739 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 740 741 final ActiveServices mServices; 742 743 /** 744 * Backup/restore process management 745 */ 746 String mBackupAppName = null; 747 BackupRecord mBackupTarget = null; 748 749 final ProviderMap mProviderMap; 750 751 /** 752 * List of content providers who have clients waiting for them. The 753 * application is currently being launched and the provider will be 754 * removed from this list once it is published. 755 */ 756 final ArrayList<ContentProviderRecord> mLaunchingProviders 757 = new ArrayList<ContentProviderRecord>(); 758 759 /** 760 * File storing persisted {@link #mGrantedUriPermissions}. 761 */ 762 private final AtomicFile mGrantFile; 763 764 /** XML constants used in {@link #mGrantFile} */ 765 private static final String TAG_URI_GRANTS = "uri-grants"; 766 private static final String TAG_URI_GRANT = "uri-grant"; 767 private static final String ATTR_USER_HANDLE = "userHandle"; 768 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 769 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 770 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 771 private static final String ATTR_TARGET_PKG = "targetPkg"; 772 private static final String ATTR_URI = "uri"; 773 private static final String ATTR_MODE_FLAGS = "modeFlags"; 774 private static final String ATTR_CREATED_TIME = "createdTime"; 775 private static final String ATTR_PREFIX = "prefix"; 776 777 /** 778 * Global set of specific {@link Uri} permissions that have been granted. 779 * This optimized lookup structure maps from {@link UriPermission#targetUid} 780 * to {@link UriPermission#uri} to {@link UriPermission}. 781 */ 782 @GuardedBy("this") 783 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 784 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 785 786 public static class GrantUri { 787 public final int sourceUserId; 788 public final Uri uri; 789 public boolean prefix; 790 791 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 792 this.sourceUserId = sourceUserId; 793 this.uri = uri; 794 this.prefix = prefix; 795 } 796 797 @Override 798 public int hashCode() { 799 int hashCode = 1; 800 hashCode = 31 * hashCode + sourceUserId; 801 hashCode = 31 * hashCode + uri.hashCode(); 802 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 803 return hashCode; 804 } 805 806 @Override 807 public boolean equals(Object o) { 808 if (o instanceof GrantUri) { 809 GrantUri other = (GrantUri) o; 810 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 811 && prefix == other.prefix; 812 } 813 return false; 814 } 815 816 @Override 817 public String toString() { 818 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 819 if (prefix) result += " [prefix]"; 820 return result; 821 } 822 823 public String toSafeString() { 824 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 825 if (prefix) result += " [prefix]"; 826 return result; 827 } 828 829 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 830 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 831 ContentProvider.getUriWithoutUserId(uri), false); 832 } 833 } 834 835 CoreSettingsObserver mCoreSettingsObserver; 836 837 /** 838 * Thread-local storage used to carry caller permissions over through 839 * indirect content-provider access. 840 */ 841 private class Identity { 842 public int pid; 843 public int uid; 844 845 Identity(int _pid, int _uid) { 846 pid = _pid; 847 uid = _uid; 848 } 849 } 850 851 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 852 853 /** 854 * All information we have collected about the runtime performance of 855 * any user id that can impact battery performance. 856 */ 857 final BatteryStatsService mBatteryStatsService; 858 859 /** 860 * Information about component usage 861 */ 862 UsageStatsManagerInternal mUsageStatsService; 863 864 /** 865 * Information about and control over application operations 866 */ 867 final AppOpsService mAppOpsService; 868 869 /** 870 * Save recent tasks information across reboots. 871 */ 872 final TaskPersister mTaskPersister; 873 874 /** 875 * Current configuration information. HistoryRecord objects are given 876 * a reference to this object to indicate which configuration they are 877 * currently running in, so this object must be kept immutable. 878 */ 879 Configuration mConfiguration = new Configuration(); 880 881 /** 882 * Current sequencing integer of the configuration, for skipping old 883 * configurations. 884 */ 885 int mConfigurationSeq = 0; 886 887 /** 888 * Hardware-reported OpenGLES version. 889 */ 890 final int GL_ES_VERSION; 891 892 /** 893 * List of initialization arguments to pass to all processes when binding applications to them. 894 * For example, references to the commonly used services. 895 */ 896 HashMap<String, IBinder> mAppBindArgs; 897 898 /** 899 * Temporary to avoid allocations. Protected by main lock. 900 */ 901 final StringBuilder mStringBuilder = new StringBuilder(256); 902 903 /** 904 * Used to control how we initialize the service. 905 */ 906 ComponentName mTopComponent; 907 String mTopAction = Intent.ACTION_MAIN; 908 String mTopData; 909 boolean mProcessesReady = false; 910 boolean mSystemReady = false; 911 boolean mBooting = false; 912 boolean mCallFinishBooting = false; 913 boolean mBootAnimationComplete = false; 914 boolean mWaitingUpdate = false; 915 boolean mDidUpdate = false; 916 boolean mOnBattery = false; 917 boolean mLaunchWarningShown = false; 918 919 Context mContext; 920 921 int mFactoryTest; 922 923 boolean mCheckedForSetup; 924 925 /** 926 * The time at which we will allow normal application switches again, 927 * after a call to {@link #stopAppSwitches()}. 928 */ 929 long mAppSwitchesAllowedTime; 930 931 /** 932 * This is set to true after the first switch after mAppSwitchesAllowedTime 933 * is set; any switches after that will clear the time. 934 */ 935 boolean mDidAppSwitch; 936 937 /** 938 * Last time (in realtime) at which we checked for power usage. 939 */ 940 long mLastPowerCheckRealtime; 941 942 /** 943 * Last time (in uptime) at which we checked for power usage. 944 */ 945 long mLastPowerCheckUptime; 946 947 /** 948 * Set while we are wanting to sleep, to prevent any 949 * activities from being started/resumed. 950 */ 951 private boolean mSleeping = false; 952 953 /** 954 * Set while we are running a voice interaction. This overrides 955 * sleeping while it is active. 956 */ 957 private boolean mRunningVoice = false; 958 959 /** 960 * State of external calls telling us if the device is asleep. 961 */ 962 private boolean mWentToSleep = false; 963 964 static final int LOCK_SCREEN_HIDDEN = 0; 965 static final int LOCK_SCREEN_LEAVING = 1; 966 static final int LOCK_SCREEN_SHOWN = 2; 967 /** 968 * State of external call telling us if the lock screen is shown. 969 */ 970 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 971 972 /** 973 * Set if we are shutting down the system, similar to sleeping. 974 */ 975 boolean mShuttingDown = false; 976 977 /** 978 * Current sequence id for oom_adj computation traversal. 979 */ 980 int mAdjSeq = 0; 981 982 /** 983 * Current sequence id for process LRU updating. 984 */ 985 int mLruSeq = 0; 986 987 /** 988 * Keep track of the non-cached/empty process we last found, to help 989 * determine how to distribute cached/empty processes next time. 990 */ 991 int mNumNonCachedProcs = 0; 992 993 /** 994 * Keep track of the number of cached hidden procs, to balance oom adj 995 * distribution between those and empty procs. 996 */ 997 int mNumCachedHiddenProcs = 0; 998 999 /** 1000 * Keep track of the number of service processes we last found, to 1001 * determine on the next iteration which should be B services. 1002 */ 1003 int mNumServiceProcs = 0; 1004 int mNewNumAServiceProcs = 0; 1005 int mNewNumServiceProcs = 0; 1006 1007 /** 1008 * Allow the current computed overall memory level of the system to go down? 1009 * This is set to false when we are killing processes for reasons other than 1010 * memory management, so that the now smaller process list will not be taken as 1011 * an indication that memory is tighter. 1012 */ 1013 boolean mAllowLowerMemLevel = false; 1014 1015 /** 1016 * The last computed memory level, for holding when we are in a state that 1017 * processes are going away for other reasons. 1018 */ 1019 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1020 1021 /** 1022 * The last total number of process we have, to determine if changes actually look 1023 * like a shrinking number of process due to lower RAM. 1024 */ 1025 int mLastNumProcesses; 1026 1027 /** 1028 * The uptime of the last time we performed idle maintenance. 1029 */ 1030 long mLastIdleTime = SystemClock.uptimeMillis(); 1031 1032 /** 1033 * Total time spent with RAM that has been added in the past since the last idle time. 1034 */ 1035 long mLowRamTimeSinceLastIdle = 0; 1036 1037 /** 1038 * If RAM is currently low, when that horrible situation started. 1039 */ 1040 long mLowRamStartTime = 0; 1041 1042 /** 1043 * For reporting to battery stats the current top application. 1044 */ 1045 private String mCurResumedPackage = null; 1046 private int mCurResumedUid = -1; 1047 1048 /** 1049 * For reporting to battery stats the apps currently running foreground 1050 * service. The ProcessMap is package/uid tuples; each of these contain 1051 * an array of the currently foreground processes. 1052 */ 1053 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1054 = new ProcessMap<ArrayList<ProcessRecord>>(); 1055 1056 /** 1057 * This is set if we had to do a delayed dexopt of an app before launching 1058 * it, to increase the ANR timeouts in that case. 1059 */ 1060 boolean mDidDexOpt; 1061 1062 /** 1063 * Set if the systemServer made a call to enterSafeMode. 1064 */ 1065 boolean mSafeMode; 1066 1067 String mDebugApp = null; 1068 boolean mWaitForDebugger = false; 1069 boolean mDebugTransient = false; 1070 String mOrigDebugApp = null; 1071 boolean mOrigWaitForDebugger = false; 1072 boolean mAlwaysFinishActivities = false; 1073 IActivityController mController = null; 1074 String mProfileApp = null; 1075 ProcessRecord mProfileProc = null; 1076 String mProfileFile; 1077 ParcelFileDescriptor mProfileFd; 1078 int mSamplingInterval = 0; 1079 boolean mAutoStopProfiler = false; 1080 int mProfileType = 0; 1081 String mOpenGlTraceApp = null; 1082 1083 static class ProcessChangeItem { 1084 static final int CHANGE_ACTIVITIES = 1<<0; 1085 static final int CHANGE_PROCESS_STATE = 1<<1; 1086 int changes; 1087 int uid; 1088 int pid; 1089 int processState; 1090 boolean foregroundActivities; 1091 } 1092 1093 final RemoteCallbackList<IProcessObserver> mProcessObservers 1094 = new RemoteCallbackList<IProcessObserver>(); 1095 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1096 1097 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1098 = new ArrayList<ProcessChangeItem>(); 1099 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1100 = new ArrayList<ProcessChangeItem>(); 1101 1102 /** 1103 * Runtime CPU use collection thread. This object's lock is used to 1104 * perform synchronization with the thread (notifying it to run). 1105 */ 1106 final Thread mProcessCpuThread; 1107 1108 /** 1109 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1110 * Must acquire this object's lock when accessing it. 1111 * NOTE: this lock will be held while doing long operations (trawling 1112 * through all processes in /proc), so it should never be acquired by 1113 * any critical paths such as when holding the main activity manager lock. 1114 */ 1115 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1116 MONITOR_THREAD_CPU_USAGE); 1117 final AtomicLong mLastCpuTime = new AtomicLong(0); 1118 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1119 1120 long mLastWriteTime = 0; 1121 1122 /** 1123 * Used to retain an update lock when the foreground activity is in 1124 * immersive mode. 1125 */ 1126 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1127 1128 /** 1129 * Set to true after the system has finished booting. 1130 */ 1131 boolean mBooted = false; 1132 1133 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1134 int mProcessLimitOverride = -1; 1135 1136 WindowManagerService mWindowManager; 1137 1138 final ActivityThread mSystemThread; 1139 1140 // Holds the current foreground user's id 1141 int mCurrentUserId = 0; 1142 // Holds the target user's id during a user switch 1143 int mTargetUserId = UserHandle.USER_NULL; 1144 // If there are multiple profiles for the current user, their ids are here 1145 // Currently only the primary user can have managed profiles 1146 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1147 1148 /** 1149 * Mapping from each known user ID to the profile group ID it is associated with. 1150 */ 1151 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1152 1153 private UserManagerService mUserManager; 1154 1155 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1156 final ProcessRecord mApp; 1157 final int mPid; 1158 final IApplicationThread mAppThread; 1159 1160 AppDeathRecipient(ProcessRecord app, int pid, 1161 IApplicationThread thread) { 1162 if (localLOGV) Slog.v( 1163 TAG, "New death recipient " + this 1164 + " for thread " + thread.asBinder()); 1165 mApp = app; 1166 mPid = pid; 1167 mAppThread = thread; 1168 } 1169 1170 @Override 1171 public void binderDied() { 1172 if (localLOGV) Slog.v( 1173 TAG, "Death received in " + this 1174 + " for thread " + mAppThread.asBinder()); 1175 synchronized(ActivityManagerService.this) { 1176 appDiedLocked(mApp, mPid, mAppThread); 1177 } 1178 } 1179 } 1180 1181 static final int SHOW_ERROR_MSG = 1; 1182 static final int SHOW_NOT_RESPONDING_MSG = 2; 1183 static final int SHOW_FACTORY_ERROR_MSG = 3; 1184 static final int UPDATE_CONFIGURATION_MSG = 4; 1185 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1186 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1187 static final int SERVICE_TIMEOUT_MSG = 12; 1188 static final int UPDATE_TIME_ZONE = 13; 1189 static final int SHOW_UID_ERROR_MSG = 14; 1190 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1191 static final int PROC_START_TIMEOUT_MSG = 20; 1192 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1193 static final int KILL_APPLICATION_MSG = 22; 1194 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1195 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1196 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1197 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1198 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1199 static final int CLEAR_DNS_CACHE_MSG = 28; 1200 static final int UPDATE_HTTP_PROXY_MSG = 29; 1201 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1202 static final int DISPATCH_PROCESSES_CHANGED = 31; 1203 static final int DISPATCH_PROCESS_DIED = 32; 1204 static final int REPORT_MEM_USAGE_MSG = 33; 1205 static final int REPORT_USER_SWITCH_MSG = 34; 1206 static final int CONTINUE_USER_SWITCH_MSG = 35; 1207 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1208 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1209 static final int PERSIST_URI_GRANTS_MSG = 38; 1210 static final int REQUEST_ALL_PSS_MSG = 39; 1211 static final int START_PROFILES_MSG = 40; 1212 static final int UPDATE_TIME = 41; 1213 static final int SYSTEM_USER_START_MSG = 42; 1214 static final int SYSTEM_USER_CURRENT_MSG = 43; 1215 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1216 static final int FINISH_BOOTING_MSG = 45; 1217 static final int START_USER_SWITCH_MSG = 46; 1218 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1219 static final int DISMISS_DIALOG_MSG = 48; 1220 1221 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1222 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1223 static final int FIRST_COMPAT_MODE_MSG = 300; 1224 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1225 1226 CompatModeDialog mCompatModeDialog; 1227 long mLastMemUsageReportTime = 0; 1228 1229 /** 1230 * Flag whether the current user is a "monkey", i.e. whether 1231 * the UI is driven by a UI automation tool. 1232 */ 1233 private boolean mUserIsMonkey; 1234 1235 /** Flag whether the device has a Recents UI */ 1236 boolean mHasRecents; 1237 1238 /** The dimensions of the thumbnails in the Recents UI. */ 1239 int mThumbnailWidth; 1240 int mThumbnailHeight; 1241 1242 final ServiceThread mHandlerThread; 1243 final MainHandler mHandler; 1244 1245 final class MainHandler extends Handler { 1246 public MainHandler(Looper looper) { 1247 super(looper, null, true); 1248 } 1249 1250 @Override 1251 public void handleMessage(Message msg) { 1252 switch (msg.what) { 1253 case SHOW_ERROR_MSG: { 1254 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1255 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1256 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1257 synchronized (ActivityManagerService.this) { 1258 ProcessRecord proc = (ProcessRecord)data.get("app"); 1259 AppErrorResult res = (AppErrorResult) data.get("result"); 1260 if (proc != null && proc.crashDialog != null) { 1261 Slog.e(TAG, "App already has crash dialog: " + proc); 1262 if (res != null) { 1263 res.set(0); 1264 } 1265 return; 1266 } 1267 boolean isBackground = (UserHandle.getAppId(proc.uid) 1268 >= Process.FIRST_APPLICATION_UID 1269 && proc.pid != MY_PID); 1270 for (int userId : mCurrentProfileIds) { 1271 isBackground &= (proc.userId != userId); 1272 } 1273 if (isBackground && !showBackground) { 1274 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1275 if (res != null) { 1276 res.set(0); 1277 } 1278 return; 1279 } 1280 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1281 Dialog d = new AppErrorDialog(mContext, 1282 ActivityManagerService.this, res, proc); 1283 d.show(); 1284 proc.crashDialog = d; 1285 } else { 1286 // The device is asleep, so just pretend that the user 1287 // saw a crash dialog and hit "force quit". 1288 if (res != null) { 1289 res.set(0); 1290 } 1291 } 1292 } 1293 1294 ensureBootCompleted(); 1295 } break; 1296 case SHOW_NOT_RESPONDING_MSG: { 1297 synchronized (ActivityManagerService.this) { 1298 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1299 ProcessRecord proc = (ProcessRecord)data.get("app"); 1300 if (proc != null && proc.anrDialog != null) { 1301 Slog.e(TAG, "App already has anr dialog: " + proc); 1302 return; 1303 } 1304 1305 Intent intent = new Intent("android.intent.action.ANR"); 1306 if (!mProcessesReady) { 1307 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1308 | Intent.FLAG_RECEIVER_FOREGROUND); 1309 } 1310 broadcastIntentLocked(null, null, intent, 1311 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1312 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1313 1314 if (mShowDialogs) { 1315 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1316 mContext, proc, (ActivityRecord)data.get("activity"), 1317 msg.arg1 != 0); 1318 d.show(); 1319 proc.anrDialog = d; 1320 } else { 1321 // Just kill the app if there is no dialog to be shown. 1322 killAppAtUsersRequest(proc, null); 1323 } 1324 } 1325 1326 ensureBootCompleted(); 1327 } break; 1328 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1329 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1330 synchronized (ActivityManagerService.this) { 1331 ProcessRecord proc = (ProcessRecord) data.get("app"); 1332 if (proc == null) { 1333 Slog.e(TAG, "App not found when showing strict mode dialog."); 1334 break; 1335 } 1336 if (proc.crashDialog != null) { 1337 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1338 return; 1339 } 1340 AppErrorResult res = (AppErrorResult) data.get("result"); 1341 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1342 Dialog d = new StrictModeViolationDialog(mContext, 1343 ActivityManagerService.this, res, proc); 1344 d.show(); 1345 proc.crashDialog = d; 1346 } else { 1347 // The device is asleep, so just pretend that the user 1348 // saw a crash dialog and hit "force quit". 1349 res.set(0); 1350 } 1351 } 1352 ensureBootCompleted(); 1353 } break; 1354 case SHOW_FACTORY_ERROR_MSG: { 1355 Dialog d = new FactoryErrorDialog( 1356 mContext, msg.getData().getCharSequence("msg")); 1357 d.show(); 1358 ensureBootCompleted(); 1359 } break; 1360 case UPDATE_CONFIGURATION_MSG: { 1361 final ContentResolver resolver = mContext.getContentResolver(); 1362 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1363 } break; 1364 case GC_BACKGROUND_PROCESSES_MSG: { 1365 synchronized (ActivityManagerService.this) { 1366 performAppGcsIfAppropriateLocked(); 1367 } 1368 } break; 1369 case WAIT_FOR_DEBUGGER_MSG: { 1370 synchronized (ActivityManagerService.this) { 1371 ProcessRecord app = (ProcessRecord)msg.obj; 1372 if (msg.arg1 != 0) { 1373 if (!app.waitedForDebugger) { 1374 Dialog d = new AppWaitingForDebuggerDialog( 1375 ActivityManagerService.this, 1376 mContext, app); 1377 app.waitDialog = d; 1378 app.waitedForDebugger = true; 1379 d.show(); 1380 } 1381 } else { 1382 if (app.waitDialog != null) { 1383 app.waitDialog.dismiss(); 1384 app.waitDialog = null; 1385 } 1386 } 1387 } 1388 } break; 1389 case SERVICE_TIMEOUT_MSG: { 1390 if (mDidDexOpt) { 1391 mDidDexOpt = false; 1392 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1393 nmsg.obj = msg.obj; 1394 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1395 return; 1396 } 1397 mServices.serviceTimeout((ProcessRecord)msg.obj); 1398 } break; 1399 case UPDATE_TIME_ZONE: { 1400 synchronized (ActivityManagerService.this) { 1401 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1402 ProcessRecord r = mLruProcesses.get(i); 1403 if (r.thread != null) { 1404 try { 1405 r.thread.updateTimeZone(); 1406 } catch (RemoteException ex) { 1407 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1408 } 1409 } 1410 } 1411 } 1412 } break; 1413 case CLEAR_DNS_CACHE_MSG: { 1414 synchronized (ActivityManagerService.this) { 1415 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1416 ProcessRecord r = mLruProcesses.get(i); 1417 if (r.thread != null) { 1418 try { 1419 r.thread.clearDnsCache(); 1420 } catch (RemoteException ex) { 1421 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1422 } 1423 } 1424 } 1425 } 1426 } break; 1427 case UPDATE_HTTP_PROXY_MSG: { 1428 ProxyInfo proxy = (ProxyInfo)msg.obj; 1429 String host = ""; 1430 String port = ""; 1431 String exclList = ""; 1432 Uri pacFileUrl = Uri.EMPTY; 1433 if (proxy != null) { 1434 host = proxy.getHost(); 1435 port = Integer.toString(proxy.getPort()); 1436 exclList = proxy.getExclusionListAsString(); 1437 pacFileUrl = proxy.getPacFileUrl(); 1438 } 1439 synchronized (ActivityManagerService.this) { 1440 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1441 ProcessRecord r = mLruProcesses.get(i); 1442 if (r.thread != null) { 1443 try { 1444 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1445 } catch (RemoteException ex) { 1446 Slog.w(TAG, "Failed to update http proxy for: " + 1447 r.info.processName); 1448 } 1449 } 1450 } 1451 } 1452 } break; 1453 case SHOW_UID_ERROR_MSG: { 1454 if (mShowDialogs) { 1455 AlertDialog d = new BaseErrorDialog(mContext); 1456 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1457 d.setCancelable(false); 1458 d.setTitle(mContext.getText(R.string.android_system_label)); 1459 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1460 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1461 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1462 d.show(); 1463 } 1464 } break; 1465 case SHOW_FINGERPRINT_ERROR_MSG: { 1466 if (mShowDialogs) { 1467 AlertDialog d = new BaseErrorDialog(mContext); 1468 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1469 d.setCancelable(false); 1470 d.setTitle(mContext.getText(R.string.android_system_label)); 1471 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1472 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1473 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1474 d.show(); 1475 } 1476 } break; 1477 case PROC_START_TIMEOUT_MSG: { 1478 if (mDidDexOpt) { 1479 mDidDexOpt = false; 1480 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1481 nmsg.obj = msg.obj; 1482 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1483 return; 1484 } 1485 ProcessRecord app = (ProcessRecord)msg.obj; 1486 synchronized (ActivityManagerService.this) { 1487 processStartTimedOutLocked(app); 1488 } 1489 } break; 1490 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1491 synchronized (ActivityManagerService.this) { 1492 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1493 } 1494 } break; 1495 case KILL_APPLICATION_MSG: { 1496 synchronized (ActivityManagerService.this) { 1497 int appid = msg.arg1; 1498 boolean restart = (msg.arg2 == 1); 1499 Bundle bundle = (Bundle)msg.obj; 1500 String pkg = bundle.getString("pkg"); 1501 String reason = bundle.getString("reason"); 1502 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1503 false, UserHandle.USER_ALL, reason); 1504 } 1505 } break; 1506 case FINALIZE_PENDING_INTENT_MSG: { 1507 ((PendingIntentRecord)msg.obj).completeFinalize(); 1508 } break; 1509 case POST_HEAVY_NOTIFICATION_MSG: { 1510 INotificationManager inm = NotificationManager.getService(); 1511 if (inm == null) { 1512 return; 1513 } 1514 1515 ActivityRecord root = (ActivityRecord)msg.obj; 1516 ProcessRecord process = root.app; 1517 if (process == null) { 1518 return; 1519 } 1520 1521 try { 1522 Context context = mContext.createPackageContext(process.info.packageName, 0); 1523 String text = mContext.getString(R.string.heavy_weight_notification, 1524 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1525 Notification notification = new Notification(); 1526 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1527 notification.when = 0; 1528 notification.flags = Notification.FLAG_ONGOING_EVENT; 1529 notification.tickerText = text; 1530 notification.defaults = 0; // please be quiet 1531 notification.sound = null; 1532 notification.vibrate = null; 1533 notification.color = mContext.getResources().getColor( 1534 com.android.internal.R.color.system_notification_accent_color); 1535 notification.setLatestEventInfo(context, text, 1536 mContext.getText(R.string.heavy_weight_notification_detail), 1537 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1538 PendingIntent.FLAG_CANCEL_CURRENT, null, 1539 new UserHandle(root.userId))); 1540 1541 try { 1542 int[] outId = new int[1]; 1543 inm.enqueueNotificationWithTag("android", "android", null, 1544 R.string.heavy_weight_notification, 1545 notification, outId, root.userId); 1546 } catch (RuntimeException e) { 1547 Slog.w(ActivityManagerService.TAG, 1548 "Error showing notification for heavy-weight app", e); 1549 } catch (RemoteException e) { 1550 } 1551 } catch (NameNotFoundException e) { 1552 Slog.w(TAG, "Unable to create context for heavy notification", e); 1553 } 1554 } break; 1555 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1556 INotificationManager inm = NotificationManager.getService(); 1557 if (inm == null) { 1558 return; 1559 } 1560 try { 1561 inm.cancelNotificationWithTag("android", null, 1562 R.string.heavy_weight_notification, msg.arg1); 1563 } catch (RuntimeException e) { 1564 Slog.w(ActivityManagerService.TAG, 1565 "Error canceling notification for service", e); 1566 } catch (RemoteException e) { 1567 } 1568 } break; 1569 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1570 synchronized (ActivityManagerService.this) { 1571 checkExcessivePowerUsageLocked(true); 1572 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1573 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1574 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1575 } 1576 } break; 1577 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1578 synchronized (ActivityManagerService.this) { 1579 ActivityRecord ar = (ActivityRecord)msg.obj; 1580 if (mCompatModeDialog != null) { 1581 if (mCompatModeDialog.mAppInfo.packageName.equals( 1582 ar.info.applicationInfo.packageName)) { 1583 return; 1584 } 1585 mCompatModeDialog.dismiss(); 1586 mCompatModeDialog = null; 1587 } 1588 if (ar != null && false) { 1589 if (mCompatModePackages.getPackageAskCompatModeLocked( 1590 ar.packageName)) { 1591 int mode = mCompatModePackages.computeCompatModeLocked( 1592 ar.info.applicationInfo); 1593 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1594 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1595 mCompatModeDialog = new CompatModeDialog( 1596 ActivityManagerService.this, mContext, 1597 ar.info.applicationInfo); 1598 mCompatModeDialog.show(); 1599 } 1600 } 1601 } 1602 } 1603 break; 1604 } 1605 case DISPATCH_PROCESSES_CHANGED: { 1606 dispatchProcessesChanged(); 1607 break; 1608 } 1609 case DISPATCH_PROCESS_DIED: { 1610 final int pid = msg.arg1; 1611 final int uid = msg.arg2; 1612 dispatchProcessDied(pid, uid); 1613 break; 1614 } 1615 case REPORT_MEM_USAGE_MSG: { 1616 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1617 Thread thread = new Thread() { 1618 @Override public void run() { 1619 reportMemUsage(memInfos); 1620 } 1621 }; 1622 thread.start(); 1623 break; 1624 } 1625 case START_USER_SWITCH_MSG: { 1626 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1627 break; 1628 } 1629 case REPORT_USER_SWITCH_MSG: { 1630 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1631 break; 1632 } 1633 case CONTINUE_USER_SWITCH_MSG: { 1634 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1635 break; 1636 } 1637 case USER_SWITCH_TIMEOUT_MSG: { 1638 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1639 break; 1640 } 1641 case IMMERSIVE_MODE_LOCK_MSG: { 1642 final boolean nextState = (msg.arg1 != 0); 1643 if (mUpdateLock.isHeld() != nextState) { 1644 if (DEBUG_IMMERSIVE) { 1645 final ActivityRecord r = (ActivityRecord) msg.obj; 1646 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1647 } 1648 if (nextState) { 1649 mUpdateLock.acquire(); 1650 } else { 1651 mUpdateLock.release(); 1652 } 1653 } 1654 break; 1655 } 1656 case PERSIST_URI_GRANTS_MSG: { 1657 writeGrantedUriPermissions(); 1658 break; 1659 } 1660 case REQUEST_ALL_PSS_MSG: { 1661 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1662 break; 1663 } 1664 case START_PROFILES_MSG: { 1665 synchronized (ActivityManagerService.this) { 1666 startProfilesLocked(); 1667 } 1668 break; 1669 } 1670 case UPDATE_TIME: { 1671 synchronized (ActivityManagerService.this) { 1672 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1673 ProcessRecord r = mLruProcesses.get(i); 1674 if (r.thread != null) { 1675 try { 1676 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1677 } catch (RemoteException ex) { 1678 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1679 } 1680 } 1681 } 1682 } 1683 break; 1684 } 1685 case SYSTEM_USER_START_MSG: { 1686 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1687 Integer.toString(msg.arg1), msg.arg1); 1688 mSystemServiceManager.startUser(msg.arg1); 1689 break; 1690 } 1691 case SYSTEM_USER_CURRENT_MSG: { 1692 mBatteryStatsService.noteEvent( 1693 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1694 Integer.toString(msg.arg2), msg.arg2); 1695 mBatteryStatsService.noteEvent( 1696 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1697 Integer.toString(msg.arg1), msg.arg1); 1698 mSystemServiceManager.switchUser(msg.arg1); 1699 break; 1700 } 1701 case ENTER_ANIMATION_COMPLETE_MSG: { 1702 synchronized (ActivityManagerService.this) { 1703 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1704 if (r != null && r.app != null && r.app.thread != null) { 1705 try { 1706 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1707 } catch (RemoteException e) { 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 case FINISH_BOOTING_MSG: { 1714 if (msg.arg1 != 0) { 1715 finishBooting(); 1716 } 1717 if (msg.arg2 != 0) { 1718 enableScreenAfterBoot(); 1719 } 1720 break; 1721 } 1722 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1723 try { 1724 Locale l = (Locale) msg.obj; 1725 IBinder service = ServiceManager.getService("mount"); 1726 IMountService mountService = IMountService.Stub.asInterface(service); 1727 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1728 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1729 } catch (RemoteException e) { 1730 Log.e(TAG, "Error storing locale for decryption UI", e); 1731 } 1732 break; 1733 } 1734 case DISMISS_DIALOG_MSG: { 1735 final Dialog d = (Dialog) msg.obj; 1736 d.dismiss(); 1737 break; 1738 } 1739 } 1740 } 1741 }; 1742 1743 static final int COLLECT_PSS_BG_MSG = 1; 1744 1745 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1746 @Override 1747 public void handleMessage(Message msg) { 1748 switch (msg.what) { 1749 case COLLECT_PSS_BG_MSG: { 1750 long start = SystemClock.uptimeMillis(); 1751 MemInfoReader memInfo = null; 1752 synchronized (ActivityManagerService.this) { 1753 if (mFullPssPending) { 1754 mFullPssPending = false; 1755 memInfo = new MemInfoReader(); 1756 } 1757 } 1758 if (memInfo != null) { 1759 updateCpuStatsNow(); 1760 long nativeTotalPss = 0; 1761 synchronized (mProcessCpuTracker) { 1762 final int N = mProcessCpuTracker.countStats(); 1763 for (int j=0; j<N; j++) { 1764 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1765 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1766 // This is definitely an application process; skip it. 1767 continue; 1768 } 1769 synchronized (mPidsSelfLocked) { 1770 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1771 // This is one of our own processes; skip it. 1772 continue; 1773 } 1774 } 1775 nativeTotalPss += Debug.getPss(st.pid, null); 1776 } 1777 } 1778 memInfo.readMemInfo(); 1779 synchronized (ActivityManagerService.this) { 1780 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1781 + (SystemClock.uptimeMillis()-start) + "ms"); 1782 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1783 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1784 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1785 } 1786 } 1787 1788 int i = 0; 1789 int num = 0; 1790 long[] tmp = new long[1]; 1791 do { 1792 ProcessRecord proc; 1793 int procState; 1794 int pid; 1795 synchronized (ActivityManagerService.this) { 1796 if (i >= mPendingPssProcesses.size()) { 1797 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1798 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1799 mPendingPssProcesses.clear(); 1800 return; 1801 } 1802 proc = mPendingPssProcesses.get(i); 1803 procState = proc.pssProcState; 1804 if (proc.thread != null && procState == proc.setProcState) { 1805 pid = proc.pid; 1806 } else { 1807 proc = null; 1808 pid = 0; 1809 } 1810 i++; 1811 } 1812 if (proc != null) { 1813 long pss = Debug.getPss(pid, tmp); 1814 synchronized (ActivityManagerService.this) { 1815 if (proc.thread != null && proc.setProcState == procState 1816 && proc.pid == pid) { 1817 num++; 1818 proc.lastPssTime = SystemClock.uptimeMillis(); 1819 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1820 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1821 + ": " + pss + " lastPss=" + proc.lastPss 1822 + " state=" + ProcessList.makeProcStateString(procState)); 1823 if (proc.initialIdlePss == 0) { 1824 proc.initialIdlePss = pss; 1825 } 1826 proc.lastPss = pss; 1827 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1828 proc.lastCachedPss = pss; 1829 } 1830 } 1831 } 1832 } 1833 } while (true); 1834 } 1835 } 1836 } 1837 }; 1838 1839 /** 1840 * Monitor for package changes and update our internal state. 1841 */ 1842 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1843 @Override 1844 public void onPackageRemoved(String packageName, int uid) { 1845 // Remove all tasks with activities in the specified package from the list of recent tasks 1846 final int eventUserId = getChangingUserId(); 1847 synchronized (ActivityManagerService.this) { 1848 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1849 TaskRecord tr = mRecentTasks.get(i); 1850 if (tr.userId != eventUserId) continue; 1851 1852 ComponentName cn = tr.intent.getComponent(); 1853 if (cn != null && cn.getPackageName().equals(packageName)) { 1854 // If the package name matches, remove the task 1855 removeTaskByIdLocked(tr.taskId, true); 1856 } 1857 } 1858 } 1859 } 1860 1861 @Override 1862 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1863 onPackageModified(packageName); 1864 return true; 1865 } 1866 1867 @Override 1868 public void onPackageModified(String packageName) { 1869 final int eventUserId = getChangingUserId(); 1870 final IPackageManager pm = AppGlobals.getPackageManager(); 1871 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1872 new ArrayList<Pair<Intent, Integer>>(); 1873 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1874 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1875 // Copy the list of recent tasks so that we don't hold onto the lock on 1876 // ActivityManagerService for long periods while checking if components exist. 1877 synchronized (ActivityManagerService.this) { 1878 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1879 TaskRecord tr = mRecentTasks.get(i); 1880 if (tr.userId != eventUserId) continue; 1881 1882 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1883 } 1884 } 1885 // Check the recent tasks and filter out all tasks with components that no longer exist. 1886 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1887 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1888 ComponentName cn = p.first.getComponent(); 1889 if (cn != null && cn.getPackageName().equals(packageName)) { 1890 if (componentsKnownToExist.contains(cn)) { 1891 // If we know that the component still exists in the package, then skip 1892 continue; 1893 } 1894 try { 1895 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1896 if (info != null) { 1897 componentsKnownToExist.add(cn); 1898 } else { 1899 tasksToRemove.add(p.second); 1900 } 1901 } catch (RemoteException e) { 1902 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1903 } 1904 } 1905 } 1906 // Prune all the tasks with removed components from the list of recent tasks 1907 synchronized (ActivityManagerService.this) { 1908 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1909 removeTaskByIdLocked(tasksToRemove.get(i), false); 1910 } 1911 } 1912 } 1913 1914 @Override 1915 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1916 // Force stop the specified packages 1917 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1918 if (packages != null) { 1919 for (String pkg : packages) { 1920 synchronized (ActivityManagerService.this) { 1921 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1922 userId, "finished booting")) { 1923 return true; 1924 } 1925 } 1926 } 1927 } 1928 return false; 1929 } 1930 }; 1931 1932 public void setSystemProcess() { 1933 try { 1934 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1935 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1936 ServiceManager.addService("meminfo", new MemBinder(this)); 1937 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1938 ServiceManager.addService("dbinfo", new DbBinder(this)); 1939 if (MONITOR_CPU_USAGE) { 1940 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1941 } 1942 ServiceManager.addService("permission", new PermissionController(this)); 1943 1944 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1945 "android", STOCK_PM_FLAGS); 1946 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1947 1948 synchronized (this) { 1949 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1950 app.persistent = true; 1951 app.pid = MY_PID; 1952 app.maxAdj = ProcessList.SYSTEM_ADJ; 1953 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1954 mProcessNames.put(app.processName, app.uid, app); 1955 synchronized (mPidsSelfLocked) { 1956 mPidsSelfLocked.put(app.pid, app); 1957 } 1958 updateLruProcessLocked(app, false, null); 1959 updateOomAdjLocked(); 1960 } 1961 } catch (PackageManager.NameNotFoundException e) { 1962 throw new RuntimeException( 1963 "Unable to find android system package", e); 1964 } 1965 } 1966 1967 public void setWindowManager(WindowManagerService wm) { 1968 mWindowManager = wm; 1969 mStackSupervisor.setWindowManager(wm); 1970 } 1971 1972 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1973 mUsageStatsService = usageStatsManager; 1974 } 1975 1976 public void startObservingNativeCrashes() { 1977 final NativeCrashListener ncl = new NativeCrashListener(this); 1978 ncl.start(); 1979 } 1980 1981 public IAppOpsService getAppOpsService() { 1982 return mAppOpsService; 1983 } 1984 1985 static class MemBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 MemBinder(ActivityManagerService activityManagerService) { 1988 mActivityManagerService = activityManagerService; 1989 } 1990 1991 @Override 1992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1993 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1994 != PackageManager.PERMISSION_GRANTED) { 1995 pw.println("Permission Denial: can't dump meminfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2002 } 2003 } 2004 2005 static class GraphicsBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 GraphicsBinder(ActivityManagerService activityManagerService) { 2008 mActivityManagerService = activityManagerService; 2009 } 2010 2011 @Override 2012 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2013 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2014 != PackageManager.PERMISSION_GRANTED) { 2015 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2022 } 2023 } 2024 2025 static class DbBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 DbBinder(ActivityManagerService activityManagerService) { 2028 mActivityManagerService = activityManagerService; 2029 } 2030 2031 @Override 2032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2033 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2034 != PackageManager.PERMISSION_GRANTED) { 2035 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 mActivityManagerService.dumpDbInfo(fd, pw, args); 2042 } 2043 } 2044 2045 static class CpuBinder extends Binder { 2046 ActivityManagerService mActivityManagerService; 2047 CpuBinder(ActivityManagerService activityManagerService) { 2048 mActivityManagerService = activityManagerService; 2049 } 2050 2051 @Override 2052 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2053 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2054 != PackageManager.PERMISSION_GRANTED) { 2055 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2056 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2057 + " without permission " + android.Manifest.permission.DUMP); 2058 return; 2059 } 2060 2061 synchronized (mActivityManagerService.mProcessCpuTracker) { 2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2063 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2064 SystemClock.uptimeMillis())); 2065 } 2066 } 2067 } 2068 2069 public static final class Lifecycle extends SystemService { 2070 private final ActivityManagerService mService; 2071 2072 public Lifecycle(Context context) { 2073 super(context); 2074 mService = new ActivityManagerService(context); 2075 } 2076 2077 @Override 2078 public void onStart() { 2079 mService.start(); 2080 } 2081 2082 public ActivityManagerService getService() { 2083 return mService; 2084 } 2085 } 2086 2087 // Note: This method is invoked on the main thread but may need to attach various 2088 // handlers to other threads. So take care to be explicit about the looper. 2089 public ActivityManagerService(Context systemContext) { 2090 mContext = systemContext; 2091 mFactoryTest = FactoryTest.getMode(); 2092 mSystemThread = ActivityThread.currentActivityThread(); 2093 2094 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2095 2096 mHandlerThread = new ServiceThread(TAG, 2097 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2098 mHandlerThread.start(); 2099 mHandler = new MainHandler(mHandlerThread.getLooper()); 2100 2101 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2102 "foreground", BROADCAST_FG_TIMEOUT, false); 2103 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2104 "background", BROADCAST_BG_TIMEOUT, true); 2105 mBroadcastQueues[0] = mFgBroadcastQueue; 2106 mBroadcastQueues[1] = mBgBroadcastQueue; 2107 2108 mServices = new ActiveServices(this); 2109 mProviderMap = new ProviderMap(this); 2110 2111 // TODO: Move creation of battery stats service outside of activity manager service. 2112 File dataDir = Environment.getDataDirectory(); 2113 File systemDir = new File(dataDir, "system"); 2114 systemDir.mkdirs(); 2115 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2116 mBatteryStatsService.getActiveStatistics().readLocked(); 2117 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2118 mOnBattery = DEBUG_POWER ? true 2119 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2120 mBatteryStatsService.getActiveStatistics().setCallback(this); 2121 2122 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2123 2124 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2125 2126 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2127 2128 // User 0 is the first and only user that runs at boot. 2129 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2130 mUserLru.add(Integer.valueOf(0)); 2131 updateStartedUserArrayLocked(); 2132 2133 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2134 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2135 2136 mConfiguration.setToDefaults(); 2137 mConfiguration.setLocale(Locale.getDefault()); 2138 2139 mConfigurationSeq = mConfiguration.seq = 1; 2140 mProcessCpuTracker.init(); 2141 2142 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2143 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2144 mStackSupervisor = new ActivityStackSupervisor(this); 2145 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2146 2147 mProcessCpuThread = new Thread("CpuTracker") { 2148 @Override 2149 public void run() { 2150 while (true) { 2151 try { 2152 try { 2153 synchronized(this) { 2154 final long now = SystemClock.uptimeMillis(); 2155 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2156 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2157 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2158 // + ", write delay=" + nextWriteDelay); 2159 if (nextWriteDelay < nextCpuDelay) { 2160 nextCpuDelay = nextWriteDelay; 2161 } 2162 if (nextCpuDelay > 0) { 2163 mProcessCpuMutexFree.set(true); 2164 this.wait(nextCpuDelay); 2165 } 2166 } 2167 } catch (InterruptedException e) { 2168 } 2169 updateCpuStatsNow(); 2170 } catch (Exception e) { 2171 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2172 } 2173 } 2174 } 2175 }; 2176 2177 Watchdog.getInstance().addMonitor(this); 2178 Watchdog.getInstance().addThread(mHandler); 2179 } 2180 2181 public void setSystemServiceManager(SystemServiceManager mgr) { 2182 mSystemServiceManager = mgr; 2183 } 2184 2185 public void setInstaller(Installer installer) { 2186 mInstaller = installer; 2187 } 2188 2189 private void start() { 2190 Process.removeAllProcessGroups(); 2191 mProcessCpuThread.start(); 2192 2193 mBatteryStatsService.publish(mContext); 2194 mAppOpsService.publish(mContext); 2195 Slog.d("AppOps", "AppOpsService published"); 2196 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2197 } 2198 2199 public void initPowerManagement() { 2200 mStackSupervisor.initPowerManagement(); 2201 mBatteryStatsService.initPowerManagement(); 2202 } 2203 2204 @Override 2205 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2206 throws RemoteException { 2207 if (code == SYSPROPS_TRANSACTION) { 2208 // We need to tell all apps about the system property change. 2209 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2210 synchronized(this) { 2211 final int NP = mProcessNames.getMap().size(); 2212 for (int ip=0; ip<NP; ip++) { 2213 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2214 final int NA = apps.size(); 2215 for (int ia=0; ia<NA; ia++) { 2216 ProcessRecord app = apps.valueAt(ia); 2217 if (app.thread != null) { 2218 procs.add(app.thread.asBinder()); 2219 } 2220 } 2221 } 2222 } 2223 2224 int N = procs.size(); 2225 for (int i=0; i<N; i++) { 2226 Parcel data2 = Parcel.obtain(); 2227 try { 2228 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2229 } catch (RemoteException e) { 2230 } 2231 data2.recycle(); 2232 } 2233 } 2234 try { 2235 return super.onTransact(code, data, reply, flags); 2236 } catch (RuntimeException e) { 2237 // The activity manager only throws security exceptions, so let's 2238 // log all others. 2239 if (!(e instanceof SecurityException)) { 2240 Slog.wtf(TAG, "Activity Manager Crash", e); 2241 } 2242 throw e; 2243 } 2244 } 2245 2246 void updateCpuStats() { 2247 final long now = SystemClock.uptimeMillis(); 2248 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2249 return; 2250 } 2251 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2252 synchronized (mProcessCpuThread) { 2253 mProcessCpuThread.notify(); 2254 } 2255 } 2256 } 2257 2258 void updateCpuStatsNow() { 2259 synchronized (mProcessCpuTracker) { 2260 mProcessCpuMutexFree.set(false); 2261 final long now = SystemClock.uptimeMillis(); 2262 boolean haveNewCpuStats = false; 2263 2264 if (MONITOR_CPU_USAGE && 2265 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2266 mLastCpuTime.set(now); 2267 haveNewCpuStats = true; 2268 mProcessCpuTracker.update(); 2269 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2270 //Slog.i(TAG, "Total CPU usage: " 2271 // + mProcessCpu.getTotalCpuPercent() + "%"); 2272 2273 // Slog the cpu usage if the property is set. 2274 if ("true".equals(SystemProperties.get("events.cpu"))) { 2275 int user = mProcessCpuTracker.getLastUserTime(); 2276 int system = mProcessCpuTracker.getLastSystemTime(); 2277 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2278 int irq = mProcessCpuTracker.getLastIrqTime(); 2279 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2280 int idle = mProcessCpuTracker.getLastIdleTime(); 2281 2282 int total = user + system + iowait + irq + softIrq + idle; 2283 if (total == 0) total = 1; 2284 2285 EventLog.writeEvent(EventLogTags.CPU, 2286 ((user+system+iowait+irq+softIrq) * 100) / total, 2287 (user * 100) / total, 2288 (system * 100) / total, 2289 (iowait * 100) / total, 2290 (irq * 100) / total, 2291 (softIrq * 100) / total); 2292 } 2293 } 2294 2295 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2296 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2297 synchronized(bstats) { 2298 synchronized(mPidsSelfLocked) { 2299 if (haveNewCpuStats) { 2300 if (mOnBattery) { 2301 int perc = bstats.startAddingCpuLocked(); 2302 int totalUTime = 0; 2303 int totalSTime = 0; 2304 final int N = mProcessCpuTracker.countStats(); 2305 for (int i=0; i<N; i++) { 2306 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2307 if (!st.working) { 2308 continue; 2309 } 2310 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2311 int otherUTime = (st.rel_utime*perc)/100; 2312 int otherSTime = (st.rel_stime*perc)/100; 2313 totalUTime += otherUTime; 2314 totalSTime += otherSTime; 2315 if (pr != null) { 2316 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2317 if (ps == null || !ps.isActive()) { 2318 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2319 pr.info.uid, pr.processName); 2320 } 2321 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2322 st.rel_stime-otherSTime); 2323 ps.addSpeedStepTimes(cpuSpeedTimes); 2324 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2325 } else { 2326 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2327 if (ps == null || !ps.isActive()) { 2328 st.batteryStats = ps = bstats.getProcessStatsLocked( 2329 bstats.mapUid(st.uid), st.name); 2330 } 2331 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2332 st.rel_stime-otherSTime); 2333 ps.addSpeedStepTimes(cpuSpeedTimes); 2334 } 2335 } 2336 bstats.finishAddingCpuLocked(perc, totalUTime, 2337 totalSTime, cpuSpeedTimes); 2338 } 2339 } 2340 } 2341 2342 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2343 mLastWriteTime = now; 2344 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2345 } 2346 } 2347 } 2348 } 2349 2350 @Override 2351 public void batteryNeedsCpuUpdate() { 2352 updateCpuStatsNow(); 2353 } 2354 2355 @Override 2356 public void batteryPowerChanged(boolean onBattery) { 2357 // When plugging in, update the CPU stats first before changing 2358 // the plug state. 2359 updateCpuStatsNow(); 2360 synchronized (this) { 2361 synchronized(mPidsSelfLocked) { 2362 mOnBattery = DEBUG_POWER ? true : onBattery; 2363 } 2364 } 2365 } 2366 2367 /** 2368 * Initialize the application bind args. These are passed to each 2369 * process when the bindApplication() IPC is sent to the process. They're 2370 * lazily setup to make sure the services are running when they're asked for. 2371 */ 2372 private HashMap<String, IBinder> getCommonServicesLocked() { 2373 if (mAppBindArgs == null) { 2374 mAppBindArgs = new HashMap<String, IBinder>(); 2375 2376 // Setup the application init args 2377 mAppBindArgs.put("package", ServiceManager.getService("package")); 2378 mAppBindArgs.put("window", ServiceManager.getService("window")); 2379 mAppBindArgs.put(Context.ALARM_SERVICE, 2380 ServiceManager.getService(Context.ALARM_SERVICE)); 2381 } 2382 return mAppBindArgs; 2383 } 2384 2385 final void setFocusedActivityLocked(ActivityRecord r) { 2386 if (mFocusedActivity != r) { 2387 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2388 mFocusedActivity = r; 2389 if (r.task != null && r.task.voiceInteractor != null) { 2390 startRunningVoiceLocked(); 2391 } else { 2392 finishRunningVoiceLocked(); 2393 } 2394 mStackSupervisor.setFocusedStack(r); 2395 if (r != null) { 2396 mWindowManager.setFocusedApp(r.appToken, true); 2397 } 2398 applyUpdateLockStateLocked(r); 2399 } 2400 } 2401 2402 final void clearFocusedActivity(ActivityRecord r) { 2403 if (mFocusedActivity == r) { 2404 mFocusedActivity = null; 2405 } 2406 } 2407 2408 @Override 2409 public void setFocusedStack(int stackId) { 2410 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2411 synchronized (ActivityManagerService.this) { 2412 ActivityStack stack = mStackSupervisor.getStack(stackId); 2413 if (stack != null) { 2414 ActivityRecord r = stack.topRunningActivityLocked(null); 2415 if (r != null) { 2416 setFocusedActivityLocked(r); 2417 } 2418 } 2419 } 2420 } 2421 2422 @Override 2423 public void notifyActivityDrawn(IBinder token) { 2424 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2425 synchronized (this) { 2426 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2427 if (r != null) { 2428 r.task.stack.notifyActivityDrawnLocked(r); 2429 } 2430 } 2431 } 2432 2433 final void applyUpdateLockStateLocked(ActivityRecord r) { 2434 // Modifications to the UpdateLock state are done on our handler, outside 2435 // the activity manager's locks. The new state is determined based on the 2436 // state *now* of the relevant activity record. The object is passed to 2437 // the handler solely for logging detail, not to be consulted/modified. 2438 final boolean nextState = r != null && r.immersive; 2439 mHandler.sendMessage( 2440 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2441 } 2442 2443 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2444 Message msg = Message.obtain(); 2445 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2446 msg.obj = r.task.askedCompatMode ? null : r; 2447 mHandler.sendMessage(msg); 2448 } 2449 2450 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2451 String what, Object obj, ProcessRecord srcApp) { 2452 app.lastActivityTime = now; 2453 2454 if (app.activities.size() > 0) { 2455 // Don't want to touch dependent processes that are hosting activities. 2456 return index; 2457 } 2458 2459 int lrui = mLruProcesses.lastIndexOf(app); 2460 if (lrui < 0) { 2461 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2462 + what + " " + obj + " from " + srcApp); 2463 return index; 2464 } 2465 2466 if (lrui >= index) { 2467 // Don't want to cause this to move dependent processes *back* in the 2468 // list as if they were less frequently used. 2469 return index; 2470 } 2471 2472 if (lrui >= mLruProcessActivityStart) { 2473 // Don't want to touch dependent processes that are hosting activities. 2474 return index; 2475 } 2476 2477 mLruProcesses.remove(lrui); 2478 if (index > 0) { 2479 index--; 2480 } 2481 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2482 + " in LRU list: " + app); 2483 mLruProcesses.add(index, app); 2484 return index; 2485 } 2486 2487 final void removeLruProcessLocked(ProcessRecord app) { 2488 int lrui = mLruProcesses.lastIndexOf(app); 2489 if (lrui >= 0) { 2490 if (!app.killed) { 2491 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2492 Process.killProcessQuiet(app.pid); 2493 Process.killProcessGroup(app.info.uid, app.pid); 2494 } 2495 if (lrui <= mLruProcessActivityStart) { 2496 mLruProcessActivityStart--; 2497 } 2498 if (lrui <= mLruProcessServiceStart) { 2499 mLruProcessServiceStart--; 2500 } 2501 mLruProcesses.remove(lrui); 2502 } 2503 } 2504 2505 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2506 ProcessRecord client) { 2507 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2508 || app.treatLikeActivity; 2509 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2510 if (!activityChange && hasActivity) { 2511 // The process has activities, so we are only allowing activity-based adjustments 2512 // to move it. It should be kept in the front of the list with other 2513 // processes that have activities, and we don't want those to change their 2514 // order except due to activity operations. 2515 return; 2516 } 2517 2518 mLruSeq++; 2519 final long now = SystemClock.uptimeMillis(); 2520 app.lastActivityTime = now; 2521 2522 // First a quick reject: if the app is already at the position we will 2523 // put it, then there is nothing to do. 2524 if (hasActivity) { 2525 final int N = mLruProcesses.size(); 2526 if (N > 0 && mLruProcesses.get(N-1) == app) { 2527 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2528 return; 2529 } 2530 } else { 2531 if (mLruProcessServiceStart > 0 2532 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2533 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2534 return; 2535 } 2536 } 2537 2538 int lrui = mLruProcesses.lastIndexOf(app); 2539 2540 if (app.persistent && lrui >= 0) { 2541 // We don't care about the position of persistent processes, as long as 2542 // they are in the list. 2543 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2544 return; 2545 } 2546 2547 /* In progress: compute new position first, so we can avoid doing work 2548 if the process is not actually going to move. Not yet working. 2549 int addIndex; 2550 int nextIndex; 2551 boolean inActivity = false, inService = false; 2552 if (hasActivity) { 2553 // Process has activities, put it at the very tipsy-top. 2554 addIndex = mLruProcesses.size(); 2555 nextIndex = mLruProcessServiceStart; 2556 inActivity = true; 2557 } else if (hasService) { 2558 // Process has services, put it at the top of the service list. 2559 addIndex = mLruProcessActivityStart; 2560 nextIndex = mLruProcessServiceStart; 2561 inActivity = true; 2562 inService = true; 2563 } else { 2564 // Process not otherwise of interest, it goes to the top of the non-service area. 2565 addIndex = mLruProcessServiceStart; 2566 if (client != null) { 2567 int clientIndex = mLruProcesses.lastIndexOf(client); 2568 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2569 + app); 2570 if (clientIndex >= 0 && addIndex > clientIndex) { 2571 addIndex = clientIndex; 2572 } 2573 } 2574 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2575 } 2576 2577 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2578 + mLruProcessActivityStart + "): " + app); 2579 */ 2580 2581 if (lrui >= 0) { 2582 if (lrui < mLruProcessActivityStart) { 2583 mLruProcessActivityStart--; 2584 } 2585 if (lrui < mLruProcessServiceStart) { 2586 mLruProcessServiceStart--; 2587 } 2588 /* 2589 if (addIndex > lrui) { 2590 addIndex--; 2591 } 2592 if (nextIndex > lrui) { 2593 nextIndex--; 2594 } 2595 */ 2596 mLruProcesses.remove(lrui); 2597 } 2598 2599 /* 2600 mLruProcesses.add(addIndex, app); 2601 if (inActivity) { 2602 mLruProcessActivityStart++; 2603 } 2604 if (inService) { 2605 mLruProcessActivityStart++; 2606 } 2607 */ 2608 2609 int nextIndex; 2610 if (hasActivity) { 2611 final int N = mLruProcesses.size(); 2612 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2613 // Process doesn't have activities, but has clients with 2614 // activities... move it up, but one below the top (the top 2615 // should always have a real activity). 2616 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2617 mLruProcesses.add(N-1, app); 2618 // To keep it from spamming the LRU list (by making a bunch of clients), 2619 // we will push down any other entries owned by the app. 2620 final int uid = app.info.uid; 2621 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2622 ProcessRecord subProc = mLruProcesses.get(i); 2623 if (subProc.info.uid == uid) { 2624 // We want to push this one down the list. If the process after 2625 // it is for the same uid, however, don't do so, because we don't 2626 // want them internally to be re-ordered. 2627 if (mLruProcesses.get(i-1).info.uid != uid) { 2628 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2629 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2630 ProcessRecord tmp = mLruProcesses.get(i); 2631 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2632 mLruProcesses.set(i-1, tmp); 2633 i--; 2634 } 2635 } else { 2636 // A gap, we can stop here. 2637 break; 2638 } 2639 } 2640 } else { 2641 // Process has activities, put it at the very tipsy-top. 2642 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2643 mLruProcesses.add(app); 2644 } 2645 nextIndex = mLruProcessServiceStart; 2646 } else if (hasService) { 2647 // Process has services, put it at the top of the service list. 2648 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2649 mLruProcesses.add(mLruProcessActivityStart, app); 2650 nextIndex = mLruProcessServiceStart; 2651 mLruProcessActivityStart++; 2652 } else { 2653 // Process not otherwise of interest, it goes to the top of the non-service area. 2654 int index = mLruProcessServiceStart; 2655 if (client != null) { 2656 // If there is a client, don't allow the process to be moved up higher 2657 // in the list than that client. 2658 int clientIndex = mLruProcesses.lastIndexOf(client); 2659 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2660 + " when updating " + app); 2661 if (clientIndex <= lrui) { 2662 // Don't allow the client index restriction to push it down farther in the 2663 // list than it already is. 2664 clientIndex = lrui; 2665 } 2666 if (clientIndex >= 0 && index > clientIndex) { 2667 index = clientIndex; 2668 } 2669 } 2670 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2671 mLruProcesses.add(index, app); 2672 nextIndex = index-1; 2673 mLruProcessActivityStart++; 2674 mLruProcessServiceStart++; 2675 } 2676 2677 // If the app is currently using a content provider or service, 2678 // bump those processes as well. 2679 for (int j=app.connections.size()-1; j>=0; j--) { 2680 ConnectionRecord cr = app.connections.valueAt(j); 2681 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2682 && cr.binding.service.app != null 2683 && cr.binding.service.app.lruSeq != mLruSeq 2684 && !cr.binding.service.app.persistent) { 2685 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2686 "service connection", cr, app); 2687 } 2688 } 2689 for (int j=app.conProviders.size()-1; j>=0; j--) { 2690 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2691 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2692 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2693 "provider reference", cpr, app); 2694 } 2695 } 2696 } 2697 2698 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2699 if (uid == Process.SYSTEM_UID) { 2700 // The system gets to run in any process. If there are multiple 2701 // processes with the same uid, just pick the first (this 2702 // should never happen). 2703 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2704 if (procs == null) return null; 2705 final int N = procs.size(); 2706 for (int i = 0; i < N; i++) { 2707 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2708 } 2709 } 2710 ProcessRecord proc = mProcessNames.get(processName, uid); 2711 if (false && proc != null && !keepIfLarge 2712 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2713 && proc.lastCachedPss >= 4000) { 2714 // Turn this condition on to cause killing to happen regularly, for testing. 2715 if (proc.baseProcessTracker != null) { 2716 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2717 } 2718 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2719 } else if (proc != null && !keepIfLarge 2720 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2721 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2722 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2723 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2724 if (proc.baseProcessTracker != null) { 2725 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2726 } 2727 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2728 } 2729 } 2730 return proc; 2731 } 2732 2733 void ensurePackageDexOpt(String packageName) { 2734 IPackageManager pm = AppGlobals.getPackageManager(); 2735 try { 2736 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2737 mDidDexOpt = true; 2738 } 2739 } catch (RemoteException e) { 2740 } 2741 } 2742 2743 boolean isNextTransitionForward() { 2744 int transit = mWindowManager.getPendingAppTransition(); 2745 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2746 || transit == AppTransition.TRANSIT_TASK_OPEN 2747 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2748 } 2749 2750 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2751 String processName, String abiOverride, int uid, Runnable crashHandler) { 2752 synchronized(this) { 2753 ApplicationInfo info = new ApplicationInfo(); 2754 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2755 // For isolated processes, the former contains the parent's uid and the latter the 2756 // actual uid of the isolated process. 2757 // In the special case introduced by this method (which is, starting an isolated 2758 // process directly from the SystemServer without an actual parent app process) the 2759 // closest thing to a parent's uid is SYSTEM_UID. 2760 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2761 // the |isolated| logic in the ProcessRecord constructor. 2762 info.uid = Process.SYSTEM_UID; 2763 info.processName = processName; 2764 info.className = entryPoint; 2765 info.packageName = "android"; 2766 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2767 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2768 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2769 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2770 crashHandler); 2771 return proc != null ? proc.pid : 0; 2772 } 2773 } 2774 2775 final ProcessRecord startProcessLocked(String processName, 2776 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2777 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2778 boolean isolated, boolean keepIfLarge) { 2779 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2780 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2781 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2782 null /* crashHandler */); 2783 } 2784 2785 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2786 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2787 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2788 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2789 long startTime = SystemClock.elapsedRealtime(); 2790 ProcessRecord app; 2791 if (!isolated) { 2792 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2793 checkTime(startTime, "startProcess: after getProcessRecord"); 2794 } else { 2795 // If this is an isolated process, it can't re-use an existing process. 2796 app = null; 2797 } 2798 // We don't have to do anything more if: 2799 // (1) There is an existing application record; and 2800 // (2) The caller doesn't think it is dead, OR there is no thread 2801 // object attached to it so we know it couldn't have crashed; and 2802 // (3) There is a pid assigned to it, so it is either starting or 2803 // already running. 2804 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2805 + " app=" + app + " knownToBeDead=" + knownToBeDead 2806 + " thread=" + (app != null ? app.thread : null) 2807 + " pid=" + (app != null ? app.pid : -1)); 2808 if (app != null && app.pid > 0) { 2809 if (!knownToBeDead || app.thread == null) { 2810 // We already have the app running, or are waiting for it to 2811 // come up (we have a pid but not yet its thread), so keep it. 2812 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2813 // If this is a new package in the process, add the package to the list 2814 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2815 checkTime(startTime, "startProcess: done, added package to proc"); 2816 return app; 2817 } 2818 2819 // An application record is attached to a previous process, 2820 // clean it up now. 2821 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2822 checkTime(startTime, "startProcess: bad proc running, killing"); 2823 Process.killProcessGroup(app.info.uid, app.pid); 2824 handleAppDiedLocked(app, true, true); 2825 checkTime(startTime, "startProcess: done killing old proc"); 2826 } 2827 2828 String hostingNameStr = hostingName != null 2829 ? hostingName.flattenToShortString() : null; 2830 2831 if (!isolated) { 2832 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2833 // If we are in the background, then check to see if this process 2834 // is bad. If so, we will just silently fail. 2835 if (mBadProcesses.get(info.processName, info.uid) != null) { 2836 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2837 + "/" + info.processName); 2838 return null; 2839 } 2840 } else { 2841 // When the user is explicitly starting a process, then clear its 2842 // crash count so that we won't make it bad until they see at 2843 // least one crash dialog again, and make the process good again 2844 // if it had been bad. 2845 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2846 + "/" + info.processName); 2847 mProcessCrashTimes.remove(info.processName, info.uid); 2848 if (mBadProcesses.get(info.processName, info.uid) != null) { 2849 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2850 UserHandle.getUserId(info.uid), info.uid, 2851 info.processName); 2852 mBadProcesses.remove(info.processName, info.uid); 2853 if (app != null) { 2854 app.bad = false; 2855 } 2856 } 2857 } 2858 } 2859 2860 if (app == null) { 2861 checkTime(startTime, "startProcess: creating new process record"); 2862 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2863 app.crashHandler = crashHandler; 2864 if (app == null) { 2865 Slog.w(TAG, "Failed making new process record for " 2866 + processName + "/" + info.uid + " isolated=" + isolated); 2867 return null; 2868 } 2869 mProcessNames.put(processName, app.uid, app); 2870 if (isolated) { 2871 mIsolatedProcesses.put(app.uid, app); 2872 } 2873 checkTime(startTime, "startProcess: done creating new process record"); 2874 } else { 2875 // If this is a new package in the process, add the package to the list 2876 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2877 checkTime(startTime, "startProcess: added package to existing proc"); 2878 } 2879 2880 // If the system is not ready yet, then hold off on starting this 2881 // process until it is. 2882 if (!mProcessesReady 2883 && !isAllowedWhileBooting(info) 2884 && !allowWhileBooting) { 2885 if (!mProcessesOnHold.contains(app)) { 2886 mProcessesOnHold.add(app); 2887 } 2888 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2889 checkTime(startTime, "startProcess: returning with proc on hold"); 2890 return app; 2891 } 2892 2893 checkTime(startTime, "startProcess: stepping in to startProcess"); 2894 startProcessLocked( 2895 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2896 checkTime(startTime, "startProcess: done starting proc!"); 2897 return (app.pid != 0) ? app : null; 2898 } 2899 2900 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2901 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2902 } 2903 2904 private final void startProcessLocked(ProcessRecord app, 2905 String hostingType, String hostingNameStr) { 2906 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2907 null /* entryPoint */, null /* entryPointArgs */); 2908 } 2909 2910 private final void startProcessLocked(ProcessRecord app, String hostingType, 2911 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2912 long startTime = SystemClock.elapsedRealtime(); 2913 if (app.pid > 0 && app.pid != MY_PID) { 2914 checkTime(startTime, "startProcess: removing from pids map"); 2915 synchronized (mPidsSelfLocked) { 2916 mPidsSelfLocked.remove(app.pid); 2917 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2918 } 2919 checkTime(startTime, "startProcess: done removing from pids map"); 2920 app.setPid(0); 2921 } 2922 2923 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2924 "startProcessLocked removing on hold: " + app); 2925 mProcessesOnHold.remove(app); 2926 2927 checkTime(startTime, "startProcess: starting to update cpu stats"); 2928 updateCpuStats(); 2929 checkTime(startTime, "startProcess: done updating cpu stats"); 2930 2931 try { 2932 int uid = app.uid; 2933 2934 int[] gids = null; 2935 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2936 if (!app.isolated) { 2937 int[] permGids = null; 2938 try { 2939 checkTime(startTime, "startProcess: getting gids from package manager"); 2940 final PackageManager pm = mContext.getPackageManager(); 2941 permGids = pm.getPackageGids(app.info.packageName); 2942 2943 if (Environment.isExternalStorageEmulated()) { 2944 checkTime(startTime, "startProcess: checking external storage perm"); 2945 if (pm.checkPermission( 2946 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2947 app.info.packageName) == PERMISSION_GRANTED) { 2948 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2949 } else { 2950 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2951 } 2952 } 2953 } catch (PackageManager.NameNotFoundException e) { 2954 Slog.w(TAG, "Unable to retrieve gids", e); 2955 } 2956 2957 /* 2958 * Add shared application and profile GIDs so applications can share some 2959 * resources like shared libraries and access user-wide resources 2960 */ 2961 if (permGids == null) { 2962 gids = new int[2]; 2963 } else { 2964 gids = new int[permGids.length + 2]; 2965 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2966 } 2967 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2968 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2969 } 2970 checkTime(startTime, "startProcess: building args"); 2971 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2972 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2973 && mTopComponent != null 2974 && app.processName.equals(mTopComponent.getPackageName())) { 2975 uid = 0; 2976 } 2977 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2978 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2979 uid = 0; 2980 } 2981 } 2982 int debugFlags = 0; 2983 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2984 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2985 // Also turn on CheckJNI for debuggable apps. It's quite 2986 // awkward to turn on otherwise. 2987 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2988 } 2989 // Run the app in safe mode if its manifest requests so or the 2990 // system is booted in safe mode. 2991 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2992 mSafeMode == true) { 2993 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2994 } 2995 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2996 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2997 } 2998 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2999 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3000 } 3001 if ("1".equals(SystemProperties.get("debug.assert"))) { 3002 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3003 } 3004 3005 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3006 if (requiredAbi == null) { 3007 requiredAbi = Build.SUPPORTED_ABIS[0]; 3008 } 3009 3010 String instructionSet = null; 3011 if (app.info.primaryCpuAbi != null) { 3012 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3013 } 3014 3015 // Start the process. It will either succeed and return a result containing 3016 // the PID of the new process, or else throw a RuntimeException. 3017 boolean isActivityProcess = (entryPoint == null); 3018 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3019 checkTime(startTime, "startProcess: asking zygote to start proc"); 3020 Process.ProcessStartResult startResult = Process.start(entryPoint, 3021 app.processName, uid, uid, gids, debugFlags, mountExternal, 3022 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3023 app.info.dataDir, entryPointArgs); 3024 checkTime(startTime, "startProcess: returned from zygote!"); 3025 3026 if (app.isolated) { 3027 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3028 } 3029 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3030 checkTime(startTime, "startProcess: done updating battery stats"); 3031 3032 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3033 UserHandle.getUserId(uid), startResult.pid, uid, 3034 app.processName, hostingType, 3035 hostingNameStr != null ? hostingNameStr : ""); 3036 3037 if (app.persistent) { 3038 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3039 } 3040 3041 checkTime(startTime, "startProcess: building log message"); 3042 StringBuilder buf = mStringBuilder; 3043 buf.setLength(0); 3044 buf.append("Start proc "); 3045 buf.append(app.processName); 3046 if (!isActivityProcess) { 3047 buf.append(" ["); 3048 buf.append(entryPoint); 3049 buf.append("]"); 3050 } 3051 buf.append(" for "); 3052 buf.append(hostingType); 3053 if (hostingNameStr != null) { 3054 buf.append(" "); 3055 buf.append(hostingNameStr); 3056 } 3057 buf.append(": pid="); 3058 buf.append(startResult.pid); 3059 buf.append(" uid="); 3060 buf.append(uid); 3061 buf.append(" gids={"); 3062 if (gids != null) { 3063 for (int gi=0; gi<gids.length; gi++) { 3064 if (gi != 0) buf.append(", "); 3065 buf.append(gids[gi]); 3066 3067 } 3068 } 3069 buf.append("}"); 3070 if (requiredAbi != null) { 3071 buf.append(" abi="); 3072 buf.append(requiredAbi); 3073 } 3074 Slog.i(TAG, buf.toString()); 3075 app.setPid(startResult.pid); 3076 app.usingWrapper = startResult.usingWrapper; 3077 app.removed = false; 3078 app.killed = false; 3079 app.killedByAm = false; 3080 checkTime(startTime, "startProcess: starting to update pids map"); 3081 synchronized (mPidsSelfLocked) { 3082 this.mPidsSelfLocked.put(startResult.pid, app); 3083 if (isActivityProcess) { 3084 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3085 msg.obj = app; 3086 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3087 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3088 } 3089 } 3090 checkTime(startTime, "startProcess: done updating pids map"); 3091 } catch (RuntimeException e) { 3092 // XXX do better error recovery. 3093 app.setPid(0); 3094 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3095 if (app.isolated) { 3096 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3097 } 3098 Slog.e(TAG, "Failure starting process " + app.processName, e); 3099 } 3100 } 3101 3102 void updateUsageStats(ActivityRecord component, boolean resumed) { 3103 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3104 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3105 if (resumed) { 3106 if (mUsageStatsService != null) { 3107 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3108 UsageEvents.Event.MOVE_TO_FOREGROUND); 3109 } 3110 synchronized (stats) { 3111 stats.noteActivityResumedLocked(component.app.uid); 3112 } 3113 } else { 3114 if (mUsageStatsService != null) { 3115 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3116 UsageEvents.Event.MOVE_TO_BACKGROUND); 3117 } 3118 synchronized (stats) { 3119 stats.noteActivityPausedLocked(component.app.uid); 3120 } 3121 } 3122 } 3123 3124 Intent getHomeIntent() { 3125 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3126 intent.setComponent(mTopComponent); 3127 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3128 intent.addCategory(Intent.CATEGORY_HOME); 3129 } 3130 return intent; 3131 } 3132 3133 boolean startHomeActivityLocked(int userId) { 3134 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3135 && mTopAction == null) { 3136 // We are running in factory test mode, but unable to find 3137 // the factory test app, so just sit around displaying the 3138 // error message and don't try to start anything. 3139 return false; 3140 } 3141 Intent intent = getHomeIntent(); 3142 ActivityInfo aInfo = 3143 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3144 if (aInfo != null) { 3145 intent.setComponent(new ComponentName( 3146 aInfo.applicationInfo.packageName, aInfo.name)); 3147 // Don't do this if the home app is currently being 3148 // instrumented. 3149 aInfo = new ActivityInfo(aInfo); 3150 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3151 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3152 aInfo.applicationInfo.uid, true); 3153 if (app == null || app.instrumentationClass == null) { 3154 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3155 mStackSupervisor.startHomeActivity(intent, aInfo); 3156 } 3157 } 3158 3159 return true; 3160 } 3161 3162 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3163 ActivityInfo ai = null; 3164 ComponentName comp = intent.getComponent(); 3165 try { 3166 if (comp != null) { 3167 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3168 } else { 3169 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3170 intent, 3171 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3172 flags, userId); 3173 3174 if (info != null) { 3175 ai = info.activityInfo; 3176 } 3177 } 3178 } catch (RemoteException e) { 3179 // ignore 3180 } 3181 3182 return ai; 3183 } 3184 3185 /** 3186 * Starts the "new version setup screen" if appropriate. 3187 */ 3188 void startSetupActivityLocked() { 3189 // Only do this once per boot. 3190 if (mCheckedForSetup) { 3191 return; 3192 } 3193 3194 // We will show this screen if the current one is a different 3195 // version than the last one shown, and we are not running in 3196 // low-level factory test mode. 3197 final ContentResolver resolver = mContext.getContentResolver(); 3198 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3199 Settings.Global.getInt(resolver, 3200 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3201 mCheckedForSetup = true; 3202 3203 // See if we should be showing the platform update setup UI. 3204 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3205 List<ResolveInfo> ris = mContext.getPackageManager() 3206 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3207 3208 // We don't allow third party apps to replace this. 3209 ResolveInfo ri = null; 3210 for (int i=0; ris != null && i<ris.size(); i++) { 3211 if ((ris.get(i).activityInfo.applicationInfo.flags 3212 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3213 ri = ris.get(i); 3214 break; 3215 } 3216 } 3217 3218 if (ri != null) { 3219 String vers = ri.activityInfo.metaData != null 3220 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3221 : null; 3222 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3223 vers = ri.activityInfo.applicationInfo.metaData.getString( 3224 Intent.METADATA_SETUP_VERSION); 3225 } 3226 String lastVers = Settings.Secure.getString( 3227 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3228 if (vers != null && !vers.equals(lastVers)) { 3229 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3230 intent.setComponent(new ComponentName( 3231 ri.activityInfo.packageName, ri.activityInfo.name)); 3232 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3233 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3234 null); 3235 } 3236 } 3237 } 3238 } 3239 3240 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3241 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3242 } 3243 3244 void enforceNotIsolatedCaller(String caller) { 3245 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3246 throw new SecurityException("Isolated process not allowed to call " + caller); 3247 } 3248 } 3249 3250 void enforceShellRestriction(String restriction, int userHandle) { 3251 if (Binder.getCallingUid() == Process.SHELL_UID) { 3252 if (userHandle < 0 3253 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3254 throw new SecurityException("Shell does not have permission to access user " 3255 + userHandle); 3256 } 3257 } 3258 } 3259 3260 @Override 3261 public int getFrontActivityScreenCompatMode() { 3262 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3263 synchronized (this) { 3264 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3265 } 3266 } 3267 3268 @Override 3269 public void setFrontActivityScreenCompatMode(int mode) { 3270 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3271 "setFrontActivityScreenCompatMode"); 3272 synchronized (this) { 3273 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3274 } 3275 } 3276 3277 @Override 3278 public int getPackageScreenCompatMode(String packageName) { 3279 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3280 synchronized (this) { 3281 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3282 } 3283 } 3284 3285 @Override 3286 public void setPackageScreenCompatMode(String packageName, int mode) { 3287 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3288 "setPackageScreenCompatMode"); 3289 synchronized (this) { 3290 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3291 } 3292 } 3293 3294 @Override 3295 public boolean getPackageAskScreenCompat(String packageName) { 3296 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3297 synchronized (this) { 3298 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3299 } 3300 } 3301 3302 @Override 3303 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3304 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3305 "setPackageAskScreenCompat"); 3306 synchronized (this) { 3307 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3308 } 3309 } 3310 3311 private void dispatchProcessesChanged() { 3312 int N; 3313 synchronized (this) { 3314 N = mPendingProcessChanges.size(); 3315 if (mActiveProcessChanges.length < N) { 3316 mActiveProcessChanges = new ProcessChangeItem[N]; 3317 } 3318 mPendingProcessChanges.toArray(mActiveProcessChanges); 3319 mAvailProcessChanges.addAll(mPendingProcessChanges); 3320 mPendingProcessChanges.clear(); 3321 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3322 } 3323 3324 int i = mProcessObservers.beginBroadcast(); 3325 while (i > 0) { 3326 i--; 3327 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3328 if (observer != null) { 3329 try { 3330 for (int j=0; j<N; j++) { 3331 ProcessChangeItem item = mActiveProcessChanges[j]; 3332 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3333 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3334 + item.pid + " uid=" + item.uid + ": " 3335 + item.foregroundActivities); 3336 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3337 item.foregroundActivities); 3338 } 3339 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3340 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3341 + item.pid + " uid=" + item.uid + ": " + item.processState); 3342 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3343 } 3344 } 3345 } catch (RemoteException e) { 3346 } 3347 } 3348 } 3349 mProcessObservers.finishBroadcast(); 3350 } 3351 3352 private void dispatchProcessDied(int pid, int uid) { 3353 int i = mProcessObservers.beginBroadcast(); 3354 while (i > 0) { 3355 i--; 3356 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3357 if (observer != null) { 3358 try { 3359 observer.onProcessDied(pid, uid); 3360 } catch (RemoteException e) { 3361 } 3362 } 3363 } 3364 mProcessObservers.finishBroadcast(); 3365 } 3366 3367 @Override 3368 public final int startActivity(IApplicationThread caller, String callingPackage, 3369 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3370 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3371 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3372 resultWho, requestCode, startFlags, profilerInfo, options, 3373 UserHandle.getCallingUserId()); 3374 } 3375 3376 @Override 3377 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3378 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3379 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3380 enforceNotIsolatedCaller("startActivity"); 3381 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3382 false, ALLOW_FULL_ONLY, "startActivity", null); 3383 // TODO: Switch to user app stacks here. 3384 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3385 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3386 profilerInfo, null, null, options, userId, null, null); 3387 } 3388 3389 @Override 3390 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3391 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3392 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3393 3394 // This is very dangerous -- it allows you to perform a start activity (including 3395 // permission grants) as any app that may launch one of your own activities. So 3396 // we will only allow this to be done from activities that are part of the core framework, 3397 // and then only when they are running as the system. 3398 final ActivityRecord sourceRecord; 3399 final int targetUid; 3400 final String targetPackage; 3401 synchronized (this) { 3402 if (resultTo == null) { 3403 throw new SecurityException("Must be called from an activity"); 3404 } 3405 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3406 if (sourceRecord == null) { 3407 throw new SecurityException("Called with bad activity token: " + resultTo); 3408 } 3409 if (!sourceRecord.info.packageName.equals("android")) { 3410 throw new SecurityException( 3411 "Must be called from an activity that is declared in the android package"); 3412 } 3413 if (sourceRecord.app == null) { 3414 throw new SecurityException("Called without a process attached to activity"); 3415 } 3416 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3417 // This is still okay, as long as this activity is running under the 3418 // uid of the original calling activity. 3419 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3420 throw new SecurityException( 3421 "Calling activity in uid " + sourceRecord.app.uid 3422 + " must be system uid or original calling uid " 3423 + sourceRecord.launchedFromUid); 3424 } 3425 } 3426 targetUid = sourceRecord.launchedFromUid; 3427 targetPackage = sourceRecord.launchedFromPackage; 3428 } 3429 3430 if (userId == UserHandle.USER_NULL) { 3431 userId = UserHandle.getUserId(sourceRecord.app.uid); 3432 } 3433 3434 // TODO: Switch to user app stacks here. 3435 try { 3436 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3437 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3438 null, null, options, userId, null, null); 3439 return ret; 3440 } catch (SecurityException e) { 3441 // XXX need to figure out how to propagate to original app. 3442 // A SecurityException here is generally actually a fault of the original 3443 // calling activity (such as a fairly granting permissions), so propagate it 3444 // back to them. 3445 /* 3446 StringBuilder msg = new StringBuilder(); 3447 msg.append("While launching"); 3448 msg.append(intent.toString()); 3449 msg.append(": "); 3450 msg.append(e.getMessage()); 3451 */ 3452 throw e; 3453 } 3454 } 3455 3456 @Override 3457 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3458 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3459 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3460 enforceNotIsolatedCaller("startActivityAndWait"); 3461 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3462 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3463 WaitResult res = new WaitResult(); 3464 // TODO: Switch to user app stacks here. 3465 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3466 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3467 options, userId, null, null); 3468 return res; 3469 } 3470 3471 @Override 3472 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3473 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3474 int startFlags, Configuration config, Bundle options, int userId) { 3475 enforceNotIsolatedCaller("startActivityWithConfig"); 3476 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3477 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3478 // TODO: Switch to user app stacks here. 3479 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3480 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3481 null, null, config, options, userId, null, null); 3482 return ret; 3483 } 3484 3485 @Override 3486 public int startActivityIntentSender(IApplicationThread caller, 3487 IntentSender intent, Intent fillInIntent, String resolvedType, 3488 IBinder resultTo, String resultWho, int requestCode, 3489 int flagsMask, int flagsValues, Bundle options) { 3490 enforceNotIsolatedCaller("startActivityIntentSender"); 3491 // Refuse possible leaked file descriptors 3492 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3493 throw new IllegalArgumentException("File descriptors passed in Intent"); 3494 } 3495 3496 IIntentSender sender = intent.getTarget(); 3497 if (!(sender instanceof PendingIntentRecord)) { 3498 throw new IllegalArgumentException("Bad PendingIntent object"); 3499 } 3500 3501 PendingIntentRecord pir = (PendingIntentRecord)sender; 3502 3503 synchronized (this) { 3504 // If this is coming from the currently resumed activity, it is 3505 // effectively saying that app switches are allowed at this point. 3506 final ActivityStack stack = getFocusedStack(); 3507 if (stack.mResumedActivity != null && 3508 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3509 mAppSwitchesAllowedTime = 0; 3510 } 3511 } 3512 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3513 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3514 return ret; 3515 } 3516 3517 @Override 3518 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3519 Intent intent, String resolvedType, IVoiceInteractionSession session, 3520 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3521 Bundle options, int userId) { 3522 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3523 != PackageManager.PERMISSION_GRANTED) { 3524 String msg = "Permission Denial: startVoiceActivity() from pid=" 3525 + Binder.getCallingPid() 3526 + ", uid=" + Binder.getCallingUid() 3527 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3528 Slog.w(TAG, msg); 3529 throw new SecurityException(msg); 3530 } 3531 if (session == null || interactor == null) { 3532 throw new NullPointerException("null session or interactor"); 3533 } 3534 userId = handleIncomingUser(callingPid, callingUid, userId, 3535 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3536 // TODO: Switch to user app stacks here. 3537 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3538 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3539 null, options, userId, null, null); 3540 } 3541 3542 @Override 3543 public boolean startNextMatchingActivity(IBinder callingActivity, 3544 Intent intent, Bundle options) { 3545 // Refuse possible leaked file descriptors 3546 if (intent != null && intent.hasFileDescriptors() == true) { 3547 throw new IllegalArgumentException("File descriptors passed in Intent"); 3548 } 3549 3550 synchronized (this) { 3551 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3552 if (r == null) { 3553 ActivityOptions.abort(options); 3554 return false; 3555 } 3556 if (r.app == null || r.app.thread == null) { 3557 // The caller is not running... d'oh! 3558 ActivityOptions.abort(options); 3559 return false; 3560 } 3561 intent = new Intent(intent); 3562 // The caller is not allowed to change the data. 3563 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3564 // And we are resetting to find the next component... 3565 intent.setComponent(null); 3566 3567 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3568 3569 ActivityInfo aInfo = null; 3570 try { 3571 List<ResolveInfo> resolves = 3572 AppGlobals.getPackageManager().queryIntentActivities( 3573 intent, r.resolvedType, 3574 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3575 UserHandle.getCallingUserId()); 3576 3577 // Look for the original activity in the list... 3578 final int N = resolves != null ? resolves.size() : 0; 3579 for (int i=0; i<N; i++) { 3580 ResolveInfo rInfo = resolves.get(i); 3581 if (rInfo.activityInfo.packageName.equals(r.packageName) 3582 && rInfo.activityInfo.name.equals(r.info.name)) { 3583 // We found the current one... the next matching is 3584 // after it. 3585 i++; 3586 if (i<N) { 3587 aInfo = resolves.get(i).activityInfo; 3588 } 3589 if (debug) { 3590 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3591 + "/" + r.info.name); 3592 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3593 + "/" + aInfo.name); 3594 } 3595 break; 3596 } 3597 } 3598 } catch (RemoteException e) { 3599 } 3600 3601 if (aInfo == null) { 3602 // Nobody who is next! 3603 ActivityOptions.abort(options); 3604 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3605 return false; 3606 } 3607 3608 intent.setComponent(new ComponentName( 3609 aInfo.applicationInfo.packageName, aInfo.name)); 3610 intent.setFlags(intent.getFlags()&~( 3611 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3612 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3613 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3614 Intent.FLAG_ACTIVITY_NEW_TASK)); 3615 3616 // Okay now we need to start the new activity, replacing the 3617 // currently running activity. This is a little tricky because 3618 // we want to start the new one as if the current one is finished, 3619 // but not finish the current one first so that there is no flicker. 3620 // And thus... 3621 final boolean wasFinishing = r.finishing; 3622 r.finishing = true; 3623 3624 // Propagate reply information over to the new activity. 3625 final ActivityRecord resultTo = r.resultTo; 3626 final String resultWho = r.resultWho; 3627 final int requestCode = r.requestCode; 3628 r.resultTo = null; 3629 if (resultTo != null) { 3630 resultTo.removeResultsLocked(r, resultWho, requestCode); 3631 } 3632 3633 final long origId = Binder.clearCallingIdentity(); 3634 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3635 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3636 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3637 -1, r.launchedFromUid, 0, options, false, null, null, null); 3638 Binder.restoreCallingIdentity(origId); 3639 3640 r.finishing = wasFinishing; 3641 if (res != ActivityManager.START_SUCCESS) { 3642 return false; 3643 } 3644 return true; 3645 } 3646 } 3647 3648 @Override 3649 public final int startActivityFromRecents(int taskId, Bundle options) { 3650 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3651 String msg = "Permission Denial: startActivityFromRecents called without " + 3652 START_TASKS_FROM_RECENTS; 3653 Slog.w(TAG, msg); 3654 throw new SecurityException(msg); 3655 } 3656 return startActivityFromRecentsInner(taskId, options); 3657 } 3658 3659 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3660 final TaskRecord task; 3661 final int callingUid; 3662 final String callingPackage; 3663 final Intent intent; 3664 final int userId; 3665 synchronized (this) { 3666 task = recentTaskForIdLocked(taskId); 3667 if (task == null) { 3668 throw new IllegalArgumentException("Task " + taskId + " not found."); 3669 } 3670 callingUid = task.mCallingUid; 3671 callingPackage = task.mCallingPackage; 3672 intent = task.intent; 3673 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3674 userId = task.userId; 3675 } 3676 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3677 options, userId, null, task); 3678 } 3679 3680 final int startActivityInPackage(int uid, String callingPackage, 3681 Intent intent, String resolvedType, IBinder resultTo, 3682 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3683 IActivityContainer container, TaskRecord inTask) { 3684 3685 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3686 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3687 3688 // TODO: Switch to user app stacks here. 3689 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3690 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3691 null, null, null, options, userId, container, inTask); 3692 return ret; 3693 } 3694 3695 @Override 3696 public final int startActivities(IApplicationThread caller, String callingPackage, 3697 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3698 int userId) { 3699 enforceNotIsolatedCaller("startActivities"); 3700 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3701 false, ALLOW_FULL_ONLY, "startActivity", null); 3702 // TODO: Switch to user app stacks here. 3703 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3704 resolvedTypes, resultTo, options, userId); 3705 return ret; 3706 } 3707 3708 final int startActivitiesInPackage(int uid, String callingPackage, 3709 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3710 Bundle options, int userId) { 3711 3712 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3713 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3714 // TODO: Switch to user app stacks here. 3715 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3716 resultTo, options, userId); 3717 return ret; 3718 } 3719 3720 //explicitly remove thd old information in mRecentTasks when removing existing user. 3721 private void removeRecentTasksForUserLocked(int userId) { 3722 if(userId <= 0) { 3723 Slog.i(TAG, "Can't remove recent task on user " + userId); 3724 return; 3725 } 3726 3727 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3728 TaskRecord tr = mRecentTasks.get(i); 3729 if (tr.userId == userId) { 3730 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3731 + " when finishing user" + userId); 3732 mRecentTasks.remove(i); 3733 tr.removedFromRecents(mTaskPersister); 3734 } 3735 } 3736 3737 // Remove tasks from persistent storage. 3738 mTaskPersister.wakeup(null, true); 3739 } 3740 3741 // Sort by taskId 3742 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3743 @Override 3744 public int compare(TaskRecord lhs, TaskRecord rhs) { 3745 return rhs.taskId - lhs.taskId; 3746 } 3747 }; 3748 3749 // Extract the affiliates of the chain containing mRecentTasks[start]. 3750 private int processNextAffiliateChain(int start) { 3751 final TaskRecord startTask = mRecentTasks.get(start); 3752 final int affiliateId = startTask.mAffiliatedTaskId; 3753 3754 // Quick identification of isolated tasks. I.e. those not launched behind. 3755 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3756 startTask.mNextAffiliate == null) { 3757 // There is still a slim chance that there are other tasks that point to this task 3758 // and that the chain is so messed up that this task no longer points to them but 3759 // the gain of this optimization outweighs the risk. 3760 startTask.inRecents = true; 3761 return start + 1; 3762 } 3763 3764 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3765 mTmpRecents.clear(); 3766 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3767 final TaskRecord task = mRecentTasks.get(i); 3768 if (task.mAffiliatedTaskId == affiliateId) { 3769 mRecentTasks.remove(i); 3770 mTmpRecents.add(task); 3771 } 3772 } 3773 3774 // Sort them all by taskId. That is the order they were create in and that order will 3775 // always be correct. 3776 Collections.sort(mTmpRecents, mTaskRecordComparator); 3777 3778 // Go through and fix up the linked list. 3779 // The first one is the end of the chain and has no next. 3780 final TaskRecord first = mTmpRecents.get(0); 3781 first.inRecents = true; 3782 if (first.mNextAffiliate != null) { 3783 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3784 first.setNextAffiliate(null); 3785 mTaskPersister.wakeup(first, false); 3786 } 3787 // Everything in the middle is doubly linked from next to prev. 3788 final int tmpSize = mTmpRecents.size(); 3789 for (int i = 0; i < tmpSize - 1; ++i) { 3790 final TaskRecord next = mTmpRecents.get(i); 3791 final TaskRecord prev = mTmpRecents.get(i + 1); 3792 if (next.mPrevAffiliate != prev) { 3793 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3794 " setting prev=" + prev); 3795 next.setPrevAffiliate(prev); 3796 mTaskPersister.wakeup(next, false); 3797 } 3798 if (prev.mNextAffiliate != next) { 3799 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3800 " setting next=" + next); 3801 prev.setNextAffiliate(next); 3802 mTaskPersister.wakeup(prev, false); 3803 } 3804 prev.inRecents = true; 3805 } 3806 // The last one is the beginning of the list and has no prev. 3807 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3808 if (last.mPrevAffiliate != null) { 3809 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3810 last.setPrevAffiliate(null); 3811 mTaskPersister.wakeup(last, false); 3812 } 3813 3814 // Insert the group back into mRecentTasks at start. 3815 mRecentTasks.addAll(start, mTmpRecents); 3816 3817 // Let the caller know where we left off. 3818 return start + tmpSize; 3819 } 3820 3821 /** 3822 * Update the recent tasks lists: make sure tasks should still be here (their 3823 * applications / activities still exist), update their availability, fixup ordering 3824 * of affiliations. 3825 */ 3826 void cleanupRecentTasksLocked(int userId) { 3827 if (mRecentTasks == null) { 3828 // Happens when called from the packagemanager broadcast before boot. 3829 return; 3830 } 3831 3832 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3833 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3834 final IPackageManager pm = AppGlobals.getPackageManager(); 3835 final ActivityInfo dummyAct = new ActivityInfo(); 3836 final ApplicationInfo dummyApp = new ApplicationInfo(); 3837 3838 int N = mRecentTasks.size(); 3839 3840 int[] users = userId == UserHandle.USER_ALL 3841 ? getUsersLocked() : new int[] { userId }; 3842 for (int user : users) { 3843 for (int i = 0; i < N; i++) { 3844 TaskRecord task = mRecentTasks.get(i); 3845 if (task.userId != user) { 3846 // Only look at tasks for the user ID of interest. 3847 continue; 3848 } 3849 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3850 // This situation is broken, and we should just get rid of it now. 3851 mRecentTasks.remove(i); 3852 task.removedFromRecents(mTaskPersister); 3853 i--; 3854 N--; 3855 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3856 continue; 3857 } 3858 // Check whether this activity is currently available. 3859 if (task.realActivity != null) { 3860 ActivityInfo ai = availActCache.get(task.realActivity); 3861 if (ai == null) { 3862 try { 3863 ai = pm.getActivityInfo(task.realActivity, 3864 PackageManager.GET_UNINSTALLED_PACKAGES 3865 | PackageManager.GET_DISABLED_COMPONENTS, user); 3866 } catch (RemoteException e) { 3867 // Will never happen. 3868 continue; 3869 } 3870 if (ai == null) { 3871 ai = dummyAct; 3872 } 3873 availActCache.put(task.realActivity, ai); 3874 } 3875 if (ai == dummyAct) { 3876 // This could be either because the activity no longer exists, or the 3877 // app is temporarily gone. For the former we want to remove the recents 3878 // entry; for the latter we want to mark it as unavailable. 3879 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3880 if (app == null) { 3881 try { 3882 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3883 PackageManager.GET_UNINSTALLED_PACKAGES 3884 | PackageManager.GET_DISABLED_COMPONENTS, user); 3885 } catch (RemoteException e) { 3886 // Will never happen. 3887 continue; 3888 } 3889 if (app == null) { 3890 app = dummyApp; 3891 } 3892 availAppCache.put(task.realActivity.getPackageName(), app); 3893 } 3894 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3895 // Doesn't exist any more! Good-bye. 3896 mRecentTasks.remove(i); 3897 task.removedFromRecents(mTaskPersister); 3898 i--; 3899 N--; 3900 Slog.w(TAG, "Removing no longer valid recent: " + task); 3901 continue; 3902 } else { 3903 // Otherwise just not available for now. 3904 if (task.isAvailable) { 3905 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3906 + task); 3907 } 3908 task.isAvailable = false; 3909 } 3910 } else { 3911 if (!ai.enabled || !ai.applicationInfo.enabled 3912 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3913 if (task.isAvailable) { 3914 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3915 + task + " (enabled=" + ai.enabled + "/" 3916 + ai.applicationInfo.enabled + " flags=" 3917 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3918 } 3919 task.isAvailable = false; 3920 } else { 3921 if (!task.isAvailable) { 3922 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3923 + task); 3924 } 3925 task.isAvailable = true; 3926 } 3927 } 3928 } 3929 } 3930 } 3931 3932 // Verify the affiliate chain for each task. 3933 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3934 } 3935 3936 mTmpRecents.clear(); 3937 // mRecentTasks is now in sorted, affiliated order. 3938 } 3939 3940 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3941 int N = mRecentTasks.size(); 3942 TaskRecord top = task; 3943 int topIndex = taskIndex; 3944 while (top.mNextAffiliate != null && topIndex > 0) { 3945 top = top.mNextAffiliate; 3946 topIndex--; 3947 } 3948 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3949 + topIndex + " from intial " + taskIndex); 3950 // Find the end of the chain, doing a sanity check along the way. 3951 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3952 int endIndex = topIndex; 3953 TaskRecord prev = top; 3954 while (endIndex < N) { 3955 TaskRecord cur = mRecentTasks.get(endIndex); 3956 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3957 + endIndex + " " + cur); 3958 if (cur == top) { 3959 // Verify start of the chain. 3960 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3961 Slog.wtf(TAG, "Bad chain @" + endIndex 3962 + ": first task has next affiliate: " + prev); 3963 sane = false; 3964 break; 3965 } 3966 } else { 3967 // Verify middle of the chain's next points back to the one before. 3968 if (cur.mNextAffiliate != prev 3969 || cur.mNextAffiliateTaskId != prev.taskId) { 3970 Slog.wtf(TAG, "Bad chain @" + endIndex 3971 + ": middle task " + cur + " @" + endIndex 3972 + " has bad next affiliate " 3973 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3974 + ", expected " + prev); 3975 sane = false; 3976 break; 3977 } 3978 } 3979 if (cur.mPrevAffiliateTaskId == -1) { 3980 // Chain ends here. 3981 if (cur.mPrevAffiliate != null) { 3982 Slog.wtf(TAG, "Bad chain @" + endIndex 3983 + ": last task " + cur + " has previous affiliate " 3984 + cur.mPrevAffiliate); 3985 sane = false; 3986 } 3987 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3988 break; 3989 } else { 3990 // Verify middle of the chain's prev points to a valid item. 3991 if (cur.mPrevAffiliate == null) { 3992 Slog.wtf(TAG, "Bad chain @" + endIndex 3993 + ": task " + cur + " has previous affiliate " 3994 + cur.mPrevAffiliate + " but should be id " 3995 + cur.mPrevAffiliate); 3996 sane = false; 3997 break; 3998 } 3999 } 4000 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4001 Slog.wtf(TAG, "Bad chain @" + endIndex 4002 + ": task " + cur + " has affiliated id " 4003 + cur.mAffiliatedTaskId + " but should be " 4004 + task.mAffiliatedTaskId); 4005 sane = false; 4006 break; 4007 } 4008 prev = cur; 4009 endIndex++; 4010 if (endIndex >= N) { 4011 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4012 + ": last task " + prev); 4013 sane = false; 4014 break; 4015 } 4016 } 4017 if (sane) { 4018 if (endIndex < taskIndex) { 4019 Slog.wtf(TAG, "Bad chain @" + endIndex 4020 + ": did not extend to task " + task + " @" + taskIndex); 4021 sane = false; 4022 } 4023 } 4024 if (sane) { 4025 // All looks good, we can just move all of the affiliated tasks 4026 // to the top. 4027 for (int i=topIndex; i<=endIndex; i++) { 4028 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4029 + " from " + i + " to " + (i-topIndex)); 4030 TaskRecord cur = mRecentTasks.remove(i); 4031 mRecentTasks.add(i-topIndex, cur); 4032 } 4033 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4034 + " to " + endIndex); 4035 return true; 4036 } 4037 4038 // Whoops, couldn't do it. 4039 return false; 4040 } 4041 4042 final void addRecentTaskLocked(TaskRecord task) { 4043 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4044 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4045 4046 int N = mRecentTasks.size(); 4047 // Quick case: check if the top-most recent task is the same. 4048 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4049 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4050 return; 4051 } 4052 // Another quick case: check if this is part of a set of affiliated 4053 // tasks that are at the top. 4054 if (isAffiliated && N > 0 && task.inRecents 4055 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4056 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4057 + " at top when adding " + task); 4058 return; 4059 } 4060 // Another quick case: never add voice sessions. 4061 if (task.voiceSession != null) { 4062 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4063 return; 4064 } 4065 4066 boolean needAffiliationFix = false; 4067 4068 // Slightly less quick case: the task is already in recents, so all we need 4069 // to do is move it. 4070 if (task.inRecents) { 4071 int taskIndex = mRecentTasks.indexOf(task); 4072 if (taskIndex >= 0) { 4073 if (!isAffiliated) { 4074 // Simple case: this is not an affiliated task, so we just move it to the front. 4075 mRecentTasks.remove(taskIndex); 4076 mRecentTasks.add(0, task); 4077 notifyTaskPersisterLocked(task, false); 4078 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4079 + " from " + taskIndex); 4080 return; 4081 } else { 4082 // More complicated: need to keep all affiliated tasks together. 4083 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4084 // All went well. 4085 return; 4086 } 4087 4088 // Uh oh... something bad in the affiliation chain, try to rebuild 4089 // everything and then go through our general path of adding a new task. 4090 needAffiliationFix = true; 4091 } 4092 } else { 4093 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4094 needAffiliationFix = true; 4095 } 4096 } 4097 4098 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4099 trimRecentsForTask(task, true); 4100 4101 N = mRecentTasks.size(); 4102 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4103 final TaskRecord tr = mRecentTasks.remove(N - 1); 4104 tr.removedFromRecents(mTaskPersister); 4105 N--; 4106 } 4107 task.inRecents = true; 4108 if (!isAffiliated || needAffiliationFix) { 4109 // If this is a simple non-affiliated task, or we had some failure trying to 4110 // handle it as part of an affilated task, then just place it at the top. 4111 mRecentTasks.add(0, task); 4112 } else if (isAffiliated) { 4113 // If this is a new affiliated task, then move all of the affiliated tasks 4114 // to the front and insert this new one. 4115 TaskRecord other = task.mNextAffiliate; 4116 if (other == null) { 4117 other = task.mPrevAffiliate; 4118 } 4119 if (other != null) { 4120 int otherIndex = mRecentTasks.indexOf(other); 4121 if (otherIndex >= 0) { 4122 // Insert new task at appropriate location. 4123 int taskIndex; 4124 if (other == task.mNextAffiliate) { 4125 // We found the index of our next affiliation, which is who is 4126 // before us in the list, so add after that point. 4127 taskIndex = otherIndex+1; 4128 } else { 4129 // We found the index of our previous affiliation, which is who is 4130 // after us in the list, so add at their position. 4131 taskIndex = otherIndex; 4132 } 4133 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4134 + taskIndex + ": " + task); 4135 mRecentTasks.add(taskIndex, task); 4136 4137 // Now move everything to the front. 4138 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4139 // All went well. 4140 return; 4141 } 4142 4143 // Uh oh... something bad in the affiliation chain, try to rebuild 4144 // everything and then go through our general path of adding a new task. 4145 needAffiliationFix = true; 4146 } else { 4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4148 + other); 4149 needAffiliationFix = true; 4150 } 4151 } else { 4152 if (DEBUG_RECENTS) Slog.d(TAG, 4153 "addRecent: adding affiliated task without next/prev:" + task); 4154 needAffiliationFix = true; 4155 } 4156 } 4157 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4158 4159 if (needAffiliationFix) { 4160 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4161 cleanupRecentTasksLocked(task.userId); 4162 } 4163 } 4164 4165 /** 4166 * If needed, remove oldest existing entries in recents that are for the same kind 4167 * of task as the given one. 4168 */ 4169 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4170 int N = mRecentTasks.size(); 4171 final Intent intent = task.intent; 4172 final boolean document = intent != null && intent.isDocument(); 4173 4174 int maxRecents = task.maxRecents - 1; 4175 for (int i=0; i<N; i++) { 4176 final TaskRecord tr = mRecentTasks.get(i); 4177 if (task != tr) { 4178 if (task.userId != tr.userId) { 4179 continue; 4180 } 4181 if (i > MAX_RECENT_BITMAPS) { 4182 tr.freeLastThumbnail(); 4183 } 4184 final Intent trIntent = tr.intent; 4185 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4186 (intent == null || !intent.filterEquals(trIntent))) { 4187 continue; 4188 } 4189 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4190 if (document && trIsDocument) { 4191 // These are the same document activity (not necessarily the same doc). 4192 if (maxRecents > 0) { 4193 --maxRecents; 4194 continue; 4195 } 4196 // Hit the maximum number of documents for this task. Fall through 4197 // and remove this document from recents. 4198 } else if (document || trIsDocument) { 4199 // Only one of these is a document. Not the droid we're looking for. 4200 continue; 4201 } 4202 } 4203 4204 if (!doTrim) { 4205 // If the caller is not actually asking for a trim, just tell them we reached 4206 // a point where the trim would happen. 4207 return i; 4208 } 4209 4210 // Either task and tr are the same or, their affinities match or their intents match 4211 // and neither of them is a document, or they are documents using the same activity 4212 // and their maxRecents has been reached. 4213 tr.disposeThumbnail(); 4214 mRecentTasks.remove(i); 4215 if (task != tr) { 4216 tr.removedFromRecents(mTaskPersister); 4217 } 4218 i--; 4219 N--; 4220 if (task.intent == null) { 4221 // If the new recent task we are adding is not fully 4222 // specified, then replace it with the existing recent task. 4223 task = tr; 4224 } 4225 notifyTaskPersisterLocked(tr, false); 4226 } 4227 4228 return -1; 4229 } 4230 4231 @Override 4232 public void reportActivityFullyDrawn(IBinder token) { 4233 synchronized (this) { 4234 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4235 if (r == null) { 4236 return; 4237 } 4238 r.reportFullyDrawnLocked(); 4239 } 4240 } 4241 4242 @Override 4243 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4244 synchronized (this) { 4245 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4246 if (r == null) { 4247 return; 4248 } 4249 final long origId = Binder.clearCallingIdentity(); 4250 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4251 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4252 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4253 if (config != null) { 4254 r.frozenBeforeDestroy = true; 4255 if (!updateConfigurationLocked(config, r, false, false)) { 4256 mStackSupervisor.resumeTopActivitiesLocked(); 4257 } 4258 } 4259 Binder.restoreCallingIdentity(origId); 4260 } 4261 } 4262 4263 @Override 4264 public int getRequestedOrientation(IBinder token) { 4265 synchronized (this) { 4266 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4267 if (r == null) { 4268 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4269 } 4270 return mWindowManager.getAppOrientation(r.appToken); 4271 } 4272 } 4273 4274 /** 4275 * This is the internal entry point for handling Activity.finish(). 4276 * 4277 * @param token The Binder token referencing the Activity we want to finish. 4278 * @param resultCode Result code, if any, from this Activity. 4279 * @param resultData Result data (Intent), if any, from this Activity. 4280 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4281 * the root Activity in the task. 4282 * 4283 * @return Returns true if the activity successfully finished, or false if it is still running. 4284 */ 4285 @Override 4286 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4287 boolean finishTask) { 4288 // Refuse possible leaked file descriptors 4289 if (resultData != null && resultData.hasFileDescriptors() == true) { 4290 throw new IllegalArgumentException("File descriptors passed in Intent"); 4291 } 4292 4293 synchronized(this) { 4294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4295 if (r == null) { 4296 return true; 4297 } 4298 // Keep track of the root activity of the task before we finish it 4299 TaskRecord tr = r.task; 4300 ActivityRecord rootR = tr.getRootActivity(); 4301 if (rootR == null) { 4302 Slog.w(TAG, "Finishing task with all activities already finished"); 4303 } 4304 // Do not allow task to finish in Lock Task mode. 4305 if (tr == mStackSupervisor.mLockTaskModeTask) { 4306 if (rootR == r) { 4307 Slog.i(TAG, "Not finishing task in lock task mode"); 4308 mStackSupervisor.showLockTaskToast(); 4309 return false; 4310 } 4311 } 4312 if (mController != null) { 4313 // Find the first activity that is not finishing. 4314 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4315 if (next != null) { 4316 // ask watcher if this is allowed 4317 boolean resumeOK = true; 4318 try { 4319 resumeOK = mController.activityResuming(next.packageName); 4320 } catch (RemoteException e) { 4321 mController = null; 4322 Watchdog.getInstance().setActivityController(null); 4323 } 4324 4325 if (!resumeOK) { 4326 Slog.i(TAG, "Not finishing activity because controller resumed"); 4327 return false; 4328 } 4329 } 4330 } 4331 final long origId = Binder.clearCallingIdentity(); 4332 try { 4333 boolean res; 4334 if (finishTask && r == rootR) { 4335 // If requested, remove the task that is associated to this activity only if it 4336 // was the root activity in the task. The result code and data is ignored 4337 // because we don't support returning them across task boundaries. 4338 res = removeTaskByIdLocked(tr.taskId, false); 4339 if (!res) { 4340 Slog.i(TAG, "Removing task failed to finish activity"); 4341 } 4342 } else { 4343 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4344 resultData, "app-request", true); 4345 if (!res) { 4346 Slog.i(TAG, "Failed to finish by app-request"); 4347 } 4348 } 4349 return res; 4350 } finally { 4351 Binder.restoreCallingIdentity(origId); 4352 } 4353 } 4354 } 4355 4356 @Override 4357 public final void finishHeavyWeightApp() { 4358 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4359 != PackageManager.PERMISSION_GRANTED) { 4360 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4361 + Binder.getCallingPid() 4362 + ", uid=" + Binder.getCallingUid() 4363 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4364 Slog.w(TAG, msg); 4365 throw new SecurityException(msg); 4366 } 4367 4368 synchronized(this) { 4369 if (mHeavyWeightProcess == null) { 4370 return; 4371 } 4372 4373 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4374 mHeavyWeightProcess.activities); 4375 for (int i=0; i<activities.size(); i++) { 4376 ActivityRecord r = activities.get(i); 4377 if (!r.finishing) { 4378 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4379 null, "finish-heavy", true); 4380 } 4381 } 4382 4383 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4384 mHeavyWeightProcess.userId, 0)); 4385 mHeavyWeightProcess = null; 4386 } 4387 } 4388 4389 @Override 4390 public void crashApplication(int uid, int initialPid, String packageName, 4391 String message) { 4392 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4393 != PackageManager.PERMISSION_GRANTED) { 4394 String msg = "Permission Denial: crashApplication() from pid=" 4395 + Binder.getCallingPid() 4396 + ", uid=" + Binder.getCallingUid() 4397 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4398 Slog.w(TAG, msg); 4399 throw new SecurityException(msg); 4400 } 4401 4402 synchronized(this) { 4403 ProcessRecord proc = null; 4404 4405 // Figure out which process to kill. We don't trust that initialPid 4406 // still has any relation to current pids, so must scan through the 4407 // list. 4408 synchronized (mPidsSelfLocked) { 4409 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4410 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4411 if (p.uid != uid) { 4412 continue; 4413 } 4414 if (p.pid == initialPid) { 4415 proc = p; 4416 break; 4417 } 4418 if (p.pkgList.containsKey(packageName)) { 4419 proc = p; 4420 } 4421 } 4422 } 4423 4424 if (proc == null) { 4425 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4426 + " initialPid=" + initialPid 4427 + " packageName=" + packageName); 4428 return; 4429 } 4430 4431 if (proc.thread != null) { 4432 if (proc.pid == Process.myPid()) { 4433 Log.w(TAG, "crashApplication: trying to crash self!"); 4434 return; 4435 } 4436 long ident = Binder.clearCallingIdentity(); 4437 try { 4438 proc.thread.scheduleCrash(message); 4439 } catch (RemoteException e) { 4440 } 4441 Binder.restoreCallingIdentity(ident); 4442 } 4443 } 4444 } 4445 4446 @Override 4447 public final void finishSubActivity(IBinder token, String resultWho, 4448 int requestCode) { 4449 synchronized(this) { 4450 final long origId = Binder.clearCallingIdentity(); 4451 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4452 if (r != null) { 4453 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4454 } 4455 Binder.restoreCallingIdentity(origId); 4456 } 4457 } 4458 4459 @Override 4460 public boolean finishActivityAffinity(IBinder token) { 4461 synchronized(this) { 4462 final long origId = Binder.clearCallingIdentity(); 4463 try { 4464 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4465 4466 ActivityRecord rootR = r.task.getRootActivity(); 4467 // Do not allow task to finish in Lock Task mode. 4468 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4469 if (rootR == r) { 4470 mStackSupervisor.showLockTaskToast(); 4471 return false; 4472 } 4473 } 4474 boolean res = false; 4475 if (r != null) { 4476 res = r.task.stack.finishActivityAffinityLocked(r); 4477 } 4478 return res; 4479 } finally { 4480 Binder.restoreCallingIdentity(origId); 4481 } 4482 } 4483 } 4484 4485 @Override 4486 public void finishVoiceTask(IVoiceInteractionSession session) { 4487 synchronized(this) { 4488 final long origId = Binder.clearCallingIdentity(); 4489 try { 4490 mStackSupervisor.finishVoiceTask(session); 4491 } finally { 4492 Binder.restoreCallingIdentity(origId); 4493 } 4494 } 4495 4496 } 4497 4498 @Override 4499 public boolean releaseActivityInstance(IBinder token) { 4500 synchronized(this) { 4501 final long origId = Binder.clearCallingIdentity(); 4502 try { 4503 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4504 if (r.task == null || r.task.stack == null) { 4505 return false; 4506 } 4507 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4508 } finally { 4509 Binder.restoreCallingIdentity(origId); 4510 } 4511 } 4512 } 4513 4514 @Override 4515 public void releaseSomeActivities(IApplicationThread appInt) { 4516 synchronized(this) { 4517 final long origId = Binder.clearCallingIdentity(); 4518 try { 4519 ProcessRecord app = getRecordForAppLocked(appInt); 4520 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4521 } finally { 4522 Binder.restoreCallingIdentity(origId); 4523 } 4524 } 4525 } 4526 4527 @Override 4528 public boolean willActivityBeVisible(IBinder token) { 4529 synchronized(this) { 4530 ActivityStack stack = ActivityRecord.getStackLocked(token); 4531 if (stack != null) { 4532 return stack.willActivityBeVisibleLocked(token); 4533 } 4534 return false; 4535 } 4536 } 4537 4538 @Override 4539 public void overridePendingTransition(IBinder token, String packageName, 4540 int enterAnim, int exitAnim) { 4541 synchronized(this) { 4542 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4543 if (self == null) { 4544 return; 4545 } 4546 4547 final long origId = Binder.clearCallingIdentity(); 4548 4549 if (self.state == ActivityState.RESUMED 4550 || self.state == ActivityState.PAUSING) { 4551 mWindowManager.overridePendingAppTransition(packageName, 4552 enterAnim, exitAnim, null); 4553 } 4554 4555 Binder.restoreCallingIdentity(origId); 4556 } 4557 } 4558 4559 /** 4560 * Main function for removing an existing process from the activity manager 4561 * as a result of that process going away. Clears out all connections 4562 * to the process. 4563 */ 4564 private final void handleAppDiedLocked(ProcessRecord app, 4565 boolean restarting, boolean allowRestart) { 4566 int pid = app.pid; 4567 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4568 if (!kept && !restarting) { 4569 removeLruProcessLocked(app); 4570 if (pid > 0) { 4571 ProcessList.remove(pid); 4572 } 4573 } 4574 4575 if (mProfileProc == app) { 4576 clearProfilerLocked(); 4577 } 4578 4579 // Remove this application's activities from active lists. 4580 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4581 4582 app.activities.clear(); 4583 4584 if (app.instrumentationClass != null) { 4585 Slog.w(TAG, "Crash of app " + app.processName 4586 + " running instrumentation " + app.instrumentationClass); 4587 Bundle info = new Bundle(); 4588 info.putString("shortMsg", "Process crashed."); 4589 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4590 } 4591 4592 if (!restarting) { 4593 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4594 // If there was nothing to resume, and we are not already 4595 // restarting this process, but there is a visible activity that 4596 // is hosted by the process... then make sure all visible 4597 // activities are running, taking care of restarting this 4598 // process. 4599 if (hasVisibleActivities) { 4600 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4601 } 4602 } 4603 } 4604 } 4605 4606 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4607 IBinder threadBinder = thread.asBinder(); 4608 // Find the application record. 4609 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4610 ProcessRecord rec = mLruProcesses.get(i); 4611 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4612 return i; 4613 } 4614 } 4615 return -1; 4616 } 4617 4618 final ProcessRecord getRecordForAppLocked( 4619 IApplicationThread thread) { 4620 if (thread == null) { 4621 return null; 4622 } 4623 4624 int appIndex = getLRURecordIndexForAppLocked(thread); 4625 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4626 } 4627 4628 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4629 // If there are no longer any background processes running, 4630 // and the app that died was not running instrumentation, 4631 // then tell everyone we are now low on memory. 4632 boolean haveBg = false; 4633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4634 ProcessRecord rec = mLruProcesses.get(i); 4635 if (rec.thread != null 4636 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4637 haveBg = true; 4638 break; 4639 } 4640 } 4641 4642 if (!haveBg) { 4643 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4644 if (doReport) { 4645 long now = SystemClock.uptimeMillis(); 4646 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4647 doReport = false; 4648 } else { 4649 mLastMemUsageReportTime = now; 4650 } 4651 } 4652 final ArrayList<ProcessMemInfo> memInfos 4653 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4654 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4655 long now = SystemClock.uptimeMillis(); 4656 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4657 ProcessRecord rec = mLruProcesses.get(i); 4658 if (rec == dyingProc || rec.thread == null) { 4659 continue; 4660 } 4661 if (doReport) { 4662 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4663 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4664 } 4665 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4666 // The low memory report is overriding any current 4667 // state for a GC request. Make sure to do 4668 // heavy/important/visible/foreground processes first. 4669 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4670 rec.lastRequestedGc = 0; 4671 } else { 4672 rec.lastRequestedGc = rec.lastLowMemory; 4673 } 4674 rec.reportLowMemory = true; 4675 rec.lastLowMemory = now; 4676 mProcessesToGc.remove(rec); 4677 addProcessToGcListLocked(rec); 4678 } 4679 } 4680 if (doReport) { 4681 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4682 mHandler.sendMessage(msg); 4683 } 4684 scheduleAppGcsLocked(); 4685 } 4686 } 4687 4688 final void appDiedLocked(ProcessRecord app) { 4689 appDiedLocked(app, app.pid, app.thread); 4690 } 4691 4692 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4693 // First check if this ProcessRecord is actually active for the pid. 4694 synchronized (mPidsSelfLocked) { 4695 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4696 if (curProc != app) { 4697 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4698 return; 4699 } 4700 } 4701 4702 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4703 synchronized (stats) { 4704 stats.noteProcessDiedLocked(app.info.uid, pid); 4705 } 4706 4707 Process.killProcessQuiet(pid); 4708 Process.killProcessGroup(app.info.uid, pid); 4709 app.killed = true; 4710 4711 // Clean up already done if the process has been re-started. 4712 if (app.pid == pid && app.thread != null && 4713 app.thread.asBinder() == thread.asBinder()) { 4714 boolean doLowMem = app.instrumentationClass == null; 4715 boolean doOomAdj = doLowMem; 4716 if (!app.killedByAm) { 4717 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4718 + ") has died"); 4719 mAllowLowerMemLevel = true; 4720 } else { 4721 // Note that we always want to do oom adj to update our state with the 4722 // new number of procs. 4723 mAllowLowerMemLevel = false; 4724 doLowMem = false; 4725 } 4726 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4727 if (DEBUG_CLEANUP) Slog.v( 4728 TAG, "Dying app: " + app + ", pid: " + pid 4729 + ", thread: " + thread.asBinder()); 4730 handleAppDiedLocked(app, false, true); 4731 4732 if (doOomAdj) { 4733 updateOomAdjLocked(); 4734 } 4735 if (doLowMem) { 4736 doLowMemReportIfNeededLocked(app); 4737 } 4738 } else if (app.pid != pid) { 4739 // A new process has already been started. 4740 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4741 + ") has died and restarted (pid " + app.pid + ")."); 4742 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4743 } else if (DEBUG_PROCESSES) { 4744 Slog.d(TAG, "Received spurious death notification for thread " 4745 + thread.asBinder()); 4746 } 4747 } 4748 4749 /** 4750 * If a stack trace dump file is configured, dump process stack traces. 4751 * @param clearTraces causes the dump file to be erased prior to the new 4752 * traces being written, if true; when false, the new traces will be 4753 * appended to any existing file content. 4754 * @param firstPids of dalvik VM processes to dump stack traces for first 4755 * @param lastPids of dalvik VM processes to dump stack traces for last 4756 * @param nativeProcs optional list of native process names to dump stack crawls 4757 * @return file containing stack traces, or null if no dump file is configured 4758 */ 4759 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4760 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4761 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4762 if (tracesPath == null || tracesPath.length() == 0) { 4763 return null; 4764 } 4765 4766 File tracesFile = new File(tracesPath); 4767 try { 4768 File tracesDir = tracesFile.getParentFile(); 4769 if (!tracesDir.exists()) { 4770 tracesDir.mkdirs(); 4771 if (!SELinux.restorecon(tracesDir)) { 4772 return null; 4773 } 4774 } 4775 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4776 4777 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4778 tracesFile.createNewFile(); 4779 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4780 } catch (IOException e) { 4781 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4782 return null; 4783 } 4784 4785 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4786 return tracesFile; 4787 } 4788 4789 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4790 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4791 // Use a FileObserver to detect when traces finish writing. 4792 // The order of traces is considered important to maintain for legibility. 4793 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4794 @Override 4795 public synchronized void onEvent(int event, String path) { notify(); } 4796 }; 4797 4798 try { 4799 observer.startWatching(); 4800 4801 // First collect all of the stacks of the most important pids. 4802 if (firstPids != null) { 4803 try { 4804 int num = firstPids.size(); 4805 for (int i = 0; i < num; i++) { 4806 synchronized (observer) { 4807 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4808 observer.wait(200); // Wait for write-close, give up after 200msec 4809 } 4810 } 4811 } catch (InterruptedException e) { 4812 Slog.wtf(TAG, e); 4813 } 4814 } 4815 4816 // Next collect the stacks of the native pids 4817 if (nativeProcs != null) { 4818 int[] pids = Process.getPidsForCommands(nativeProcs); 4819 if (pids != null) { 4820 for (int pid : pids) { 4821 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4822 } 4823 } 4824 } 4825 4826 // Lastly, measure CPU usage. 4827 if (processCpuTracker != null) { 4828 processCpuTracker.init(); 4829 System.gc(); 4830 processCpuTracker.update(); 4831 try { 4832 synchronized (processCpuTracker) { 4833 processCpuTracker.wait(500); // measure over 1/2 second. 4834 } 4835 } catch (InterruptedException e) { 4836 } 4837 processCpuTracker.update(); 4838 4839 // We'll take the stack crawls of just the top apps using CPU. 4840 final int N = processCpuTracker.countWorkingStats(); 4841 int numProcs = 0; 4842 for (int i=0; i<N && numProcs<5; i++) { 4843 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4844 if (lastPids.indexOfKey(stats.pid) >= 0) { 4845 numProcs++; 4846 try { 4847 synchronized (observer) { 4848 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4849 observer.wait(200); // Wait for write-close, give up after 200msec 4850 } 4851 } catch (InterruptedException e) { 4852 Slog.wtf(TAG, e); 4853 } 4854 4855 } 4856 } 4857 } 4858 } finally { 4859 observer.stopWatching(); 4860 } 4861 } 4862 4863 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4864 if (true || IS_USER_BUILD) { 4865 return; 4866 } 4867 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4868 if (tracesPath == null || tracesPath.length() == 0) { 4869 return; 4870 } 4871 4872 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4873 StrictMode.allowThreadDiskWrites(); 4874 try { 4875 final File tracesFile = new File(tracesPath); 4876 final File tracesDir = tracesFile.getParentFile(); 4877 final File tracesTmp = new File(tracesDir, "__tmp__"); 4878 try { 4879 if (!tracesDir.exists()) { 4880 tracesDir.mkdirs(); 4881 if (!SELinux.restorecon(tracesDir.getPath())) { 4882 return; 4883 } 4884 } 4885 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4886 4887 if (tracesFile.exists()) { 4888 tracesTmp.delete(); 4889 tracesFile.renameTo(tracesTmp); 4890 } 4891 StringBuilder sb = new StringBuilder(); 4892 Time tobj = new Time(); 4893 tobj.set(System.currentTimeMillis()); 4894 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4895 sb.append(": "); 4896 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4897 sb.append(" since "); 4898 sb.append(msg); 4899 FileOutputStream fos = new FileOutputStream(tracesFile); 4900 fos.write(sb.toString().getBytes()); 4901 if (app == null) { 4902 fos.write("\n*** No application process!".getBytes()); 4903 } 4904 fos.close(); 4905 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4906 } catch (IOException e) { 4907 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4908 return; 4909 } 4910 4911 if (app != null) { 4912 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4913 firstPids.add(app.pid); 4914 dumpStackTraces(tracesPath, firstPids, null, null, null); 4915 } 4916 4917 File lastTracesFile = null; 4918 File curTracesFile = null; 4919 for (int i=9; i>=0; i--) { 4920 String name = String.format(Locale.US, "slow%02d.txt", i); 4921 curTracesFile = new File(tracesDir, name); 4922 if (curTracesFile.exists()) { 4923 if (lastTracesFile != null) { 4924 curTracesFile.renameTo(lastTracesFile); 4925 } else { 4926 curTracesFile.delete(); 4927 } 4928 } 4929 lastTracesFile = curTracesFile; 4930 } 4931 tracesFile.renameTo(curTracesFile); 4932 if (tracesTmp.exists()) { 4933 tracesTmp.renameTo(tracesFile); 4934 } 4935 } finally { 4936 StrictMode.setThreadPolicy(oldPolicy); 4937 } 4938 } 4939 4940 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4941 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4942 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4943 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4944 4945 if (mController != null) { 4946 try { 4947 // 0 == continue, -1 = kill process immediately 4948 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4949 if (res < 0 && app.pid != MY_PID) { 4950 app.kill("anr", true); 4951 } 4952 } catch (RemoteException e) { 4953 mController = null; 4954 Watchdog.getInstance().setActivityController(null); 4955 } 4956 } 4957 4958 long anrTime = SystemClock.uptimeMillis(); 4959 if (MONITOR_CPU_USAGE) { 4960 updateCpuStatsNow(); 4961 } 4962 4963 synchronized (this) { 4964 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4965 if (mShuttingDown) { 4966 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4967 return; 4968 } else if (app.notResponding) { 4969 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4970 return; 4971 } else if (app.crashing) { 4972 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4973 return; 4974 } 4975 4976 // In case we come through here for the same app before completing 4977 // this one, mark as anring now so we will bail out. 4978 app.notResponding = true; 4979 4980 // Log the ANR to the event log. 4981 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4982 app.processName, app.info.flags, annotation); 4983 4984 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4985 firstPids.add(app.pid); 4986 4987 int parentPid = app.pid; 4988 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4989 if (parentPid != app.pid) firstPids.add(parentPid); 4990 4991 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4992 4993 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4994 ProcessRecord r = mLruProcesses.get(i); 4995 if (r != null && r.thread != null) { 4996 int pid = r.pid; 4997 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4998 if (r.persistent) { 4999 firstPids.add(pid); 5000 } else { 5001 lastPids.put(pid, Boolean.TRUE); 5002 } 5003 } 5004 } 5005 } 5006 } 5007 5008 // Log the ANR to the main log. 5009 StringBuilder info = new StringBuilder(); 5010 info.setLength(0); 5011 info.append("ANR in ").append(app.processName); 5012 if (activity != null && activity.shortComponentName != null) { 5013 info.append(" (").append(activity.shortComponentName).append(")"); 5014 } 5015 info.append("\n"); 5016 info.append("PID: ").append(app.pid).append("\n"); 5017 if (annotation != null) { 5018 info.append("Reason: ").append(annotation).append("\n"); 5019 } 5020 if (parent != null && parent != activity) { 5021 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5022 } 5023 5024 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5025 5026 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5027 NATIVE_STACKS_OF_INTEREST); 5028 5029 String cpuInfo = null; 5030 if (MONITOR_CPU_USAGE) { 5031 updateCpuStatsNow(); 5032 synchronized (mProcessCpuTracker) { 5033 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5034 } 5035 info.append(processCpuTracker.printCurrentLoad()); 5036 info.append(cpuInfo); 5037 } 5038 5039 info.append(processCpuTracker.printCurrentState(anrTime)); 5040 5041 Slog.e(TAG, info.toString()); 5042 if (tracesFile == null) { 5043 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5044 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5045 } 5046 5047 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5048 cpuInfo, tracesFile, null); 5049 5050 if (mController != null) { 5051 try { 5052 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5053 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5054 if (res != 0) { 5055 if (res < 0 && app.pid != MY_PID) { 5056 app.kill("anr", true); 5057 } else { 5058 synchronized (this) { 5059 mServices.scheduleServiceTimeoutLocked(app); 5060 } 5061 } 5062 return; 5063 } 5064 } catch (RemoteException e) { 5065 mController = null; 5066 Watchdog.getInstance().setActivityController(null); 5067 } 5068 } 5069 5070 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5071 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5072 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5073 5074 synchronized (this) { 5075 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5076 app.kill("bg anr", true); 5077 return; 5078 } 5079 5080 // Set the app's notResponding state, and look up the errorReportReceiver 5081 makeAppNotRespondingLocked(app, 5082 activity != null ? activity.shortComponentName : null, 5083 annotation != null ? "ANR " + annotation : "ANR", 5084 info.toString()); 5085 5086 // Bring up the infamous App Not Responding dialog 5087 Message msg = Message.obtain(); 5088 HashMap<String, Object> map = new HashMap<String, Object>(); 5089 msg.what = SHOW_NOT_RESPONDING_MSG; 5090 msg.obj = map; 5091 msg.arg1 = aboveSystem ? 1 : 0; 5092 map.put("app", app); 5093 if (activity != null) { 5094 map.put("activity", activity); 5095 } 5096 5097 mHandler.sendMessage(msg); 5098 } 5099 } 5100 5101 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5102 if (!mLaunchWarningShown) { 5103 mLaunchWarningShown = true; 5104 mHandler.post(new Runnable() { 5105 @Override 5106 public void run() { 5107 synchronized (ActivityManagerService.this) { 5108 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5109 d.show(); 5110 mHandler.postDelayed(new Runnable() { 5111 @Override 5112 public void run() { 5113 synchronized (ActivityManagerService.this) { 5114 d.dismiss(); 5115 mLaunchWarningShown = false; 5116 } 5117 } 5118 }, 4000); 5119 } 5120 } 5121 }); 5122 } 5123 } 5124 5125 @Override 5126 public boolean clearApplicationUserData(final String packageName, 5127 final IPackageDataObserver observer, int userId) { 5128 enforceNotIsolatedCaller("clearApplicationUserData"); 5129 int uid = Binder.getCallingUid(); 5130 int pid = Binder.getCallingPid(); 5131 userId = handleIncomingUser(pid, uid, 5132 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5133 long callingId = Binder.clearCallingIdentity(); 5134 try { 5135 IPackageManager pm = AppGlobals.getPackageManager(); 5136 int pkgUid = -1; 5137 synchronized(this) { 5138 try { 5139 pkgUid = pm.getPackageUid(packageName, userId); 5140 } catch (RemoteException e) { 5141 } 5142 if (pkgUid == -1) { 5143 Slog.w(TAG, "Invalid packageName: " + packageName); 5144 if (observer != null) { 5145 try { 5146 observer.onRemoveCompleted(packageName, false); 5147 } catch (RemoteException e) { 5148 Slog.i(TAG, "Observer no longer exists."); 5149 } 5150 } 5151 return false; 5152 } 5153 if (uid == pkgUid || checkComponentPermission( 5154 android.Manifest.permission.CLEAR_APP_USER_DATA, 5155 pid, uid, -1, true) 5156 == PackageManager.PERMISSION_GRANTED) { 5157 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5158 } else { 5159 throw new SecurityException("PID " + pid + " does not have permission " 5160 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5161 + " of package " + packageName); 5162 } 5163 5164 // Remove all tasks match the cleared application package and user 5165 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5166 final TaskRecord tr = mRecentTasks.get(i); 5167 final String taskPackageName = 5168 tr.getBaseIntent().getComponent().getPackageName(); 5169 if (tr.userId != userId) continue; 5170 if (!taskPackageName.equals(packageName)) continue; 5171 removeTaskByIdLocked(tr.taskId, false); 5172 } 5173 } 5174 5175 try { 5176 // Clear application user data 5177 pm.clearApplicationUserData(packageName, observer, userId); 5178 5179 synchronized(this) { 5180 // Remove all permissions granted from/to this package 5181 removeUriPermissionsForPackageLocked(packageName, userId, true); 5182 } 5183 5184 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5185 Uri.fromParts("package", packageName, null)); 5186 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5187 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5188 null, null, 0, null, null, null, false, false, userId); 5189 } catch (RemoteException e) { 5190 } 5191 } finally { 5192 Binder.restoreCallingIdentity(callingId); 5193 } 5194 return true; 5195 } 5196 5197 @Override 5198 public void killBackgroundProcesses(final String packageName, int userId) { 5199 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5200 != PackageManager.PERMISSION_GRANTED && 5201 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5202 != PackageManager.PERMISSION_GRANTED) { 5203 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5204 + Binder.getCallingPid() 5205 + ", uid=" + Binder.getCallingUid() 5206 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5207 Slog.w(TAG, msg); 5208 throw new SecurityException(msg); 5209 } 5210 5211 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5212 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5213 long callingId = Binder.clearCallingIdentity(); 5214 try { 5215 IPackageManager pm = AppGlobals.getPackageManager(); 5216 synchronized(this) { 5217 int appId = -1; 5218 try { 5219 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5220 } catch (RemoteException e) { 5221 } 5222 if (appId == -1) { 5223 Slog.w(TAG, "Invalid packageName: " + packageName); 5224 return; 5225 } 5226 killPackageProcessesLocked(packageName, appId, userId, 5227 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5228 } 5229 } finally { 5230 Binder.restoreCallingIdentity(callingId); 5231 } 5232 } 5233 5234 @Override 5235 public void killAllBackgroundProcesses() { 5236 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5237 != PackageManager.PERMISSION_GRANTED) { 5238 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5239 + Binder.getCallingPid() 5240 + ", uid=" + Binder.getCallingUid() 5241 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5242 Slog.w(TAG, msg); 5243 throw new SecurityException(msg); 5244 } 5245 5246 long callingId = Binder.clearCallingIdentity(); 5247 try { 5248 synchronized(this) { 5249 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5250 final int NP = mProcessNames.getMap().size(); 5251 for (int ip=0; ip<NP; ip++) { 5252 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5253 final int NA = apps.size(); 5254 for (int ia=0; ia<NA; ia++) { 5255 ProcessRecord app = apps.valueAt(ia); 5256 if (app.persistent) { 5257 // we don't kill persistent processes 5258 continue; 5259 } 5260 if (app.removed) { 5261 procs.add(app); 5262 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5263 app.removed = true; 5264 procs.add(app); 5265 } 5266 } 5267 } 5268 5269 int N = procs.size(); 5270 for (int i=0; i<N; i++) { 5271 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5272 } 5273 mAllowLowerMemLevel = true; 5274 updateOomAdjLocked(); 5275 doLowMemReportIfNeededLocked(null); 5276 } 5277 } finally { 5278 Binder.restoreCallingIdentity(callingId); 5279 } 5280 } 5281 5282 @Override 5283 public void forceStopPackage(final String packageName, int userId) { 5284 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5285 != PackageManager.PERMISSION_GRANTED) { 5286 String msg = "Permission Denial: forceStopPackage() from pid=" 5287 + Binder.getCallingPid() 5288 + ", uid=" + Binder.getCallingUid() 5289 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5290 Slog.w(TAG, msg); 5291 throw new SecurityException(msg); 5292 } 5293 final int callingPid = Binder.getCallingPid(); 5294 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5295 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5296 long callingId = Binder.clearCallingIdentity(); 5297 try { 5298 IPackageManager pm = AppGlobals.getPackageManager(); 5299 synchronized(this) { 5300 int[] users = userId == UserHandle.USER_ALL 5301 ? getUsersLocked() : new int[] { userId }; 5302 for (int user : users) { 5303 int pkgUid = -1; 5304 try { 5305 pkgUid = pm.getPackageUid(packageName, user); 5306 } catch (RemoteException e) { 5307 } 5308 if (pkgUid == -1) { 5309 Slog.w(TAG, "Invalid packageName: " + packageName); 5310 continue; 5311 } 5312 try { 5313 pm.setPackageStoppedState(packageName, true, user); 5314 } catch (RemoteException e) { 5315 } catch (IllegalArgumentException e) { 5316 Slog.w(TAG, "Failed trying to unstop package " 5317 + packageName + ": " + e); 5318 } 5319 if (isUserRunningLocked(user, false)) { 5320 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5321 } 5322 } 5323 } 5324 } finally { 5325 Binder.restoreCallingIdentity(callingId); 5326 } 5327 } 5328 5329 @Override 5330 public void addPackageDependency(String packageName) { 5331 synchronized (this) { 5332 int callingPid = Binder.getCallingPid(); 5333 if (callingPid == Process.myPid()) { 5334 // Yeah, um, no. 5335 Slog.w(TAG, "Can't addPackageDependency on system process"); 5336 return; 5337 } 5338 ProcessRecord proc; 5339 synchronized (mPidsSelfLocked) { 5340 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5341 } 5342 if (proc != null) { 5343 if (proc.pkgDeps == null) { 5344 proc.pkgDeps = new ArraySet<String>(1); 5345 } 5346 proc.pkgDeps.add(packageName); 5347 } 5348 } 5349 } 5350 5351 /* 5352 * The pkg name and app id have to be specified. 5353 */ 5354 @Override 5355 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5356 if (pkg == null) { 5357 return; 5358 } 5359 // Make sure the uid is valid. 5360 if (appid < 0) { 5361 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5362 return; 5363 } 5364 int callerUid = Binder.getCallingUid(); 5365 // Only the system server can kill an application 5366 if (callerUid == Process.SYSTEM_UID) { 5367 // Post an aysnc message to kill the application 5368 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5369 msg.arg1 = appid; 5370 msg.arg2 = 0; 5371 Bundle bundle = new Bundle(); 5372 bundle.putString("pkg", pkg); 5373 bundle.putString("reason", reason); 5374 msg.obj = bundle; 5375 mHandler.sendMessage(msg); 5376 } else { 5377 throw new SecurityException(callerUid + " cannot kill pkg: " + 5378 pkg); 5379 } 5380 } 5381 5382 @Override 5383 public void closeSystemDialogs(String reason) { 5384 enforceNotIsolatedCaller("closeSystemDialogs"); 5385 5386 final int pid = Binder.getCallingPid(); 5387 final int uid = Binder.getCallingUid(); 5388 final long origId = Binder.clearCallingIdentity(); 5389 try { 5390 synchronized (this) { 5391 // Only allow this from foreground processes, so that background 5392 // applications can't abuse it to prevent system UI from being shown. 5393 if (uid >= Process.FIRST_APPLICATION_UID) { 5394 ProcessRecord proc; 5395 synchronized (mPidsSelfLocked) { 5396 proc = mPidsSelfLocked.get(pid); 5397 } 5398 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5399 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5400 + " from background process " + proc); 5401 return; 5402 } 5403 } 5404 closeSystemDialogsLocked(reason); 5405 } 5406 } finally { 5407 Binder.restoreCallingIdentity(origId); 5408 } 5409 } 5410 5411 void closeSystemDialogsLocked(String reason) { 5412 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5413 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5414 | Intent.FLAG_RECEIVER_FOREGROUND); 5415 if (reason != null) { 5416 intent.putExtra("reason", reason); 5417 } 5418 mWindowManager.closeSystemDialogs(reason); 5419 5420 mStackSupervisor.closeSystemDialogsLocked(); 5421 5422 broadcastIntentLocked(null, null, intent, null, 5423 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5424 Process.SYSTEM_UID, UserHandle.USER_ALL); 5425 } 5426 5427 @Override 5428 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5429 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5430 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5431 for (int i=pids.length-1; i>=0; i--) { 5432 ProcessRecord proc; 5433 int oomAdj; 5434 synchronized (this) { 5435 synchronized (mPidsSelfLocked) { 5436 proc = mPidsSelfLocked.get(pids[i]); 5437 oomAdj = proc != null ? proc.setAdj : 0; 5438 } 5439 } 5440 infos[i] = new Debug.MemoryInfo(); 5441 Debug.getMemoryInfo(pids[i], infos[i]); 5442 if (proc != null) { 5443 synchronized (this) { 5444 if (proc.thread != null && proc.setAdj == oomAdj) { 5445 // Record this for posterity if the process has been stable. 5446 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5447 infos[i].getTotalUss(), false, proc.pkgList); 5448 } 5449 } 5450 } 5451 } 5452 return infos; 5453 } 5454 5455 @Override 5456 public long[] getProcessPss(int[] pids) { 5457 enforceNotIsolatedCaller("getProcessPss"); 5458 long[] pss = new long[pids.length]; 5459 for (int i=pids.length-1; i>=0; i--) { 5460 ProcessRecord proc; 5461 int oomAdj; 5462 synchronized (this) { 5463 synchronized (mPidsSelfLocked) { 5464 proc = mPidsSelfLocked.get(pids[i]); 5465 oomAdj = proc != null ? proc.setAdj : 0; 5466 } 5467 } 5468 long[] tmpUss = new long[1]; 5469 pss[i] = Debug.getPss(pids[i], tmpUss); 5470 if (proc != null) { 5471 synchronized (this) { 5472 if (proc.thread != null && proc.setAdj == oomAdj) { 5473 // Record this for posterity if the process has been stable. 5474 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5475 } 5476 } 5477 } 5478 } 5479 return pss; 5480 } 5481 5482 @Override 5483 public void killApplicationProcess(String processName, int uid) { 5484 if (processName == null) { 5485 return; 5486 } 5487 5488 int callerUid = Binder.getCallingUid(); 5489 // Only the system server can kill an application 5490 if (callerUid == Process.SYSTEM_UID) { 5491 synchronized (this) { 5492 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5493 if (app != null && app.thread != null) { 5494 try { 5495 app.thread.scheduleSuicide(); 5496 } catch (RemoteException e) { 5497 // If the other end already died, then our work here is done. 5498 } 5499 } else { 5500 Slog.w(TAG, "Process/uid not found attempting kill of " 5501 + processName + " / " + uid); 5502 } 5503 } 5504 } else { 5505 throw new SecurityException(callerUid + " cannot kill app process: " + 5506 processName); 5507 } 5508 } 5509 5510 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5511 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5512 false, true, false, false, UserHandle.getUserId(uid), reason); 5513 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5514 Uri.fromParts("package", packageName, null)); 5515 if (!mProcessesReady) { 5516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5517 | Intent.FLAG_RECEIVER_FOREGROUND); 5518 } 5519 intent.putExtra(Intent.EXTRA_UID, uid); 5520 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5521 broadcastIntentLocked(null, null, intent, 5522 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5523 false, false, 5524 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5525 } 5526 5527 private void forceStopUserLocked(int userId, String reason) { 5528 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5529 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5530 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5531 | Intent.FLAG_RECEIVER_FOREGROUND); 5532 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5533 broadcastIntentLocked(null, null, intent, 5534 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5535 false, false, 5536 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5537 } 5538 5539 private final boolean killPackageProcessesLocked(String packageName, int appId, 5540 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5541 boolean doit, boolean evenPersistent, String reason) { 5542 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5543 5544 // Remove all processes this package may have touched: all with the 5545 // same UID (except for the system or root user), and all whose name 5546 // matches the package name. 5547 final int NP = mProcessNames.getMap().size(); 5548 for (int ip=0; ip<NP; ip++) { 5549 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5550 final int NA = apps.size(); 5551 for (int ia=0; ia<NA; ia++) { 5552 ProcessRecord app = apps.valueAt(ia); 5553 if (app.persistent && !evenPersistent) { 5554 // we don't kill persistent processes 5555 continue; 5556 } 5557 if (app.removed) { 5558 if (doit) { 5559 procs.add(app); 5560 } 5561 continue; 5562 } 5563 5564 // Skip process if it doesn't meet our oom adj requirement. 5565 if (app.setAdj < minOomAdj) { 5566 continue; 5567 } 5568 5569 // If no package is specified, we call all processes under the 5570 // give user id. 5571 if (packageName == null) { 5572 if (app.userId != userId) { 5573 continue; 5574 } 5575 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5576 continue; 5577 } 5578 // Package has been specified, we want to hit all processes 5579 // that match it. We need to qualify this by the processes 5580 // that are running under the specified app and user ID. 5581 } else { 5582 final boolean isDep = app.pkgDeps != null 5583 && app.pkgDeps.contains(packageName); 5584 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5585 continue; 5586 } 5587 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5588 continue; 5589 } 5590 if (!app.pkgList.containsKey(packageName) && !isDep) { 5591 continue; 5592 } 5593 } 5594 5595 // Process has passed all conditions, kill it! 5596 if (!doit) { 5597 return true; 5598 } 5599 app.removed = true; 5600 procs.add(app); 5601 } 5602 } 5603 5604 int N = procs.size(); 5605 for (int i=0; i<N; i++) { 5606 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5607 } 5608 updateOomAdjLocked(); 5609 return N > 0; 5610 } 5611 5612 private final boolean forceStopPackageLocked(String name, int appId, 5613 boolean callerWillRestart, boolean purgeCache, boolean doit, 5614 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5615 int i; 5616 int N; 5617 5618 if (userId == UserHandle.USER_ALL && name == null) { 5619 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5620 } 5621 5622 if (appId < 0 && name != null) { 5623 try { 5624 appId = UserHandle.getAppId( 5625 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5626 } catch (RemoteException e) { 5627 } 5628 } 5629 5630 if (doit) { 5631 if (name != null) { 5632 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5633 + " user=" + userId + ": " + reason); 5634 } else { 5635 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5636 } 5637 5638 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5639 for (int ip=pmap.size()-1; ip>=0; ip--) { 5640 SparseArray<Long> ba = pmap.valueAt(ip); 5641 for (i=ba.size()-1; i>=0; i--) { 5642 boolean remove = false; 5643 final int entUid = ba.keyAt(i); 5644 if (name != null) { 5645 if (userId == UserHandle.USER_ALL) { 5646 if (UserHandle.getAppId(entUid) == appId) { 5647 remove = true; 5648 } 5649 } else { 5650 if (entUid == UserHandle.getUid(userId, appId)) { 5651 remove = true; 5652 } 5653 } 5654 } else if (UserHandle.getUserId(entUid) == userId) { 5655 remove = true; 5656 } 5657 if (remove) { 5658 ba.removeAt(i); 5659 } 5660 } 5661 if (ba.size() == 0) { 5662 pmap.removeAt(ip); 5663 } 5664 } 5665 } 5666 5667 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5668 -100, callerWillRestart, true, doit, evenPersistent, 5669 name == null ? ("stop user " + userId) : ("stop " + name)); 5670 5671 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5672 if (!doit) { 5673 return true; 5674 } 5675 didSomething = true; 5676 } 5677 5678 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5679 if (!doit) { 5680 return true; 5681 } 5682 didSomething = true; 5683 } 5684 5685 if (name == null) { 5686 // Remove all sticky broadcasts from this user. 5687 mStickyBroadcasts.remove(userId); 5688 } 5689 5690 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5691 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5692 userId, providers)) { 5693 if (!doit) { 5694 return true; 5695 } 5696 didSomething = true; 5697 } 5698 N = providers.size(); 5699 for (i=0; i<N; i++) { 5700 removeDyingProviderLocked(null, providers.get(i), true); 5701 } 5702 5703 // Remove transient permissions granted from/to this package/user 5704 removeUriPermissionsForPackageLocked(name, userId, false); 5705 5706 if (name == null || uninstalling) { 5707 // Remove pending intents. For now we only do this when force 5708 // stopping users, because we have some problems when doing this 5709 // for packages -- app widgets are not currently cleaned up for 5710 // such packages, so they can be left with bad pending intents. 5711 if (mIntentSenderRecords.size() > 0) { 5712 Iterator<WeakReference<PendingIntentRecord>> it 5713 = mIntentSenderRecords.values().iterator(); 5714 while (it.hasNext()) { 5715 WeakReference<PendingIntentRecord> wpir = it.next(); 5716 if (wpir == null) { 5717 it.remove(); 5718 continue; 5719 } 5720 PendingIntentRecord pir = wpir.get(); 5721 if (pir == null) { 5722 it.remove(); 5723 continue; 5724 } 5725 if (name == null) { 5726 // Stopping user, remove all objects for the user. 5727 if (pir.key.userId != userId) { 5728 // Not the same user, skip it. 5729 continue; 5730 } 5731 } else { 5732 if (UserHandle.getAppId(pir.uid) != appId) { 5733 // Different app id, skip it. 5734 continue; 5735 } 5736 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5737 // Different user, skip it. 5738 continue; 5739 } 5740 if (!pir.key.packageName.equals(name)) { 5741 // Different package, skip it. 5742 continue; 5743 } 5744 } 5745 if (!doit) { 5746 return true; 5747 } 5748 didSomething = true; 5749 it.remove(); 5750 pir.canceled = true; 5751 if (pir.key.activity != null) { 5752 pir.key.activity.pendingResults.remove(pir.ref); 5753 } 5754 } 5755 } 5756 } 5757 5758 if (doit) { 5759 if (purgeCache && name != null) { 5760 AttributeCache ac = AttributeCache.instance(); 5761 if (ac != null) { 5762 ac.removePackage(name); 5763 } 5764 } 5765 if (mBooted) { 5766 mStackSupervisor.resumeTopActivitiesLocked(); 5767 mStackSupervisor.scheduleIdleLocked(); 5768 } 5769 } 5770 5771 return didSomething; 5772 } 5773 5774 private final boolean removeProcessLocked(ProcessRecord app, 5775 boolean callerWillRestart, boolean allowRestart, String reason) { 5776 final String name = app.processName; 5777 final int uid = app.uid; 5778 if (DEBUG_PROCESSES) Slog.d( 5779 TAG, "Force removing proc " + app.toShortString() + " (" + name 5780 + "/" + uid + ")"); 5781 5782 mProcessNames.remove(name, uid); 5783 mIsolatedProcesses.remove(app.uid); 5784 if (mHeavyWeightProcess == app) { 5785 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5786 mHeavyWeightProcess.userId, 0)); 5787 mHeavyWeightProcess = null; 5788 } 5789 boolean needRestart = false; 5790 if (app.pid > 0 && app.pid != MY_PID) { 5791 int pid = app.pid; 5792 synchronized (mPidsSelfLocked) { 5793 mPidsSelfLocked.remove(pid); 5794 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5795 } 5796 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5797 if (app.isolated) { 5798 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5799 } 5800 app.kill(reason, true); 5801 handleAppDiedLocked(app, true, allowRestart); 5802 removeLruProcessLocked(app); 5803 5804 if (app.persistent && !app.isolated) { 5805 if (!callerWillRestart) { 5806 addAppLocked(app.info, false, null /* ABI override */); 5807 } else { 5808 needRestart = true; 5809 } 5810 } 5811 } else { 5812 mRemovedProcesses.add(app); 5813 } 5814 5815 return needRestart; 5816 } 5817 5818 private final void processStartTimedOutLocked(ProcessRecord app) { 5819 final int pid = app.pid; 5820 boolean gone = false; 5821 synchronized (mPidsSelfLocked) { 5822 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5823 if (knownApp != null && knownApp.thread == null) { 5824 mPidsSelfLocked.remove(pid); 5825 gone = true; 5826 } 5827 } 5828 5829 if (gone) { 5830 Slog.w(TAG, "Process " + app + " failed to attach"); 5831 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5832 pid, app.uid, app.processName); 5833 mProcessNames.remove(app.processName, app.uid); 5834 mIsolatedProcesses.remove(app.uid); 5835 if (mHeavyWeightProcess == app) { 5836 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5837 mHeavyWeightProcess.userId, 0)); 5838 mHeavyWeightProcess = null; 5839 } 5840 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5841 if (app.isolated) { 5842 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5843 } 5844 // Take care of any launching providers waiting for this process. 5845 checkAppInLaunchingProvidersLocked(app, true); 5846 // Take care of any services that are waiting for the process. 5847 mServices.processStartTimedOutLocked(app); 5848 app.kill("start timeout", true); 5849 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5850 Slog.w(TAG, "Unattached app died before backup, skipping"); 5851 try { 5852 IBackupManager bm = IBackupManager.Stub.asInterface( 5853 ServiceManager.getService(Context.BACKUP_SERVICE)); 5854 bm.agentDisconnected(app.info.packageName); 5855 } catch (RemoteException e) { 5856 // Can't happen; the backup manager is local 5857 } 5858 } 5859 if (isPendingBroadcastProcessLocked(pid)) { 5860 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5861 skipPendingBroadcastLocked(pid); 5862 } 5863 } else { 5864 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5865 } 5866 } 5867 5868 private final boolean attachApplicationLocked(IApplicationThread thread, 5869 int pid) { 5870 5871 // Find the application record that is being attached... either via 5872 // the pid if we are running in multiple processes, or just pull the 5873 // next app record if we are emulating process with anonymous threads. 5874 ProcessRecord app; 5875 if (pid != MY_PID && pid >= 0) { 5876 synchronized (mPidsSelfLocked) { 5877 app = mPidsSelfLocked.get(pid); 5878 } 5879 } else { 5880 app = null; 5881 } 5882 5883 if (app == null) { 5884 Slog.w(TAG, "No pending application record for pid " + pid 5885 + " (IApplicationThread " + thread + "); dropping process"); 5886 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5887 if (pid > 0 && pid != MY_PID) { 5888 Process.killProcessQuiet(pid); 5889 //TODO: Process.killProcessGroup(app.info.uid, pid); 5890 } else { 5891 try { 5892 thread.scheduleExit(); 5893 } catch (Exception e) { 5894 // Ignore exceptions. 5895 } 5896 } 5897 return false; 5898 } 5899 5900 // If this application record is still attached to a previous 5901 // process, clean it up now. 5902 if (app.thread != null) { 5903 handleAppDiedLocked(app, true, true); 5904 } 5905 5906 // Tell the process all about itself. 5907 5908 if (localLOGV) Slog.v( 5909 TAG, "Binding process pid " + pid + " to record " + app); 5910 5911 final String processName = app.processName; 5912 try { 5913 AppDeathRecipient adr = new AppDeathRecipient( 5914 app, pid, thread); 5915 thread.asBinder().linkToDeath(adr, 0); 5916 app.deathRecipient = adr; 5917 } catch (RemoteException e) { 5918 app.resetPackageList(mProcessStats); 5919 startProcessLocked(app, "link fail", processName); 5920 return false; 5921 } 5922 5923 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5924 5925 app.makeActive(thread, mProcessStats); 5926 app.curAdj = app.setAdj = -100; 5927 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5928 app.forcingToForeground = null; 5929 updateProcessForegroundLocked(app, false, false); 5930 app.hasShownUi = false; 5931 app.debugging = false; 5932 app.cached = false; 5933 5934 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5935 5936 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5937 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5938 5939 if (!normalMode) { 5940 Slog.i(TAG, "Launching preboot mode app: " + app); 5941 } 5942 5943 if (localLOGV) Slog.v( 5944 TAG, "New app record " + app 5945 + " thread=" + thread.asBinder() + " pid=" + pid); 5946 try { 5947 int testMode = IApplicationThread.DEBUG_OFF; 5948 if (mDebugApp != null && mDebugApp.equals(processName)) { 5949 testMode = mWaitForDebugger 5950 ? IApplicationThread.DEBUG_WAIT 5951 : IApplicationThread.DEBUG_ON; 5952 app.debugging = true; 5953 if (mDebugTransient) { 5954 mDebugApp = mOrigDebugApp; 5955 mWaitForDebugger = mOrigWaitForDebugger; 5956 } 5957 } 5958 String profileFile = app.instrumentationProfileFile; 5959 ParcelFileDescriptor profileFd = null; 5960 int samplingInterval = 0; 5961 boolean profileAutoStop = false; 5962 if (mProfileApp != null && mProfileApp.equals(processName)) { 5963 mProfileProc = app; 5964 profileFile = mProfileFile; 5965 profileFd = mProfileFd; 5966 samplingInterval = mSamplingInterval; 5967 profileAutoStop = mAutoStopProfiler; 5968 } 5969 boolean enableOpenGlTrace = false; 5970 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5971 enableOpenGlTrace = true; 5972 mOpenGlTraceApp = null; 5973 } 5974 5975 // If the app is being launched for restore or full backup, set it up specially 5976 boolean isRestrictedBackupMode = false; 5977 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5978 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5979 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5980 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5981 } 5982 5983 ensurePackageDexOpt(app.instrumentationInfo != null 5984 ? app.instrumentationInfo.packageName 5985 : app.info.packageName); 5986 if (app.instrumentationClass != null) { 5987 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5988 } 5989 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5990 + processName + " with config " + mConfiguration); 5991 ApplicationInfo appInfo = app.instrumentationInfo != null 5992 ? app.instrumentationInfo : app.info; 5993 app.compat = compatibilityInfoForPackageLocked(appInfo); 5994 if (profileFd != null) { 5995 profileFd = profileFd.dup(); 5996 } 5997 ProfilerInfo profilerInfo = profileFile == null ? null 5998 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5999 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6000 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6001 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6002 isRestrictedBackupMode || !normalMode, app.persistent, 6003 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6004 mCoreSettingsObserver.getCoreSettingsLocked()); 6005 updateLruProcessLocked(app, false, null); 6006 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6007 } catch (Exception e) { 6008 // todo: Yikes! What should we do? For now we will try to 6009 // start another process, but that could easily get us in 6010 // an infinite loop of restarting processes... 6011 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6012 6013 app.resetPackageList(mProcessStats); 6014 app.unlinkDeathRecipient(); 6015 startProcessLocked(app, "bind fail", processName); 6016 return false; 6017 } 6018 6019 // Remove this record from the list of starting applications. 6020 mPersistentStartingProcesses.remove(app); 6021 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6022 "Attach application locked removing on hold: " + app); 6023 mProcessesOnHold.remove(app); 6024 6025 boolean badApp = false; 6026 boolean didSomething = false; 6027 6028 // See if the top visible activity is waiting to run in this process... 6029 if (normalMode) { 6030 try { 6031 if (mStackSupervisor.attachApplicationLocked(app)) { 6032 didSomething = true; 6033 } 6034 } catch (Exception e) { 6035 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6036 badApp = true; 6037 } 6038 } 6039 6040 // Find any services that should be running in this process... 6041 if (!badApp) { 6042 try { 6043 didSomething |= mServices.attachApplicationLocked(app, processName); 6044 } catch (Exception e) { 6045 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6046 badApp = true; 6047 } 6048 } 6049 6050 // Check if a next-broadcast receiver is in this process... 6051 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6052 try { 6053 didSomething |= sendPendingBroadcastsLocked(app); 6054 } catch (Exception e) { 6055 // If the app died trying to launch the receiver we declare it 'bad' 6056 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6057 badApp = true; 6058 } 6059 } 6060 6061 // Check whether the next backup agent is in this process... 6062 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6063 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6064 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6065 try { 6066 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6067 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6068 mBackupTarget.backupMode); 6069 } catch (Exception e) { 6070 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6071 badApp = true; 6072 } 6073 } 6074 6075 if (badApp) { 6076 app.kill("error during init", true); 6077 handleAppDiedLocked(app, false, true); 6078 return false; 6079 } 6080 6081 if (!didSomething) { 6082 updateOomAdjLocked(); 6083 } 6084 6085 return true; 6086 } 6087 6088 @Override 6089 public final void attachApplication(IApplicationThread thread) { 6090 synchronized (this) { 6091 int callingPid = Binder.getCallingPid(); 6092 final long origId = Binder.clearCallingIdentity(); 6093 attachApplicationLocked(thread, callingPid); 6094 Binder.restoreCallingIdentity(origId); 6095 } 6096 } 6097 6098 @Override 6099 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6100 final long origId = Binder.clearCallingIdentity(); 6101 synchronized (this) { 6102 ActivityStack stack = ActivityRecord.getStackLocked(token); 6103 if (stack != null) { 6104 ActivityRecord r = 6105 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6106 if (stopProfiling) { 6107 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6108 try { 6109 mProfileFd.close(); 6110 } catch (IOException e) { 6111 } 6112 clearProfilerLocked(); 6113 } 6114 } 6115 } 6116 } 6117 Binder.restoreCallingIdentity(origId); 6118 } 6119 6120 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6121 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6122 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6123 } 6124 6125 void enableScreenAfterBoot() { 6126 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6127 SystemClock.uptimeMillis()); 6128 mWindowManager.enableScreenAfterBoot(); 6129 6130 synchronized (this) { 6131 updateEventDispatchingLocked(); 6132 } 6133 } 6134 6135 @Override 6136 public void showBootMessage(final CharSequence msg, final boolean always) { 6137 enforceNotIsolatedCaller("showBootMessage"); 6138 mWindowManager.showBootMessage(msg, always); 6139 } 6140 6141 @Override 6142 public void keyguardWaitingForActivityDrawn() { 6143 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6144 final long token = Binder.clearCallingIdentity(); 6145 try { 6146 synchronized (this) { 6147 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6148 mWindowManager.keyguardWaitingForActivityDrawn(); 6149 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6150 mLockScreenShown = LOCK_SCREEN_LEAVING; 6151 } 6152 } 6153 } finally { 6154 Binder.restoreCallingIdentity(token); 6155 } 6156 } 6157 6158 final void finishBooting() { 6159 synchronized (this) { 6160 if (!mBootAnimationComplete) { 6161 mCallFinishBooting = true; 6162 return; 6163 } 6164 mCallFinishBooting = false; 6165 } 6166 6167 ArraySet<String> completedIsas = new ArraySet<String>(); 6168 for (String abi : Build.SUPPORTED_ABIS) { 6169 Process.establishZygoteConnectionForAbi(abi); 6170 final String instructionSet = VMRuntime.getInstructionSet(abi); 6171 if (!completedIsas.contains(instructionSet)) { 6172 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6173 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6174 } 6175 completedIsas.add(instructionSet); 6176 } 6177 } 6178 6179 // Register receivers to handle package update events 6180 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6181 6182 // Let system services know. 6183 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6184 6185 synchronized (this) { 6186 // Ensure that any processes we had put on hold are now started 6187 // up. 6188 final int NP = mProcessesOnHold.size(); 6189 if (NP > 0) { 6190 ArrayList<ProcessRecord> procs = 6191 new ArrayList<ProcessRecord>(mProcessesOnHold); 6192 for (int ip=0; ip<NP; ip++) { 6193 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6194 + procs.get(ip)); 6195 startProcessLocked(procs.get(ip), "on-hold", null); 6196 } 6197 } 6198 6199 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6200 // Start looking for apps that are abusing wake locks. 6201 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6202 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6203 // Tell anyone interested that we are done booting! 6204 SystemProperties.set("sys.boot_completed", "1"); 6205 6206 // And trigger dev.bootcomplete if we are not showing encryption progress 6207 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6208 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6209 SystemProperties.set("dev.bootcomplete", "1"); 6210 } 6211 for (int i=0; i<mStartedUsers.size(); i++) { 6212 UserStartedState uss = mStartedUsers.valueAt(i); 6213 if (uss.mState == UserStartedState.STATE_BOOTING) { 6214 uss.mState = UserStartedState.STATE_RUNNING; 6215 final int userId = mStartedUsers.keyAt(i); 6216 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6217 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6218 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6219 broadcastIntentLocked(null, null, intent, null, 6220 new IIntentReceiver.Stub() { 6221 @Override 6222 public void performReceive(Intent intent, int resultCode, 6223 String data, Bundle extras, boolean ordered, 6224 boolean sticky, int sendingUser) { 6225 synchronized (ActivityManagerService.this) { 6226 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6227 true, false); 6228 } 6229 } 6230 }, 6231 0, null, null, 6232 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6233 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6234 userId); 6235 } 6236 } 6237 scheduleStartProfilesLocked(); 6238 } 6239 } 6240 } 6241 6242 @Override 6243 public void bootAnimationComplete() { 6244 final boolean callFinishBooting; 6245 synchronized (this) { 6246 callFinishBooting = mCallFinishBooting; 6247 mBootAnimationComplete = true; 6248 } 6249 if (callFinishBooting) { 6250 finishBooting(); 6251 } 6252 } 6253 6254 final void ensureBootCompleted() { 6255 boolean booting; 6256 boolean enableScreen; 6257 synchronized (this) { 6258 booting = mBooting; 6259 mBooting = false; 6260 enableScreen = !mBooted; 6261 mBooted = true; 6262 } 6263 6264 if (booting) { 6265 finishBooting(); 6266 } 6267 6268 if (enableScreen) { 6269 enableScreenAfterBoot(); 6270 } 6271 } 6272 6273 @Override 6274 public final void activityResumed(IBinder token) { 6275 final long origId = Binder.clearCallingIdentity(); 6276 synchronized(this) { 6277 ActivityStack stack = ActivityRecord.getStackLocked(token); 6278 if (stack != null) { 6279 ActivityRecord.activityResumedLocked(token); 6280 } 6281 } 6282 Binder.restoreCallingIdentity(origId); 6283 } 6284 6285 @Override 6286 public final void activityPaused(IBinder token) { 6287 final long origId = Binder.clearCallingIdentity(); 6288 synchronized(this) { 6289 ActivityStack stack = ActivityRecord.getStackLocked(token); 6290 if (stack != null) { 6291 stack.activityPausedLocked(token, false); 6292 } 6293 } 6294 Binder.restoreCallingIdentity(origId); 6295 } 6296 6297 @Override 6298 public final void activityStopped(IBinder token, Bundle icicle, 6299 PersistableBundle persistentState, CharSequence description) { 6300 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6301 6302 // Refuse possible leaked file descriptors 6303 if (icicle != null && icicle.hasFileDescriptors()) { 6304 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6305 } 6306 6307 final long origId = Binder.clearCallingIdentity(); 6308 6309 synchronized (this) { 6310 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6311 if (r != null) { 6312 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6313 } 6314 } 6315 6316 trimApplications(); 6317 6318 Binder.restoreCallingIdentity(origId); 6319 } 6320 6321 @Override 6322 public final void activityDestroyed(IBinder token) { 6323 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6324 synchronized (this) { 6325 ActivityStack stack = ActivityRecord.getStackLocked(token); 6326 if (stack != null) { 6327 stack.activityDestroyedLocked(token); 6328 } 6329 } 6330 } 6331 6332 @Override 6333 public final void backgroundResourcesReleased(IBinder token) { 6334 final long origId = Binder.clearCallingIdentity(); 6335 try { 6336 synchronized (this) { 6337 ActivityStack stack = ActivityRecord.getStackLocked(token); 6338 if (stack != null) { 6339 stack.backgroundResourcesReleased(token); 6340 } 6341 } 6342 } finally { 6343 Binder.restoreCallingIdentity(origId); 6344 } 6345 } 6346 6347 @Override 6348 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6349 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6350 } 6351 6352 @Override 6353 public final void notifyEnterAnimationComplete(IBinder token) { 6354 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6355 } 6356 6357 @Override 6358 public String getCallingPackage(IBinder token) { 6359 synchronized (this) { 6360 ActivityRecord r = getCallingRecordLocked(token); 6361 return r != null ? r.info.packageName : null; 6362 } 6363 } 6364 6365 @Override 6366 public ComponentName getCallingActivity(IBinder token) { 6367 synchronized (this) { 6368 ActivityRecord r = getCallingRecordLocked(token); 6369 return r != null ? r.intent.getComponent() : null; 6370 } 6371 } 6372 6373 private ActivityRecord getCallingRecordLocked(IBinder token) { 6374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6375 if (r == null) { 6376 return null; 6377 } 6378 return r.resultTo; 6379 } 6380 6381 @Override 6382 public ComponentName getActivityClassForToken(IBinder token) { 6383 synchronized(this) { 6384 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6385 if (r == null) { 6386 return null; 6387 } 6388 return r.intent.getComponent(); 6389 } 6390 } 6391 6392 @Override 6393 public String getPackageForToken(IBinder token) { 6394 synchronized(this) { 6395 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6396 if (r == null) { 6397 return null; 6398 } 6399 return r.packageName; 6400 } 6401 } 6402 6403 @Override 6404 public IIntentSender getIntentSender(int type, 6405 String packageName, IBinder token, String resultWho, 6406 int requestCode, Intent[] intents, String[] resolvedTypes, 6407 int flags, Bundle options, int userId) { 6408 enforceNotIsolatedCaller("getIntentSender"); 6409 // Refuse possible leaked file descriptors 6410 if (intents != null) { 6411 if (intents.length < 1) { 6412 throw new IllegalArgumentException("Intents array length must be >= 1"); 6413 } 6414 for (int i=0; i<intents.length; i++) { 6415 Intent intent = intents[i]; 6416 if (intent != null) { 6417 if (intent.hasFileDescriptors()) { 6418 throw new IllegalArgumentException("File descriptors passed in Intent"); 6419 } 6420 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6421 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6422 throw new IllegalArgumentException( 6423 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6424 } 6425 intents[i] = new Intent(intent); 6426 } 6427 } 6428 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6429 throw new IllegalArgumentException( 6430 "Intent array length does not match resolvedTypes length"); 6431 } 6432 } 6433 if (options != null) { 6434 if (options.hasFileDescriptors()) { 6435 throw new IllegalArgumentException("File descriptors passed in options"); 6436 } 6437 } 6438 6439 synchronized(this) { 6440 int callingUid = Binder.getCallingUid(); 6441 int origUserId = userId; 6442 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6443 type == ActivityManager.INTENT_SENDER_BROADCAST, 6444 ALLOW_NON_FULL, "getIntentSender", null); 6445 if (origUserId == UserHandle.USER_CURRENT) { 6446 // We don't want to evaluate this until the pending intent is 6447 // actually executed. However, we do want to always do the 6448 // security checking for it above. 6449 userId = UserHandle.USER_CURRENT; 6450 } 6451 try { 6452 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6453 int uid = AppGlobals.getPackageManager() 6454 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6455 if (!UserHandle.isSameApp(callingUid, uid)) { 6456 String msg = "Permission Denial: getIntentSender() from pid=" 6457 + Binder.getCallingPid() 6458 + ", uid=" + Binder.getCallingUid() 6459 + ", (need uid=" + uid + ")" 6460 + " is not allowed to send as package " + packageName; 6461 Slog.w(TAG, msg); 6462 throw new SecurityException(msg); 6463 } 6464 } 6465 6466 return getIntentSenderLocked(type, packageName, callingUid, userId, 6467 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6468 6469 } catch (RemoteException e) { 6470 throw new SecurityException(e); 6471 } 6472 } 6473 } 6474 6475 IIntentSender getIntentSenderLocked(int type, String packageName, 6476 int callingUid, int userId, IBinder token, String resultWho, 6477 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6478 Bundle options) { 6479 if (DEBUG_MU) 6480 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6481 ActivityRecord activity = null; 6482 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6483 activity = ActivityRecord.isInStackLocked(token); 6484 if (activity == null) { 6485 return null; 6486 } 6487 if (activity.finishing) { 6488 return null; 6489 } 6490 } 6491 6492 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6493 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6494 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6495 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6496 |PendingIntent.FLAG_UPDATE_CURRENT); 6497 6498 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6499 type, packageName, activity, resultWho, 6500 requestCode, intents, resolvedTypes, flags, options, userId); 6501 WeakReference<PendingIntentRecord> ref; 6502 ref = mIntentSenderRecords.get(key); 6503 PendingIntentRecord rec = ref != null ? ref.get() : null; 6504 if (rec != null) { 6505 if (!cancelCurrent) { 6506 if (updateCurrent) { 6507 if (rec.key.requestIntent != null) { 6508 rec.key.requestIntent.replaceExtras(intents != null ? 6509 intents[intents.length - 1] : null); 6510 } 6511 if (intents != null) { 6512 intents[intents.length-1] = rec.key.requestIntent; 6513 rec.key.allIntents = intents; 6514 rec.key.allResolvedTypes = resolvedTypes; 6515 } else { 6516 rec.key.allIntents = null; 6517 rec.key.allResolvedTypes = null; 6518 } 6519 } 6520 return rec; 6521 } 6522 rec.canceled = true; 6523 mIntentSenderRecords.remove(key); 6524 } 6525 if (noCreate) { 6526 return rec; 6527 } 6528 rec = new PendingIntentRecord(this, key, callingUid); 6529 mIntentSenderRecords.put(key, rec.ref); 6530 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6531 if (activity.pendingResults == null) { 6532 activity.pendingResults 6533 = new HashSet<WeakReference<PendingIntentRecord>>(); 6534 } 6535 activity.pendingResults.add(rec.ref); 6536 } 6537 return rec; 6538 } 6539 6540 @Override 6541 public void cancelIntentSender(IIntentSender sender) { 6542 if (!(sender instanceof PendingIntentRecord)) { 6543 return; 6544 } 6545 synchronized(this) { 6546 PendingIntentRecord rec = (PendingIntentRecord)sender; 6547 try { 6548 int uid = AppGlobals.getPackageManager() 6549 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6550 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6551 String msg = "Permission Denial: cancelIntentSender() from pid=" 6552 + Binder.getCallingPid() 6553 + ", uid=" + Binder.getCallingUid() 6554 + " is not allowed to cancel packges " 6555 + rec.key.packageName; 6556 Slog.w(TAG, msg); 6557 throw new SecurityException(msg); 6558 } 6559 } catch (RemoteException e) { 6560 throw new SecurityException(e); 6561 } 6562 cancelIntentSenderLocked(rec, true); 6563 } 6564 } 6565 6566 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6567 rec.canceled = true; 6568 mIntentSenderRecords.remove(rec.key); 6569 if (cleanActivity && rec.key.activity != null) { 6570 rec.key.activity.pendingResults.remove(rec.ref); 6571 } 6572 } 6573 6574 @Override 6575 public String getPackageForIntentSender(IIntentSender pendingResult) { 6576 if (!(pendingResult instanceof PendingIntentRecord)) { 6577 return null; 6578 } 6579 try { 6580 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6581 return res.key.packageName; 6582 } catch (ClassCastException e) { 6583 } 6584 return null; 6585 } 6586 6587 @Override 6588 public int getUidForIntentSender(IIntentSender sender) { 6589 if (sender instanceof PendingIntentRecord) { 6590 try { 6591 PendingIntentRecord res = (PendingIntentRecord)sender; 6592 return res.uid; 6593 } catch (ClassCastException e) { 6594 } 6595 } 6596 return -1; 6597 } 6598 6599 @Override 6600 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6601 if (!(pendingResult instanceof PendingIntentRecord)) { 6602 return false; 6603 } 6604 try { 6605 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6606 if (res.key.allIntents == null) { 6607 return false; 6608 } 6609 for (int i=0; i<res.key.allIntents.length; i++) { 6610 Intent intent = res.key.allIntents[i]; 6611 if (intent.getPackage() != null && intent.getComponent() != null) { 6612 return false; 6613 } 6614 } 6615 return true; 6616 } catch (ClassCastException e) { 6617 } 6618 return false; 6619 } 6620 6621 @Override 6622 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6623 if (!(pendingResult instanceof PendingIntentRecord)) { 6624 return false; 6625 } 6626 try { 6627 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6628 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6629 return true; 6630 } 6631 return false; 6632 } catch (ClassCastException e) { 6633 } 6634 return false; 6635 } 6636 6637 @Override 6638 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6639 if (!(pendingResult instanceof PendingIntentRecord)) { 6640 return null; 6641 } 6642 try { 6643 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6644 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6645 } catch (ClassCastException e) { 6646 } 6647 return null; 6648 } 6649 6650 @Override 6651 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6652 if (!(pendingResult instanceof PendingIntentRecord)) { 6653 return null; 6654 } 6655 try { 6656 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6657 Intent intent = res.key.requestIntent; 6658 if (intent != null) { 6659 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6660 || res.lastTagPrefix.equals(prefix))) { 6661 return res.lastTag; 6662 } 6663 res.lastTagPrefix = prefix; 6664 StringBuilder sb = new StringBuilder(128); 6665 if (prefix != null) { 6666 sb.append(prefix); 6667 } 6668 if (intent.getAction() != null) { 6669 sb.append(intent.getAction()); 6670 } else if (intent.getComponent() != null) { 6671 intent.getComponent().appendShortString(sb); 6672 } else { 6673 sb.append("?"); 6674 } 6675 return res.lastTag = sb.toString(); 6676 } 6677 } catch (ClassCastException e) { 6678 } 6679 return null; 6680 } 6681 6682 @Override 6683 public void setProcessLimit(int max) { 6684 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6685 "setProcessLimit()"); 6686 synchronized (this) { 6687 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6688 mProcessLimitOverride = max; 6689 } 6690 trimApplications(); 6691 } 6692 6693 @Override 6694 public int getProcessLimit() { 6695 synchronized (this) { 6696 return mProcessLimitOverride; 6697 } 6698 } 6699 6700 void foregroundTokenDied(ForegroundToken token) { 6701 synchronized (ActivityManagerService.this) { 6702 synchronized (mPidsSelfLocked) { 6703 ForegroundToken cur 6704 = mForegroundProcesses.get(token.pid); 6705 if (cur != token) { 6706 return; 6707 } 6708 mForegroundProcesses.remove(token.pid); 6709 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6710 if (pr == null) { 6711 return; 6712 } 6713 pr.forcingToForeground = null; 6714 updateProcessForegroundLocked(pr, false, false); 6715 } 6716 updateOomAdjLocked(); 6717 } 6718 } 6719 6720 @Override 6721 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6722 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6723 "setProcessForeground()"); 6724 synchronized(this) { 6725 boolean changed = false; 6726 6727 synchronized (mPidsSelfLocked) { 6728 ProcessRecord pr = mPidsSelfLocked.get(pid); 6729 if (pr == null && isForeground) { 6730 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6731 return; 6732 } 6733 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6734 if (oldToken != null) { 6735 oldToken.token.unlinkToDeath(oldToken, 0); 6736 mForegroundProcesses.remove(pid); 6737 if (pr != null) { 6738 pr.forcingToForeground = null; 6739 } 6740 changed = true; 6741 } 6742 if (isForeground && token != null) { 6743 ForegroundToken newToken = new ForegroundToken() { 6744 @Override 6745 public void binderDied() { 6746 foregroundTokenDied(this); 6747 } 6748 }; 6749 newToken.pid = pid; 6750 newToken.token = token; 6751 try { 6752 token.linkToDeath(newToken, 0); 6753 mForegroundProcesses.put(pid, newToken); 6754 pr.forcingToForeground = token; 6755 changed = true; 6756 } catch (RemoteException e) { 6757 // If the process died while doing this, we will later 6758 // do the cleanup with the process death link. 6759 } 6760 } 6761 } 6762 6763 if (changed) { 6764 updateOomAdjLocked(); 6765 } 6766 } 6767 } 6768 6769 // ========================================================= 6770 // PERMISSIONS 6771 // ========================================================= 6772 6773 static class PermissionController extends IPermissionController.Stub { 6774 ActivityManagerService mActivityManagerService; 6775 PermissionController(ActivityManagerService activityManagerService) { 6776 mActivityManagerService = activityManagerService; 6777 } 6778 6779 @Override 6780 public boolean checkPermission(String permission, int pid, int uid) { 6781 return mActivityManagerService.checkPermission(permission, pid, 6782 uid) == PackageManager.PERMISSION_GRANTED; 6783 } 6784 } 6785 6786 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6787 @Override 6788 public int checkComponentPermission(String permission, int pid, int uid, 6789 int owningUid, boolean exported) { 6790 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6791 owningUid, exported); 6792 } 6793 6794 @Override 6795 public Object getAMSLock() { 6796 return ActivityManagerService.this; 6797 } 6798 } 6799 6800 /** 6801 * This can be called with or without the global lock held. 6802 */ 6803 int checkComponentPermission(String permission, int pid, int uid, 6804 int owningUid, boolean exported) { 6805 // We might be performing an operation on behalf of an indirect binder 6806 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6807 // client identity accordingly before proceeding. 6808 Identity tlsIdentity = sCallerIdentity.get(); 6809 if (tlsIdentity != null) { 6810 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6811 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6812 uid = tlsIdentity.uid; 6813 pid = tlsIdentity.pid; 6814 } 6815 6816 if (pid == MY_PID) { 6817 return PackageManager.PERMISSION_GRANTED; 6818 } 6819 6820 return ActivityManager.checkComponentPermission(permission, uid, 6821 owningUid, exported); 6822 } 6823 6824 /** 6825 * As the only public entry point for permissions checking, this method 6826 * can enforce the semantic that requesting a check on a null global 6827 * permission is automatically denied. (Internally a null permission 6828 * string is used when calling {@link #checkComponentPermission} in cases 6829 * when only uid-based security is needed.) 6830 * 6831 * This can be called with or without the global lock held. 6832 */ 6833 @Override 6834 public int checkPermission(String permission, int pid, int uid) { 6835 if (permission == null) { 6836 return PackageManager.PERMISSION_DENIED; 6837 } 6838 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6839 } 6840 6841 /** 6842 * Binder IPC calls go through the public entry point. 6843 * This can be called with or without the global lock held. 6844 */ 6845 int checkCallingPermission(String permission) { 6846 return checkPermission(permission, 6847 Binder.getCallingPid(), 6848 UserHandle.getAppId(Binder.getCallingUid())); 6849 } 6850 6851 /** 6852 * This can be called with or without the global lock held. 6853 */ 6854 void enforceCallingPermission(String permission, String func) { 6855 if (checkCallingPermission(permission) 6856 == PackageManager.PERMISSION_GRANTED) { 6857 return; 6858 } 6859 6860 String msg = "Permission Denial: " + func + " from pid=" 6861 + Binder.getCallingPid() 6862 + ", uid=" + Binder.getCallingUid() 6863 + " requires " + permission; 6864 Slog.w(TAG, msg); 6865 throw new SecurityException(msg); 6866 } 6867 6868 /** 6869 * Determine if UID is holding permissions required to access {@link Uri} in 6870 * the given {@link ProviderInfo}. Final permission checking is always done 6871 * in {@link ContentProvider}. 6872 */ 6873 private final boolean checkHoldingPermissionsLocked( 6874 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6875 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6876 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6877 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6878 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6879 != PERMISSION_GRANTED) { 6880 return false; 6881 } 6882 } 6883 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6884 } 6885 6886 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6887 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6888 if (pi.applicationInfo.uid == uid) { 6889 return true; 6890 } else if (!pi.exported) { 6891 return false; 6892 } 6893 6894 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6895 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6896 try { 6897 // check if target holds top-level <provider> permissions 6898 if (!readMet && pi.readPermission != null && considerUidPermissions 6899 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6900 readMet = true; 6901 } 6902 if (!writeMet && pi.writePermission != null && considerUidPermissions 6903 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6904 writeMet = true; 6905 } 6906 6907 // track if unprotected read/write is allowed; any denied 6908 // <path-permission> below removes this ability 6909 boolean allowDefaultRead = pi.readPermission == null; 6910 boolean allowDefaultWrite = pi.writePermission == null; 6911 6912 // check if target holds any <path-permission> that match uri 6913 final PathPermission[] pps = pi.pathPermissions; 6914 if (pps != null) { 6915 final String path = grantUri.uri.getPath(); 6916 int i = pps.length; 6917 while (i > 0 && (!readMet || !writeMet)) { 6918 i--; 6919 PathPermission pp = pps[i]; 6920 if (pp.match(path)) { 6921 if (!readMet) { 6922 final String pprperm = pp.getReadPermission(); 6923 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6924 + pprperm + " for " + pp.getPath() 6925 + ": match=" + pp.match(path) 6926 + " check=" + pm.checkUidPermission(pprperm, uid)); 6927 if (pprperm != null) { 6928 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6929 == PERMISSION_GRANTED) { 6930 readMet = true; 6931 } else { 6932 allowDefaultRead = false; 6933 } 6934 } 6935 } 6936 if (!writeMet) { 6937 final String ppwperm = pp.getWritePermission(); 6938 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6939 + ppwperm + " for " + pp.getPath() 6940 + ": match=" + pp.match(path) 6941 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6942 if (ppwperm != null) { 6943 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6944 == PERMISSION_GRANTED) { 6945 writeMet = true; 6946 } else { 6947 allowDefaultWrite = false; 6948 } 6949 } 6950 } 6951 } 6952 } 6953 } 6954 6955 // grant unprotected <provider> read/write, if not blocked by 6956 // <path-permission> above 6957 if (allowDefaultRead) readMet = true; 6958 if (allowDefaultWrite) writeMet = true; 6959 6960 } catch (RemoteException e) { 6961 return false; 6962 } 6963 6964 return readMet && writeMet; 6965 } 6966 6967 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6968 ProviderInfo pi = null; 6969 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6970 if (cpr != null) { 6971 pi = cpr.info; 6972 } else { 6973 try { 6974 pi = AppGlobals.getPackageManager().resolveContentProvider( 6975 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6976 } catch (RemoteException ex) { 6977 } 6978 } 6979 return pi; 6980 } 6981 6982 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6983 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6984 if (targetUris != null) { 6985 return targetUris.get(grantUri); 6986 } 6987 return null; 6988 } 6989 6990 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6991 String targetPkg, int targetUid, GrantUri grantUri) { 6992 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6993 if (targetUris == null) { 6994 targetUris = Maps.newArrayMap(); 6995 mGrantedUriPermissions.put(targetUid, targetUris); 6996 } 6997 6998 UriPermission perm = targetUris.get(grantUri); 6999 if (perm == null) { 7000 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7001 targetUris.put(grantUri, perm); 7002 } 7003 7004 return perm; 7005 } 7006 7007 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7008 final int modeFlags) { 7009 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7010 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7011 : UriPermission.STRENGTH_OWNED; 7012 7013 // Root gets to do everything. 7014 if (uid == 0) { 7015 return true; 7016 } 7017 7018 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7019 if (perms == null) return false; 7020 7021 // First look for exact match 7022 final UriPermission exactPerm = perms.get(grantUri); 7023 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7024 return true; 7025 } 7026 7027 // No exact match, look for prefixes 7028 final int N = perms.size(); 7029 for (int i = 0; i < N; i++) { 7030 final UriPermission perm = perms.valueAt(i); 7031 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7032 && perm.getStrength(modeFlags) >= minStrength) { 7033 return true; 7034 } 7035 } 7036 7037 return false; 7038 } 7039 7040 /** 7041 * @param uri This uri must NOT contain an embedded userId. 7042 * @param userId The userId in which the uri is to be resolved. 7043 */ 7044 @Override 7045 public int checkUriPermission(Uri uri, int pid, int uid, 7046 final int modeFlags, int userId) { 7047 enforceNotIsolatedCaller("checkUriPermission"); 7048 7049 // Another redirected-binder-call permissions check as in 7050 // {@link checkComponentPermission}. 7051 Identity tlsIdentity = sCallerIdentity.get(); 7052 if (tlsIdentity != null) { 7053 uid = tlsIdentity.uid; 7054 pid = tlsIdentity.pid; 7055 } 7056 7057 // Our own process gets to do everything. 7058 if (pid == MY_PID) { 7059 return PackageManager.PERMISSION_GRANTED; 7060 } 7061 synchronized (this) { 7062 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7063 ? PackageManager.PERMISSION_GRANTED 7064 : PackageManager.PERMISSION_DENIED; 7065 } 7066 } 7067 7068 /** 7069 * Check if the targetPkg can be granted permission to access uri by 7070 * the callingUid using the given modeFlags. Throws a security exception 7071 * if callingUid is not allowed to do this. Returns the uid of the target 7072 * if the URI permission grant should be performed; returns -1 if it is not 7073 * needed (for example targetPkg already has permission to access the URI). 7074 * If you already know the uid of the target, you can supply it in 7075 * lastTargetUid else set that to -1. 7076 */ 7077 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7078 final int modeFlags, int lastTargetUid) { 7079 if (!Intent.isAccessUriMode(modeFlags)) { 7080 return -1; 7081 } 7082 7083 if (targetPkg != null) { 7084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7085 "Checking grant " + targetPkg + " permission to " + grantUri); 7086 } 7087 7088 final IPackageManager pm = AppGlobals.getPackageManager(); 7089 7090 // If this is not a content: uri, we can't do anything with it. 7091 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7092 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7093 "Can't grant URI permission for non-content URI: " + grantUri); 7094 return -1; 7095 } 7096 7097 final String authority = grantUri.uri.getAuthority(); 7098 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7099 if (pi == null) { 7100 Slog.w(TAG, "No content provider found for permission check: " + 7101 grantUri.uri.toSafeString()); 7102 return -1; 7103 } 7104 7105 int targetUid = lastTargetUid; 7106 if (targetUid < 0 && targetPkg != null) { 7107 try { 7108 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7109 if (targetUid < 0) { 7110 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7111 "Can't grant URI permission no uid for: " + targetPkg); 7112 return -1; 7113 } 7114 } catch (RemoteException ex) { 7115 return -1; 7116 } 7117 } 7118 7119 if (targetUid >= 0) { 7120 // First... does the target actually need this permission? 7121 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7122 // No need to grant the target this permission. 7123 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7124 "Target " + targetPkg + " already has full permission to " + grantUri); 7125 return -1; 7126 } 7127 } else { 7128 // First... there is no target package, so can anyone access it? 7129 boolean allowed = pi.exported; 7130 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7131 if (pi.readPermission != null) { 7132 allowed = false; 7133 } 7134 } 7135 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7136 if (pi.writePermission != null) { 7137 allowed = false; 7138 } 7139 } 7140 if (allowed) { 7141 return -1; 7142 } 7143 } 7144 7145 /* There is a special cross user grant if: 7146 * - The target is on another user. 7147 * - Apps on the current user can access the uri without any uid permissions. 7148 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7149 * grant uri permissions. 7150 */ 7151 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7152 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7153 modeFlags, false /*without considering the uid permissions*/); 7154 7155 // Second... is the provider allowing granting of URI permissions? 7156 if (!specialCrossUserGrant) { 7157 if (!pi.grantUriPermissions) { 7158 throw new SecurityException("Provider " + pi.packageName 7159 + "/" + pi.name 7160 + " does not allow granting of Uri permissions (uri " 7161 + grantUri + ")"); 7162 } 7163 if (pi.uriPermissionPatterns != null) { 7164 final int N = pi.uriPermissionPatterns.length; 7165 boolean allowed = false; 7166 for (int i=0; i<N; i++) { 7167 if (pi.uriPermissionPatterns[i] != null 7168 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7169 allowed = true; 7170 break; 7171 } 7172 } 7173 if (!allowed) { 7174 throw new SecurityException("Provider " + pi.packageName 7175 + "/" + pi.name 7176 + " does not allow granting of permission to path of Uri " 7177 + grantUri); 7178 } 7179 } 7180 } 7181 7182 // Third... does the caller itself have permission to access 7183 // this uri? 7184 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7185 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7186 // Require they hold a strong enough Uri permission 7187 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7188 throw new SecurityException("Uid " + callingUid 7189 + " does not have permission to uri " + grantUri); 7190 } 7191 } 7192 } 7193 return targetUid; 7194 } 7195 7196 /** 7197 * @param uri This uri must NOT contain an embedded userId. 7198 * @param userId The userId in which the uri is to be resolved. 7199 */ 7200 @Override 7201 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7202 final int modeFlags, int userId) { 7203 enforceNotIsolatedCaller("checkGrantUriPermission"); 7204 synchronized(this) { 7205 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7206 new GrantUri(userId, uri, false), modeFlags, -1); 7207 } 7208 } 7209 7210 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7211 final int modeFlags, UriPermissionOwner owner) { 7212 if (!Intent.isAccessUriMode(modeFlags)) { 7213 return; 7214 } 7215 7216 // So here we are: the caller has the assumed permission 7217 // to the uri, and the target doesn't. Let's now give this to 7218 // the target. 7219 7220 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7221 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7222 7223 final String authority = grantUri.uri.getAuthority(); 7224 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7225 if (pi == null) { 7226 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7227 return; 7228 } 7229 7230 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7231 grantUri.prefix = true; 7232 } 7233 final UriPermission perm = findOrCreateUriPermissionLocked( 7234 pi.packageName, targetPkg, targetUid, grantUri); 7235 perm.grantModes(modeFlags, owner); 7236 } 7237 7238 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7239 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7240 if (targetPkg == null) { 7241 throw new NullPointerException("targetPkg"); 7242 } 7243 int targetUid; 7244 final IPackageManager pm = AppGlobals.getPackageManager(); 7245 try { 7246 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7247 } catch (RemoteException ex) { 7248 return; 7249 } 7250 7251 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7252 targetUid); 7253 if (targetUid < 0) { 7254 return; 7255 } 7256 7257 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7258 owner); 7259 } 7260 7261 static class NeededUriGrants extends ArrayList<GrantUri> { 7262 final String targetPkg; 7263 final int targetUid; 7264 final int flags; 7265 7266 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7267 this.targetPkg = targetPkg; 7268 this.targetUid = targetUid; 7269 this.flags = flags; 7270 } 7271 } 7272 7273 /** 7274 * Like checkGrantUriPermissionLocked, but takes an Intent. 7275 */ 7276 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7277 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7278 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7279 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7280 + " clip=" + (intent != null ? intent.getClipData() : null) 7281 + " from " + intent + "; flags=0x" 7282 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7283 7284 if (targetPkg == null) { 7285 throw new NullPointerException("targetPkg"); 7286 } 7287 7288 if (intent == null) { 7289 return null; 7290 } 7291 Uri data = intent.getData(); 7292 ClipData clip = intent.getClipData(); 7293 if (data == null && clip == null) { 7294 return null; 7295 } 7296 // Default userId for uris in the intent (if they don't specify it themselves) 7297 int contentUserHint = intent.getContentUserHint(); 7298 if (contentUserHint == UserHandle.USER_CURRENT) { 7299 contentUserHint = UserHandle.getUserId(callingUid); 7300 } 7301 final IPackageManager pm = AppGlobals.getPackageManager(); 7302 int targetUid; 7303 if (needed != null) { 7304 targetUid = needed.targetUid; 7305 } else { 7306 try { 7307 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7308 } catch (RemoteException ex) { 7309 return null; 7310 } 7311 if (targetUid < 0) { 7312 if (DEBUG_URI_PERMISSION) { 7313 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7314 + " on user " + targetUserId); 7315 } 7316 return null; 7317 } 7318 } 7319 if (data != null) { 7320 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7321 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7322 targetUid); 7323 if (targetUid > 0) { 7324 if (needed == null) { 7325 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7326 } 7327 needed.add(grantUri); 7328 } 7329 } 7330 if (clip != null) { 7331 for (int i=0; i<clip.getItemCount(); i++) { 7332 Uri uri = clip.getItemAt(i).getUri(); 7333 if (uri != null) { 7334 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7335 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7336 targetUid); 7337 if (targetUid > 0) { 7338 if (needed == null) { 7339 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7340 } 7341 needed.add(grantUri); 7342 } 7343 } else { 7344 Intent clipIntent = clip.getItemAt(i).getIntent(); 7345 if (clipIntent != null) { 7346 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7347 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7348 if (newNeeded != null) { 7349 needed = newNeeded; 7350 } 7351 } 7352 } 7353 } 7354 } 7355 7356 return needed; 7357 } 7358 7359 /** 7360 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7361 */ 7362 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7363 UriPermissionOwner owner) { 7364 if (needed != null) { 7365 for (int i=0; i<needed.size(); i++) { 7366 GrantUri grantUri = needed.get(i); 7367 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7368 grantUri, needed.flags, owner); 7369 } 7370 } 7371 } 7372 7373 void grantUriPermissionFromIntentLocked(int callingUid, 7374 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7375 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7376 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7377 if (needed == null) { 7378 return; 7379 } 7380 7381 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7382 } 7383 7384 /** 7385 * @param uri This uri must NOT contain an embedded userId. 7386 * @param userId The userId in which the uri is to be resolved. 7387 */ 7388 @Override 7389 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7390 final int modeFlags, int userId) { 7391 enforceNotIsolatedCaller("grantUriPermission"); 7392 GrantUri grantUri = new GrantUri(userId, uri, false); 7393 synchronized(this) { 7394 final ProcessRecord r = getRecordForAppLocked(caller); 7395 if (r == null) { 7396 throw new SecurityException("Unable to find app for caller " 7397 + caller 7398 + " when granting permission to uri " + grantUri); 7399 } 7400 if (targetPkg == null) { 7401 throw new IllegalArgumentException("null target"); 7402 } 7403 if (grantUri == null) { 7404 throw new IllegalArgumentException("null uri"); 7405 } 7406 7407 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7408 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7409 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7410 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7411 7412 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7413 UserHandle.getUserId(r.uid)); 7414 } 7415 } 7416 7417 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7418 if (perm.modeFlags == 0) { 7419 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7420 perm.targetUid); 7421 if (perms != null) { 7422 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7423 "Removing " + perm.targetUid + " permission to " + perm.uri); 7424 7425 perms.remove(perm.uri); 7426 if (perms.isEmpty()) { 7427 mGrantedUriPermissions.remove(perm.targetUid); 7428 } 7429 } 7430 } 7431 } 7432 7433 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7434 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7435 7436 final IPackageManager pm = AppGlobals.getPackageManager(); 7437 final String authority = grantUri.uri.getAuthority(); 7438 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7439 if (pi == null) { 7440 Slog.w(TAG, "No content provider found for permission revoke: " 7441 + grantUri.toSafeString()); 7442 return; 7443 } 7444 7445 // Does the caller have this permission on the URI? 7446 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7447 // If they don't have direct access to the URI, then revoke any 7448 // ownerless URI permissions that have been granted to them. 7449 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7450 if (perms != null) { 7451 boolean persistChanged = false; 7452 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7453 final UriPermission perm = it.next(); 7454 if (perm.uri.sourceUserId == grantUri.sourceUserId 7455 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7456 if (DEBUG_URI_PERMISSION) 7457 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7458 " permission to " + perm.uri); 7459 persistChanged |= perm.revokeModes( 7460 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7461 if (perm.modeFlags == 0) { 7462 it.remove(); 7463 } 7464 } 7465 } 7466 if (perms.isEmpty()) { 7467 mGrantedUriPermissions.remove(callingUid); 7468 } 7469 if (persistChanged) { 7470 schedulePersistUriGrants(); 7471 } 7472 } 7473 return; 7474 } 7475 7476 boolean persistChanged = false; 7477 7478 // Go through all of the permissions and remove any that match. 7479 int N = mGrantedUriPermissions.size(); 7480 for (int i = 0; i < N; i++) { 7481 final int targetUid = mGrantedUriPermissions.keyAt(i); 7482 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7483 7484 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7485 final UriPermission perm = it.next(); 7486 if (perm.uri.sourceUserId == grantUri.sourceUserId 7487 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7488 if (DEBUG_URI_PERMISSION) 7489 Slog.v(TAG, 7490 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7491 persistChanged |= perm.revokeModes( 7492 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7493 if (perm.modeFlags == 0) { 7494 it.remove(); 7495 } 7496 } 7497 } 7498 7499 if (perms.isEmpty()) { 7500 mGrantedUriPermissions.remove(targetUid); 7501 N--; 7502 i--; 7503 } 7504 } 7505 7506 if (persistChanged) { 7507 schedulePersistUriGrants(); 7508 } 7509 } 7510 7511 /** 7512 * @param uri This uri must NOT contain an embedded userId. 7513 * @param userId The userId in which the uri is to be resolved. 7514 */ 7515 @Override 7516 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7517 int userId) { 7518 enforceNotIsolatedCaller("revokeUriPermission"); 7519 synchronized(this) { 7520 final ProcessRecord r = getRecordForAppLocked(caller); 7521 if (r == null) { 7522 throw new SecurityException("Unable to find app for caller " 7523 + caller 7524 + " when revoking permission to uri " + uri); 7525 } 7526 if (uri == null) { 7527 Slog.w(TAG, "revokeUriPermission: null uri"); 7528 return; 7529 } 7530 7531 if (!Intent.isAccessUriMode(modeFlags)) { 7532 return; 7533 } 7534 7535 final IPackageManager pm = AppGlobals.getPackageManager(); 7536 final String authority = uri.getAuthority(); 7537 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7538 if (pi == null) { 7539 Slog.w(TAG, "No content provider found for permission revoke: " 7540 + uri.toSafeString()); 7541 return; 7542 } 7543 7544 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7545 } 7546 } 7547 7548 /** 7549 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7550 * given package. 7551 * 7552 * @param packageName Package name to match, or {@code null} to apply to all 7553 * packages. 7554 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7555 * to all users. 7556 * @param persistable If persistable grants should be removed. 7557 */ 7558 private void removeUriPermissionsForPackageLocked( 7559 String packageName, int userHandle, boolean persistable) { 7560 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7561 throw new IllegalArgumentException("Must narrow by either package or user"); 7562 } 7563 7564 boolean persistChanged = false; 7565 7566 int N = mGrantedUriPermissions.size(); 7567 for (int i = 0; i < N; i++) { 7568 final int targetUid = mGrantedUriPermissions.keyAt(i); 7569 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7570 7571 // Only inspect grants matching user 7572 if (userHandle == UserHandle.USER_ALL 7573 || userHandle == UserHandle.getUserId(targetUid)) { 7574 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7575 final UriPermission perm = it.next(); 7576 7577 // Only inspect grants matching package 7578 if (packageName == null || perm.sourcePkg.equals(packageName) 7579 || perm.targetPkg.equals(packageName)) { 7580 persistChanged |= perm.revokeModes(persistable 7581 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7582 7583 // Only remove when no modes remain; any persisted grants 7584 // will keep this alive. 7585 if (perm.modeFlags == 0) { 7586 it.remove(); 7587 } 7588 } 7589 } 7590 7591 if (perms.isEmpty()) { 7592 mGrantedUriPermissions.remove(targetUid); 7593 N--; 7594 i--; 7595 } 7596 } 7597 } 7598 7599 if (persistChanged) { 7600 schedulePersistUriGrants(); 7601 } 7602 } 7603 7604 @Override 7605 public IBinder newUriPermissionOwner(String name) { 7606 enforceNotIsolatedCaller("newUriPermissionOwner"); 7607 synchronized(this) { 7608 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7609 return owner.getExternalTokenLocked(); 7610 } 7611 } 7612 7613 /** 7614 * @param uri This uri must NOT contain an embedded userId. 7615 * @param sourceUserId The userId in which the uri is to be resolved. 7616 * @param targetUserId The userId of the app that receives the grant. 7617 */ 7618 @Override 7619 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7620 final int modeFlags, int sourceUserId, int targetUserId) { 7621 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7622 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7623 synchronized(this) { 7624 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7625 if (owner == null) { 7626 throw new IllegalArgumentException("Unknown owner: " + token); 7627 } 7628 if (fromUid != Binder.getCallingUid()) { 7629 if (Binder.getCallingUid() != Process.myUid()) { 7630 // Only system code can grant URI permissions on behalf 7631 // of other users. 7632 throw new SecurityException("nice try"); 7633 } 7634 } 7635 if (targetPkg == null) { 7636 throw new IllegalArgumentException("null target"); 7637 } 7638 if (uri == null) { 7639 throw new IllegalArgumentException("null uri"); 7640 } 7641 7642 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7643 modeFlags, owner, targetUserId); 7644 } 7645 } 7646 7647 /** 7648 * @param uri This uri must NOT contain an embedded userId. 7649 * @param userId The userId in which the uri is to be resolved. 7650 */ 7651 @Override 7652 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7653 synchronized(this) { 7654 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7655 if (owner == null) { 7656 throw new IllegalArgumentException("Unknown owner: " + token); 7657 } 7658 7659 if (uri == null) { 7660 owner.removeUriPermissionsLocked(mode); 7661 } else { 7662 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7663 } 7664 } 7665 } 7666 7667 private void schedulePersistUriGrants() { 7668 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7669 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7670 10 * DateUtils.SECOND_IN_MILLIS); 7671 } 7672 } 7673 7674 private void writeGrantedUriPermissions() { 7675 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7676 7677 // Snapshot permissions so we can persist without lock 7678 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7679 synchronized (this) { 7680 final int size = mGrantedUriPermissions.size(); 7681 for (int i = 0; i < size; i++) { 7682 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7683 for (UriPermission perm : perms.values()) { 7684 if (perm.persistedModeFlags != 0) { 7685 persist.add(perm.snapshot()); 7686 } 7687 } 7688 } 7689 } 7690 7691 FileOutputStream fos = null; 7692 try { 7693 fos = mGrantFile.startWrite(); 7694 7695 XmlSerializer out = new FastXmlSerializer(); 7696 out.setOutput(fos, "utf-8"); 7697 out.startDocument(null, true); 7698 out.startTag(null, TAG_URI_GRANTS); 7699 for (UriPermission.Snapshot perm : persist) { 7700 out.startTag(null, TAG_URI_GRANT); 7701 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7702 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7703 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7704 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7705 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7706 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7707 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7708 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7709 out.endTag(null, TAG_URI_GRANT); 7710 } 7711 out.endTag(null, TAG_URI_GRANTS); 7712 out.endDocument(); 7713 7714 mGrantFile.finishWrite(fos); 7715 } catch (IOException e) { 7716 if (fos != null) { 7717 mGrantFile.failWrite(fos); 7718 } 7719 } 7720 } 7721 7722 private void readGrantedUriPermissionsLocked() { 7723 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7724 7725 final long now = System.currentTimeMillis(); 7726 7727 FileInputStream fis = null; 7728 try { 7729 fis = mGrantFile.openRead(); 7730 final XmlPullParser in = Xml.newPullParser(); 7731 in.setInput(fis, null); 7732 7733 int type; 7734 while ((type = in.next()) != END_DOCUMENT) { 7735 final String tag = in.getName(); 7736 if (type == START_TAG) { 7737 if (TAG_URI_GRANT.equals(tag)) { 7738 final int sourceUserId; 7739 final int targetUserId; 7740 final int userHandle = readIntAttribute(in, 7741 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7742 if (userHandle != UserHandle.USER_NULL) { 7743 // For backwards compatibility. 7744 sourceUserId = userHandle; 7745 targetUserId = userHandle; 7746 } else { 7747 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7748 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7749 } 7750 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7751 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7752 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7753 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7754 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7755 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7756 7757 // Sanity check that provider still belongs to source package 7758 final ProviderInfo pi = getProviderInfoLocked( 7759 uri.getAuthority(), sourceUserId); 7760 if (pi != null && sourcePkg.equals(pi.packageName)) { 7761 int targetUid = -1; 7762 try { 7763 targetUid = AppGlobals.getPackageManager() 7764 .getPackageUid(targetPkg, targetUserId); 7765 } catch (RemoteException e) { 7766 } 7767 if (targetUid != -1) { 7768 final UriPermission perm = findOrCreateUriPermissionLocked( 7769 sourcePkg, targetPkg, targetUid, 7770 new GrantUri(sourceUserId, uri, prefix)); 7771 perm.initPersistedModes(modeFlags, createdTime); 7772 } 7773 } else { 7774 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7775 + " but instead found " + pi); 7776 } 7777 } 7778 } 7779 } 7780 } catch (FileNotFoundException e) { 7781 // Missing grants is okay 7782 } catch (IOException e) { 7783 Slog.wtf(TAG, "Failed reading Uri grants", e); 7784 } catch (XmlPullParserException e) { 7785 Slog.wtf(TAG, "Failed reading Uri grants", e); 7786 } finally { 7787 IoUtils.closeQuietly(fis); 7788 } 7789 } 7790 7791 /** 7792 * @param uri This uri must NOT contain an embedded userId. 7793 * @param userId The userId in which the uri is to be resolved. 7794 */ 7795 @Override 7796 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7797 enforceNotIsolatedCaller("takePersistableUriPermission"); 7798 7799 Preconditions.checkFlagsArgument(modeFlags, 7800 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7801 7802 synchronized (this) { 7803 final int callingUid = Binder.getCallingUid(); 7804 boolean persistChanged = false; 7805 GrantUri grantUri = new GrantUri(userId, uri, false); 7806 7807 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7808 new GrantUri(userId, uri, false)); 7809 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7810 new GrantUri(userId, uri, true)); 7811 7812 final boolean exactValid = (exactPerm != null) 7813 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7814 final boolean prefixValid = (prefixPerm != null) 7815 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7816 7817 if (!(exactValid || prefixValid)) { 7818 throw new SecurityException("No persistable permission grants found for UID " 7819 + callingUid + " and Uri " + grantUri.toSafeString()); 7820 } 7821 7822 if (exactValid) { 7823 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7824 } 7825 if (prefixValid) { 7826 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7827 } 7828 7829 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7830 7831 if (persistChanged) { 7832 schedulePersistUriGrants(); 7833 } 7834 } 7835 } 7836 7837 /** 7838 * @param uri This uri must NOT contain an embedded userId. 7839 * @param userId The userId in which the uri is to be resolved. 7840 */ 7841 @Override 7842 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7843 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7844 7845 Preconditions.checkFlagsArgument(modeFlags, 7846 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7847 7848 synchronized (this) { 7849 final int callingUid = Binder.getCallingUid(); 7850 boolean persistChanged = false; 7851 7852 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7853 new GrantUri(userId, uri, false)); 7854 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7855 new GrantUri(userId, uri, true)); 7856 if (exactPerm == null && prefixPerm == null) { 7857 throw new SecurityException("No permission grants found for UID " + callingUid 7858 + " and Uri " + uri.toSafeString()); 7859 } 7860 7861 if (exactPerm != null) { 7862 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7863 removeUriPermissionIfNeededLocked(exactPerm); 7864 } 7865 if (prefixPerm != null) { 7866 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7867 removeUriPermissionIfNeededLocked(prefixPerm); 7868 } 7869 7870 if (persistChanged) { 7871 schedulePersistUriGrants(); 7872 } 7873 } 7874 } 7875 7876 /** 7877 * Prune any older {@link UriPermission} for the given UID until outstanding 7878 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7879 * 7880 * @return if any mutations occured that require persisting. 7881 */ 7882 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7883 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7884 if (perms == null) return false; 7885 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7886 7887 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7888 for (UriPermission perm : perms.values()) { 7889 if (perm.persistedModeFlags != 0) { 7890 persisted.add(perm); 7891 } 7892 } 7893 7894 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7895 if (trimCount <= 0) return false; 7896 7897 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7898 for (int i = 0; i < trimCount; i++) { 7899 final UriPermission perm = persisted.get(i); 7900 7901 if (DEBUG_URI_PERMISSION) { 7902 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7903 } 7904 7905 perm.releasePersistableModes(~0); 7906 removeUriPermissionIfNeededLocked(perm); 7907 } 7908 7909 return true; 7910 } 7911 7912 @Override 7913 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7914 String packageName, boolean incoming) { 7915 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7916 Preconditions.checkNotNull(packageName, "packageName"); 7917 7918 final int callingUid = Binder.getCallingUid(); 7919 final IPackageManager pm = AppGlobals.getPackageManager(); 7920 try { 7921 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7922 if (packageUid != callingUid) { 7923 throw new SecurityException( 7924 "Package " + packageName + " does not belong to calling UID " + callingUid); 7925 } 7926 } catch (RemoteException e) { 7927 throw new SecurityException("Failed to verify package name ownership"); 7928 } 7929 7930 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7931 synchronized (this) { 7932 if (incoming) { 7933 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7934 callingUid); 7935 if (perms == null) { 7936 Slog.w(TAG, "No permission grants found for " + packageName); 7937 } else { 7938 for (UriPermission perm : perms.values()) { 7939 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7940 result.add(perm.buildPersistedPublicApiObject()); 7941 } 7942 } 7943 } 7944 } else { 7945 final int size = mGrantedUriPermissions.size(); 7946 for (int i = 0; i < size; i++) { 7947 final ArrayMap<GrantUri, UriPermission> perms = 7948 mGrantedUriPermissions.valueAt(i); 7949 for (UriPermission perm : perms.values()) { 7950 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7951 result.add(perm.buildPersistedPublicApiObject()); 7952 } 7953 } 7954 } 7955 } 7956 } 7957 return new ParceledListSlice<android.content.UriPermission>(result); 7958 } 7959 7960 @Override 7961 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7962 synchronized (this) { 7963 ProcessRecord app = 7964 who != null ? getRecordForAppLocked(who) : null; 7965 if (app == null) return; 7966 7967 Message msg = Message.obtain(); 7968 msg.what = WAIT_FOR_DEBUGGER_MSG; 7969 msg.obj = app; 7970 msg.arg1 = waiting ? 1 : 0; 7971 mHandler.sendMessage(msg); 7972 } 7973 } 7974 7975 @Override 7976 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7977 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7978 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7979 outInfo.availMem = Process.getFreeMemory(); 7980 outInfo.totalMem = Process.getTotalMemory(); 7981 outInfo.threshold = homeAppMem; 7982 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7983 outInfo.hiddenAppThreshold = cachedAppMem; 7984 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7985 ProcessList.SERVICE_ADJ); 7986 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7987 ProcessList.VISIBLE_APP_ADJ); 7988 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7989 ProcessList.FOREGROUND_APP_ADJ); 7990 } 7991 7992 // ========================================================= 7993 // TASK MANAGEMENT 7994 // ========================================================= 7995 7996 @Override 7997 public List<IAppTask> getAppTasks(String callingPackage) { 7998 int callingUid = Binder.getCallingUid(); 7999 long ident = Binder.clearCallingIdentity(); 8000 8001 synchronized(this) { 8002 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8003 try { 8004 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8005 8006 final int N = mRecentTasks.size(); 8007 for (int i = 0; i < N; i++) { 8008 TaskRecord tr = mRecentTasks.get(i); 8009 // Skip tasks that do not match the caller. We don't need to verify 8010 // callingPackage, because we are also limiting to callingUid and know 8011 // that will limit to the correct security sandbox. 8012 if (tr.effectiveUid != callingUid) { 8013 continue; 8014 } 8015 Intent intent = tr.getBaseIntent(); 8016 if (intent == null || 8017 !callingPackage.equals(intent.getComponent().getPackageName())) { 8018 continue; 8019 } 8020 ActivityManager.RecentTaskInfo taskInfo = 8021 createRecentTaskInfoFromTaskRecord(tr); 8022 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8023 list.add(taskImpl); 8024 } 8025 } finally { 8026 Binder.restoreCallingIdentity(ident); 8027 } 8028 return list; 8029 } 8030 } 8031 8032 @Override 8033 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8034 final int callingUid = Binder.getCallingUid(); 8035 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8036 8037 synchronized(this) { 8038 if (localLOGV) Slog.v( 8039 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8040 8041 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8042 callingUid); 8043 8044 // TODO: Improve with MRU list from all ActivityStacks. 8045 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8046 } 8047 8048 return list; 8049 } 8050 8051 TaskRecord getMostRecentTask() { 8052 return mRecentTasks.get(0); 8053 } 8054 8055 /** 8056 * Creates a new RecentTaskInfo from a TaskRecord. 8057 */ 8058 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8059 // Update the task description to reflect any changes in the task stack 8060 tr.updateTaskDescription(); 8061 8062 // Compose the recent task info 8063 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8064 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8065 rti.persistentId = tr.taskId; 8066 rti.baseIntent = new Intent(tr.getBaseIntent()); 8067 rti.origActivity = tr.origActivity; 8068 rti.description = tr.lastDescription; 8069 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8070 rti.userId = tr.userId; 8071 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8072 rti.firstActiveTime = tr.firstActiveTime; 8073 rti.lastActiveTime = tr.lastActiveTime; 8074 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8075 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8076 return rti; 8077 } 8078 8079 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8080 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8081 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8082 if (!allowed) { 8083 if (checkPermission(android.Manifest.permission.GET_TASKS, 8084 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8085 // Temporary compatibility: some existing apps on the system image may 8086 // still be requesting the old permission and not switched to the new 8087 // one; if so, we'll still allow them full access. This means we need 8088 // to see if they are holding the old permission and are a system app. 8089 try { 8090 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8091 allowed = true; 8092 Slog.w(TAG, caller + ": caller " + callingUid 8093 + " is using old GET_TASKS but privileged; allowing"); 8094 } 8095 } catch (RemoteException e) { 8096 } 8097 } 8098 } 8099 if (!allowed) { 8100 Slog.w(TAG, caller + ": caller " + callingUid 8101 + " does not hold GET_TASKS; limiting output"); 8102 } 8103 return allowed; 8104 } 8105 8106 @Override 8107 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8108 final int callingUid = Binder.getCallingUid(); 8109 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8110 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8111 8112 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8113 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8114 synchronized (this) { 8115 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8116 callingUid); 8117 final boolean detailed = checkCallingPermission( 8118 android.Manifest.permission.GET_DETAILED_TASKS) 8119 == PackageManager.PERMISSION_GRANTED; 8120 8121 final int N = mRecentTasks.size(); 8122 ArrayList<ActivityManager.RecentTaskInfo> res 8123 = new ArrayList<ActivityManager.RecentTaskInfo>( 8124 maxNum < N ? maxNum : N); 8125 8126 final Set<Integer> includedUsers; 8127 if (includeProfiles) { 8128 includedUsers = getProfileIdsLocked(userId); 8129 } else { 8130 includedUsers = new HashSet<Integer>(); 8131 } 8132 includedUsers.add(Integer.valueOf(userId)); 8133 8134 for (int i=0; i<N && maxNum > 0; i++) { 8135 TaskRecord tr = mRecentTasks.get(i); 8136 // Only add calling user or related users recent tasks 8137 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8138 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8139 continue; 8140 } 8141 8142 // Return the entry if desired by the caller. We always return 8143 // the first entry, because callers always expect this to be the 8144 // foreground app. We may filter others if the caller has 8145 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8146 // we should exclude the entry. 8147 8148 if (i == 0 8149 || withExcluded 8150 || (tr.intent == null) 8151 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8152 == 0)) { 8153 if (!allowed) { 8154 // If the caller doesn't have the GET_TASKS permission, then only 8155 // allow them to see a small subset of tasks -- their own and home. 8156 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8157 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8158 continue; 8159 } 8160 } 8161 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8162 if (tr.stack != null && tr.stack.isHomeStack()) { 8163 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8164 continue; 8165 } 8166 } 8167 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8168 // Don't include auto remove tasks that are finished or finishing. 8169 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8170 + tr); 8171 continue; 8172 } 8173 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8174 && !tr.isAvailable) { 8175 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8176 continue; 8177 } 8178 8179 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8180 if (!detailed) { 8181 rti.baseIntent.replaceExtras((Bundle)null); 8182 } 8183 8184 res.add(rti); 8185 maxNum--; 8186 } 8187 } 8188 return res; 8189 } 8190 } 8191 8192 private TaskRecord taskForIdLocked(int id) { 8193 final TaskRecord task = recentTaskForIdLocked(id); 8194 if (task != null) { 8195 return task; 8196 } 8197 8198 // Don't give up. Sometimes it just hasn't made it to recents yet. 8199 return mStackSupervisor.anyTaskForIdLocked(id); 8200 } 8201 8202 private TaskRecord recentTaskForIdLocked(int id) { 8203 final int N = mRecentTasks.size(); 8204 for (int i=0; i<N; i++) { 8205 TaskRecord tr = mRecentTasks.get(i); 8206 if (tr.taskId == id) { 8207 return tr; 8208 } 8209 } 8210 return null; 8211 } 8212 8213 @Override 8214 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8215 synchronized (this) { 8216 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8217 "getTaskThumbnail()"); 8218 TaskRecord tr = recentTaskForIdLocked(id); 8219 if (tr != null) { 8220 return tr.getTaskThumbnailLocked(); 8221 } 8222 } 8223 return null; 8224 } 8225 8226 @Override 8227 public int addAppTask(IBinder activityToken, Intent intent, 8228 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8229 final int callingUid = Binder.getCallingUid(); 8230 final long callingIdent = Binder.clearCallingIdentity(); 8231 8232 try { 8233 synchronized (this) { 8234 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8235 if (r == null) { 8236 throw new IllegalArgumentException("Activity does not exist; token=" 8237 + activityToken); 8238 } 8239 ComponentName comp = intent.getComponent(); 8240 if (comp == null) { 8241 throw new IllegalArgumentException("Intent " + intent 8242 + " must specify explicit component"); 8243 } 8244 if (thumbnail.getWidth() != mThumbnailWidth 8245 || thumbnail.getHeight() != mThumbnailHeight) { 8246 throw new IllegalArgumentException("Bad thumbnail size: got " 8247 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8248 + mThumbnailWidth + "x" + mThumbnailHeight); 8249 } 8250 if (intent.getSelector() != null) { 8251 intent.setSelector(null); 8252 } 8253 if (intent.getSourceBounds() != null) { 8254 intent.setSourceBounds(null); 8255 } 8256 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8257 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8258 // The caller has added this as an auto-remove task... that makes no 8259 // sense, so turn off auto-remove. 8260 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8261 } 8262 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8263 // Must be a new task. 8264 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8265 } 8266 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8267 mLastAddedTaskActivity = null; 8268 } 8269 ActivityInfo ainfo = mLastAddedTaskActivity; 8270 if (ainfo == null) { 8271 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8272 comp, 0, UserHandle.getUserId(callingUid)); 8273 if (ainfo.applicationInfo.uid != callingUid) { 8274 throw new SecurityException( 8275 "Can't add task for another application: target uid=" 8276 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8277 } 8278 } 8279 8280 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8281 intent, description); 8282 8283 int trimIdx = trimRecentsForTask(task, false); 8284 if (trimIdx >= 0) { 8285 // If this would have caused a trim, then we'll abort because that 8286 // means it would be added at the end of the list but then just removed. 8287 return -1; 8288 } 8289 8290 final int N = mRecentTasks.size(); 8291 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8292 final TaskRecord tr = mRecentTasks.remove(N - 1); 8293 tr.removedFromRecents(mTaskPersister); 8294 } 8295 8296 task.inRecents = true; 8297 mRecentTasks.add(task); 8298 r.task.stack.addTask(task, false, false); 8299 8300 task.setLastThumbnail(thumbnail); 8301 task.freeLastThumbnail(); 8302 8303 return task.taskId; 8304 } 8305 } finally { 8306 Binder.restoreCallingIdentity(callingIdent); 8307 } 8308 } 8309 8310 @Override 8311 public Point getAppTaskThumbnailSize() { 8312 synchronized (this) { 8313 return new Point(mThumbnailWidth, mThumbnailHeight); 8314 } 8315 } 8316 8317 @Override 8318 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8319 synchronized (this) { 8320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8321 if (r != null) { 8322 r.setTaskDescription(td); 8323 r.task.updateTaskDescription(); 8324 } 8325 } 8326 } 8327 8328 @Override 8329 public Bitmap getTaskDescriptionIcon(String filename) { 8330 if (!FileUtils.isValidExtFilename(filename) 8331 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8332 throw new IllegalArgumentException("Bad filename: " + filename); 8333 } 8334 return mTaskPersister.getTaskDescriptionIcon(filename); 8335 } 8336 8337 @Override 8338 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8339 throws RemoteException { 8340 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8341 opts.getCustomInPlaceResId() == 0) { 8342 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8343 "with valid animation"); 8344 } 8345 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8346 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8347 opts.getCustomInPlaceResId()); 8348 mWindowManager.executeAppTransition(); 8349 } 8350 8351 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8352 mRecentTasks.remove(tr); 8353 tr.removedFromRecents(mTaskPersister); 8354 ComponentName component = tr.getBaseIntent().getComponent(); 8355 if (component == null) { 8356 Slog.w(TAG, "No component for base intent of task: " + tr); 8357 return; 8358 } 8359 8360 if (!killProcess) { 8361 return; 8362 } 8363 8364 // Determine if the process(es) for this task should be killed. 8365 final String pkg = component.getPackageName(); 8366 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8367 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8368 for (int i = 0; i < pmap.size(); i++) { 8369 8370 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8371 for (int j = 0; j < uids.size(); j++) { 8372 ProcessRecord proc = uids.valueAt(j); 8373 if (proc.userId != tr.userId) { 8374 // Don't kill process for a different user. 8375 continue; 8376 } 8377 if (proc == mHomeProcess) { 8378 // Don't kill the home process along with tasks from the same package. 8379 continue; 8380 } 8381 if (!proc.pkgList.containsKey(pkg)) { 8382 // Don't kill process that is not associated with this task. 8383 continue; 8384 } 8385 8386 for (int k = 0; k < proc.activities.size(); k++) { 8387 TaskRecord otherTask = proc.activities.get(k).task; 8388 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8389 // Don't kill process(es) that has an activity in a different task that is 8390 // also in recents. 8391 return; 8392 } 8393 } 8394 8395 // Add process to kill list. 8396 procsToKill.add(proc); 8397 } 8398 } 8399 8400 // Find any running services associated with this app and stop if needed. 8401 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8402 8403 // Kill the running processes. 8404 for (int i = 0; i < procsToKill.size(); i++) { 8405 ProcessRecord pr = procsToKill.get(i); 8406 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8407 pr.kill("remove task", true); 8408 } else { 8409 pr.waitingToKill = "remove task"; 8410 } 8411 } 8412 } 8413 8414 /** 8415 * Removes the task with the specified task id. 8416 * 8417 * @param taskId Identifier of the task to be removed. 8418 * @param killProcess Kill any process associated with the task if possible. 8419 * @return Returns true if the given task was found and removed. 8420 */ 8421 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8422 TaskRecord tr = taskForIdLocked(taskId); 8423 if (tr != null) { 8424 tr.removeTaskActivitiesLocked(); 8425 cleanUpRemovedTaskLocked(tr, killProcess); 8426 if (tr.isPersistable) { 8427 notifyTaskPersisterLocked(null, true); 8428 } 8429 return true; 8430 } 8431 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8432 return false; 8433 } 8434 8435 @Override 8436 public boolean removeTask(int taskId) { 8437 synchronized (this) { 8438 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8439 "removeTask()"); 8440 long ident = Binder.clearCallingIdentity(); 8441 try { 8442 return removeTaskByIdLocked(taskId, true); 8443 } finally { 8444 Binder.restoreCallingIdentity(ident); 8445 } 8446 } 8447 } 8448 8449 /** 8450 * TODO: Add mController hook 8451 */ 8452 @Override 8453 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8454 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8455 "moveTaskToFront()"); 8456 8457 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8458 synchronized(this) { 8459 moveTaskToFrontLocked(taskId, flags, options); 8460 } 8461 } 8462 8463 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8464 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8465 Binder.getCallingUid(), -1, -1, "Task to front")) { 8466 ActivityOptions.abort(options); 8467 return; 8468 } 8469 final long origId = Binder.clearCallingIdentity(); 8470 try { 8471 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8472 if (task == null) { 8473 Slog.d(TAG, "Could not find task for id: "+ taskId); 8474 return; 8475 } 8476 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8477 mStackSupervisor.showLockTaskToast(); 8478 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8479 return; 8480 } 8481 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8482 if (prev != null && prev.isRecentsActivity()) { 8483 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8484 } 8485 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8486 } finally { 8487 Binder.restoreCallingIdentity(origId); 8488 } 8489 ActivityOptions.abort(options); 8490 } 8491 8492 @Override 8493 public void moveTaskToBack(int taskId) { 8494 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8495 "moveTaskToBack()"); 8496 8497 synchronized(this) { 8498 TaskRecord tr = taskForIdLocked(taskId); 8499 if (tr != null) { 8500 if (tr == mStackSupervisor.mLockTaskModeTask) { 8501 mStackSupervisor.showLockTaskToast(); 8502 return; 8503 } 8504 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8505 ActivityStack stack = tr.stack; 8506 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8507 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8508 Binder.getCallingUid(), -1, -1, "Task to back")) { 8509 return; 8510 } 8511 } 8512 final long origId = Binder.clearCallingIdentity(); 8513 try { 8514 stack.moveTaskToBackLocked(taskId, null); 8515 } finally { 8516 Binder.restoreCallingIdentity(origId); 8517 } 8518 } 8519 } 8520 } 8521 8522 /** 8523 * Moves an activity, and all of the other activities within the same task, to the bottom 8524 * of the history stack. The activity's order within the task is unchanged. 8525 * 8526 * @param token A reference to the activity we wish to move 8527 * @param nonRoot If false then this only works if the activity is the root 8528 * of a task; if true it will work for any activity in a task. 8529 * @return Returns true if the move completed, false if not. 8530 */ 8531 @Override 8532 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8533 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8534 synchronized(this) { 8535 final long origId = Binder.clearCallingIdentity(); 8536 try { 8537 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8538 if (taskId >= 0) { 8539 if ((mStackSupervisor.mLockTaskModeTask != null) 8540 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8541 mStackSupervisor.showLockTaskToast(); 8542 return false; 8543 } 8544 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8545 } 8546 } finally { 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 } 8550 return false; 8551 } 8552 8553 @Override 8554 public void moveTaskBackwards(int task) { 8555 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8556 "moveTaskBackwards()"); 8557 8558 synchronized(this) { 8559 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8560 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8561 return; 8562 } 8563 final long origId = Binder.clearCallingIdentity(); 8564 moveTaskBackwardsLocked(task); 8565 Binder.restoreCallingIdentity(origId); 8566 } 8567 } 8568 8569 private final void moveTaskBackwardsLocked(int task) { 8570 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8571 } 8572 8573 @Override 8574 public IBinder getHomeActivityToken() throws RemoteException { 8575 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8576 "getHomeActivityToken()"); 8577 synchronized (this) { 8578 return mStackSupervisor.getHomeActivityToken(); 8579 } 8580 } 8581 8582 @Override 8583 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8584 IActivityContainerCallback callback) throws RemoteException { 8585 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8586 "createActivityContainer()"); 8587 synchronized (this) { 8588 if (parentActivityToken == null) { 8589 throw new IllegalArgumentException("parent token must not be null"); 8590 } 8591 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8592 if (r == null) { 8593 return null; 8594 } 8595 if (callback == null) { 8596 throw new IllegalArgumentException("callback must not be null"); 8597 } 8598 return mStackSupervisor.createActivityContainer(r, callback); 8599 } 8600 } 8601 8602 @Override 8603 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8604 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8605 "deleteActivityContainer()"); 8606 synchronized (this) { 8607 mStackSupervisor.deleteActivityContainer(container); 8608 } 8609 } 8610 8611 @Override 8612 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8613 throws RemoteException { 8614 synchronized (this) { 8615 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8616 if (stack != null) { 8617 return stack.mActivityContainer; 8618 } 8619 return null; 8620 } 8621 } 8622 8623 @Override 8624 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8625 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8626 "moveTaskToStack()"); 8627 if (stackId == HOME_STACK_ID) { 8628 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8629 new RuntimeException("here").fillInStackTrace()); 8630 } 8631 synchronized (this) { 8632 long ident = Binder.clearCallingIdentity(); 8633 try { 8634 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8635 + stackId + " toTop=" + toTop); 8636 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8637 } finally { 8638 Binder.restoreCallingIdentity(ident); 8639 } 8640 } 8641 } 8642 8643 @Override 8644 public void resizeStack(int stackBoxId, Rect bounds) { 8645 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8646 "resizeStackBox()"); 8647 long ident = Binder.clearCallingIdentity(); 8648 try { 8649 mWindowManager.resizeStack(stackBoxId, bounds); 8650 } finally { 8651 Binder.restoreCallingIdentity(ident); 8652 } 8653 } 8654 8655 @Override 8656 public List<StackInfo> getAllStackInfos() { 8657 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8658 "getAllStackInfos()"); 8659 long ident = Binder.clearCallingIdentity(); 8660 try { 8661 synchronized (this) { 8662 return mStackSupervisor.getAllStackInfosLocked(); 8663 } 8664 } finally { 8665 Binder.restoreCallingIdentity(ident); 8666 } 8667 } 8668 8669 @Override 8670 public StackInfo getStackInfo(int stackId) { 8671 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8672 "getStackInfo()"); 8673 long ident = Binder.clearCallingIdentity(); 8674 try { 8675 synchronized (this) { 8676 return mStackSupervisor.getStackInfoLocked(stackId); 8677 } 8678 } finally { 8679 Binder.restoreCallingIdentity(ident); 8680 } 8681 } 8682 8683 @Override 8684 public boolean isInHomeStack(int taskId) { 8685 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8686 "getStackInfo()"); 8687 long ident = Binder.clearCallingIdentity(); 8688 try { 8689 synchronized (this) { 8690 TaskRecord tr = taskForIdLocked(taskId); 8691 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8692 } 8693 } finally { 8694 Binder.restoreCallingIdentity(ident); 8695 } 8696 } 8697 8698 @Override 8699 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8700 synchronized(this) { 8701 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8702 } 8703 } 8704 8705 private boolean isLockTaskAuthorized(String pkg) { 8706 final DevicePolicyManager dpm = (DevicePolicyManager) 8707 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8708 try { 8709 int uid = mContext.getPackageManager().getPackageUid(pkg, 8710 Binder.getCallingUserHandle().getIdentifier()); 8711 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8712 } catch (NameNotFoundException e) { 8713 return false; 8714 } 8715 } 8716 8717 void startLockTaskMode(TaskRecord task) { 8718 final String pkg; 8719 synchronized (this) { 8720 pkg = task.intent.getComponent().getPackageName(); 8721 } 8722 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8723 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8724 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8725 StatusBarManagerInternal.class); 8726 if (statusBarManager != null) { 8727 statusBarManager.showScreenPinningRequest(); 8728 } 8729 return; 8730 } 8731 long ident = Binder.clearCallingIdentity(); 8732 try { 8733 synchronized (this) { 8734 // Since we lost lock on task, make sure it is still there. 8735 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8736 if (task != null) { 8737 if (!isSystemInitiated 8738 && ((mStackSupervisor.getFocusedStack() == null) 8739 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8740 throw new IllegalArgumentException("Invalid task, not in foreground"); 8741 } 8742 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8743 } 8744 } 8745 } finally { 8746 Binder.restoreCallingIdentity(ident); 8747 } 8748 } 8749 8750 @Override 8751 public void startLockTaskMode(int taskId) { 8752 final TaskRecord task; 8753 long ident = Binder.clearCallingIdentity(); 8754 try { 8755 synchronized (this) { 8756 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8757 } 8758 } finally { 8759 Binder.restoreCallingIdentity(ident); 8760 } 8761 if (task != null) { 8762 startLockTaskMode(task); 8763 } 8764 } 8765 8766 @Override 8767 public void startLockTaskMode(IBinder token) { 8768 final TaskRecord task; 8769 long ident = Binder.clearCallingIdentity(); 8770 try { 8771 synchronized (this) { 8772 final ActivityRecord r = ActivityRecord.forToken(token); 8773 if (r == null) { 8774 return; 8775 } 8776 task = r.task; 8777 } 8778 } finally { 8779 Binder.restoreCallingIdentity(ident); 8780 } 8781 if (task != null) { 8782 startLockTaskMode(task); 8783 } 8784 } 8785 8786 @Override 8787 public void startLockTaskModeOnCurrent() throws RemoteException { 8788 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8789 "startLockTaskModeOnCurrent"); 8790 long ident = Binder.clearCallingIdentity(); 8791 try { 8792 ActivityRecord r = null; 8793 synchronized (this) { 8794 r = mStackSupervisor.topRunningActivityLocked(); 8795 } 8796 startLockTaskMode(r.task); 8797 } finally { 8798 Binder.restoreCallingIdentity(ident); 8799 } 8800 } 8801 8802 @Override 8803 public void stopLockTaskMode() { 8804 // Verify that the user matches the package of the intent for the TaskRecord 8805 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8806 // and stopLockTaskMode. 8807 final int callingUid = Binder.getCallingUid(); 8808 if (callingUid != Process.SYSTEM_UID) { 8809 try { 8810 String pkg = 8811 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8812 int uid = mContext.getPackageManager().getPackageUid(pkg, 8813 Binder.getCallingUserHandle().getIdentifier()); 8814 if (uid != callingUid) { 8815 throw new SecurityException("Invalid uid, expected " + uid); 8816 } 8817 } catch (NameNotFoundException e) { 8818 Log.d(TAG, "stopLockTaskMode " + e); 8819 return; 8820 } 8821 } 8822 long ident = Binder.clearCallingIdentity(); 8823 try { 8824 Log.d(TAG, "stopLockTaskMode"); 8825 // Stop lock task 8826 synchronized (this) { 8827 mStackSupervisor.setLockTaskModeLocked(null, false); 8828 } 8829 } finally { 8830 Binder.restoreCallingIdentity(ident); 8831 } 8832 } 8833 8834 @Override 8835 public void stopLockTaskModeOnCurrent() throws RemoteException { 8836 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8837 "stopLockTaskModeOnCurrent"); 8838 long ident = Binder.clearCallingIdentity(); 8839 try { 8840 stopLockTaskMode(); 8841 } finally { 8842 Binder.restoreCallingIdentity(ident); 8843 } 8844 } 8845 8846 @Override 8847 public boolean isInLockTaskMode() { 8848 synchronized (this) { 8849 return mStackSupervisor.isInLockTaskMode(); 8850 } 8851 } 8852 8853 // ========================================================= 8854 // CONTENT PROVIDERS 8855 // ========================================================= 8856 8857 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8858 List<ProviderInfo> providers = null; 8859 try { 8860 providers = AppGlobals.getPackageManager(). 8861 queryContentProviders(app.processName, app.uid, 8862 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8863 } catch (RemoteException ex) { 8864 } 8865 if (DEBUG_MU) 8866 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8867 int userId = app.userId; 8868 if (providers != null) { 8869 int N = providers.size(); 8870 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8871 for (int i=0; i<N; i++) { 8872 ProviderInfo cpi = 8873 (ProviderInfo)providers.get(i); 8874 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8875 cpi.name, cpi.flags); 8876 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8877 // This is a singleton provider, but a user besides the 8878 // default user is asking to initialize a process it runs 8879 // in... well, no, it doesn't actually run in this process, 8880 // it runs in the process of the default user. Get rid of it. 8881 providers.remove(i); 8882 N--; 8883 i--; 8884 continue; 8885 } 8886 8887 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8888 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8889 if (cpr == null) { 8890 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8891 mProviderMap.putProviderByClass(comp, cpr); 8892 } 8893 if (DEBUG_MU) 8894 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8895 app.pubProviders.put(cpi.name, cpr); 8896 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8897 // Don't add this if it is a platform component that is marked 8898 // to run in multiple processes, because this is actually 8899 // part of the framework so doesn't make sense to track as a 8900 // separate apk in the process. 8901 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8902 mProcessStats); 8903 } 8904 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8905 } 8906 } 8907 return providers; 8908 } 8909 8910 /** 8911 * Check if {@link ProcessRecord} has a possible chance at accessing the 8912 * given {@link ProviderInfo}. Final permission checking is always done 8913 * in {@link ContentProvider}. 8914 */ 8915 private final String checkContentProviderPermissionLocked( 8916 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8917 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8918 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8919 boolean checkedGrants = false; 8920 if (checkUser) { 8921 // Looking for cross-user grants before enforcing the typical cross-users permissions 8922 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8923 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8924 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8925 return null; 8926 } 8927 checkedGrants = true; 8928 } 8929 userId = handleIncomingUser(callingPid, callingUid, userId, 8930 false, ALLOW_NON_FULL, 8931 "checkContentProviderPermissionLocked " + cpi.authority, null); 8932 if (userId != tmpTargetUserId) { 8933 // When we actually went to determine the final targer user ID, this ended 8934 // up different than our initial check for the authority. This is because 8935 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8936 // SELF. So we need to re-check the grants again. 8937 checkedGrants = false; 8938 } 8939 } 8940 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8941 cpi.applicationInfo.uid, cpi.exported) 8942 == PackageManager.PERMISSION_GRANTED) { 8943 return null; 8944 } 8945 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8946 cpi.applicationInfo.uid, cpi.exported) 8947 == PackageManager.PERMISSION_GRANTED) { 8948 return null; 8949 } 8950 8951 PathPermission[] pps = cpi.pathPermissions; 8952 if (pps != null) { 8953 int i = pps.length; 8954 while (i > 0) { 8955 i--; 8956 PathPermission pp = pps[i]; 8957 String pprperm = pp.getReadPermission(); 8958 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8959 cpi.applicationInfo.uid, cpi.exported) 8960 == PackageManager.PERMISSION_GRANTED) { 8961 return null; 8962 } 8963 String ppwperm = pp.getWritePermission(); 8964 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8965 cpi.applicationInfo.uid, cpi.exported) 8966 == PackageManager.PERMISSION_GRANTED) { 8967 return null; 8968 } 8969 } 8970 } 8971 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8972 return null; 8973 } 8974 8975 String msg; 8976 if (!cpi.exported) { 8977 msg = "Permission Denial: opening provider " + cpi.name 8978 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8979 + ", uid=" + callingUid + ") that is not exported from uid " 8980 + cpi.applicationInfo.uid; 8981 } else { 8982 msg = "Permission Denial: opening provider " + cpi.name 8983 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8984 + ", uid=" + callingUid + ") requires " 8985 + cpi.readPermission + " or " + cpi.writePermission; 8986 } 8987 Slog.w(TAG, msg); 8988 return msg; 8989 } 8990 8991 /** 8992 * Returns if the ContentProvider has granted a uri to callingUid 8993 */ 8994 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8995 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8996 if (perms != null) { 8997 for (int i=perms.size()-1; i>=0; i--) { 8998 GrantUri grantUri = perms.keyAt(i); 8999 if (grantUri.sourceUserId == userId || !checkUser) { 9000 if (matchesProvider(grantUri.uri, cpi)) { 9001 return true; 9002 } 9003 } 9004 } 9005 } 9006 return false; 9007 } 9008 9009 /** 9010 * Returns true if the uri authority is one of the authorities specified in the provider. 9011 */ 9012 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9013 String uriAuth = uri.getAuthority(); 9014 String cpiAuth = cpi.authority; 9015 if (cpiAuth.indexOf(';') == -1) { 9016 return cpiAuth.equals(uriAuth); 9017 } 9018 String[] cpiAuths = cpiAuth.split(";"); 9019 int length = cpiAuths.length; 9020 for (int i = 0; i < length; i++) { 9021 if (cpiAuths[i].equals(uriAuth)) return true; 9022 } 9023 return false; 9024 } 9025 9026 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9027 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9028 if (r != null) { 9029 for (int i=0; i<r.conProviders.size(); i++) { 9030 ContentProviderConnection conn = r.conProviders.get(i); 9031 if (conn.provider == cpr) { 9032 if (DEBUG_PROVIDER) Slog.v(TAG, 9033 "Adding provider requested by " 9034 + r.processName + " from process " 9035 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9036 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9037 if (stable) { 9038 conn.stableCount++; 9039 conn.numStableIncs++; 9040 } else { 9041 conn.unstableCount++; 9042 conn.numUnstableIncs++; 9043 } 9044 return conn; 9045 } 9046 } 9047 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9048 if (stable) { 9049 conn.stableCount = 1; 9050 conn.numStableIncs = 1; 9051 } else { 9052 conn.unstableCount = 1; 9053 conn.numUnstableIncs = 1; 9054 } 9055 cpr.connections.add(conn); 9056 r.conProviders.add(conn); 9057 return conn; 9058 } 9059 cpr.addExternalProcessHandleLocked(externalProcessToken); 9060 return null; 9061 } 9062 9063 boolean decProviderCountLocked(ContentProviderConnection conn, 9064 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9065 if (conn != null) { 9066 cpr = conn.provider; 9067 if (DEBUG_PROVIDER) Slog.v(TAG, 9068 "Removing provider requested by " 9069 + conn.client.processName + " from process " 9070 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9071 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9072 if (stable) { 9073 conn.stableCount--; 9074 } else { 9075 conn.unstableCount--; 9076 } 9077 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9078 cpr.connections.remove(conn); 9079 conn.client.conProviders.remove(conn); 9080 return true; 9081 } 9082 return false; 9083 } 9084 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9085 return false; 9086 } 9087 9088 private void checkTime(long startTime, String where) { 9089 long now = SystemClock.elapsedRealtime(); 9090 if ((now-startTime) > 1000) { 9091 // If we are taking more than a second, log about it. 9092 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9093 } 9094 } 9095 9096 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9097 String name, IBinder token, boolean stable, int userId) { 9098 ContentProviderRecord cpr; 9099 ContentProviderConnection conn = null; 9100 ProviderInfo cpi = null; 9101 9102 synchronized(this) { 9103 long startTime = SystemClock.elapsedRealtime(); 9104 9105 ProcessRecord r = null; 9106 if (caller != null) { 9107 r = getRecordForAppLocked(caller); 9108 if (r == null) { 9109 throw new SecurityException( 9110 "Unable to find app for caller " + caller 9111 + " (pid=" + Binder.getCallingPid() 9112 + ") when getting content provider " + name); 9113 } 9114 } 9115 9116 boolean checkCrossUser = true; 9117 9118 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9119 9120 // First check if this content provider has been published... 9121 cpr = mProviderMap.getProviderByName(name, userId); 9122 // If that didn't work, check if it exists for user 0 and then 9123 // verify that it's a singleton provider before using it. 9124 if (cpr == null && userId != UserHandle.USER_OWNER) { 9125 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9126 if (cpr != null) { 9127 cpi = cpr.info; 9128 if (isSingleton(cpi.processName, cpi.applicationInfo, 9129 cpi.name, cpi.flags) 9130 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9131 userId = UserHandle.USER_OWNER; 9132 checkCrossUser = false; 9133 } else { 9134 cpr = null; 9135 cpi = null; 9136 } 9137 } 9138 } 9139 9140 boolean providerRunning = cpr != null; 9141 if (providerRunning) { 9142 cpi = cpr.info; 9143 String msg; 9144 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9145 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9146 != null) { 9147 throw new SecurityException(msg); 9148 } 9149 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9150 9151 if (r != null && cpr.canRunHere(r)) { 9152 // This provider has been published or is in the process 9153 // of being published... but it is also allowed to run 9154 // in the caller's process, so don't make a connection 9155 // and just let the caller instantiate its own instance. 9156 ContentProviderHolder holder = cpr.newHolder(null); 9157 // don't give caller the provider object, it needs 9158 // to make its own. 9159 holder.provider = null; 9160 return holder; 9161 } 9162 9163 final long origId = Binder.clearCallingIdentity(); 9164 9165 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9166 9167 // In this case the provider instance already exists, so we can 9168 // return it right away. 9169 conn = incProviderCountLocked(r, cpr, token, stable); 9170 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9171 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9172 // If this is a perceptible app accessing the provider, 9173 // make sure to count it as being accessed and thus 9174 // back up on the LRU list. This is good because 9175 // content providers are often expensive to start. 9176 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9177 updateLruProcessLocked(cpr.proc, false, null); 9178 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9179 } 9180 } 9181 9182 if (cpr.proc != null) { 9183 if (false) { 9184 if (cpr.name.flattenToShortString().equals( 9185 "com.android.providers.calendar/.CalendarProvider2")) { 9186 Slog.v(TAG, "****************** KILLING " 9187 + cpr.name.flattenToShortString()); 9188 Process.killProcess(cpr.proc.pid); 9189 } 9190 } 9191 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9192 boolean success = updateOomAdjLocked(cpr.proc); 9193 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9194 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9195 // NOTE: there is still a race here where a signal could be 9196 // pending on the process even though we managed to update its 9197 // adj level. Not sure what to do about this, but at least 9198 // the race is now smaller. 9199 if (!success) { 9200 // Uh oh... it looks like the provider's process 9201 // has been killed on us. We need to wait for a new 9202 // process to be started, and make sure its death 9203 // doesn't kill our process. 9204 Slog.i(TAG, 9205 "Existing provider " + cpr.name.flattenToShortString() 9206 + " is crashing; detaching " + r); 9207 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9208 checkTime(startTime, "getContentProviderImpl: before appDied"); 9209 appDiedLocked(cpr.proc); 9210 checkTime(startTime, "getContentProviderImpl: after appDied"); 9211 if (!lastRef) { 9212 // This wasn't the last ref our process had on 9213 // the provider... we have now been killed, bail. 9214 return null; 9215 } 9216 providerRunning = false; 9217 conn = null; 9218 } 9219 } 9220 9221 Binder.restoreCallingIdentity(origId); 9222 } 9223 9224 boolean singleton; 9225 if (!providerRunning) { 9226 try { 9227 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9228 cpi = AppGlobals.getPackageManager(). 9229 resolveContentProvider(name, 9230 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9231 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9232 } catch (RemoteException ex) { 9233 } 9234 if (cpi == null) { 9235 return null; 9236 } 9237 // If the provider is a singleton AND 9238 // (it's a call within the same user || the provider is a 9239 // privileged app) 9240 // Then allow connecting to the singleton provider 9241 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9242 cpi.name, cpi.flags) 9243 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9244 if (singleton) { 9245 userId = UserHandle.USER_OWNER; 9246 } 9247 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9248 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9249 9250 String msg; 9251 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9252 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9253 != null) { 9254 throw new SecurityException(msg); 9255 } 9256 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9257 9258 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9259 && !cpi.processName.equals("system")) { 9260 // If this content provider does not run in the system 9261 // process, and the system is not yet ready to run other 9262 // processes, then fail fast instead of hanging. 9263 throw new IllegalArgumentException( 9264 "Attempt to launch content provider before system ready"); 9265 } 9266 9267 // Make sure that the user who owns this provider is started. If not, 9268 // we don't want to allow it to run. 9269 if (mStartedUsers.get(userId) == null) { 9270 Slog.w(TAG, "Unable to launch app " 9271 + cpi.applicationInfo.packageName + "/" 9272 + cpi.applicationInfo.uid + " for provider " 9273 + name + ": user " + userId + " is stopped"); 9274 return null; 9275 } 9276 9277 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9278 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9279 cpr = mProviderMap.getProviderByClass(comp, userId); 9280 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9281 final boolean firstClass = cpr == null; 9282 if (firstClass) { 9283 final long ident = Binder.clearCallingIdentity(); 9284 try { 9285 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9286 ApplicationInfo ai = 9287 AppGlobals.getPackageManager(). 9288 getApplicationInfo( 9289 cpi.applicationInfo.packageName, 9290 STOCK_PM_FLAGS, userId); 9291 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9292 if (ai == null) { 9293 Slog.w(TAG, "No package info for content provider " 9294 + cpi.name); 9295 return null; 9296 } 9297 ai = getAppInfoForUser(ai, userId); 9298 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9299 } catch (RemoteException ex) { 9300 // pm is in same process, this will never happen. 9301 } finally { 9302 Binder.restoreCallingIdentity(ident); 9303 } 9304 } 9305 9306 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9307 9308 if (r != null && cpr.canRunHere(r)) { 9309 // If this is a multiprocess provider, then just return its 9310 // info and allow the caller to instantiate it. Only do 9311 // this if the provider is the same user as the caller's 9312 // process, or can run as root (so can be in any process). 9313 return cpr.newHolder(null); 9314 } 9315 9316 if (DEBUG_PROVIDER) { 9317 RuntimeException e = new RuntimeException("here"); 9318 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9319 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9320 } 9321 9322 // This is single process, and our app is now connecting to it. 9323 // See if we are already in the process of launching this 9324 // provider. 9325 final int N = mLaunchingProviders.size(); 9326 int i; 9327 for (i=0; i<N; i++) { 9328 if (mLaunchingProviders.get(i) == cpr) { 9329 break; 9330 } 9331 } 9332 9333 // If the provider is not already being launched, then get it 9334 // started. 9335 if (i >= N) { 9336 final long origId = Binder.clearCallingIdentity(); 9337 9338 try { 9339 // Content provider is now in use, its package can't be stopped. 9340 try { 9341 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9342 AppGlobals.getPackageManager().setPackageStoppedState( 9343 cpr.appInfo.packageName, false, userId); 9344 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9345 } catch (RemoteException e) { 9346 } catch (IllegalArgumentException e) { 9347 Slog.w(TAG, "Failed trying to unstop package " 9348 + cpr.appInfo.packageName + ": " + e); 9349 } 9350 9351 // Use existing process if already started 9352 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9353 ProcessRecord proc = getProcessRecordLocked( 9354 cpi.processName, cpr.appInfo.uid, false); 9355 if (proc != null && proc.thread != null) { 9356 if (DEBUG_PROVIDER) { 9357 Slog.d(TAG, "Installing in existing process " + proc); 9358 } 9359 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9360 proc.pubProviders.put(cpi.name, cpr); 9361 try { 9362 proc.thread.scheduleInstallProvider(cpi); 9363 } catch (RemoteException e) { 9364 } 9365 } else { 9366 checkTime(startTime, "getContentProviderImpl: before start process"); 9367 proc = startProcessLocked(cpi.processName, 9368 cpr.appInfo, false, 0, "content provider", 9369 new ComponentName(cpi.applicationInfo.packageName, 9370 cpi.name), false, false, false); 9371 checkTime(startTime, "getContentProviderImpl: after start process"); 9372 if (proc == null) { 9373 Slog.w(TAG, "Unable to launch app " 9374 + cpi.applicationInfo.packageName + "/" 9375 + cpi.applicationInfo.uid + " for provider " 9376 + name + ": process is bad"); 9377 return null; 9378 } 9379 } 9380 cpr.launchingApp = proc; 9381 mLaunchingProviders.add(cpr); 9382 } finally { 9383 Binder.restoreCallingIdentity(origId); 9384 } 9385 } 9386 9387 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9388 9389 // Make sure the provider is published (the same provider class 9390 // may be published under multiple names). 9391 if (firstClass) { 9392 mProviderMap.putProviderByClass(comp, cpr); 9393 } 9394 9395 mProviderMap.putProviderByName(name, cpr); 9396 conn = incProviderCountLocked(r, cpr, token, stable); 9397 if (conn != null) { 9398 conn.waiting = true; 9399 } 9400 } 9401 checkTime(startTime, "getContentProviderImpl: done!"); 9402 } 9403 9404 // Wait for the provider to be published... 9405 synchronized (cpr) { 9406 while (cpr.provider == null) { 9407 if (cpr.launchingApp == null) { 9408 Slog.w(TAG, "Unable to launch app " 9409 + cpi.applicationInfo.packageName + "/" 9410 + cpi.applicationInfo.uid + " for provider " 9411 + name + ": launching app became null"); 9412 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9413 UserHandle.getUserId(cpi.applicationInfo.uid), 9414 cpi.applicationInfo.packageName, 9415 cpi.applicationInfo.uid, name); 9416 return null; 9417 } 9418 try { 9419 if (DEBUG_MU) { 9420 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9421 + cpr.launchingApp); 9422 } 9423 if (conn != null) { 9424 conn.waiting = true; 9425 } 9426 cpr.wait(); 9427 } catch (InterruptedException ex) { 9428 } finally { 9429 if (conn != null) { 9430 conn.waiting = false; 9431 } 9432 } 9433 } 9434 } 9435 return cpr != null ? cpr.newHolder(conn) : null; 9436 } 9437 9438 @Override 9439 public final ContentProviderHolder getContentProvider( 9440 IApplicationThread caller, String name, int userId, boolean stable) { 9441 enforceNotIsolatedCaller("getContentProvider"); 9442 if (caller == null) { 9443 String msg = "null IApplicationThread when getting content provider " 9444 + name; 9445 Slog.w(TAG, msg); 9446 throw new SecurityException(msg); 9447 } 9448 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9449 // with cross-user grant. 9450 return getContentProviderImpl(caller, name, null, stable, userId); 9451 } 9452 9453 public ContentProviderHolder getContentProviderExternal( 9454 String name, int userId, IBinder token) { 9455 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9456 "Do not have permission in call getContentProviderExternal()"); 9457 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9458 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9459 return getContentProviderExternalUnchecked(name, token, userId); 9460 } 9461 9462 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9463 IBinder token, int userId) { 9464 return getContentProviderImpl(null, name, token, true, userId); 9465 } 9466 9467 /** 9468 * Drop a content provider from a ProcessRecord's bookkeeping 9469 */ 9470 public void removeContentProvider(IBinder connection, boolean stable) { 9471 enforceNotIsolatedCaller("removeContentProvider"); 9472 long ident = Binder.clearCallingIdentity(); 9473 try { 9474 synchronized (this) { 9475 ContentProviderConnection conn; 9476 try { 9477 conn = (ContentProviderConnection)connection; 9478 } catch (ClassCastException e) { 9479 String msg ="removeContentProvider: " + connection 9480 + " not a ContentProviderConnection"; 9481 Slog.w(TAG, msg); 9482 throw new IllegalArgumentException(msg); 9483 } 9484 if (conn == null) { 9485 throw new NullPointerException("connection is null"); 9486 } 9487 if (decProviderCountLocked(conn, null, null, stable)) { 9488 updateOomAdjLocked(); 9489 } 9490 } 9491 } finally { 9492 Binder.restoreCallingIdentity(ident); 9493 } 9494 } 9495 9496 public void removeContentProviderExternal(String name, IBinder token) { 9497 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9498 "Do not have permission in call removeContentProviderExternal()"); 9499 int userId = UserHandle.getCallingUserId(); 9500 long ident = Binder.clearCallingIdentity(); 9501 try { 9502 removeContentProviderExternalUnchecked(name, token, userId); 9503 } finally { 9504 Binder.restoreCallingIdentity(ident); 9505 } 9506 } 9507 9508 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9509 synchronized (this) { 9510 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9511 if(cpr == null) { 9512 //remove from mProvidersByClass 9513 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9514 return; 9515 } 9516 9517 //update content provider record entry info 9518 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9519 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9520 if (localCpr.hasExternalProcessHandles()) { 9521 if (localCpr.removeExternalProcessHandleLocked(token)) { 9522 updateOomAdjLocked(); 9523 } else { 9524 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9525 + " with no external reference for token: " 9526 + token + "."); 9527 } 9528 } else { 9529 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9530 + " with no external references."); 9531 } 9532 } 9533 } 9534 9535 public final void publishContentProviders(IApplicationThread caller, 9536 List<ContentProviderHolder> providers) { 9537 if (providers == null) { 9538 return; 9539 } 9540 9541 enforceNotIsolatedCaller("publishContentProviders"); 9542 synchronized (this) { 9543 final ProcessRecord r = getRecordForAppLocked(caller); 9544 if (DEBUG_MU) 9545 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9546 if (r == null) { 9547 throw new SecurityException( 9548 "Unable to find app for caller " + caller 9549 + " (pid=" + Binder.getCallingPid() 9550 + ") when publishing content providers"); 9551 } 9552 9553 final long origId = Binder.clearCallingIdentity(); 9554 9555 final int N = providers.size(); 9556 for (int i=0; i<N; i++) { 9557 ContentProviderHolder src = providers.get(i); 9558 if (src == null || src.info == null || src.provider == null) { 9559 continue; 9560 } 9561 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9562 if (DEBUG_MU) 9563 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9564 if (dst != null) { 9565 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9566 mProviderMap.putProviderByClass(comp, dst); 9567 String names[] = dst.info.authority.split(";"); 9568 for (int j = 0; j < names.length; j++) { 9569 mProviderMap.putProviderByName(names[j], dst); 9570 } 9571 9572 int NL = mLaunchingProviders.size(); 9573 int j; 9574 for (j=0; j<NL; j++) { 9575 if (mLaunchingProviders.get(j) == dst) { 9576 mLaunchingProviders.remove(j); 9577 j--; 9578 NL--; 9579 } 9580 } 9581 synchronized (dst) { 9582 dst.provider = src.provider; 9583 dst.proc = r; 9584 dst.notifyAll(); 9585 } 9586 updateOomAdjLocked(r); 9587 } 9588 } 9589 9590 Binder.restoreCallingIdentity(origId); 9591 } 9592 } 9593 9594 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9595 ContentProviderConnection conn; 9596 try { 9597 conn = (ContentProviderConnection)connection; 9598 } catch (ClassCastException e) { 9599 String msg ="refContentProvider: " + connection 9600 + " not a ContentProviderConnection"; 9601 Slog.w(TAG, msg); 9602 throw new IllegalArgumentException(msg); 9603 } 9604 if (conn == null) { 9605 throw new NullPointerException("connection is null"); 9606 } 9607 9608 synchronized (this) { 9609 if (stable > 0) { 9610 conn.numStableIncs += stable; 9611 } 9612 stable = conn.stableCount + stable; 9613 if (stable < 0) { 9614 throw new IllegalStateException("stableCount < 0: " + stable); 9615 } 9616 9617 if (unstable > 0) { 9618 conn.numUnstableIncs += unstable; 9619 } 9620 unstable = conn.unstableCount + unstable; 9621 if (unstable < 0) { 9622 throw new IllegalStateException("unstableCount < 0: " + unstable); 9623 } 9624 9625 if ((stable+unstable) <= 0) { 9626 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9627 + stable + " unstable=" + unstable); 9628 } 9629 conn.stableCount = stable; 9630 conn.unstableCount = unstable; 9631 return !conn.dead; 9632 } 9633 } 9634 9635 public void unstableProviderDied(IBinder connection) { 9636 ContentProviderConnection conn; 9637 try { 9638 conn = (ContentProviderConnection)connection; 9639 } catch (ClassCastException e) { 9640 String msg ="refContentProvider: " + connection 9641 + " not a ContentProviderConnection"; 9642 Slog.w(TAG, msg); 9643 throw new IllegalArgumentException(msg); 9644 } 9645 if (conn == null) { 9646 throw new NullPointerException("connection is null"); 9647 } 9648 9649 // Safely retrieve the content provider associated with the connection. 9650 IContentProvider provider; 9651 synchronized (this) { 9652 provider = conn.provider.provider; 9653 } 9654 9655 if (provider == null) { 9656 // Um, yeah, we're way ahead of you. 9657 return; 9658 } 9659 9660 // Make sure the caller is being honest with us. 9661 if (provider.asBinder().pingBinder()) { 9662 // Er, no, still looks good to us. 9663 synchronized (this) { 9664 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9665 + " says " + conn + " died, but we don't agree"); 9666 return; 9667 } 9668 } 9669 9670 // Well look at that! It's dead! 9671 synchronized (this) { 9672 if (conn.provider.provider != provider) { 9673 // But something changed... good enough. 9674 return; 9675 } 9676 9677 ProcessRecord proc = conn.provider.proc; 9678 if (proc == null || proc.thread == null) { 9679 // Seems like the process is already cleaned up. 9680 return; 9681 } 9682 9683 // As far as we're concerned, this is just like receiving a 9684 // death notification... just a bit prematurely. 9685 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9686 + ") early provider death"); 9687 final long ident = Binder.clearCallingIdentity(); 9688 try { 9689 appDiedLocked(proc); 9690 } finally { 9691 Binder.restoreCallingIdentity(ident); 9692 } 9693 } 9694 } 9695 9696 @Override 9697 public void appNotRespondingViaProvider(IBinder connection) { 9698 enforceCallingPermission( 9699 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9700 9701 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9702 if (conn == null) { 9703 Slog.w(TAG, "ContentProviderConnection is null"); 9704 return; 9705 } 9706 9707 final ProcessRecord host = conn.provider.proc; 9708 if (host == null) { 9709 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9710 return; 9711 } 9712 9713 final long token = Binder.clearCallingIdentity(); 9714 try { 9715 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9716 } finally { 9717 Binder.restoreCallingIdentity(token); 9718 } 9719 } 9720 9721 public final void installSystemProviders() { 9722 List<ProviderInfo> providers; 9723 synchronized (this) { 9724 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9725 providers = generateApplicationProvidersLocked(app); 9726 if (providers != null) { 9727 for (int i=providers.size()-1; i>=0; i--) { 9728 ProviderInfo pi = (ProviderInfo)providers.get(i); 9729 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9730 Slog.w(TAG, "Not installing system proc provider " + pi.name 9731 + ": not system .apk"); 9732 providers.remove(i); 9733 } 9734 } 9735 } 9736 } 9737 if (providers != null) { 9738 mSystemThread.installSystemProviders(providers); 9739 } 9740 9741 mCoreSettingsObserver = new CoreSettingsObserver(this); 9742 9743 //mUsageStatsService.monitorPackages(); 9744 } 9745 9746 /** 9747 * Allows apps to retrieve the MIME type of a URI. 9748 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9749 * users, then it does not need permission to access the ContentProvider. 9750 * Either, it needs cross-user uri grants. 9751 * 9752 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9753 * 9754 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9755 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9756 */ 9757 public String getProviderMimeType(Uri uri, int userId) { 9758 enforceNotIsolatedCaller("getProviderMimeType"); 9759 final String name = uri.getAuthority(); 9760 int callingUid = Binder.getCallingUid(); 9761 int callingPid = Binder.getCallingPid(); 9762 long ident = 0; 9763 boolean clearedIdentity = false; 9764 userId = unsafeConvertIncomingUser(userId); 9765 if (canClearIdentity(callingPid, callingUid, userId)) { 9766 clearedIdentity = true; 9767 ident = Binder.clearCallingIdentity(); 9768 } 9769 ContentProviderHolder holder = null; 9770 try { 9771 holder = getContentProviderExternalUnchecked(name, null, userId); 9772 if (holder != null) { 9773 return holder.provider.getType(uri); 9774 } 9775 } catch (RemoteException e) { 9776 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9777 return null; 9778 } finally { 9779 // We need to clear the identity to call removeContentProviderExternalUnchecked 9780 if (!clearedIdentity) { 9781 ident = Binder.clearCallingIdentity(); 9782 } 9783 try { 9784 if (holder != null) { 9785 removeContentProviderExternalUnchecked(name, null, userId); 9786 } 9787 } finally { 9788 Binder.restoreCallingIdentity(ident); 9789 } 9790 } 9791 9792 return null; 9793 } 9794 9795 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9796 if (UserHandle.getUserId(callingUid) == userId) { 9797 return true; 9798 } 9799 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9800 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9801 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9802 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9803 return true; 9804 } 9805 return false; 9806 } 9807 9808 // ========================================================= 9809 // GLOBAL MANAGEMENT 9810 // ========================================================= 9811 9812 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9813 boolean isolated, int isolatedUid) { 9814 String proc = customProcess != null ? customProcess : info.processName; 9815 BatteryStatsImpl.Uid.Proc ps = null; 9816 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9817 int uid = info.uid; 9818 if (isolated) { 9819 if (isolatedUid == 0) { 9820 int userId = UserHandle.getUserId(uid); 9821 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9822 while (true) { 9823 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9824 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9825 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9826 } 9827 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9828 mNextIsolatedProcessUid++; 9829 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9830 // No process for this uid, use it. 9831 break; 9832 } 9833 stepsLeft--; 9834 if (stepsLeft <= 0) { 9835 return null; 9836 } 9837 } 9838 } else { 9839 // Special case for startIsolatedProcess (internal only), where 9840 // the uid of the isolated process is specified by the caller. 9841 uid = isolatedUid; 9842 } 9843 } 9844 return new ProcessRecord(stats, info, proc, uid); 9845 } 9846 9847 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9848 String abiOverride) { 9849 ProcessRecord app; 9850 if (!isolated) { 9851 app = getProcessRecordLocked(info.processName, info.uid, true); 9852 } else { 9853 app = null; 9854 } 9855 9856 if (app == null) { 9857 app = newProcessRecordLocked(info, null, isolated, 0); 9858 mProcessNames.put(info.processName, app.uid, app); 9859 if (isolated) { 9860 mIsolatedProcesses.put(app.uid, app); 9861 } 9862 updateLruProcessLocked(app, false, null); 9863 updateOomAdjLocked(); 9864 } 9865 9866 // This package really, really can not be stopped. 9867 try { 9868 AppGlobals.getPackageManager().setPackageStoppedState( 9869 info.packageName, false, UserHandle.getUserId(app.uid)); 9870 } catch (RemoteException e) { 9871 } catch (IllegalArgumentException e) { 9872 Slog.w(TAG, "Failed trying to unstop package " 9873 + info.packageName + ": " + e); 9874 } 9875 9876 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9877 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9878 app.persistent = true; 9879 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9880 } 9881 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9882 mPersistentStartingProcesses.add(app); 9883 startProcessLocked(app, "added application", app.processName, abiOverride, 9884 null /* entryPoint */, null /* entryPointArgs */); 9885 } 9886 9887 return app; 9888 } 9889 9890 public void unhandledBack() { 9891 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9892 "unhandledBack()"); 9893 9894 synchronized(this) { 9895 final long origId = Binder.clearCallingIdentity(); 9896 try { 9897 getFocusedStack().unhandledBackLocked(); 9898 } finally { 9899 Binder.restoreCallingIdentity(origId); 9900 } 9901 } 9902 } 9903 9904 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9905 enforceNotIsolatedCaller("openContentUri"); 9906 final int userId = UserHandle.getCallingUserId(); 9907 String name = uri.getAuthority(); 9908 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9909 ParcelFileDescriptor pfd = null; 9910 if (cph != null) { 9911 // We record the binder invoker's uid in thread-local storage before 9912 // going to the content provider to open the file. Later, in the code 9913 // that handles all permissions checks, we look for this uid and use 9914 // that rather than the Activity Manager's own uid. The effect is that 9915 // we do the check against the caller's permissions even though it looks 9916 // to the content provider like the Activity Manager itself is making 9917 // the request. 9918 sCallerIdentity.set(new Identity( 9919 Binder.getCallingPid(), Binder.getCallingUid())); 9920 try { 9921 pfd = cph.provider.openFile(null, uri, "r", null); 9922 } catch (FileNotFoundException e) { 9923 // do nothing; pfd will be returned null 9924 } finally { 9925 // Ensure that whatever happens, we clean up the identity state 9926 sCallerIdentity.remove(); 9927 } 9928 9929 // We've got the fd now, so we're done with the provider. 9930 removeContentProviderExternalUnchecked(name, null, userId); 9931 } else { 9932 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9933 } 9934 return pfd; 9935 } 9936 9937 // Actually is sleeping or shutting down or whatever else in the future 9938 // is an inactive state. 9939 public boolean isSleepingOrShuttingDown() { 9940 return isSleeping() || mShuttingDown; 9941 } 9942 9943 public boolean isSleeping() { 9944 return mSleeping; 9945 } 9946 9947 void goingToSleep() { 9948 synchronized(this) { 9949 mWentToSleep = true; 9950 goToSleepIfNeededLocked(); 9951 } 9952 } 9953 9954 void finishRunningVoiceLocked() { 9955 if (mRunningVoice) { 9956 mRunningVoice = false; 9957 goToSleepIfNeededLocked(); 9958 } 9959 } 9960 9961 void goToSleepIfNeededLocked() { 9962 if (mWentToSleep && !mRunningVoice) { 9963 if (!mSleeping) { 9964 mSleeping = true; 9965 mStackSupervisor.goingToSleepLocked(); 9966 9967 // Initialize the wake times of all processes. 9968 checkExcessivePowerUsageLocked(false); 9969 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9970 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9971 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9972 } 9973 } 9974 } 9975 9976 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9977 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9978 // Never persist the home stack. 9979 return; 9980 } 9981 mTaskPersister.wakeup(task, flush); 9982 } 9983 9984 @Override 9985 public boolean shutdown(int timeout) { 9986 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9987 != PackageManager.PERMISSION_GRANTED) { 9988 throw new SecurityException("Requires permission " 9989 + android.Manifest.permission.SHUTDOWN); 9990 } 9991 9992 boolean timedout = false; 9993 9994 synchronized(this) { 9995 mShuttingDown = true; 9996 updateEventDispatchingLocked(); 9997 timedout = mStackSupervisor.shutdownLocked(timeout); 9998 } 9999 10000 mAppOpsService.shutdown(); 10001 if (mUsageStatsService != null) { 10002 mUsageStatsService.prepareShutdown(); 10003 } 10004 mBatteryStatsService.shutdown(); 10005 synchronized (this) { 10006 mProcessStats.shutdownLocked(); 10007 } 10008 notifyTaskPersisterLocked(null, true); 10009 10010 return timedout; 10011 } 10012 10013 public final void activitySlept(IBinder token) { 10014 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10015 10016 final long origId = Binder.clearCallingIdentity(); 10017 10018 synchronized (this) { 10019 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10020 if (r != null) { 10021 mStackSupervisor.activitySleptLocked(r); 10022 } 10023 } 10024 10025 Binder.restoreCallingIdentity(origId); 10026 } 10027 10028 private String lockScreenShownToString() { 10029 switch (mLockScreenShown) { 10030 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10031 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10032 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10033 default: return "Unknown=" + mLockScreenShown; 10034 } 10035 } 10036 10037 void logLockScreen(String msg) { 10038 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10039 " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" + 10040 mWentToSleep + " mSleeping=" + mSleeping); 10041 } 10042 10043 void comeOutOfSleepIfNeededLocked() { 10044 if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) { 10045 if (mSleeping) { 10046 mSleeping = false; 10047 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10048 } 10049 } 10050 } 10051 10052 void wakingUp() { 10053 synchronized(this) { 10054 mWentToSleep = false; 10055 comeOutOfSleepIfNeededLocked(); 10056 } 10057 } 10058 10059 void startRunningVoiceLocked() { 10060 if (!mRunningVoice) { 10061 mRunningVoice = true; 10062 comeOutOfSleepIfNeededLocked(); 10063 } 10064 } 10065 10066 private void updateEventDispatchingLocked() { 10067 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10068 } 10069 10070 public void setLockScreenShown(boolean shown) { 10071 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10072 != PackageManager.PERMISSION_GRANTED) { 10073 throw new SecurityException("Requires permission " 10074 + android.Manifest.permission.DEVICE_POWER); 10075 } 10076 10077 synchronized(this) { 10078 long ident = Binder.clearCallingIdentity(); 10079 try { 10080 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10081 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10082 comeOutOfSleepIfNeededLocked(); 10083 } finally { 10084 Binder.restoreCallingIdentity(ident); 10085 } 10086 } 10087 } 10088 10089 @Override 10090 public void stopAppSwitches() { 10091 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10092 != PackageManager.PERMISSION_GRANTED) { 10093 throw new SecurityException("Requires permission " 10094 + android.Manifest.permission.STOP_APP_SWITCHES); 10095 } 10096 10097 synchronized(this) { 10098 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10099 + APP_SWITCH_DELAY_TIME; 10100 mDidAppSwitch = false; 10101 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10102 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10103 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10104 } 10105 } 10106 10107 public void resumeAppSwitches() { 10108 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10109 != PackageManager.PERMISSION_GRANTED) { 10110 throw new SecurityException("Requires permission " 10111 + android.Manifest.permission.STOP_APP_SWITCHES); 10112 } 10113 10114 synchronized(this) { 10115 // Note that we don't execute any pending app switches... we will 10116 // let those wait until either the timeout, or the next start 10117 // activity request. 10118 mAppSwitchesAllowedTime = 0; 10119 } 10120 } 10121 10122 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10123 int callingPid, int callingUid, String name) { 10124 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10125 return true; 10126 } 10127 10128 int perm = checkComponentPermission( 10129 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10130 sourceUid, -1, true); 10131 if (perm == PackageManager.PERMISSION_GRANTED) { 10132 return true; 10133 } 10134 10135 // If the actual IPC caller is different from the logical source, then 10136 // also see if they are allowed to control app switches. 10137 if (callingUid != -1 && callingUid != sourceUid) { 10138 perm = checkComponentPermission( 10139 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10140 callingUid, -1, true); 10141 if (perm == PackageManager.PERMISSION_GRANTED) { 10142 return true; 10143 } 10144 } 10145 10146 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10147 return false; 10148 } 10149 10150 public void setDebugApp(String packageName, boolean waitForDebugger, 10151 boolean persistent) { 10152 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10153 "setDebugApp()"); 10154 10155 long ident = Binder.clearCallingIdentity(); 10156 try { 10157 // Note that this is not really thread safe if there are multiple 10158 // callers into it at the same time, but that's not a situation we 10159 // care about. 10160 if (persistent) { 10161 final ContentResolver resolver = mContext.getContentResolver(); 10162 Settings.Global.putString( 10163 resolver, Settings.Global.DEBUG_APP, 10164 packageName); 10165 Settings.Global.putInt( 10166 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10167 waitForDebugger ? 1 : 0); 10168 } 10169 10170 synchronized (this) { 10171 if (!persistent) { 10172 mOrigDebugApp = mDebugApp; 10173 mOrigWaitForDebugger = mWaitForDebugger; 10174 } 10175 mDebugApp = packageName; 10176 mWaitForDebugger = waitForDebugger; 10177 mDebugTransient = !persistent; 10178 if (packageName != null) { 10179 forceStopPackageLocked(packageName, -1, false, false, true, true, 10180 false, UserHandle.USER_ALL, "set debug app"); 10181 } 10182 } 10183 } finally { 10184 Binder.restoreCallingIdentity(ident); 10185 } 10186 } 10187 10188 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10189 synchronized (this) { 10190 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10191 if (!isDebuggable) { 10192 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10193 throw new SecurityException("Process not debuggable: " + app.packageName); 10194 } 10195 } 10196 10197 mOpenGlTraceApp = processName; 10198 } 10199 } 10200 10201 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10202 synchronized (this) { 10203 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10204 if (!isDebuggable) { 10205 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10206 throw new SecurityException("Process not debuggable: " + app.packageName); 10207 } 10208 } 10209 mProfileApp = processName; 10210 mProfileFile = profilerInfo.profileFile; 10211 if (mProfileFd != null) { 10212 try { 10213 mProfileFd.close(); 10214 } catch (IOException e) { 10215 } 10216 mProfileFd = null; 10217 } 10218 mProfileFd = profilerInfo.profileFd; 10219 mSamplingInterval = profilerInfo.samplingInterval; 10220 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10221 mProfileType = 0; 10222 } 10223 } 10224 10225 @Override 10226 public void setAlwaysFinish(boolean enabled) { 10227 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10228 "setAlwaysFinish()"); 10229 10230 Settings.Global.putInt( 10231 mContext.getContentResolver(), 10232 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10233 10234 synchronized (this) { 10235 mAlwaysFinishActivities = enabled; 10236 } 10237 } 10238 10239 @Override 10240 public void setActivityController(IActivityController controller) { 10241 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10242 "setActivityController()"); 10243 synchronized (this) { 10244 mController = controller; 10245 Watchdog.getInstance().setActivityController(controller); 10246 } 10247 } 10248 10249 @Override 10250 public void setUserIsMonkey(boolean userIsMonkey) { 10251 synchronized (this) { 10252 synchronized (mPidsSelfLocked) { 10253 final int callingPid = Binder.getCallingPid(); 10254 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10255 if (precessRecord == null) { 10256 throw new SecurityException("Unknown process: " + callingPid); 10257 } 10258 if (precessRecord.instrumentationUiAutomationConnection == null) { 10259 throw new SecurityException("Only an instrumentation process " 10260 + "with a UiAutomation can call setUserIsMonkey"); 10261 } 10262 } 10263 mUserIsMonkey = userIsMonkey; 10264 } 10265 } 10266 10267 @Override 10268 public boolean isUserAMonkey() { 10269 synchronized (this) { 10270 // If there is a controller also implies the user is a monkey. 10271 return (mUserIsMonkey || mController != null); 10272 } 10273 } 10274 10275 public void requestBugReport() { 10276 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10277 SystemProperties.set("ctl.start", "bugreport"); 10278 } 10279 10280 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10281 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10282 } 10283 10284 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10285 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10286 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10287 } 10288 return KEY_DISPATCHING_TIMEOUT; 10289 } 10290 10291 @Override 10292 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10293 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10294 != PackageManager.PERMISSION_GRANTED) { 10295 throw new SecurityException("Requires permission " 10296 + android.Manifest.permission.FILTER_EVENTS); 10297 } 10298 ProcessRecord proc; 10299 long timeout; 10300 synchronized (this) { 10301 synchronized (mPidsSelfLocked) { 10302 proc = mPidsSelfLocked.get(pid); 10303 } 10304 timeout = getInputDispatchingTimeoutLocked(proc); 10305 } 10306 10307 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10308 return -1; 10309 } 10310 10311 return timeout; 10312 } 10313 10314 /** 10315 * Handle input dispatching timeouts. 10316 * Returns whether input dispatching should be aborted or not. 10317 */ 10318 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10319 final ActivityRecord activity, final ActivityRecord parent, 10320 final boolean aboveSystem, String reason) { 10321 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10322 != PackageManager.PERMISSION_GRANTED) { 10323 throw new SecurityException("Requires permission " 10324 + android.Manifest.permission.FILTER_EVENTS); 10325 } 10326 10327 final String annotation; 10328 if (reason == null) { 10329 annotation = "Input dispatching timed out"; 10330 } else { 10331 annotation = "Input dispatching timed out (" + reason + ")"; 10332 } 10333 10334 if (proc != null) { 10335 synchronized (this) { 10336 if (proc.debugging) { 10337 return false; 10338 } 10339 10340 if (mDidDexOpt) { 10341 // Give more time since we were dexopting. 10342 mDidDexOpt = false; 10343 return false; 10344 } 10345 10346 if (proc.instrumentationClass != null) { 10347 Bundle info = new Bundle(); 10348 info.putString("shortMsg", "keyDispatchingTimedOut"); 10349 info.putString("longMsg", annotation); 10350 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10351 return true; 10352 } 10353 } 10354 mHandler.post(new Runnable() { 10355 @Override 10356 public void run() { 10357 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10358 } 10359 }); 10360 } 10361 10362 return true; 10363 } 10364 10365 public Bundle getAssistContextExtras(int requestType) { 10366 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10367 UserHandle.getCallingUserId()); 10368 if (pae == null) { 10369 return null; 10370 } 10371 synchronized (pae) { 10372 while (!pae.haveResult) { 10373 try { 10374 pae.wait(); 10375 } catch (InterruptedException e) { 10376 } 10377 } 10378 if (pae.result != null) { 10379 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10380 } 10381 } 10382 synchronized (this) { 10383 mPendingAssistExtras.remove(pae); 10384 mHandler.removeCallbacks(pae); 10385 } 10386 return pae.extras; 10387 } 10388 10389 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10390 int userHandle) { 10391 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10392 "getAssistContextExtras()"); 10393 PendingAssistExtras pae; 10394 Bundle extras = new Bundle(); 10395 synchronized (this) { 10396 ActivityRecord activity = getFocusedStack().mResumedActivity; 10397 if (activity == null) { 10398 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10399 return null; 10400 } 10401 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10402 if (activity.app == null || activity.app.thread == null) { 10403 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10404 return null; 10405 } 10406 if (activity.app.pid == Binder.getCallingPid()) { 10407 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10408 return null; 10409 } 10410 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10411 try { 10412 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10413 requestType); 10414 mPendingAssistExtras.add(pae); 10415 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10416 } catch (RemoteException e) { 10417 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10418 return null; 10419 } 10420 return pae; 10421 } 10422 } 10423 10424 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10425 PendingAssistExtras pae = (PendingAssistExtras)token; 10426 synchronized (pae) { 10427 pae.result = extras; 10428 pae.haveResult = true; 10429 pae.notifyAll(); 10430 if (pae.intent == null) { 10431 // Caller is just waiting for the result. 10432 return; 10433 } 10434 } 10435 10436 // We are now ready to launch the assist activity. 10437 synchronized (this) { 10438 boolean exists = mPendingAssistExtras.remove(pae); 10439 mHandler.removeCallbacks(pae); 10440 if (!exists) { 10441 // Timed out. 10442 return; 10443 } 10444 } 10445 pae.intent.replaceExtras(extras); 10446 if (pae.hint != null) { 10447 pae.intent.putExtra(pae.hint, true); 10448 } 10449 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10450 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10451 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10452 closeSystemDialogs("assist"); 10453 try { 10454 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10455 } catch (ActivityNotFoundException e) { 10456 Slog.w(TAG, "No activity to handle assist action.", e); 10457 } 10458 } 10459 10460 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10461 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10462 } 10463 10464 public void registerProcessObserver(IProcessObserver observer) { 10465 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10466 "registerProcessObserver()"); 10467 synchronized (this) { 10468 mProcessObservers.register(observer); 10469 } 10470 } 10471 10472 @Override 10473 public void unregisterProcessObserver(IProcessObserver observer) { 10474 synchronized (this) { 10475 mProcessObservers.unregister(observer); 10476 } 10477 } 10478 10479 @Override 10480 public boolean convertFromTranslucent(IBinder token) { 10481 final long origId = Binder.clearCallingIdentity(); 10482 try { 10483 synchronized (this) { 10484 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10485 if (r == null) { 10486 return false; 10487 } 10488 final boolean translucentChanged = r.changeWindowTranslucency(true); 10489 if (translucentChanged) { 10490 r.task.stack.releaseBackgroundResources(); 10491 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10492 } 10493 mWindowManager.setAppFullscreen(token, true); 10494 return translucentChanged; 10495 } 10496 } finally { 10497 Binder.restoreCallingIdentity(origId); 10498 } 10499 } 10500 10501 @Override 10502 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10503 final long origId = Binder.clearCallingIdentity(); 10504 try { 10505 synchronized (this) { 10506 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10507 if (r == null) { 10508 return false; 10509 } 10510 int index = r.task.mActivities.lastIndexOf(r); 10511 if (index > 0) { 10512 ActivityRecord under = r.task.mActivities.get(index - 1); 10513 under.returningOptions = options; 10514 } 10515 final boolean translucentChanged = r.changeWindowTranslucency(false); 10516 if (translucentChanged) { 10517 r.task.stack.convertToTranslucent(r); 10518 } 10519 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10520 mWindowManager.setAppFullscreen(token, false); 10521 return translucentChanged; 10522 } 10523 } finally { 10524 Binder.restoreCallingIdentity(origId); 10525 } 10526 } 10527 10528 @Override 10529 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10530 final long origId = Binder.clearCallingIdentity(); 10531 try { 10532 synchronized (this) { 10533 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10534 if (r != null) { 10535 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10536 } 10537 } 10538 return false; 10539 } finally { 10540 Binder.restoreCallingIdentity(origId); 10541 } 10542 } 10543 10544 @Override 10545 public boolean isBackgroundVisibleBehind(IBinder token) { 10546 final long origId = Binder.clearCallingIdentity(); 10547 try { 10548 synchronized (this) { 10549 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10550 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10551 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10552 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10553 return visible; 10554 } 10555 } finally { 10556 Binder.restoreCallingIdentity(origId); 10557 } 10558 } 10559 10560 @Override 10561 public ActivityOptions getActivityOptions(IBinder token) { 10562 final long origId = Binder.clearCallingIdentity(); 10563 try { 10564 synchronized (this) { 10565 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10566 if (r != null) { 10567 final ActivityOptions activityOptions = r.pendingOptions; 10568 r.pendingOptions = null; 10569 return activityOptions; 10570 } 10571 return null; 10572 } 10573 } finally { 10574 Binder.restoreCallingIdentity(origId); 10575 } 10576 } 10577 10578 @Override 10579 public void setImmersive(IBinder token, boolean immersive) { 10580 synchronized(this) { 10581 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10582 if (r == null) { 10583 throw new IllegalArgumentException(); 10584 } 10585 r.immersive = immersive; 10586 10587 // update associated state if we're frontmost 10588 if (r == mFocusedActivity) { 10589 if (DEBUG_IMMERSIVE) { 10590 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10591 } 10592 applyUpdateLockStateLocked(r); 10593 } 10594 } 10595 } 10596 10597 @Override 10598 public boolean isImmersive(IBinder token) { 10599 synchronized (this) { 10600 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10601 if (r == null) { 10602 throw new IllegalArgumentException(); 10603 } 10604 return r.immersive; 10605 } 10606 } 10607 10608 public boolean isTopActivityImmersive() { 10609 enforceNotIsolatedCaller("startActivity"); 10610 synchronized (this) { 10611 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10612 return (r != null) ? r.immersive : false; 10613 } 10614 } 10615 10616 @Override 10617 public boolean isTopOfTask(IBinder token) { 10618 synchronized (this) { 10619 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10620 if (r == null) { 10621 throw new IllegalArgumentException(); 10622 } 10623 return r.task.getTopActivity() == r; 10624 } 10625 } 10626 10627 public final void enterSafeMode() { 10628 synchronized(this) { 10629 // It only makes sense to do this before the system is ready 10630 // and started launching other packages. 10631 if (!mSystemReady) { 10632 try { 10633 AppGlobals.getPackageManager().enterSafeMode(); 10634 } catch (RemoteException e) { 10635 } 10636 } 10637 10638 mSafeMode = true; 10639 } 10640 } 10641 10642 public final void showSafeModeOverlay() { 10643 View v = LayoutInflater.from(mContext).inflate( 10644 com.android.internal.R.layout.safe_mode, null); 10645 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10646 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10647 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10648 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10649 lp.gravity = Gravity.BOTTOM | Gravity.START; 10650 lp.format = v.getBackground().getOpacity(); 10651 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10652 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10653 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10654 ((WindowManager)mContext.getSystemService( 10655 Context.WINDOW_SERVICE)).addView(v, lp); 10656 } 10657 10658 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10659 if (!(sender instanceof PendingIntentRecord)) { 10660 return; 10661 } 10662 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10663 synchronized (stats) { 10664 if (mBatteryStatsService.isOnBattery()) { 10665 mBatteryStatsService.enforceCallingPermission(); 10666 PendingIntentRecord rec = (PendingIntentRecord)sender; 10667 int MY_UID = Binder.getCallingUid(); 10668 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10669 BatteryStatsImpl.Uid.Pkg pkg = 10670 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10671 sourcePkg != null ? sourcePkg : rec.key.packageName); 10672 pkg.incWakeupsLocked(); 10673 } 10674 } 10675 } 10676 10677 public boolean killPids(int[] pids, String pReason, boolean secure) { 10678 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10679 throw new SecurityException("killPids only available to the system"); 10680 } 10681 String reason = (pReason == null) ? "Unknown" : pReason; 10682 // XXX Note: don't acquire main activity lock here, because the window 10683 // manager calls in with its locks held. 10684 10685 boolean killed = false; 10686 synchronized (mPidsSelfLocked) { 10687 int[] types = new int[pids.length]; 10688 int worstType = 0; 10689 for (int i=0; i<pids.length; i++) { 10690 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10691 if (proc != null) { 10692 int type = proc.setAdj; 10693 types[i] = type; 10694 if (type > worstType) { 10695 worstType = type; 10696 } 10697 } 10698 } 10699 10700 // If the worst oom_adj is somewhere in the cached proc LRU range, 10701 // then constrain it so we will kill all cached procs. 10702 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10703 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10704 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10705 } 10706 10707 // If this is not a secure call, don't let it kill processes that 10708 // are important. 10709 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10710 worstType = ProcessList.SERVICE_ADJ; 10711 } 10712 10713 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10714 for (int i=0; i<pids.length; i++) { 10715 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10716 if (proc == null) { 10717 continue; 10718 } 10719 int adj = proc.setAdj; 10720 if (adj >= worstType && !proc.killedByAm) { 10721 proc.kill(reason, true); 10722 killed = true; 10723 } 10724 } 10725 } 10726 return killed; 10727 } 10728 10729 @Override 10730 public void killUid(int uid, String reason) { 10731 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10732 throw new SecurityException("killUid only available to the system"); 10733 } 10734 synchronized (this) { 10735 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10736 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10737 reason != null ? reason : "kill uid"); 10738 } 10739 } 10740 10741 @Override 10742 public boolean killProcessesBelowForeground(String reason) { 10743 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10744 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10745 } 10746 10747 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10748 } 10749 10750 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10751 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10752 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10753 } 10754 10755 boolean killed = false; 10756 synchronized (mPidsSelfLocked) { 10757 final int size = mPidsSelfLocked.size(); 10758 for (int i = 0; i < size; i++) { 10759 final int pid = mPidsSelfLocked.keyAt(i); 10760 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10761 if (proc == null) continue; 10762 10763 final int adj = proc.setAdj; 10764 if (adj > belowAdj && !proc.killedByAm) { 10765 proc.kill(reason, true); 10766 killed = true; 10767 } 10768 } 10769 } 10770 return killed; 10771 } 10772 10773 @Override 10774 public void hang(final IBinder who, boolean allowRestart) { 10775 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10776 != PackageManager.PERMISSION_GRANTED) { 10777 throw new SecurityException("Requires permission " 10778 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10779 } 10780 10781 final IBinder.DeathRecipient death = new DeathRecipient() { 10782 @Override 10783 public void binderDied() { 10784 synchronized (this) { 10785 notifyAll(); 10786 } 10787 } 10788 }; 10789 10790 try { 10791 who.linkToDeath(death, 0); 10792 } catch (RemoteException e) { 10793 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10794 return; 10795 } 10796 10797 synchronized (this) { 10798 Watchdog.getInstance().setAllowRestart(allowRestart); 10799 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10800 synchronized (death) { 10801 while (who.isBinderAlive()) { 10802 try { 10803 death.wait(); 10804 } catch (InterruptedException e) { 10805 } 10806 } 10807 } 10808 Watchdog.getInstance().setAllowRestart(true); 10809 } 10810 } 10811 10812 @Override 10813 public void restart() { 10814 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10815 != PackageManager.PERMISSION_GRANTED) { 10816 throw new SecurityException("Requires permission " 10817 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10818 } 10819 10820 Log.i(TAG, "Sending shutdown broadcast..."); 10821 10822 BroadcastReceiver br = new BroadcastReceiver() { 10823 @Override public void onReceive(Context context, Intent intent) { 10824 // Now the broadcast is done, finish up the low-level shutdown. 10825 Log.i(TAG, "Shutting down activity manager..."); 10826 shutdown(10000); 10827 Log.i(TAG, "Shutdown complete, restarting!"); 10828 Process.killProcess(Process.myPid()); 10829 System.exit(10); 10830 } 10831 }; 10832 10833 // First send the high-level shut down broadcast. 10834 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10835 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10836 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10837 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10838 mContext.sendOrderedBroadcastAsUser(intent, 10839 UserHandle.ALL, null, br, mHandler, 0, null, null); 10840 */ 10841 br.onReceive(mContext, intent); 10842 } 10843 10844 private long getLowRamTimeSinceIdle(long now) { 10845 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10846 } 10847 10848 @Override 10849 public void performIdleMaintenance() { 10850 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10851 != PackageManager.PERMISSION_GRANTED) { 10852 throw new SecurityException("Requires permission " 10853 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10854 } 10855 10856 synchronized (this) { 10857 final long now = SystemClock.uptimeMillis(); 10858 final long timeSinceLastIdle = now - mLastIdleTime; 10859 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10860 mLastIdleTime = now; 10861 mLowRamTimeSinceLastIdle = 0; 10862 if (mLowRamStartTime != 0) { 10863 mLowRamStartTime = now; 10864 } 10865 10866 StringBuilder sb = new StringBuilder(128); 10867 sb.append("Idle maintenance over "); 10868 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10869 sb.append(" low RAM for "); 10870 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10871 Slog.i(TAG, sb.toString()); 10872 10873 // If at least 1/3 of our time since the last idle period has been spent 10874 // with RAM low, then we want to kill processes. 10875 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10876 10877 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10878 ProcessRecord proc = mLruProcesses.get(i); 10879 if (proc.notCachedSinceIdle) { 10880 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10881 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10882 if (doKilling && proc.initialIdlePss != 0 10883 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10884 proc.kill("idle maint (pss " + proc.lastPss 10885 + " from " + proc.initialIdlePss + ")", true); 10886 } 10887 } 10888 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10889 proc.notCachedSinceIdle = true; 10890 proc.initialIdlePss = 0; 10891 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10892 isSleeping(), now); 10893 } 10894 } 10895 10896 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10897 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10898 } 10899 } 10900 10901 private void retrieveSettings() { 10902 final ContentResolver resolver = mContext.getContentResolver(); 10903 String debugApp = Settings.Global.getString( 10904 resolver, Settings.Global.DEBUG_APP); 10905 boolean waitForDebugger = Settings.Global.getInt( 10906 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10907 boolean alwaysFinishActivities = Settings.Global.getInt( 10908 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10909 boolean forceRtl = Settings.Global.getInt( 10910 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10911 // Transfer any global setting for forcing RTL layout, into a System Property 10912 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10913 10914 Configuration configuration = new Configuration(); 10915 Settings.System.getConfiguration(resolver, configuration); 10916 if (forceRtl) { 10917 // This will take care of setting the correct layout direction flags 10918 configuration.setLayoutDirection(configuration.locale); 10919 } 10920 10921 synchronized (this) { 10922 mDebugApp = mOrigDebugApp = debugApp; 10923 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10924 mAlwaysFinishActivities = alwaysFinishActivities; 10925 // This happens before any activities are started, so we can 10926 // change mConfiguration in-place. 10927 updateConfigurationLocked(configuration, null, false, true); 10928 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10929 } 10930 } 10931 10932 /** Loads resources after the current configuration has been set. */ 10933 private void loadResourcesOnSystemReady() { 10934 final Resources res = mContext.getResources(); 10935 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10936 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10937 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10938 } 10939 10940 public boolean testIsSystemReady() { 10941 // no need to synchronize(this) just to read & return the value 10942 return mSystemReady; 10943 } 10944 10945 private static File getCalledPreBootReceiversFile() { 10946 File dataDir = Environment.getDataDirectory(); 10947 File systemDir = new File(dataDir, "system"); 10948 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10949 return fname; 10950 } 10951 10952 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10953 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10954 File file = getCalledPreBootReceiversFile(); 10955 FileInputStream fis = null; 10956 try { 10957 fis = new FileInputStream(file); 10958 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10959 int fvers = dis.readInt(); 10960 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10961 String vers = dis.readUTF(); 10962 String codename = dis.readUTF(); 10963 String build = dis.readUTF(); 10964 if (android.os.Build.VERSION.RELEASE.equals(vers) 10965 && android.os.Build.VERSION.CODENAME.equals(codename) 10966 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10967 int num = dis.readInt(); 10968 while (num > 0) { 10969 num--; 10970 String pkg = dis.readUTF(); 10971 String cls = dis.readUTF(); 10972 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10973 } 10974 } 10975 } 10976 } catch (FileNotFoundException e) { 10977 } catch (IOException e) { 10978 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10979 } finally { 10980 if (fis != null) { 10981 try { 10982 fis.close(); 10983 } catch (IOException e) { 10984 } 10985 } 10986 } 10987 return lastDoneReceivers; 10988 } 10989 10990 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10991 File file = getCalledPreBootReceiversFile(); 10992 FileOutputStream fos = null; 10993 DataOutputStream dos = null; 10994 try { 10995 fos = new FileOutputStream(file); 10996 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10997 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10998 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10999 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11000 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11001 dos.writeInt(list.size()); 11002 for (int i=0; i<list.size(); i++) { 11003 dos.writeUTF(list.get(i).getPackageName()); 11004 dos.writeUTF(list.get(i).getClassName()); 11005 } 11006 } catch (IOException e) { 11007 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11008 file.delete(); 11009 } finally { 11010 FileUtils.sync(fos); 11011 if (dos != null) { 11012 try { 11013 dos.close(); 11014 } catch (IOException e) { 11015 // TODO Auto-generated catch block 11016 e.printStackTrace(); 11017 } 11018 } 11019 } 11020 } 11021 11022 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11023 ArrayList<ComponentName> doneReceivers, int userId) { 11024 boolean waitingUpdate = false; 11025 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11026 List<ResolveInfo> ris = null; 11027 try { 11028 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11029 intent, null, 0, userId); 11030 } catch (RemoteException e) { 11031 } 11032 if (ris != null) { 11033 for (int i=ris.size()-1; i>=0; i--) { 11034 if ((ris.get(i).activityInfo.applicationInfo.flags 11035 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11036 ris.remove(i); 11037 } 11038 } 11039 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11040 11041 // For User 0, load the version number. When delivering to a new user, deliver 11042 // to all receivers. 11043 if (userId == UserHandle.USER_OWNER) { 11044 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11045 for (int i=0; i<ris.size(); i++) { 11046 ActivityInfo ai = ris.get(i).activityInfo; 11047 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11048 if (lastDoneReceivers.contains(comp)) { 11049 // We already did the pre boot receiver for this app with the current 11050 // platform version, so don't do it again... 11051 ris.remove(i); 11052 i--; 11053 // ...however, do keep it as one that has been done, so we don't 11054 // forget about it when rewriting the file of last done receivers. 11055 doneReceivers.add(comp); 11056 } 11057 } 11058 } 11059 11060 // If primary user, send broadcast to all available users, else just to userId 11061 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11062 : new int[] { userId }; 11063 for (int i = 0; i < ris.size(); i++) { 11064 ActivityInfo ai = ris.get(i).activityInfo; 11065 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11066 doneReceivers.add(comp); 11067 intent.setComponent(comp); 11068 for (int j=0; j<users.length; j++) { 11069 IIntentReceiver finisher = null; 11070 // On last receiver and user, set up a completion callback 11071 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11072 finisher = new IIntentReceiver.Stub() { 11073 public void performReceive(Intent intent, int resultCode, 11074 String data, Bundle extras, boolean ordered, 11075 boolean sticky, int sendingUser) { 11076 // The raw IIntentReceiver interface is called 11077 // with the AM lock held, so redispatch to 11078 // execute our code without the lock. 11079 mHandler.post(onFinishCallback); 11080 } 11081 }; 11082 } 11083 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11084 + " for user " + users[j]); 11085 broadcastIntentLocked(null, null, intent, null, finisher, 11086 0, null, null, null, AppOpsManager.OP_NONE, 11087 true, false, MY_PID, Process.SYSTEM_UID, 11088 users[j]); 11089 if (finisher != null) { 11090 waitingUpdate = true; 11091 } 11092 } 11093 } 11094 } 11095 11096 return waitingUpdate; 11097 } 11098 11099 public void systemReady(final Runnable goingCallback) { 11100 synchronized(this) { 11101 if (mSystemReady) { 11102 // If we're done calling all the receivers, run the next "boot phase" passed in 11103 // by the SystemServer 11104 if (goingCallback != null) { 11105 goingCallback.run(); 11106 } 11107 return; 11108 } 11109 11110 // Make sure we have the current profile info, since it is needed for 11111 // security checks. 11112 updateCurrentProfileIdsLocked(); 11113 11114 if (mRecentTasks == null) { 11115 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11116 if (!mRecentTasks.isEmpty()) { 11117 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11118 } 11119 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11120 mTaskPersister.startPersisting(); 11121 } 11122 11123 // Check to see if there are any update receivers to run. 11124 if (!mDidUpdate) { 11125 if (mWaitingUpdate) { 11126 return; 11127 } 11128 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11129 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11130 public void run() { 11131 synchronized (ActivityManagerService.this) { 11132 mDidUpdate = true; 11133 } 11134 writeLastDonePreBootReceivers(doneReceivers); 11135 showBootMessage(mContext.getText( 11136 R.string.android_upgrading_complete), 11137 false); 11138 systemReady(goingCallback); 11139 } 11140 }, doneReceivers, UserHandle.USER_OWNER); 11141 11142 if (mWaitingUpdate) { 11143 return; 11144 } 11145 mDidUpdate = true; 11146 } 11147 11148 mAppOpsService.systemReady(); 11149 mSystemReady = true; 11150 } 11151 11152 ArrayList<ProcessRecord> procsToKill = null; 11153 synchronized(mPidsSelfLocked) { 11154 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11155 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11156 if (!isAllowedWhileBooting(proc.info)){ 11157 if (procsToKill == null) { 11158 procsToKill = new ArrayList<ProcessRecord>(); 11159 } 11160 procsToKill.add(proc); 11161 } 11162 } 11163 } 11164 11165 synchronized(this) { 11166 if (procsToKill != null) { 11167 for (int i=procsToKill.size()-1; i>=0; i--) { 11168 ProcessRecord proc = procsToKill.get(i); 11169 Slog.i(TAG, "Removing system update proc: " + proc); 11170 removeProcessLocked(proc, true, false, "system update done"); 11171 } 11172 } 11173 11174 // Now that we have cleaned up any update processes, we 11175 // are ready to start launching real processes and know that 11176 // we won't trample on them any more. 11177 mProcessesReady = true; 11178 } 11179 11180 Slog.i(TAG, "System now ready"); 11181 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11182 SystemClock.uptimeMillis()); 11183 11184 synchronized(this) { 11185 // Make sure we have no pre-ready processes sitting around. 11186 11187 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11188 ResolveInfo ri = mContext.getPackageManager() 11189 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11190 STOCK_PM_FLAGS); 11191 CharSequence errorMsg = null; 11192 if (ri != null) { 11193 ActivityInfo ai = ri.activityInfo; 11194 ApplicationInfo app = ai.applicationInfo; 11195 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11196 mTopAction = Intent.ACTION_FACTORY_TEST; 11197 mTopData = null; 11198 mTopComponent = new ComponentName(app.packageName, 11199 ai.name); 11200 } else { 11201 errorMsg = mContext.getResources().getText( 11202 com.android.internal.R.string.factorytest_not_system); 11203 } 11204 } else { 11205 errorMsg = mContext.getResources().getText( 11206 com.android.internal.R.string.factorytest_no_action); 11207 } 11208 if (errorMsg != null) { 11209 mTopAction = null; 11210 mTopData = null; 11211 mTopComponent = null; 11212 Message msg = Message.obtain(); 11213 msg.what = SHOW_FACTORY_ERROR_MSG; 11214 msg.getData().putCharSequence("msg", errorMsg); 11215 mHandler.sendMessage(msg); 11216 } 11217 } 11218 } 11219 11220 retrieveSettings(); 11221 loadResourcesOnSystemReady(); 11222 11223 synchronized (this) { 11224 readGrantedUriPermissionsLocked(); 11225 } 11226 11227 if (goingCallback != null) goingCallback.run(); 11228 11229 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11230 Integer.toString(mCurrentUserId), mCurrentUserId); 11231 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11232 Integer.toString(mCurrentUserId), mCurrentUserId); 11233 mSystemServiceManager.startUser(mCurrentUserId); 11234 11235 synchronized (this) { 11236 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11237 try { 11238 List apps = AppGlobals.getPackageManager(). 11239 getPersistentApplications(STOCK_PM_FLAGS); 11240 if (apps != null) { 11241 int N = apps.size(); 11242 int i; 11243 for (i=0; i<N; i++) { 11244 ApplicationInfo info 11245 = (ApplicationInfo)apps.get(i); 11246 if (info != null && 11247 !info.packageName.equals("android")) { 11248 addAppLocked(info, false, null /* ABI override */); 11249 } 11250 } 11251 } 11252 } catch (RemoteException ex) { 11253 // pm is in same process, this will never happen. 11254 } 11255 } 11256 11257 // Start up initial activity. 11258 mBooting = true; 11259 startHomeActivityLocked(mCurrentUserId); 11260 11261 try { 11262 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11263 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11264 + " data partition or your device will be unstable."); 11265 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11266 } 11267 } catch (RemoteException e) { 11268 } 11269 11270 if (!Build.isFingerprintConsistent()) { 11271 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11272 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11273 } 11274 11275 long ident = Binder.clearCallingIdentity(); 11276 try { 11277 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11278 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11279 | Intent.FLAG_RECEIVER_FOREGROUND); 11280 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11281 broadcastIntentLocked(null, null, intent, 11282 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11283 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11284 intent = new Intent(Intent.ACTION_USER_STARTING); 11285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11286 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11287 broadcastIntentLocked(null, null, intent, 11288 null, new IIntentReceiver.Stub() { 11289 @Override 11290 public void performReceive(Intent intent, int resultCode, String data, 11291 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11292 throws RemoteException { 11293 } 11294 }, 0, null, null, 11295 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11296 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11297 } catch (Throwable t) { 11298 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11299 } finally { 11300 Binder.restoreCallingIdentity(ident); 11301 } 11302 mStackSupervisor.resumeTopActivitiesLocked(); 11303 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11304 } 11305 } 11306 11307 private boolean makeAppCrashingLocked(ProcessRecord app, 11308 String shortMsg, String longMsg, String stackTrace) { 11309 app.crashing = true; 11310 app.crashingReport = generateProcessError(app, 11311 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11312 startAppProblemLocked(app); 11313 app.stopFreezingAllLocked(); 11314 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11315 } 11316 11317 private void makeAppNotRespondingLocked(ProcessRecord app, 11318 String activity, String shortMsg, String longMsg) { 11319 app.notResponding = true; 11320 app.notRespondingReport = generateProcessError(app, 11321 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11322 activity, shortMsg, longMsg, null); 11323 startAppProblemLocked(app); 11324 app.stopFreezingAllLocked(); 11325 } 11326 11327 /** 11328 * Generate a process error record, suitable for attachment to a ProcessRecord. 11329 * 11330 * @param app The ProcessRecord in which the error occurred. 11331 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11332 * ActivityManager.AppErrorStateInfo 11333 * @param activity The activity associated with the crash, if known. 11334 * @param shortMsg Short message describing the crash. 11335 * @param longMsg Long message describing the crash. 11336 * @param stackTrace Full crash stack trace, may be null. 11337 * 11338 * @return Returns a fully-formed AppErrorStateInfo record. 11339 */ 11340 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11341 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11342 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11343 11344 report.condition = condition; 11345 report.processName = app.processName; 11346 report.pid = app.pid; 11347 report.uid = app.info.uid; 11348 report.tag = activity; 11349 report.shortMsg = shortMsg; 11350 report.longMsg = longMsg; 11351 report.stackTrace = stackTrace; 11352 11353 return report; 11354 } 11355 11356 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11357 synchronized (this) { 11358 app.crashing = false; 11359 app.crashingReport = null; 11360 app.notResponding = false; 11361 app.notRespondingReport = null; 11362 if (app.anrDialog == fromDialog) { 11363 app.anrDialog = null; 11364 } 11365 if (app.waitDialog == fromDialog) { 11366 app.waitDialog = null; 11367 } 11368 if (app.pid > 0 && app.pid != MY_PID) { 11369 handleAppCrashLocked(app, null, null, null); 11370 app.kill("user request after error", true); 11371 } 11372 } 11373 } 11374 11375 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11376 String stackTrace) { 11377 long now = SystemClock.uptimeMillis(); 11378 11379 Long crashTime; 11380 if (!app.isolated) { 11381 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11382 } else { 11383 crashTime = null; 11384 } 11385 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11386 // This process loses! 11387 Slog.w(TAG, "Process " + app.info.processName 11388 + " has crashed too many times: killing!"); 11389 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11390 app.userId, app.info.processName, app.uid); 11391 mStackSupervisor.handleAppCrashLocked(app); 11392 if (!app.persistent) { 11393 // We don't want to start this process again until the user 11394 // explicitly does so... but for persistent process, we really 11395 // need to keep it running. If a persistent process is actually 11396 // repeatedly crashing, then badness for everyone. 11397 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11398 app.info.processName); 11399 if (!app.isolated) { 11400 // XXX We don't have a way to mark isolated processes 11401 // as bad, since they don't have a peristent identity. 11402 mBadProcesses.put(app.info.processName, app.uid, 11403 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11404 mProcessCrashTimes.remove(app.info.processName, app.uid); 11405 } 11406 app.bad = true; 11407 app.removed = true; 11408 // Don't let services in this process be restarted and potentially 11409 // annoy the user repeatedly. Unless it is persistent, since those 11410 // processes run critical code. 11411 removeProcessLocked(app, false, false, "crash"); 11412 mStackSupervisor.resumeTopActivitiesLocked(); 11413 return false; 11414 } 11415 mStackSupervisor.resumeTopActivitiesLocked(); 11416 } else { 11417 mStackSupervisor.finishTopRunningActivityLocked(app); 11418 } 11419 11420 // Bump up the crash count of any services currently running in the proc. 11421 for (int i=app.services.size()-1; i>=0; i--) { 11422 // Any services running in the application need to be placed 11423 // back in the pending list. 11424 ServiceRecord sr = app.services.valueAt(i); 11425 sr.crashCount++; 11426 } 11427 11428 // If the crashing process is what we consider to be the "home process" and it has been 11429 // replaced by a third-party app, clear the package preferred activities from packages 11430 // with a home activity running in the process to prevent a repeatedly crashing app 11431 // from blocking the user to manually clear the list. 11432 final ArrayList<ActivityRecord> activities = app.activities; 11433 if (app == mHomeProcess && activities.size() > 0 11434 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11435 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11436 final ActivityRecord r = activities.get(activityNdx); 11437 if (r.isHomeActivity()) { 11438 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11439 try { 11440 ActivityThread.getPackageManager() 11441 .clearPackagePreferredActivities(r.packageName); 11442 } catch (RemoteException c) { 11443 // pm is in same process, this will never happen. 11444 } 11445 } 11446 } 11447 } 11448 11449 if (!app.isolated) { 11450 // XXX Can't keep track of crash times for isolated processes, 11451 // because they don't have a perisistent identity. 11452 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11453 } 11454 11455 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11456 return true; 11457 } 11458 11459 void startAppProblemLocked(ProcessRecord app) { 11460 // If this app is not running under the current user, then we 11461 // can't give it a report button because that would require 11462 // launching the report UI under a different user. 11463 app.errorReportReceiver = null; 11464 11465 for (int userId : mCurrentProfileIds) { 11466 if (app.userId == userId) { 11467 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11468 mContext, app.info.packageName, app.info.flags); 11469 } 11470 } 11471 skipCurrentReceiverLocked(app); 11472 } 11473 11474 void skipCurrentReceiverLocked(ProcessRecord app) { 11475 for (BroadcastQueue queue : mBroadcastQueues) { 11476 queue.skipCurrentReceiverLocked(app); 11477 } 11478 } 11479 11480 /** 11481 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11482 * The application process will exit immediately after this call returns. 11483 * @param app object of the crashing app, null for the system server 11484 * @param crashInfo describing the exception 11485 */ 11486 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11487 ProcessRecord r = findAppProcess(app, "Crash"); 11488 final String processName = app == null ? "system_server" 11489 : (r == null ? "unknown" : r.processName); 11490 11491 handleApplicationCrashInner("crash", r, processName, crashInfo); 11492 } 11493 11494 /* Native crash reporting uses this inner version because it needs to be somewhat 11495 * decoupled from the AM-managed cleanup lifecycle 11496 */ 11497 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11498 ApplicationErrorReport.CrashInfo crashInfo) { 11499 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11500 UserHandle.getUserId(Binder.getCallingUid()), processName, 11501 r == null ? -1 : r.info.flags, 11502 crashInfo.exceptionClassName, 11503 crashInfo.exceptionMessage, 11504 crashInfo.throwFileName, 11505 crashInfo.throwLineNumber); 11506 11507 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11508 11509 crashApplication(r, crashInfo); 11510 } 11511 11512 public void handleApplicationStrictModeViolation( 11513 IBinder app, 11514 int violationMask, 11515 StrictMode.ViolationInfo info) { 11516 ProcessRecord r = findAppProcess(app, "StrictMode"); 11517 if (r == null) { 11518 return; 11519 } 11520 11521 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11522 Integer stackFingerprint = info.hashCode(); 11523 boolean logIt = true; 11524 synchronized (mAlreadyLoggedViolatedStacks) { 11525 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11526 logIt = false; 11527 // TODO: sub-sample into EventLog for these, with 11528 // the info.durationMillis? Then we'd get 11529 // the relative pain numbers, without logging all 11530 // the stack traces repeatedly. We'd want to do 11531 // likewise in the client code, which also does 11532 // dup suppression, before the Binder call. 11533 } else { 11534 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11535 mAlreadyLoggedViolatedStacks.clear(); 11536 } 11537 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11538 } 11539 } 11540 if (logIt) { 11541 logStrictModeViolationToDropBox(r, info); 11542 } 11543 } 11544 11545 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11546 AppErrorResult result = new AppErrorResult(); 11547 synchronized (this) { 11548 final long origId = Binder.clearCallingIdentity(); 11549 11550 Message msg = Message.obtain(); 11551 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11552 HashMap<String, Object> data = new HashMap<String, Object>(); 11553 data.put("result", result); 11554 data.put("app", r); 11555 data.put("violationMask", violationMask); 11556 data.put("info", info); 11557 msg.obj = data; 11558 mHandler.sendMessage(msg); 11559 11560 Binder.restoreCallingIdentity(origId); 11561 } 11562 int res = result.get(); 11563 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11564 } 11565 } 11566 11567 // Depending on the policy in effect, there could be a bunch of 11568 // these in quick succession so we try to batch these together to 11569 // minimize disk writes, number of dropbox entries, and maximize 11570 // compression, by having more fewer, larger records. 11571 private void logStrictModeViolationToDropBox( 11572 ProcessRecord process, 11573 StrictMode.ViolationInfo info) { 11574 if (info == null) { 11575 return; 11576 } 11577 final boolean isSystemApp = process == null || 11578 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11579 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11580 final String processName = process == null ? "unknown" : process.processName; 11581 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11582 final DropBoxManager dbox = (DropBoxManager) 11583 mContext.getSystemService(Context.DROPBOX_SERVICE); 11584 11585 // Exit early if the dropbox isn't configured to accept this report type. 11586 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11587 11588 boolean bufferWasEmpty; 11589 boolean needsFlush; 11590 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11591 synchronized (sb) { 11592 bufferWasEmpty = sb.length() == 0; 11593 appendDropBoxProcessHeaders(process, processName, sb); 11594 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11595 sb.append("System-App: ").append(isSystemApp).append("\n"); 11596 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11597 if (info.violationNumThisLoop != 0) { 11598 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11599 } 11600 if (info.numAnimationsRunning != 0) { 11601 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11602 } 11603 if (info.broadcastIntentAction != null) { 11604 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11605 } 11606 if (info.durationMillis != -1) { 11607 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11608 } 11609 if (info.numInstances != -1) { 11610 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11611 } 11612 if (info.tags != null) { 11613 for (String tag : info.tags) { 11614 sb.append("Span-Tag: ").append(tag).append("\n"); 11615 } 11616 } 11617 sb.append("\n"); 11618 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11619 sb.append(info.crashInfo.stackTrace); 11620 } 11621 sb.append("\n"); 11622 11623 // Only buffer up to ~64k. Various logging bits truncate 11624 // things at 128k. 11625 needsFlush = (sb.length() > 64 * 1024); 11626 } 11627 11628 // Flush immediately if the buffer's grown too large, or this 11629 // is a non-system app. Non-system apps are isolated with a 11630 // different tag & policy and not batched. 11631 // 11632 // Batching is useful during internal testing with 11633 // StrictMode settings turned up high. Without batching, 11634 // thousands of separate files could be created on boot. 11635 if (!isSystemApp || needsFlush) { 11636 new Thread("Error dump: " + dropboxTag) { 11637 @Override 11638 public void run() { 11639 String report; 11640 synchronized (sb) { 11641 report = sb.toString(); 11642 sb.delete(0, sb.length()); 11643 sb.trimToSize(); 11644 } 11645 if (report.length() != 0) { 11646 dbox.addText(dropboxTag, report); 11647 } 11648 } 11649 }.start(); 11650 return; 11651 } 11652 11653 // System app batching: 11654 if (!bufferWasEmpty) { 11655 // An existing dropbox-writing thread is outstanding, so 11656 // we don't need to start it up. The existing thread will 11657 // catch the buffer appends we just did. 11658 return; 11659 } 11660 11661 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11662 // (After this point, we shouldn't access AMS internal data structures.) 11663 new Thread("Error dump: " + dropboxTag) { 11664 @Override 11665 public void run() { 11666 // 5 second sleep to let stacks arrive and be batched together 11667 try { 11668 Thread.sleep(5000); // 5 seconds 11669 } catch (InterruptedException e) {} 11670 11671 String errorReport; 11672 synchronized (mStrictModeBuffer) { 11673 errorReport = mStrictModeBuffer.toString(); 11674 if (errorReport.length() == 0) { 11675 return; 11676 } 11677 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11678 mStrictModeBuffer.trimToSize(); 11679 } 11680 dbox.addText(dropboxTag, errorReport); 11681 } 11682 }.start(); 11683 } 11684 11685 /** 11686 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11687 * @param app object of the crashing app, null for the system server 11688 * @param tag reported by the caller 11689 * @param system whether this wtf is coming from the system 11690 * @param crashInfo describing the context of the error 11691 * @return true if the process should exit immediately (WTF is fatal) 11692 */ 11693 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11694 final ApplicationErrorReport.CrashInfo crashInfo) { 11695 final int callingUid = Binder.getCallingUid(); 11696 final int callingPid = Binder.getCallingPid(); 11697 11698 if (system) { 11699 // If this is coming from the system, we could very well have low-level 11700 // system locks held, so we want to do this all asynchronously. And we 11701 // never want this to become fatal, so there is that too. 11702 mHandler.post(new Runnable() { 11703 @Override public void run() { 11704 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11705 } 11706 }); 11707 return false; 11708 } 11709 11710 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11711 crashInfo); 11712 11713 if (r != null && r.pid != Process.myPid() && 11714 Settings.Global.getInt(mContext.getContentResolver(), 11715 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11716 crashApplication(r, crashInfo); 11717 return true; 11718 } else { 11719 return false; 11720 } 11721 } 11722 11723 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11724 final ApplicationErrorReport.CrashInfo crashInfo) { 11725 final ProcessRecord r = findAppProcess(app, "WTF"); 11726 final String processName = app == null ? "system_server" 11727 : (r == null ? "unknown" : r.processName); 11728 11729 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11730 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11731 11732 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11733 11734 return r; 11735 } 11736 11737 /** 11738 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11739 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11740 */ 11741 private ProcessRecord findAppProcess(IBinder app, String reason) { 11742 if (app == null) { 11743 return null; 11744 } 11745 11746 synchronized (this) { 11747 final int NP = mProcessNames.getMap().size(); 11748 for (int ip=0; ip<NP; ip++) { 11749 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11750 final int NA = apps.size(); 11751 for (int ia=0; ia<NA; ia++) { 11752 ProcessRecord p = apps.valueAt(ia); 11753 if (p.thread != null && p.thread.asBinder() == app) { 11754 return p; 11755 } 11756 } 11757 } 11758 11759 Slog.w(TAG, "Can't find mystery application for " + reason 11760 + " from pid=" + Binder.getCallingPid() 11761 + " uid=" + Binder.getCallingUid() + ": " + app); 11762 return null; 11763 } 11764 } 11765 11766 /** 11767 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11768 * to append various headers to the dropbox log text. 11769 */ 11770 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11771 StringBuilder sb) { 11772 // Watchdog thread ends up invoking this function (with 11773 // a null ProcessRecord) to add the stack file to dropbox. 11774 // Do not acquire a lock on this (am) in such cases, as it 11775 // could cause a potential deadlock, if and when watchdog 11776 // is invoked due to unavailability of lock on am and it 11777 // would prevent watchdog from killing system_server. 11778 if (process == null) { 11779 sb.append("Process: ").append(processName).append("\n"); 11780 return; 11781 } 11782 // Note: ProcessRecord 'process' is guarded by the service 11783 // instance. (notably process.pkgList, which could otherwise change 11784 // concurrently during execution of this method) 11785 synchronized (this) { 11786 sb.append("Process: ").append(processName).append("\n"); 11787 int flags = process.info.flags; 11788 IPackageManager pm = AppGlobals.getPackageManager(); 11789 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11790 for (int ip=0; ip<process.pkgList.size(); ip++) { 11791 String pkg = process.pkgList.keyAt(ip); 11792 sb.append("Package: ").append(pkg); 11793 try { 11794 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11795 if (pi != null) { 11796 sb.append(" v").append(pi.versionCode); 11797 if (pi.versionName != null) { 11798 sb.append(" (").append(pi.versionName).append(")"); 11799 } 11800 } 11801 } catch (RemoteException e) { 11802 Slog.e(TAG, "Error getting package info: " + pkg, e); 11803 } 11804 sb.append("\n"); 11805 } 11806 } 11807 } 11808 11809 private static String processClass(ProcessRecord process) { 11810 if (process == null || process.pid == MY_PID) { 11811 return "system_server"; 11812 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11813 return "system_app"; 11814 } else { 11815 return "data_app"; 11816 } 11817 } 11818 11819 /** 11820 * Write a description of an error (crash, WTF, ANR) to the drop box. 11821 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11822 * @param process which caused the error, null means the system server 11823 * @param activity which triggered the error, null if unknown 11824 * @param parent activity related to the error, null if unknown 11825 * @param subject line related to the error, null if absent 11826 * @param report in long form describing the error, null if absent 11827 * @param logFile to include in the report, null if none 11828 * @param crashInfo giving an application stack trace, null if absent 11829 */ 11830 public void addErrorToDropBox(String eventType, 11831 ProcessRecord process, String processName, ActivityRecord activity, 11832 ActivityRecord parent, String subject, 11833 final String report, final File logFile, 11834 final ApplicationErrorReport.CrashInfo crashInfo) { 11835 // NOTE -- this must never acquire the ActivityManagerService lock, 11836 // otherwise the watchdog may be prevented from resetting the system. 11837 11838 final String dropboxTag = processClass(process) + "_" + eventType; 11839 final DropBoxManager dbox = (DropBoxManager) 11840 mContext.getSystemService(Context.DROPBOX_SERVICE); 11841 11842 // Exit early if the dropbox isn't configured to accept this report type. 11843 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11844 11845 final StringBuilder sb = new StringBuilder(1024); 11846 appendDropBoxProcessHeaders(process, processName, sb); 11847 if (activity != null) { 11848 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11849 } 11850 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11851 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11852 } 11853 if (parent != null && parent != activity) { 11854 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11855 } 11856 if (subject != null) { 11857 sb.append("Subject: ").append(subject).append("\n"); 11858 } 11859 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11860 if (Debug.isDebuggerConnected()) { 11861 sb.append("Debugger: Connected\n"); 11862 } 11863 sb.append("\n"); 11864 11865 // Do the rest in a worker thread to avoid blocking the caller on I/O 11866 // (After this point, we shouldn't access AMS internal data structures.) 11867 Thread worker = new Thread("Error dump: " + dropboxTag) { 11868 @Override 11869 public void run() { 11870 if (report != null) { 11871 sb.append(report); 11872 } 11873 if (logFile != null) { 11874 try { 11875 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11876 "\n\n[[TRUNCATED]]")); 11877 } catch (IOException e) { 11878 Slog.e(TAG, "Error reading " + logFile, e); 11879 } 11880 } 11881 if (crashInfo != null && crashInfo.stackTrace != null) { 11882 sb.append(crashInfo.stackTrace); 11883 } 11884 11885 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11886 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11887 if (lines > 0) { 11888 sb.append("\n"); 11889 11890 // Merge several logcat streams, and take the last N lines 11891 InputStreamReader input = null; 11892 try { 11893 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11894 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11895 "-b", "crash", 11896 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11897 11898 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11899 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11900 input = new InputStreamReader(logcat.getInputStream()); 11901 11902 int num; 11903 char[] buf = new char[8192]; 11904 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11905 } catch (IOException e) { 11906 Slog.e(TAG, "Error running logcat", e); 11907 } finally { 11908 if (input != null) try { input.close(); } catch (IOException e) {} 11909 } 11910 } 11911 11912 dbox.addText(dropboxTag, sb.toString()); 11913 } 11914 }; 11915 11916 if (process == null) { 11917 // If process is null, we are being called from some internal code 11918 // and may be about to die -- run this synchronously. 11919 worker.run(); 11920 } else { 11921 worker.start(); 11922 } 11923 } 11924 11925 /** 11926 * Bring up the "unexpected error" dialog box for a crashing app. 11927 * Deal with edge cases (intercepts from instrumented applications, 11928 * ActivityController, error intent receivers, that sort of thing). 11929 * @param r the application crashing 11930 * @param crashInfo describing the failure 11931 */ 11932 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11933 long timeMillis = System.currentTimeMillis(); 11934 String shortMsg = crashInfo.exceptionClassName; 11935 String longMsg = crashInfo.exceptionMessage; 11936 String stackTrace = crashInfo.stackTrace; 11937 if (shortMsg != null && longMsg != null) { 11938 longMsg = shortMsg + ": " + longMsg; 11939 } else if (shortMsg != null) { 11940 longMsg = shortMsg; 11941 } 11942 11943 AppErrorResult result = new AppErrorResult(); 11944 synchronized (this) { 11945 if (mController != null) { 11946 try { 11947 String name = r != null ? r.processName : null; 11948 int pid = r != null ? r.pid : Binder.getCallingPid(); 11949 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11950 if (!mController.appCrashed(name, pid, 11951 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11952 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11953 && "Native crash".equals(crashInfo.exceptionClassName)) { 11954 Slog.w(TAG, "Skip killing native crashed app " + name 11955 + "(" + pid + ") during testing"); 11956 } else { 11957 Slog.w(TAG, "Force-killing crashed app " + name 11958 + " at watcher's request"); 11959 if (r != null) { 11960 r.kill("crash", true); 11961 } else { 11962 // Huh. 11963 Process.killProcess(pid); 11964 Process.killProcessGroup(uid, pid); 11965 } 11966 } 11967 return; 11968 } 11969 } catch (RemoteException e) { 11970 mController = null; 11971 Watchdog.getInstance().setActivityController(null); 11972 } 11973 } 11974 11975 final long origId = Binder.clearCallingIdentity(); 11976 11977 // If this process is running instrumentation, finish it. 11978 if (r != null && r.instrumentationClass != null) { 11979 Slog.w(TAG, "Error in app " + r.processName 11980 + " running instrumentation " + r.instrumentationClass + ":"); 11981 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11982 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11983 Bundle info = new Bundle(); 11984 info.putString("shortMsg", shortMsg); 11985 info.putString("longMsg", longMsg); 11986 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11987 Binder.restoreCallingIdentity(origId); 11988 return; 11989 } 11990 11991 // If we can't identify the process or it's already exceeded its crash quota, 11992 // quit right away without showing a crash dialog. 11993 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11994 Binder.restoreCallingIdentity(origId); 11995 return; 11996 } 11997 11998 Message msg = Message.obtain(); 11999 msg.what = SHOW_ERROR_MSG; 12000 HashMap data = new HashMap(); 12001 data.put("result", result); 12002 data.put("app", r); 12003 msg.obj = data; 12004 mHandler.sendMessage(msg); 12005 12006 Binder.restoreCallingIdentity(origId); 12007 } 12008 12009 int res = result.get(); 12010 12011 Intent appErrorIntent = null; 12012 synchronized (this) { 12013 if (r != null && !r.isolated) { 12014 // XXX Can't keep track of crash time for isolated processes, 12015 // since they don't have a persistent identity. 12016 mProcessCrashTimes.put(r.info.processName, r.uid, 12017 SystemClock.uptimeMillis()); 12018 } 12019 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12020 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12021 } 12022 } 12023 12024 if (appErrorIntent != null) { 12025 try { 12026 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12027 } catch (ActivityNotFoundException e) { 12028 Slog.w(TAG, "bug report receiver dissappeared", e); 12029 } 12030 } 12031 } 12032 12033 Intent createAppErrorIntentLocked(ProcessRecord r, 12034 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12035 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12036 if (report == null) { 12037 return null; 12038 } 12039 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12040 result.setComponent(r.errorReportReceiver); 12041 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12042 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12043 return result; 12044 } 12045 12046 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12047 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12048 if (r.errorReportReceiver == null) { 12049 return null; 12050 } 12051 12052 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12053 return null; 12054 } 12055 12056 ApplicationErrorReport report = new ApplicationErrorReport(); 12057 report.packageName = r.info.packageName; 12058 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12059 report.processName = r.processName; 12060 report.time = timeMillis; 12061 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12062 12063 if (r.crashing || r.forceCrashReport) { 12064 report.type = ApplicationErrorReport.TYPE_CRASH; 12065 report.crashInfo = crashInfo; 12066 } else if (r.notResponding) { 12067 report.type = ApplicationErrorReport.TYPE_ANR; 12068 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12069 12070 report.anrInfo.activity = r.notRespondingReport.tag; 12071 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12072 report.anrInfo.info = r.notRespondingReport.longMsg; 12073 } 12074 12075 return report; 12076 } 12077 12078 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12079 enforceNotIsolatedCaller("getProcessesInErrorState"); 12080 // assume our apps are happy - lazy create the list 12081 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12082 12083 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12084 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12085 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12086 12087 synchronized (this) { 12088 12089 // iterate across all processes 12090 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12091 ProcessRecord app = mLruProcesses.get(i); 12092 if (!allUsers && app.userId != userId) { 12093 continue; 12094 } 12095 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12096 // This one's in trouble, so we'll generate a report for it 12097 // crashes are higher priority (in case there's a crash *and* an anr) 12098 ActivityManager.ProcessErrorStateInfo report = null; 12099 if (app.crashing) { 12100 report = app.crashingReport; 12101 } else if (app.notResponding) { 12102 report = app.notRespondingReport; 12103 } 12104 12105 if (report != null) { 12106 if (errList == null) { 12107 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12108 } 12109 errList.add(report); 12110 } else { 12111 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12112 " crashing = " + app.crashing + 12113 " notResponding = " + app.notResponding); 12114 } 12115 } 12116 } 12117 } 12118 12119 return errList; 12120 } 12121 12122 static int procStateToImportance(int procState, int memAdj, 12123 ActivityManager.RunningAppProcessInfo currApp) { 12124 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12125 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12126 currApp.lru = memAdj; 12127 } else { 12128 currApp.lru = 0; 12129 } 12130 return imp; 12131 } 12132 12133 private void fillInProcMemInfo(ProcessRecord app, 12134 ActivityManager.RunningAppProcessInfo outInfo) { 12135 outInfo.pid = app.pid; 12136 outInfo.uid = app.info.uid; 12137 if (mHeavyWeightProcess == app) { 12138 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12139 } 12140 if (app.persistent) { 12141 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12142 } 12143 if (app.activities.size() > 0) { 12144 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12145 } 12146 outInfo.lastTrimLevel = app.trimMemoryLevel; 12147 int adj = app.curAdj; 12148 int procState = app.curProcState; 12149 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12150 outInfo.importanceReasonCode = app.adjTypeCode; 12151 outInfo.processState = app.curProcState; 12152 } 12153 12154 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12155 enforceNotIsolatedCaller("getRunningAppProcesses"); 12156 // Lazy instantiation of list 12157 List<ActivityManager.RunningAppProcessInfo> runList = null; 12158 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12159 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12160 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12161 synchronized (this) { 12162 // Iterate across all processes 12163 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12164 ProcessRecord app = mLruProcesses.get(i); 12165 if (!allUsers && app.userId != userId) { 12166 continue; 12167 } 12168 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12169 // Generate process state info for running application 12170 ActivityManager.RunningAppProcessInfo currApp = 12171 new ActivityManager.RunningAppProcessInfo(app.processName, 12172 app.pid, app.getPackageList()); 12173 fillInProcMemInfo(app, currApp); 12174 if (app.adjSource instanceof ProcessRecord) { 12175 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12176 currApp.importanceReasonImportance = 12177 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12178 app.adjSourceProcState); 12179 } else if (app.adjSource instanceof ActivityRecord) { 12180 ActivityRecord r = (ActivityRecord)app.adjSource; 12181 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12182 } 12183 if (app.adjTarget instanceof ComponentName) { 12184 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12185 } 12186 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12187 // + " lru=" + currApp.lru); 12188 if (runList == null) { 12189 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12190 } 12191 runList.add(currApp); 12192 } 12193 } 12194 } 12195 return runList; 12196 } 12197 12198 public List<ApplicationInfo> getRunningExternalApplications() { 12199 enforceNotIsolatedCaller("getRunningExternalApplications"); 12200 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12201 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12202 if (runningApps != null && runningApps.size() > 0) { 12203 Set<String> extList = new HashSet<String>(); 12204 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12205 if (app.pkgList != null) { 12206 for (String pkg : app.pkgList) { 12207 extList.add(pkg); 12208 } 12209 } 12210 } 12211 IPackageManager pm = AppGlobals.getPackageManager(); 12212 for (String pkg : extList) { 12213 try { 12214 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12215 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12216 retList.add(info); 12217 } 12218 } catch (RemoteException e) { 12219 } 12220 } 12221 } 12222 return retList; 12223 } 12224 12225 @Override 12226 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12227 enforceNotIsolatedCaller("getMyMemoryState"); 12228 synchronized (this) { 12229 ProcessRecord proc; 12230 synchronized (mPidsSelfLocked) { 12231 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12232 } 12233 fillInProcMemInfo(proc, outInfo); 12234 } 12235 } 12236 12237 @Override 12238 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12239 if (checkCallingPermission(android.Manifest.permission.DUMP) 12240 != PackageManager.PERMISSION_GRANTED) { 12241 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12242 + Binder.getCallingPid() 12243 + ", uid=" + Binder.getCallingUid() 12244 + " without permission " 12245 + android.Manifest.permission.DUMP); 12246 return; 12247 } 12248 12249 boolean dumpAll = false; 12250 boolean dumpClient = false; 12251 String dumpPackage = null; 12252 12253 int opti = 0; 12254 while (opti < args.length) { 12255 String opt = args[opti]; 12256 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12257 break; 12258 } 12259 opti++; 12260 if ("-a".equals(opt)) { 12261 dumpAll = true; 12262 } else if ("-c".equals(opt)) { 12263 dumpClient = true; 12264 } else if ("-h".equals(opt)) { 12265 pw.println("Activity manager dump options:"); 12266 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12267 pw.println(" cmd may be one of:"); 12268 pw.println(" a[ctivities]: activity stack state"); 12269 pw.println(" r[recents]: recent activities state"); 12270 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12271 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12272 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12273 pw.println(" o[om]: out of memory management"); 12274 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12275 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12276 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12277 pw.println(" service [COMP_SPEC]: service client-side state"); 12278 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12279 pw.println(" all: dump all activities"); 12280 pw.println(" top: dump the top activity"); 12281 pw.println(" write: write all pending state to storage"); 12282 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12283 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12284 pw.println(" a partial substring in a component name, a"); 12285 pw.println(" hex object identifier."); 12286 pw.println(" -a: include all available server state."); 12287 pw.println(" -c: include client state."); 12288 return; 12289 } else { 12290 pw.println("Unknown argument: " + opt + "; use -h for help"); 12291 } 12292 } 12293 12294 long origId = Binder.clearCallingIdentity(); 12295 boolean more = false; 12296 // Is the caller requesting to dump a particular piece of data? 12297 if (opti < args.length) { 12298 String cmd = args[opti]; 12299 opti++; 12300 if ("activities".equals(cmd) || "a".equals(cmd)) { 12301 synchronized (this) { 12302 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12303 } 12304 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12305 synchronized (this) { 12306 dumpRecentsLocked(fd, pw, args, opti, true, null); 12307 } 12308 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12309 String[] newArgs; 12310 String name; 12311 if (opti >= args.length) { 12312 name = null; 12313 newArgs = EMPTY_STRING_ARRAY; 12314 } else { 12315 name = args[opti]; 12316 opti++; 12317 newArgs = new String[args.length - opti]; 12318 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12319 args.length - opti); 12320 } 12321 synchronized (this) { 12322 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12323 } 12324 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12325 String[] newArgs; 12326 String name; 12327 if (opti >= args.length) { 12328 name = null; 12329 newArgs = EMPTY_STRING_ARRAY; 12330 } else { 12331 name = args[opti]; 12332 opti++; 12333 newArgs = new String[args.length - opti]; 12334 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12335 args.length - opti); 12336 } 12337 synchronized (this) { 12338 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12339 } 12340 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12341 String[] newArgs; 12342 String name; 12343 if (opti >= args.length) { 12344 name = null; 12345 newArgs = EMPTY_STRING_ARRAY; 12346 } else { 12347 name = args[opti]; 12348 opti++; 12349 newArgs = new String[args.length - opti]; 12350 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12351 args.length - opti); 12352 } 12353 synchronized (this) { 12354 dumpProcessesLocked(fd, pw, args, opti, true, name); 12355 } 12356 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12357 synchronized (this) { 12358 dumpOomLocked(fd, pw, args, opti, true); 12359 } 12360 } else if ("provider".equals(cmd)) { 12361 String[] newArgs; 12362 String name; 12363 if (opti >= args.length) { 12364 name = null; 12365 newArgs = EMPTY_STRING_ARRAY; 12366 } else { 12367 name = args[opti]; 12368 opti++; 12369 newArgs = new String[args.length - opti]; 12370 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12371 } 12372 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12373 pw.println("No providers match: " + name); 12374 pw.println("Use -h for help."); 12375 } 12376 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12377 synchronized (this) { 12378 dumpProvidersLocked(fd, pw, args, opti, true, null); 12379 } 12380 } else if ("service".equals(cmd)) { 12381 String[] newArgs; 12382 String name; 12383 if (opti >= args.length) { 12384 name = null; 12385 newArgs = EMPTY_STRING_ARRAY; 12386 } else { 12387 name = args[opti]; 12388 opti++; 12389 newArgs = new String[args.length - opti]; 12390 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12391 args.length - opti); 12392 } 12393 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12394 pw.println("No services match: " + name); 12395 pw.println("Use -h for help."); 12396 } 12397 } else if ("package".equals(cmd)) { 12398 String[] newArgs; 12399 if (opti >= args.length) { 12400 pw.println("package: no package name specified"); 12401 pw.println("Use -h for help."); 12402 } else { 12403 dumpPackage = args[opti]; 12404 opti++; 12405 newArgs = new String[args.length - opti]; 12406 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12407 args.length - opti); 12408 args = newArgs; 12409 opti = 0; 12410 more = true; 12411 } 12412 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12413 synchronized (this) { 12414 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12415 } 12416 } else if ("write".equals(cmd)) { 12417 mTaskPersister.flush(); 12418 pw.println("All tasks persisted."); 12419 return; 12420 } else { 12421 // Dumping a single activity? 12422 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12423 pw.println("Bad activity command, or no activities match: " + cmd); 12424 pw.println("Use -h for help."); 12425 } 12426 } 12427 if (!more) { 12428 Binder.restoreCallingIdentity(origId); 12429 return; 12430 } 12431 } 12432 12433 // No piece of data specified, dump everything. 12434 synchronized (this) { 12435 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12436 pw.println(); 12437 if (dumpAll) { 12438 pw.println("-------------------------------------------------------------------------------"); 12439 } 12440 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12441 pw.println(); 12442 if (dumpAll) { 12443 pw.println("-------------------------------------------------------------------------------"); 12444 } 12445 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12446 pw.println(); 12447 if (dumpAll) { 12448 pw.println("-------------------------------------------------------------------------------"); 12449 } 12450 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12451 pw.println(); 12452 if (dumpAll) { 12453 pw.println("-------------------------------------------------------------------------------"); 12454 } 12455 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12456 pw.println(); 12457 if (dumpAll) { 12458 pw.println("-------------------------------------------------------------------------------"); 12459 } 12460 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12461 pw.println(); 12462 if (dumpAll) { 12463 pw.println("-------------------------------------------------------------------------------"); 12464 } 12465 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12466 } 12467 Binder.restoreCallingIdentity(origId); 12468 } 12469 12470 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12471 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12472 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12473 12474 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12475 dumpPackage); 12476 boolean needSep = printedAnything; 12477 12478 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12479 dumpPackage, needSep, " mFocusedActivity: "); 12480 if (printed) { 12481 printedAnything = true; 12482 needSep = false; 12483 } 12484 12485 if (dumpPackage == null) { 12486 if (needSep) { 12487 pw.println(); 12488 } 12489 needSep = true; 12490 printedAnything = true; 12491 mStackSupervisor.dump(pw, " "); 12492 } 12493 12494 if (!printedAnything) { 12495 pw.println(" (nothing)"); 12496 } 12497 } 12498 12499 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12500 int opti, boolean dumpAll, String dumpPackage) { 12501 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12502 12503 boolean printedAnything = false; 12504 12505 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12506 boolean printedHeader = false; 12507 12508 final int N = mRecentTasks.size(); 12509 for (int i=0; i<N; i++) { 12510 TaskRecord tr = mRecentTasks.get(i); 12511 if (dumpPackage != null) { 12512 if (tr.realActivity == null || 12513 !dumpPackage.equals(tr.realActivity)) { 12514 continue; 12515 } 12516 } 12517 if (!printedHeader) { 12518 pw.println(" Recent tasks:"); 12519 printedHeader = true; 12520 printedAnything = true; 12521 } 12522 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12523 pw.println(tr); 12524 if (dumpAll) { 12525 mRecentTasks.get(i).dump(pw, " "); 12526 } 12527 } 12528 } 12529 12530 if (!printedAnything) { 12531 pw.println(" (nothing)"); 12532 } 12533 } 12534 12535 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12536 int opti, boolean dumpAll, String dumpPackage) { 12537 boolean needSep = false; 12538 boolean printedAnything = false; 12539 int numPers = 0; 12540 12541 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12542 12543 if (dumpAll) { 12544 final int NP = mProcessNames.getMap().size(); 12545 for (int ip=0; ip<NP; ip++) { 12546 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12547 final int NA = procs.size(); 12548 for (int ia=0; ia<NA; ia++) { 12549 ProcessRecord r = procs.valueAt(ia); 12550 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12551 continue; 12552 } 12553 if (!needSep) { 12554 pw.println(" All known processes:"); 12555 needSep = true; 12556 printedAnything = true; 12557 } 12558 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12559 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12560 pw.print(" "); pw.println(r); 12561 r.dump(pw, " "); 12562 if (r.persistent) { 12563 numPers++; 12564 } 12565 } 12566 } 12567 } 12568 12569 if (mIsolatedProcesses.size() > 0) { 12570 boolean printed = false; 12571 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12572 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12573 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12574 continue; 12575 } 12576 if (!printed) { 12577 if (needSep) { 12578 pw.println(); 12579 } 12580 pw.println(" Isolated process list (sorted by uid):"); 12581 printedAnything = true; 12582 printed = true; 12583 needSep = true; 12584 } 12585 pw.println(String.format("%sIsolated #%2d: %s", 12586 " ", i, r.toString())); 12587 } 12588 } 12589 12590 if (mLruProcesses.size() > 0) { 12591 if (needSep) { 12592 pw.println(); 12593 } 12594 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12595 pw.print(" total, non-act at "); 12596 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12597 pw.print(", non-svc at "); 12598 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12599 pw.println("):"); 12600 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12601 needSep = true; 12602 printedAnything = true; 12603 } 12604 12605 if (dumpAll || dumpPackage != null) { 12606 synchronized (mPidsSelfLocked) { 12607 boolean printed = false; 12608 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12609 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12610 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12611 continue; 12612 } 12613 if (!printed) { 12614 if (needSep) pw.println(); 12615 needSep = true; 12616 pw.println(" PID mappings:"); 12617 printed = true; 12618 printedAnything = true; 12619 } 12620 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12621 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12622 } 12623 } 12624 } 12625 12626 if (mForegroundProcesses.size() > 0) { 12627 synchronized (mPidsSelfLocked) { 12628 boolean printed = false; 12629 for (int i=0; i<mForegroundProcesses.size(); i++) { 12630 ProcessRecord r = mPidsSelfLocked.get( 12631 mForegroundProcesses.valueAt(i).pid); 12632 if (dumpPackage != null && (r == null 12633 || !r.pkgList.containsKey(dumpPackage))) { 12634 continue; 12635 } 12636 if (!printed) { 12637 if (needSep) pw.println(); 12638 needSep = true; 12639 pw.println(" Foreground Processes:"); 12640 printed = true; 12641 printedAnything = true; 12642 } 12643 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12644 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12645 } 12646 } 12647 } 12648 12649 if (mPersistentStartingProcesses.size() > 0) { 12650 if (needSep) pw.println(); 12651 needSep = true; 12652 printedAnything = true; 12653 pw.println(" Persisent processes that are starting:"); 12654 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12655 "Starting Norm", "Restarting PERS", dumpPackage); 12656 } 12657 12658 if (mRemovedProcesses.size() > 0) { 12659 if (needSep) pw.println(); 12660 needSep = true; 12661 printedAnything = true; 12662 pw.println(" Processes that are being removed:"); 12663 dumpProcessList(pw, this, mRemovedProcesses, " ", 12664 "Removed Norm", "Removed PERS", dumpPackage); 12665 } 12666 12667 if (mProcessesOnHold.size() > 0) { 12668 if (needSep) pw.println(); 12669 needSep = true; 12670 printedAnything = true; 12671 pw.println(" Processes that are on old until the system is ready:"); 12672 dumpProcessList(pw, this, mProcessesOnHold, " ", 12673 "OnHold Norm", "OnHold PERS", dumpPackage); 12674 } 12675 12676 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12677 12678 if (mProcessCrashTimes.getMap().size() > 0) { 12679 boolean printed = false; 12680 long now = SystemClock.uptimeMillis(); 12681 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12682 final int NP = pmap.size(); 12683 for (int ip=0; ip<NP; ip++) { 12684 String pname = pmap.keyAt(ip); 12685 SparseArray<Long> uids = pmap.valueAt(ip); 12686 final int N = uids.size(); 12687 for (int i=0; i<N; i++) { 12688 int puid = uids.keyAt(i); 12689 ProcessRecord r = mProcessNames.get(pname, puid); 12690 if (dumpPackage != null && (r == null 12691 || !r.pkgList.containsKey(dumpPackage))) { 12692 continue; 12693 } 12694 if (!printed) { 12695 if (needSep) pw.println(); 12696 needSep = true; 12697 pw.println(" Time since processes crashed:"); 12698 printed = true; 12699 printedAnything = true; 12700 } 12701 pw.print(" Process "); pw.print(pname); 12702 pw.print(" uid "); pw.print(puid); 12703 pw.print(": last crashed "); 12704 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12705 pw.println(" ago"); 12706 } 12707 } 12708 } 12709 12710 if (mBadProcesses.getMap().size() > 0) { 12711 boolean printed = false; 12712 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12713 final int NP = pmap.size(); 12714 for (int ip=0; ip<NP; ip++) { 12715 String pname = pmap.keyAt(ip); 12716 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12717 final int N = uids.size(); 12718 for (int i=0; i<N; i++) { 12719 int puid = uids.keyAt(i); 12720 ProcessRecord r = mProcessNames.get(pname, puid); 12721 if (dumpPackage != null && (r == null 12722 || !r.pkgList.containsKey(dumpPackage))) { 12723 continue; 12724 } 12725 if (!printed) { 12726 if (needSep) pw.println(); 12727 needSep = true; 12728 pw.println(" Bad processes:"); 12729 printedAnything = true; 12730 } 12731 BadProcessInfo info = uids.valueAt(i); 12732 pw.print(" Bad process "); pw.print(pname); 12733 pw.print(" uid "); pw.print(puid); 12734 pw.print(": crashed at time "); pw.println(info.time); 12735 if (info.shortMsg != null) { 12736 pw.print(" Short msg: "); pw.println(info.shortMsg); 12737 } 12738 if (info.longMsg != null) { 12739 pw.print(" Long msg: "); pw.println(info.longMsg); 12740 } 12741 if (info.stack != null) { 12742 pw.println(" Stack:"); 12743 int lastPos = 0; 12744 for (int pos=0; pos<info.stack.length(); pos++) { 12745 if (info.stack.charAt(pos) == '\n') { 12746 pw.print(" "); 12747 pw.write(info.stack, lastPos, pos-lastPos); 12748 pw.println(); 12749 lastPos = pos+1; 12750 } 12751 } 12752 if (lastPos < info.stack.length()) { 12753 pw.print(" "); 12754 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12755 pw.println(); 12756 } 12757 } 12758 } 12759 } 12760 } 12761 12762 if (dumpPackage == null) { 12763 pw.println(); 12764 needSep = false; 12765 pw.println(" mStartedUsers:"); 12766 for (int i=0; i<mStartedUsers.size(); i++) { 12767 UserStartedState uss = mStartedUsers.valueAt(i); 12768 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12769 pw.print(": "); uss.dump("", pw); 12770 } 12771 pw.print(" mStartedUserArray: ["); 12772 for (int i=0; i<mStartedUserArray.length; i++) { 12773 if (i > 0) pw.print(", "); 12774 pw.print(mStartedUserArray[i]); 12775 } 12776 pw.println("]"); 12777 pw.print(" mUserLru: ["); 12778 for (int i=0; i<mUserLru.size(); i++) { 12779 if (i > 0) pw.print(", "); 12780 pw.print(mUserLru.get(i)); 12781 } 12782 pw.println("]"); 12783 if (dumpAll) { 12784 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12785 } 12786 synchronized (mUserProfileGroupIdsSelfLocked) { 12787 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12788 pw.println(" mUserProfileGroupIds:"); 12789 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12790 pw.print(" User #"); 12791 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12792 pw.print(" -> profile #"); 12793 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12794 } 12795 } 12796 } 12797 } 12798 if (mHomeProcess != null && (dumpPackage == null 12799 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12800 if (needSep) { 12801 pw.println(); 12802 needSep = false; 12803 } 12804 pw.println(" mHomeProcess: " + mHomeProcess); 12805 } 12806 if (mPreviousProcess != null && (dumpPackage == null 12807 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12808 if (needSep) { 12809 pw.println(); 12810 needSep = false; 12811 } 12812 pw.println(" mPreviousProcess: " + mPreviousProcess); 12813 } 12814 if (dumpAll) { 12815 StringBuilder sb = new StringBuilder(128); 12816 sb.append(" mPreviousProcessVisibleTime: "); 12817 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12818 pw.println(sb); 12819 } 12820 if (mHeavyWeightProcess != null && (dumpPackage == null 12821 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12822 if (needSep) { 12823 pw.println(); 12824 needSep = false; 12825 } 12826 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12827 } 12828 if (dumpPackage == null) { 12829 pw.println(" mConfiguration: " + mConfiguration); 12830 } 12831 if (dumpAll) { 12832 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12833 if (mCompatModePackages.getPackages().size() > 0) { 12834 boolean printed = false; 12835 for (Map.Entry<String, Integer> entry 12836 : mCompatModePackages.getPackages().entrySet()) { 12837 String pkg = entry.getKey(); 12838 int mode = entry.getValue(); 12839 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12840 continue; 12841 } 12842 if (!printed) { 12843 pw.println(" mScreenCompatPackages:"); 12844 printed = true; 12845 } 12846 pw.print(" "); pw.print(pkg); pw.print(": "); 12847 pw.print(mode); pw.println(); 12848 } 12849 } 12850 } 12851 if (dumpPackage == null) { 12852 if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) { 12853 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12854 + " mLockScreenShown " + lockScreenShownToString()); 12855 } 12856 if (mShuttingDown || mRunningVoice) { 12857 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12858 } 12859 } 12860 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12861 || mOrigWaitForDebugger) { 12862 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12863 || dumpPackage.equals(mOrigDebugApp)) { 12864 if (needSep) { 12865 pw.println(); 12866 needSep = false; 12867 } 12868 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12869 + " mDebugTransient=" + mDebugTransient 12870 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12871 } 12872 } 12873 if (mOpenGlTraceApp != null) { 12874 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12875 if (needSep) { 12876 pw.println(); 12877 needSep = false; 12878 } 12879 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12880 } 12881 } 12882 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12883 || mProfileFd != null) { 12884 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12885 if (needSep) { 12886 pw.println(); 12887 needSep = false; 12888 } 12889 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12890 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12891 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12892 + mAutoStopProfiler); 12893 pw.println(" mProfileType=" + mProfileType); 12894 } 12895 } 12896 if (dumpPackage == null) { 12897 if (mAlwaysFinishActivities || mController != null) { 12898 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12899 + " mController=" + mController); 12900 } 12901 if (dumpAll) { 12902 pw.println(" Total persistent processes: " + numPers); 12903 pw.println(" mProcessesReady=" + mProcessesReady 12904 + " mSystemReady=" + mSystemReady 12905 + " mBooted=" + mBooted 12906 + " mFactoryTest=" + mFactoryTest); 12907 pw.println(" mBooting=" + mBooting 12908 + " mCallFinishBooting=" + mCallFinishBooting 12909 + " mBootAnimationComplete=" + mBootAnimationComplete); 12910 pw.print(" mLastPowerCheckRealtime="); 12911 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12912 pw.println(""); 12913 pw.print(" mLastPowerCheckUptime="); 12914 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12915 pw.println(""); 12916 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12917 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12918 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12919 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12920 + " (" + mLruProcesses.size() + " total)" 12921 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12922 + " mNumServiceProcs=" + mNumServiceProcs 12923 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12924 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12925 + " mLastMemoryLevel" + mLastMemoryLevel 12926 + " mLastNumProcesses" + mLastNumProcesses); 12927 long now = SystemClock.uptimeMillis(); 12928 pw.print(" mLastIdleTime="); 12929 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12930 pw.print(" mLowRamSinceLastIdle="); 12931 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12932 pw.println(); 12933 } 12934 } 12935 12936 if (!printedAnything) { 12937 pw.println(" (nothing)"); 12938 } 12939 } 12940 12941 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12942 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12943 if (mProcessesToGc.size() > 0) { 12944 boolean printed = false; 12945 long now = SystemClock.uptimeMillis(); 12946 for (int i=0; i<mProcessesToGc.size(); i++) { 12947 ProcessRecord proc = mProcessesToGc.get(i); 12948 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12949 continue; 12950 } 12951 if (!printed) { 12952 if (needSep) pw.println(); 12953 needSep = true; 12954 pw.println(" Processes that are waiting to GC:"); 12955 printed = true; 12956 } 12957 pw.print(" Process "); pw.println(proc); 12958 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12959 pw.print(", last gced="); 12960 pw.print(now-proc.lastRequestedGc); 12961 pw.print(" ms ago, last lowMem="); 12962 pw.print(now-proc.lastLowMemory); 12963 pw.println(" ms ago"); 12964 12965 } 12966 } 12967 return needSep; 12968 } 12969 12970 void printOomLevel(PrintWriter pw, String name, int adj) { 12971 pw.print(" "); 12972 if (adj >= 0) { 12973 pw.print(' '); 12974 if (adj < 10) pw.print(' '); 12975 } else { 12976 if (adj > -10) pw.print(' '); 12977 } 12978 pw.print(adj); 12979 pw.print(": "); 12980 pw.print(name); 12981 pw.print(" ("); 12982 pw.print(mProcessList.getMemLevel(adj)/1024); 12983 pw.println(" kB)"); 12984 } 12985 12986 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12987 int opti, boolean dumpAll) { 12988 boolean needSep = false; 12989 12990 if (mLruProcesses.size() > 0) { 12991 if (needSep) pw.println(); 12992 needSep = true; 12993 pw.println(" OOM levels:"); 12994 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12995 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12996 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12997 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12998 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12999 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13000 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13001 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13002 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13003 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13004 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13005 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13006 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13007 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13008 13009 if (needSep) pw.println(); 13010 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13011 pw.print(" total, non-act at "); 13012 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13013 pw.print(", non-svc at "); 13014 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13015 pw.println("):"); 13016 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13017 needSep = true; 13018 } 13019 13020 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13021 13022 pw.println(); 13023 pw.println(" mHomeProcess: " + mHomeProcess); 13024 pw.println(" mPreviousProcess: " + mPreviousProcess); 13025 if (mHeavyWeightProcess != null) { 13026 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13027 } 13028 13029 return true; 13030 } 13031 13032 /** 13033 * There are three ways to call this: 13034 * - no provider specified: dump all the providers 13035 * - a flattened component name that matched an existing provider was specified as the 13036 * first arg: dump that one provider 13037 * - the first arg isn't the flattened component name of an existing provider: 13038 * dump all providers whose component contains the first arg as a substring 13039 */ 13040 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13041 int opti, boolean dumpAll) { 13042 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13043 } 13044 13045 static class ItemMatcher { 13046 ArrayList<ComponentName> components; 13047 ArrayList<String> strings; 13048 ArrayList<Integer> objects; 13049 boolean all; 13050 13051 ItemMatcher() { 13052 all = true; 13053 } 13054 13055 void build(String name) { 13056 ComponentName componentName = ComponentName.unflattenFromString(name); 13057 if (componentName != null) { 13058 if (components == null) { 13059 components = new ArrayList<ComponentName>(); 13060 } 13061 components.add(componentName); 13062 all = false; 13063 } else { 13064 int objectId = 0; 13065 // Not a '/' separated full component name; maybe an object ID? 13066 try { 13067 objectId = Integer.parseInt(name, 16); 13068 if (objects == null) { 13069 objects = new ArrayList<Integer>(); 13070 } 13071 objects.add(objectId); 13072 all = false; 13073 } catch (RuntimeException e) { 13074 // Not an integer; just do string match. 13075 if (strings == null) { 13076 strings = new ArrayList<String>(); 13077 } 13078 strings.add(name); 13079 all = false; 13080 } 13081 } 13082 } 13083 13084 int build(String[] args, int opti) { 13085 for (; opti<args.length; opti++) { 13086 String name = args[opti]; 13087 if ("--".equals(name)) { 13088 return opti+1; 13089 } 13090 build(name); 13091 } 13092 return opti; 13093 } 13094 13095 boolean match(Object object, ComponentName comp) { 13096 if (all) { 13097 return true; 13098 } 13099 if (components != null) { 13100 for (int i=0; i<components.size(); i++) { 13101 if (components.get(i).equals(comp)) { 13102 return true; 13103 } 13104 } 13105 } 13106 if (objects != null) { 13107 for (int i=0; i<objects.size(); i++) { 13108 if (System.identityHashCode(object) == objects.get(i)) { 13109 return true; 13110 } 13111 } 13112 } 13113 if (strings != null) { 13114 String flat = comp.flattenToString(); 13115 for (int i=0; i<strings.size(); i++) { 13116 if (flat.contains(strings.get(i))) { 13117 return true; 13118 } 13119 } 13120 } 13121 return false; 13122 } 13123 } 13124 13125 /** 13126 * There are three things that cmd can be: 13127 * - a flattened component name that matches an existing activity 13128 * - the cmd arg isn't the flattened component name of an existing activity: 13129 * dump all activity whose component contains the cmd as a substring 13130 * - A hex number of the ActivityRecord object instance. 13131 */ 13132 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13133 int opti, boolean dumpAll) { 13134 ArrayList<ActivityRecord> activities; 13135 13136 synchronized (this) { 13137 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13138 } 13139 13140 if (activities.size() <= 0) { 13141 return false; 13142 } 13143 13144 String[] newArgs = new String[args.length - opti]; 13145 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13146 13147 TaskRecord lastTask = null; 13148 boolean needSep = false; 13149 for (int i=activities.size()-1; i>=0; i--) { 13150 ActivityRecord r = activities.get(i); 13151 if (needSep) { 13152 pw.println(); 13153 } 13154 needSep = true; 13155 synchronized (this) { 13156 if (lastTask != r.task) { 13157 lastTask = r.task; 13158 pw.print("TASK "); pw.print(lastTask.affinity); 13159 pw.print(" id="); pw.println(lastTask.taskId); 13160 if (dumpAll) { 13161 lastTask.dump(pw, " "); 13162 } 13163 } 13164 } 13165 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13166 } 13167 return true; 13168 } 13169 13170 /** 13171 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13172 * there is a thread associated with the activity. 13173 */ 13174 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13175 final ActivityRecord r, String[] args, boolean dumpAll) { 13176 String innerPrefix = prefix + " "; 13177 synchronized (this) { 13178 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13179 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13180 pw.print(" pid="); 13181 if (r.app != null) pw.println(r.app.pid); 13182 else pw.println("(not running)"); 13183 if (dumpAll) { 13184 r.dump(pw, innerPrefix); 13185 } 13186 } 13187 if (r.app != null && r.app.thread != null) { 13188 // flush anything that is already in the PrintWriter since the thread is going 13189 // to write to the file descriptor directly 13190 pw.flush(); 13191 try { 13192 TransferPipe tp = new TransferPipe(); 13193 try { 13194 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13195 r.appToken, innerPrefix, args); 13196 tp.go(fd); 13197 } finally { 13198 tp.kill(); 13199 } 13200 } catch (IOException e) { 13201 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13202 } catch (RemoteException e) { 13203 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13204 } 13205 } 13206 } 13207 13208 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13209 int opti, boolean dumpAll, String dumpPackage) { 13210 boolean needSep = false; 13211 boolean onlyHistory = false; 13212 boolean printedAnything = false; 13213 13214 if ("history".equals(dumpPackage)) { 13215 if (opti < args.length && "-s".equals(args[opti])) { 13216 dumpAll = false; 13217 } 13218 onlyHistory = true; 13219 dumpPackage = null; 13220 } 13221 13222 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13223 if (!onlyHistory && dumpAll) { 13224 if (mRegisteredReceivers.size() > 0) { 13225 boolean printed = false; 13226 Iterator it = mRegisteredReceivers.values().iterator(); 13227 while (it.hasNext()) { 13228 ReceiverList r = (ReceiverList)it.next(); 13229 if (dumpPackage != null && (r.app == null || 13230 !dumpPackage.equals(r.app.info.packageName))) { 13231 continue; 13232 } 13233 if (!printed) { 13234 pw.println(" Registered Receivers:"); 13235 needSep = true; 13236 printed = true; 13237 printedAnything = true; 13238 } 13239 pw.print(" * "); pw.println(r); 13240 r.dump(pw, " "); 13241 } 13242 } 13243 13244 if (mReceiverResolver.dump(pw, needSep ? 13245 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13246 " ", dumpPackage, false)) { 13247 needSep = true; 13248 printedAnything = true; 13249 } 13250 } 13251 13252 for (BroadcastQueue q : mBroadcastQueues) { 13253 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13254 printedAnything |= needSep; 13255 } 13256 13257 needSep = true; 13258 13259 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13260 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13261 if (needSep) { 13262 pw.println(); 13263 } 13264 needSep = true; 13265 printedAnything = true; 13266 pw.print(" Sticky broadcasts for user "); 13267 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13268 StringBuilder sb = new StringBuilder(128); 13269 for (Map.Entry<String, ArrayList<Intent>> ent 13270 : mStickyBroadcasts.valueAt(user).entrySet()) { 13271 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13272 if (dumpAll) { 13273 pw.println(":"); 13274 ArrayList<Intent> intents = ent.getValue(); 13275 final int N = intents.size(); 13276 for (int i=0; i<N; i++) { 13277 sb.setLength(0); 13278 sb.append(" Intent: "); 13279 intents.get(i).toShortString(sb, false, true, false, false); 13280 pw.println(sb.toString()); 13281 Bundle bundle = intents.get(i).getExtras(); 13282 if (bundle != null) { 13283 pw.print(" "); 13284 pw.println(bundle.toString()); 13285 } 13286 } 13287 } else { 13288 pw.println(""); 13289 } 13290 } 13291 } 13292 } 13293 13294 if (!onlyHistory && dumpAll) { 13295 pw.println(); 13296 for (BroadcastQueue queue : mBroadcastQueues) { 13297 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13298 + queue.mBroadcastsScheduled); 13299 } 13300 pw.println(" mHandler:"); 13301 mHandler.dump(new PrintWriterPrinter(pw), " "); 13302 needSep = true; 13303 printedAnything = true; 13304 } 13305 13306 if (!printedAnything) { 13307 pw.println(" (nothing)"); 13308 } 13309 } 13310 13311 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13312 int opti, boolean dumpAll, String dumpPackage) { 13313 boolean needSep; 13314 boolean printedAnything = false; 13315 13316 ItemMatcher matcher = new ItemMatcher(); 13317 matcher.build(args, opti); 13318 13319 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13320 13321 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13322 printedAnything |= needSep; 13323 13324 if (mLaunchingProviders.size() > 0) { 13325 boolean printed = false; 13326 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13327 ContentProviderRecord r = mLaunchingProviders.get(i); 13328 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13329 continue; 13330 } 13331 if (!printed) { 13332 if (needSep) pw.println(); 13333 needSep = true; 13334 pw.println(" Launching content providers:"); 13335 printed = true; 13336 printedAnything = true; 13337 } 13338 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13339 pw.println(r); 13340 } 13341 } 13342 13343 if (mGrantedUriPermissions.size() > 0) { 13344 boolean printed = false; 13345 int dumpUid = -2; 13346 if (dumpPackage != null) { 13347 try { 13348 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13349 } catch (NameNotFoundException e) { 13350 dumpUid = -1; 13351 } 13352 } 13353 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13354 int uid = mGrantedUriPermissions.keyAt(i); 13355 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13356 continue; 13357 } 13358 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13359 if (!printed) { 13360 if (needSep) pw.println(); 13361 needSep = true; 13362 pw.println(" Granted Uri Permissions:"); 13363 printed = true; 13364 printedAnything = true; 13365 } 13366 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13367 for (UriPermission perm : perms.values()) { 13368 pw.print(" "); pw.println(perm); 13369 if (dumpAll) { 13370 perm.dump(pw, " "); 13371 } 13372 } 13373 } 13374 } 13375 13376 if (!printedAnything) { 13377 pw.println(" (nothing)"); 13378 } 13379 } 13380 13381 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13382 int opti, boolean dumpAll, String dumpPackage) { 13383 boolean printed = false; 13384 13385 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13386 13387 if (mIntentSenderRecords.size() > 0) { 13388 Iterator<WeakReference<PendingIntentRecord>> it 13389 = mIntentSenderRecords.values().iterator(); 13390 while (it.hasNext()) { 13391 WeakReference<PendingIntentRecord> ref = it.next(); 13392 PendingIntentRecord rec = ref != null ? ref.get(): null; 13393 if (dumpPackage != null && (rec == null 13394 || !dumpPackage.equals(rec.key.packageName))) { 13395 continue; 13396 } 13397 printed = true; 13398 if (rec != null) { 13399 pw.print(" * "); pw.println(rec); 13400 if (dumpAll) { 13401 rec.dump(pw, " "); 13402 } 13403 } else { 13404 pw.print(" * "); pw.println(ref); 13405 } 13406 } 13407 } 13408 13409 if (!printed) { 13410 pw.println(" (nothing)"); 13411 } 13412 } 13413 13414 private static final int dumpProcessList(PrintWriter pw, 13415 ActivityManagerService service, List list, 13416 String prefix, String normalLabel, String persistentLabel, 13417 String dumpPackage) { 13418 int numPers = 0; 13419 final int N = list.size()-1; 13420 for (int i=N; i>=0; i--) { 13421 ProcessRecord r = (ProcessRecord)list.get(i); 13422 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13423 continue; 13424 } 13425 pw.println(String.format("%s%s #%2d: %s", 13426 prefix, (r.persistent ? persistentLabel : normalLabel), 13427 i, r.toString())); 13428 if (r.persistent) { 13429 numPers++; 13430 } 13431 } 13432 return numPers; 13433 } 13434 13435 private static final boolean dumpProcessOomList(PrintWriter pw, 13436 ActivityManagerService service, List<ProcessRecord> origList, 13437 String prefix, String normalLabel, String persistentLabel, 13438 boolean inclDetails, String dumpPackage) { 13439 13440 ArrayList<Pair<ProcessRecord, Integer>> list 13441 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13442 for (int i=0; i<origList.size(); i++) { 13443 ProcessRecord r = origList.get(i); 13444 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13445 continue; 13446 } 13447 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13448 } 13449 13450 if (list.size() <= 0) { 13451 return false; 13452 } 13453 13454 Comparator<Pair<ProcessRecord, Integer>> comparator 13455 = new Comparator<Pair<ProcessRecord, Integer>>() { 13456 @Override 13457 public int compare(Pair<ProcessRecord, Integer> object1, 13458 Pair<ProcessRecord, Integer> object2) { 13459 if (object1.first.setAdj != object2.first.setAdj) { 13460 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13461 } 13462 if (object1.second.intValue() != object2.second.intValue()) { 13463 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13464 } 13465 return 0; 13466 } 13467 }; 13468 13469 Collections.sort(list, comparator); 13470 13471 final long curRealtime = SystemClock.elapsedRealtime(); 13472 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13473 final long curUptime = SystemClock.uptimeMillis(); 13474 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13475 13476 for (int i=list.size()-1; i>=0; i--) { 13477 ProcessRecord r = list.get(i).first; 13478 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13479 char schedGroup; 13480 switch (r.setSchedGroup) { 13481 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13482 schedGroup = 'B'; 13483 break; 13484 case Process.THREAD_GROUP_DEFAULT: 13485 schedGroup = 'F'; 13486 break; 13487 default: 13488 schedGroup = '?'; 13489 break; 13490 } 13491 char foreground; 13492 if (r.foregroundActivities) { 13493 foreground = 'A'; 13494 } else if (r.foregroundServices) { 13495 foreground = 'S'; 13496 } else { 13497 foreground = ' '; 13498 } 13499 String procState = ProcessList.makeProcStateString(r.curProcState); 13500 pw.print(prefix); 13501 pw.print(r.persistent ? persistentLabel : normalLabel); 13502 pw.print(" #"); 13503 int num = (origList.size()-1)-list.get(i).second; 13504 if (num < 10) pw.print(' '); 13505 pw.print(num); 13506 pw.print(": "); 13507 pw.print(oomAdj); 13508 pw.print(' '); 13509 pw.print(schedGroup); 13510 pw.print('/'); 13511 pw.print(foreground); 13512 pw.print('/'); 13513 pw.print(procState); 13514 pw.print(" trm:"); 13515 if (r.trimMemoryLevel < 10) pw.print(' '); 13516 pw.print(r.trimMemoryLevel); 13517 pw.print(' '); 13518 pw.print(r.toShortString()); 13519 pw.print(" ("); 13520 pw.print(r.adjType); 13521 pw.println(')'); 13522 if (r.adjSource != null || r.adjTarget != null) { 13523 pw.print(prefix); 13524 pw.print(" "); 13525 if (r.adjTarget instanceof ComponentName) { 13526 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13527 } else if (r.adjTarget != null) { 13528 pw.print(r.adjTarget.toString()); 13529 } else { 13530 pw.print("{null}"); 13531 } 13532 pw.print("<="); 13533 if (r.adjSource instanceof ProcessRecord) { 13534 pw.print("Proc{"); 13535 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13536 pw.println("}"); 13537 } else if (r.adjSource != null) { 13538 pw.println(r.adjSource.toString()); 13539 } else { 13540 pw.println("{null}"); 13541 } 13542 } 13543 if (inclDetails) { 13544 pw.print(prefix); 13545 pw.print(" "); 13546 pw.print("oom: max="); pw.print(r.maxAdj); 13547 pw.print(" curRaw="); pw.print(r.curRawAdj); 13548 pw.print(" setRaw="); pw.print(r.setRawAdj); 13549 pw.print(" cur="); pw.print(r.curAdj); 13550 pw.print(" set="); pw.println(r.setAdj); 13551 pw.print(prefix); 13552 pw.print(" "); 13553 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13554 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13555 pw.print(" lastPss="); pw.print(r.lastPss); 13556 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13557 pw.print(prefix); 13558 pw.print(" "); 13559 pw.print("cached="); pw.print(r.cached); 13560 pw.print(" empty="); pw.print(r.empty); 13561 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13562 13563 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13564 if (r.lastWakeTime != 0) { 13565 long wtime; 13566 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13567 synchronized (stats) { 13568 wtime = stats.getProcessWakeTime(r.info.uid, 13569 r.pid, curRealtime); 13570 } 13571 long timeUsed = wtime - r.lastWakeTime; 13572 pw.print(prefix); 13573 pw.print(" "); 13574 pw.print("keep awake over "); 13575 TimeUtils.formatDuration(realtimeSince, pw); 13576 pw.print(" used "); 13577 TimeUtils.formatDuration(timeUsed, pw); 13578 pw.print(" ("); 13579 pw.print((timeUsed*100)/realtimeSince); 13580 pw.println("%)"); 13581 } 13582 if (r.lastCpuTime != 0) { 13583 long timeUsed = r.curCpuTime - r.lastCpuTime; 13584 pw.print(prefix); 13585 pw.print(" "); 13586 pw.print("run cpu over "); 13587 TimeUtils.formatDuration(uptimeSince, pw); 13588 pw.print(" used "); 13589 TimeUtils.formatDuration(timeUsed, pw); 13590 pw.print(" ("); 13591 pw.print((timeUsed*100)/uptimeSince); 13592 pw.println("%)"); 13593 } 13594 } 13595 } 13596 } 13597 return true; 13598 } 13599 13600 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13601 String[] args) { 13602 ArrayList<ProcessRecord> procs; 13603 synchronized (this) { 13604 if (args != null && args.length > start 13605 && args[start].charAt(0) != '-') { 13606 procs = new ArrayList<ProcessRecord>(); 13607 int pid = -1; 13608 try { 13609 pid = Integer.parseInt(args[start]); 13610 } catch (NumberFormatException e) { 13611 } 13612 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13613 ProcessRecord proc = mLruProcesses.get(i); 13614 if (proc.pid == pid) { 13615 procs.add(proc); 13616 } else if (allPkgs && proc.pkgList != null 13617 && proc.pkgList.containsKey(args[start])) { 13618 procs.add(proc); 13619 } else if (proc.processName.equals(args[start])) { 13620 procs.add(proc); 13621 } 13622 } 13623 if (procs.size() <= 0) { 13624 return null; 13625 } 13626 } else { 13627 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13628 } 13629 } 13630 return procs; 13631 } 13632 13633 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13634 PrintWriter pw, String[] args) { 13635 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13636 if (procs == null) { 13637 pw.println("No process found for: " + args[0]); 13638 return; 13639 } 13640 13641 long uptime = SystemClock.uptimeMillis(); 13642 long realtime = SystemClock.elapsedRealtime(); 13643 pw.println("Applications Graphics Acceleration Info:"); 13644 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13645 13646 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13647 ProcessRecord r = procs.get(i); 13648 if (r.thread != null) { 13649 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13650 pw.flush(); 13651 try { 13652 TransferPipe tp = new TransferPipe(); 13653 try { 13654 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13655 tp.go(fd); 13656 } finally { 13657 tp.kill(); 13658 } 13659 } catch (IOException e) { 13660 pw.println("Failure while dumping the app: " + r); 13661 pw.flush(); 13662 } catch (RemoteException e) { 13663 pw.println("Got a RemoteException while dumping the app " + r); 13664 pw.flush(); 13665 } 13666 } 13667 } 13668 } 13669 13670 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13671 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13672 if (procs == null) { 13673 pw.println("No process found for: " + args[0]); 13674 return; 13675 } 13676 13677 pw.println("Applications Database Info:"); 13678 13679 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13680 ProcessRecord r = procs.get(i); 13681 if (r.thread != null) { 13682 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13683 pw.flush(); 13684 try { 13685 TransferPipe tp = new TransferPipe(); 13686 try { 13687 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13688 tp.go(fd); 13689 } finally { 13690 tp.kill(); 13691 } 13692 } catch (IOException e) { 13693 pw.println("Failure while dumping the app: " + r); 13694 pw.flush(); 13695 } catch (RemoteException e) { 13696 pw.println("Got a RemoteException while dumping the app " + r); 13697 pw.flush(); 13698 } 13699 } 13700 } 13701 } 13702 13703 final static class MemItem { 13704 final boolean isProc; 13705 final String label; 13706 final String shortLabel; 13707 final long pss; 13708 final int id; 13709 final boolean hasActivities; 13710 ArrayList<MemItem> subitems; 13711 13712 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13713 boolean _hasActivities) { 13714 isProc = true; 13715 label = _label; 13716 shortLabel = _shortLabel; 13717 pss = _pss; 13718 id = _id; 13719 hasActivities = _hasActivities; 13720 } 13721 13722 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13723 isProc = false; 13724 label = _label; 13725 shortLabel = _shortLabel; 13726 pss = _pss; 13727 id = _id; 13728 hasActivities = false; 13729 } 13730 } 13731 13732 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13733 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13734 if (sort && !isCompact) { 13735 Collections.sort(items, new Comparator<MemItem>() { 13736 @Override 13737 public int compare(MemItem lhs, MemItem rhs) { 13738 if (lhs.pss < rhs.pss) { 13739 return 1; 13740 } else if (lhs.pss > rhs.pss) { 13741 return -1; 13742 } 13743 return 0; 13744 } 13745 }); 13746 } 13747 13748 for (int i=0; i<items.size(); i++) { 13749 MemItem mi = items.get(i); 13750 if (!isCompact) { 13751 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13752 } else if (mi.isProc) { 13753 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13754 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13755 pw.println(mi.hasActivities ? ",a" : ",e"); 13756 } else { 13757 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13758 pw.println(mi.pss); 13759 } 13760 if (mi.subitems != null) { 13761 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13762 true, isCompact); 13763 } 13764 } 13765 } 13766 13767 // These are in KB. 13768 static final long[] DUMP_MEM_BUCKETS = new long[] { 13769 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13770 120*1024, 160*1024, 200*1024, 13771 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13772 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13773 }; 13774 13775 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13776 boolean stackLike) { 13777 int start = label.lastIndexOf('.'); 13778 if (start >= 0) start++; 13779 else start = 0; 13780 int end = label.length(); 13781 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13782 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13783 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13784 out.append(bucket); 13785 out.append(stackLike ? "MB." : "MB "); 13786 out.append(label, start, end); 13787 return; 13788 } 13789 } 13790 out.append(memKB/1024); 13791 out.append(stackLike ? "MB." : "MB "); 13792 out.append(label, start, end); 13793 } 13794 13795 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13796 ProcessList.NATIVE_ADJ, 13797 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13798 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13799 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13800 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13801 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13802 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13803 }; 13804 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13805 "Native", 13806 "System", "Persistent", "Persistent Service", "Foreground", 13807 "Visible", "Perceptible", 13808 "Heavy Weight", "Backup", 13809 "A Services", "Home", 13810 "Previous", "B Services", "Cached" 13811 }; 13812 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13813 "native", 13814 "sys", "pers", "persvc", "fore", 13815 "vis", "percept", 13816 "heavy", "backup", 13817 "servicea", "home", 13818 "prev", "serviceb", "cached" 13819 }; 13820 13821 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13822 long realtime, boolean isCheckinRequest, boolean isCompact) { 13823 if (isCheckinRequest || isCompact) { 13824 // short checkin version 13825 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13826 } else { 13827 pw.println("Applications Memory Usage (kB):"); 13828 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13829 } 13830 } 13831 13832 private static final int KSM_SHARED = 0; 13833 private static final int KSM_SHARING = 1; 13834 private static final int KSM_UNSHARED = 2; 13835 private static final int KSM_VOLATILE = 3; 13836 13837 private final long[] getKsmInfo() { 13838 long[] longOut = new long[4]; 13839 final int[] SINGLE_LONG_FORMAT = new int[] { 13840 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13841 }; 13842 long[] longTmp = new long[1]; 13843 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13844 SINGLE_LONG_FORMAT, null, longTmp, null); 13845 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13846 longTmp[0] = 0; 13847 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13848 SINGLE_LONG_FORMAT, null, longTmp, null); 13849 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13850 longTmp[0] = 0; 13851 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13852 SINGLE_LONG_FORMAT, null, longTmp, null); 13853 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13854 longTmp[0] = 0; 13855 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13856 SINGLE_LONG_FORMAT, null, longTmp, null); 13857 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13858 return longOut; 13859 } 13860 13861 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13862 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13863 boolean dumpDetails = false; 13864 boolean dumpFullDetails = false; 13865 boolean dumpDalvik = false; 13866 boolean oomOnly = false; 13867 boolean isCompact = false; 13868 boolean localOnly = false; 13869 boolean packages = false; 13870 13871 int opti = 0; 13872 while (opti < args.length) { 13873 String opt = args[opti]; 13874 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13875 break; 13876 } 13877 opti++; 13878 if ("-a".equals(opt)) { 13879 dumpDetails = true; 13880 dumpFullDetails = true; 13881 dumpDalvik = true; 13882 } else if ("-d".equals(opt)) { 13883 dumpDalvik = true; 13884 } else if ("-c".equals(opt)) { 13885 isCompact = true; 13886 } else if ("--oom".equals(opt)) { 13887 oomOnly = true; 13888 } else if ("--local".equals(opt)) { 13889 localOnly = true; 13890 } else if ("--package".equals(opt)) { 13891 packages = true; 13892 } else if ("-h".equals(opt)) { 13893 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13894 pw.println(" -a: include all available information for each process."); 13895 pw.println(" -d: include dalvik details when dumping process details."); 13896 pw.println(" -c: dump in a compact machine-parseable representation."); 13897 pw.println(" --oom: only show processes organized by oom adj."); 13898 pw.println(" --local: only collect details locally, don't call process."); 13899 pw.println(" --package: interpret process arg as package, dumping all"); 13900 pw.println(" processes that have loaded that package."); 13901 pw.println("If [process] is specified it can be the name or "); 13902 pw.println("pid of a specific process to dump."); 13903 return; 13904 } else { 13905 pw.println("Unknown argument: " + opt + "; use -h for help"); 13906 } 13907 } 13908 13909 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13910 long uptime = SystemClock.uptimeMillis(); 13911 long realtime = SystemClock.elapsedRealtime(); 13912 final long[] tmpLong = new long[1]; 13913 13914 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13915 if (procs == null) { 13916 // No Java processes. Maybe they want to print a native process. 13917 if (args != null && args.length > opti 13918 && args[opti].charAt(0) != '-') { 13919 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13920 = new ArrayList<ProcessCpuTracker.Stats>(); 13921 updateCpuStatsNow(); 13922 int findPid = -1; 13923 try { 13924 findPid = Integer.parseInt(args[opti]); 13925 } catch (NumberFormatException e) { 13926 } 13927 synchronized (mProcessCpuTracker) { 13928 final int N = mProcessCpuTracker.countStats(); 13929 for (int i=0; i<N; i++) { 13930 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13931 if (st.pid == findPid || (st.baseName != null 13932 && st.baseName.equals(args[opti]))) { 13933 nativeProcs.add(st); 13934 } 13935 } 13936 } 13937 if (nativeProcs.size() > 0) { 13938 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13939 isCompact); 13940 Debug.MemoryInfo mi = null; 13941 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13942 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13943 final int pid = r.pid; 13944 if (!isCheckinRequest && dumpDetails) { 13945 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13946 } 13947 if (mi == null) { 13948 mi = new Debug.MemoryInfo(); 13949 } 13950 if (dumpDetails || (!brief && !oomOnly)) { 13951 Debug.getMemoryInfo(pid, mi); 13952 } else { 13953 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13954 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13955 } 13956 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13957 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13958 if (isCheckinRequest) { 13959 pw.println(); 13960 } 13961 } 13962 return; 13963 } 13964 } 13965 pw.println("No process found for: " + args[opti]); 13966 return; 13967 } 13968 13969 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13970 dumpDetails = true; 13971 } 13972 13973 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13974 13975 String[] innerArgs = new String[args.length-opti]; 13976 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13977 13978 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13979 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13980 long nativePss = 0; 13981 long dalvikPss = 0; 13982 long otherPss = 0; 13983 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13984 13985 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13986 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13987 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13988 13989 long totalPss = 0; 13990 long cachedPss = 0; 13991 13992 Debug.MemoryInfo mi = null; 13993 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13994 final ProcessRecord r = procs.get(i); 13995 final IApplicationThread thread; 13996 final int pid; 13997 final int oomAdj; 13998 final boolean hasActivities; 13999 synchronized (this) { 14000 thread = r.thread; 14001 pid = r.pid; 14002 oomAdj = r.getSetAdjWithServices(); 14003 hasActivities = r.activities.size() > 0; 14004 } 14005 if (thread != null) { 14006 if (!isCheckinRequest && dumpDetails) { 14007 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14008 } 14009 if (mi == null) { 14010 mi = new Debug.MemoryInfo(); 14011 } 14012 if (dumpDetails || (!brief && !oomOnly)) { 14013 Debug.getMemoryInfo(pid, mi); 14014 } else { 14015 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14016 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14017 } 14018 if (dumpDetails) { 14019 if (localOnly) { 14020 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14021 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14022 if (isCheckinRequest) { 14023 pw.println(); 14024 } 14025 } else { 14026 try { 14027 pw.flush(); 14028 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14029 dumpDalvik, innerArgs); 14030 } catch (RemoteException e) { 14031 if (!isCheckinRequest) { 14032 pw.println("Got RemoteException!"); 14033 pw.flush(); 14034 } 14035 } 14036 } 14037 } 14038 14039 final long myTotalPss = mi.getTotalPss(); 14040 final long myTotalUss = mi.getTotalUss(); 14041 14042 synchronized (this) { 14043 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14044 // Record this for posterity if the process has been stable. 14045 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14046 } 14047 } 14048 14049 if (!isCheckinRequest && mi != null) { 14050 totalPss += myTotalPss; 14051 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14052 (hasActivities ? " / activities)" : ")"), 14053 r.processName, myTotalPss, pid, hasActivities); 14054 procMems.add(pssItem); 14055 procMemsMap.put(pid, pssItem); 14056 14057 nativePss += mi.nativePss; 14058 dalvikPss += mi.dalvikPss; 14059 otherPss += mi.otherPss; 14060 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14061 long mem = mi.getOtherPss(j); 14062 miscPss[j] += mem; 14063 otherPss -= mem; 14064 } 14065 14066 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14067 cachedPss += myTotalPss; 14068 } 14069 14070 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14071 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14072 || oomIndex == (oomPss.length-1)) { 14073 oomPss[oomIndex] += myTotalPss; 14074 if (oomProcs[oomIndex] == null) { 14075 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14076 } 14077 oomProcs[oomIndex].add(pssItem); 14078 break; 14079 } 14080 } 14081 } 14082 } 14083 } 14084 14085 long nativeProcTotalPss = 0; 14086 14087 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14088 // If we are showing aggregations, also look for native processes to 14089 // include so that our aggregations are more accurate. 14090 updateCpuStatsNow(); 14091 synchronized (mProcessCpuTracker) { 14092 final int N = mProcessCpuTracker.countStats(); 14093 for (int i=0; i<N; i++) { 14094 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14095 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14096 if (mi == null) { 14097 mi = new Debug.MemoryInfo(); 14098 } 14099 if (!brief && !oomOnly) { 14100 Debug.getMemoryInfo(st.pid, mi); 14101 } else { 14102 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14103 mi.nativePrivateDirty = (int)tmpLong[0]; 14104 } 14105 14106 final long myTotalPss = mi.getTotalPss(); 14107 totalPss += myTotalPss; 14108 nativeProcTotalPss += myTotalPss; 14109 14110 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14111 st.name, myTotalPss, st.pid, false); 14112 procMems.add(pssItem); 14113 14114 nativePss += mi.nativePss; 14115 dalvikPss += mi.dalvikPss; 14116 otherPss += mi.otherPss; 14117 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14118 long mem = mi.getOtherPss(j); 14119 miscPss[j] += mem; 14120 otherPss -= mem; 14121 } 14122 oomPss[0] += myTotalPss; 14123 if (oomProcs[0] == null) { 14124 oomProcs[0] = new ArrayList<MemItem>(); 14125 } 14126 oomProcs[0].add(pssItem); 14127 } 14128 } 14129 } 14130 14131 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14132 14133 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14134 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14135 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14136 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14137 String label = Debug.MemoryInfo.getOtherLabel(j); 14138 catMems.add(new MemItem(label, label, miscPss[j], j)); 14139 } 14140 14141 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14142 for (int j=0; j<oomPss.length; j++) { 14143 if (oomPss[j] != 0) { 14144 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14145 : DUMP_MEM_OOM_LABEL[j]; 14146 MemItem item = new MemItem(label, label, oomPss[j], 14147 DUMP_MEM_OOM_ADJ[j]); 14148 item.subitems = oomProcs[j]; 14149 oomMems.add(item); 14150 } 14151 } 14152 14153 if (!brief && !oomOnly && !isCompact) { 14154 pw.println(); 14155 pw.println("Total PSS by process:"); 14156 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14157 pw.println(); 14158 } 14159 if (!isCompact) { 14160 pw.println("Total PSS by OOM adjustment:"); 14161 } 14162 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14163 if (!brief && !oomOnly) { 14164 PrintWriter out = categoryPw != null ? categoryPw : pw; 14165 if (!isCompact) { 14166 out.println(); 14167 out.println("Total PSS by category:"); 14168 } 14169 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14170 } 14171 if (!isCompact) { 14172 pw.println(); 14173 } 14174 MemInfoReader memInfo = new MemInfoReader(); 14175 memInfo.readMemInfo(); 14176 if (nativeProcTotalPss > 0) { 14177 synchronized (this) { 14178 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14179 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14180 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14181 } 14182 } 14183 if (!brief) { 14184 if (!isCompact) { 14185 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14186 pw.print(" kB (status "); 14187 switch (mLastMemoryLevel) { 14188 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14189 pw.println("normal)"); 14190 break; 14191 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14192 pw.println("moderate)"); 14193 break; 14194 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14195 pw.println("low)"); 14196 break; 14197 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14198 pw.println("critical)"); 14199 break; 14200 default: 14201 pw.print(mLastMemoryLevel); 14202 pw.println(")"); 14203 break; 14204 } 14205 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14206 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14207 pw.print(cachedPss); pw.print(" cached pss + "); 14208 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14209 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14210 } else { 14211 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14212 pw.print(cachedPss + memInfo.getCachedSizeKb() 14213 + memInfo.getFreeSizeKb()); pw.print(","); 14214 pw.println(totalPss - cachedPss); 14215 } 14216 } 14217 if (!isCompact) { 14218 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14219 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14220 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14221 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14222 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14223 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14224 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14225 } 14226 if (!brief) { 14227 if (memInfo.getZramTotalSizeKb() != 0) { 14228 if (!isCompact) { 14229 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14230 pw.print(" kB physical used for "); 14231 pw.print(memInfo.getSwapTotalSizeKb() 14232 - memInfo.getSwapFreeSizeKb()); 14233 pw.print(" kB in swap ("); 14234 pw.print(memInfo.getSwapTotalSizeKb()); 14235 pw.println(" kB total swap)"); 14236 } else { 14237 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14238 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14239 pw.println(memInfo.getSwapFreeSizeKb()); 14240 } 14241 } 14242 final long[] ksm = getKsmInfo(); 14243 if (!isCompact) { 14244 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14245 || ksm[KSM_VOLATILE] != 0) { 14246 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14247 pw.print(" kB saved from shared "); 14248 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14249 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14250 pw.print(" kB unshared; "); 14251 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14252 } 14253 pw.print(" Tuning: "); 14254 pw.print(ActivityManager.staticGetMemoryClass()); 14255 pw.print(" (large "); 14256 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14257 pw.print("), oom "); 14258 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14259 pw.print(" kB"); 14260 pw.print(", restore limit "); 14261 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14262 pw.print(" kB"); 14263 if (ActivityManager.isLowRamDeviceStatic()) { 14264 pw.print(" (low-ram)"); 14265 } 14266 if (ActivityManager.isHighEndGfx()) { 14267 pw.print(" (high-end-gfx)"); 14268 } 14269 pw.println(); 14270 } else { 14271 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14272 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14273 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14274 pw.print("tuning,"); 14275 pw.print(ActivityManager.staticGetMemoryClass()); 14276 pw.print(','); 14277 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14278 pw.print(','); 14279 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14280 if (ActivityManager.isLowRamDeviceStatic()) { 14281 pw.print(",low-ram"); 14282 } 14283 if (ActivityManager.isHighEndGfx()) { 14284 pw.print(",high-end-gfx"); 14285 } 14286 pw.println(); 14287 } 14288 } 14289 } 14290 } 14291 14292 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14293 String name) { 14294 sb.append(" "); 14295 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14296 sb.append(' '); 14297 sb.append(ProcessList.makeProcStateString(procState)); 14298 sb.append(' '); 14299 ProcessList.appendRamKb(sb, pss); 14300 sb.append(" kB: "); 14301 sb.append(name); 14302 } 14303 14304 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14305 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14306 sb.append(" ("); 14307 sb.append(mi.pid); 14308 sb.append(") "); 14309 sb.append(mi.adjType); 14310 sb.append('\n'); 14311 if (mi.adjReason != null) { 14312 sb.append(" "); 14313 sb.append(mi.adjReason); 14314 sb.append('\n'); 14315 } 14316 } 14317 14318 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14319 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14320 for (int i=0, N=memInfos.size(); i<N; i++) { 14321 ProcessMemInfo mi = memInfos.get(i); 14322 infoMap.put(mi.pid, mi); 14323 } 14324 updateCpuStatsNow(); 14325 synchronized (mProcessCpuTracker) { 14326 final int N = mProcessCpuTracker.countStats(); 14327 for (int i=0; i<N; i++) { 14328 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14329 if (st.vsize > 0) { 14330 long pss = Debug.getPss(st.pid, null); 14331 if (pss > 0) { 14332 if (infoMap.indexOfKey(st.pid) < 0) { 14333 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14334 ProcessList.NATIVE_ADJ, -1, "native", null); 14335 mi.pss = pss; 14336 memInfos.add(mi); 14337 } 14338 } 14339 } 14340 } 14341 } 14342 14343 long totalPss = 0; 14344 for (int i=0, N=memInfos.size(); i<N; i++) { 14345 ProcessMemInfo mi = memInfos.get(i); 14346 if (mi.pss == 0) { 14347 mi.pss = Debug.getPss(mi.pid, null); 14348 } 14349 totalPss += mi.pss; 14350 } 14351 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14352 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14353 if (lhs.oomAdj != rhs.oomAdj) { 14354 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14355 } 14356 if (lhs.pss != rhs.pss) { 14357 return lhs.pss < rhs.pss ? 1 : -1; 14358 } 14359 return 0; 14360 } 14361 }); 14362 14363 StringBuilder tag = new StringBuilder(128); 14364 StringBuilder stack = new StringBuilder(128); 14365 tag.append("Low on memory -- "); 14366 appendMemBucket(tag, totalPss, "total", false); 14367 appendMemBucket(stack, totalPss, "total", true); 14368 14369 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14370 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14371 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14372 14373 boolean firstLine = true; 14374 int lastOomAdj = Integer.MIN_VALUE; 14375 long extraNativeRam = 0; 14376 long cachedPss = 0; 14377 for (int i=0, N=memInfos.size(); i<N; i++) { 14378 ProcessMemInfo mi = memInfos.get(i); 14379 14380 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14381 cachedPss += mi.pss; 14382 } 14383 14384 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14385 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14386 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14387 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14388 if (lastOomAdj != mi.oomAdj) { 14389 lastOomAdj = mi.oomAdj; 14390 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14391 tag.append(" / "); 14392 } 14393 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14394 if (firstLine) { 14395 stack.append(":"); 14396 firstLine = false; 14397 } 14398 stack.append("\n\t at "); 14399 } else { 14400 stack.append("$"); 14401 } 14402 } else { 14403 tag.append(" "); 14404 stack.append("$"); 14405 } 14406 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14407 appendMemBucket(tag, mi.pss, mi.name, false); 14408 } 14409 appendMemBucket(stack, mi.pss, mi.name, true); 14410 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14411 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14412 stack.append("("); 14413 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14414 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14415 stack.append(DUMP_MEM_OOM_LABEL[k]); 14416 stack.append(":"); 14417 stack.append(DUMP_MEM_OOM_ADJ[k]); 14418 } 14419 } 14420 stack.append(")"); 14421 } 14422 } 14423 14424 appendMemInfo(fullNativeBuilder, mi); 14425 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14426 // The short form only has native processes that are >= 1MB. 14427 if (mi.pss >= 1000) { 14428 appendMemInfo(shortNativeBuilder, mi); 14429 } else { 14430 extraNativeRam += mi.pss; 14431 } 14432 } else { 14433 // Short form has all other details, but if we have collected RAM 14434 // from smaller native processes let's dump a summary of that. 14435 if (extraNativeRam > 0) { 14436 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14437 -1, extraNativeRam, "(Other native)"); 14438 shortNativeBuilder.append('\n'); 14439 extraNativeRam = 0; 14440 } 14441 appendMemInfo(fullJavaBuilder, mi); 14442 } 14443 } 14444 14445 fullJavaBuilder.append(" "); 14446 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14447 fullJavaBuilder.append(" kB: TOTAL\n"); 14448 14449 MemInfoReader memInfo = new MemInfoReader(); 14450 memInfo.readMemInfo(); 14451 final long[] infos = memInfo.getRawInfo(); 14452 14453 StringBuilder memInfoBuilder = new StringBuilder(1024); 14454 Debug.getMemInfo(infos); 14455 memInfoBuilder.append(" MemInfo: "); 14456 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14457 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14458 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14459 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14460 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14461 memInfoBuilder.append(" "); 14462 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14463 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14464 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14465 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14466 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14467 memInfoBuilder.append(" ZRAM: "); 14468 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14469 memInfoBuilder.append(" kB RAM, "); 14470 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14471 memInfoBuilder.append(" kB swap total, "); 14472 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14473 memInfoBuilder.append(" kB swap free\n"); 14474 } 14475 final long[] ksm = getKsmInfo(); 14476 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14477 || ksm[KSM_VOLATILE] != 0) { 14478 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14479 memInfoBuilder.append(" kB saved from shared "); 14480 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14481 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14482 memInfoBuilder.append(" kB unshared; "); 14483 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14484 } 14485 memInfoBuilder.append(" Free RAM: "); 14486 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14487 + memInfo.getFreeSizeKb()); 14488 memInfoBuilder.append(" kB\n"); 14489 memInfoBuilder.append(" Used RAM: "); 14490 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14491 memInfoBuilder.append(" kB\n"); 14492 memInfoBuilder.append(" Lost RAM: "); 14493 memInfoBuilder.append(memInfo.getTotalSizeKb() 14494 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14495 - memInfo.getKernelUsedSizeKb()); 14496 memInfoBuilder.append(" kB\n"); 14497 Slog.i(TAG, "Low on memory:"); 14498 Slog.i(TAG, shortNativeBuilder.toString()); 14499 Slog.i(TAG, fullJavaBuilder.toString()); 14500 Slog.i(TAG, memInfoBuilder.toString()); 14501 14502 StringBuilder dropBuilder = new StringBuilder(1024); 14503 /* 14504 StringWriter oomSw = new StringWriter(); 14505 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14506 StringWriter catSw = new StringWriter(); 14507 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14508 String[] emptyArgs = new String[] { }; 14509 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14510 oomPw.flush(); 14511 String oomString = oomSw.toString(); 14512 */ 14513 dropBuilder.append("Low on memory:"); 14514 dropBuilder.append(stack); 14515 dropBuilder.append('\n'); 14516 dropBuilder.append(fullNativeBuilder); 14517 dropBuilder.append(fullJavaBuilder); 14518 dropBuilder.append('\n'); 14519 dropBuilder.append(memInfoBuilder); 14520 dropBuilder.append('\n'); 14521 /* 14522 dropBuilder.append(oomString); 14523 dropBuilder.append('\n'); 14524 */ 14525 StringWriter catSw = new StringWriter(); 14526 synchronized (ActivityManagerService.this) { 14527 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14528 String[] emptyArgs = new String[] { }; 14529 catPw.println(); 14530 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14531 catPw.println(); 14532 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14533 false, false, null); 14534 catPw.println(); 14535 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14536 catPw.flush(); 14537 } 14538 dropBuilder.append(catSw.toString()); 14539 addErrorToDropBox("lowmem", null, "system_server", null, 14540 null, tag.toString(), dropBuilder.toString(), null, null); 14541 //Slog.i(TAG, "Sent to dropbox:"); 14542 //Slog.i(TAG, dropBuilder.toString()); 14543 synchronized (ActivityManagerService.this) { 14544 long now = SystemClock.uptimeMillis(); 14545 if (mLastMemUsageReportTime < now) { 14546 mLastMemUsageReportTime = now; 14547 } 14548 } 14549 } 14550 14551 /** 14552 * Searches array of arguments for the specified string 14553 * @param args array of argument strings 14554 * @param value value to search for 14555 * @return true if the value is contained in the array 14556 */ 14557 private static boolean scanArgs(String[] args, String value) { 14558 if (args != null) { 14559 for (String arg : args) { 14560 if (value.equals(arg)) { 14561 return true; 14562 } 14563 } 14564 } 14565 return false; 14566 } 14567 14568 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14569 ContentProviderRecord cpr, boolean always) { 14570 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14571 14572 if (!inLaunching || always) { 14573 synchronized (cpr) { 14574 cpr.launchingApp = null; 14575 cpr.notifyAll(); 14576 } 14577 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14578 String names[] = cpr.info.authority.split(";"); 14579 for (int j = 0; j < names.length; j++) { 14580 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14581 } 14582 } 14583 14584 for (int i=0; i<cpr.connections.size(); i++) { 14585 ContentProviderConnection conn = cpr.connections.get(i); 14586 if (conn.waiting) { 14587 // If this connection is waiting for the provider, then we don't 14588 // need to mess with its process unless we are always removing 14589 // or for some reason the provider is not currently launching. 14590 if (inLaunching && !always) { 14591 continue; 14592 } 14593 } 14594 ProcessRecord capp = conn.client; 14595 conn.dead = true; 14596 if (conn.stableCount > 0) { 14597 if (!capp.persistent && capp.thread != null 14598 && capp.pid != 0 14599 && capp.pid != MY_PID) { 14600 capp.kill("depends on provider " 14601 + cpr.name.flattenToShortString() 14602 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14603 } 14604 } else if (capp.thread != null && conn.provider.provider != null) { 14605 try { 14606 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14607 } catch (RemoteException e) { 14608 } 14609 // In the protocol here, we don't expect the client to correctly 14610 // clean up this connection, we'll just remove it. 14611 cpr.connections.remove(i); 14612 conn.client.conProviders.remove(conn); 14613 } 14614 } 14615 14616 if (inLaunching && always) { 14617 mLaunchingProviders.remove(cpr); 14618 } 14619 return inLaunching; 14620 } 14621 14622 /** 14623 * Main code for cleaning up a process when it has gone away. This is 14624 * called both as a result of the process dying, or directly when stopping 14625 * a process when running in single process mode. 14626 * 14627 * @return Returns true if the given process has been restarted, so the 14628 * app that was passed in must remain on the process lists. 14629 */ 14630 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14631 boolean restarting, boolean allowRestart, int index) { 14632 if (index >= 0) { 14633 removeLruProcessLocked(app); 14634 ProcessList.remove(app.pid); 14635 } 14636 14637 mProcessesToGc.remove(app); 14638 mPendingPssProcesses.remove(app); 14639 14640 // Dismiss any open dialogs. 14641 if (app.crashDialog != null && !app.forceCrashReport) { 14642 app.crashDialog.dismiss(); 14643 app.crashDialog = null; 14644 } 14645 if (app.anrDialog != null) { 14646 app.anrDialog.dismiss(); 14647 app.anrDialog = null; 14648 } 14649 if (app.waitDialog != null) { 14650 app.waitDialog.dismiss(); 14651 app.waitDialog = null; 14652 } 14653 14654 app.crashing = false; 14655 app.notResponding = false; 14656 14657 app.resetPackageList(mProcessStats); 14658 app.unlinkDeathRecipient(); 14659 app.makeInactive(mProcessStats); 14660 app.waitingToKill = null; 14661 app.forcingToForeground = null; 14662 updateProcessForegroundLocked(app, false, false); 14663 app.foregroundActivities = false; 14664 app.hasShownUi = false; 14665 app.treatLikeActivity = false; 14666 app.hasAboveClient = false; 14667 app.hasClientActivities = false; 14668 14669 mServices.killServicesLocked(app, allowRestart); 14670 14671 boolean restart = false; 14672 14673 // Remove published content providers. 14674 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14675 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14676 final boolean always = app.bad || !allowRestart; 14677 if (removeDyingProviderLocked(app, cpr, always) || always) { 14678 // We left the provider in the launching list, need to 14679 // restart it. 14680 restart = true; 14681 } 14682 14683 cpr.provider = null; 14684 cpr.proc = null; 14685 } 14686 app.pubProviders.clear(); 14687 14688 // Take care of any launching providers waiting for this process. 14689 if (checkAppInLaunchingProvidersLocked(app, false)) { 14690 restart = true; 14691 } 14692 14693 // Unregister from connected content providers. 14694 if (!app.conProviders.isEmpty()) { 14695 for (int i=0; i<app.conProviders.size(); i++) { 14696 ContentProviderConnection conn = app.conProviders.get(i); 14697 conn.provider.connections.remove(conn); 14698 } 14699 app.conProviders.clear(); 14700 } 14701 14702 // At this point there may be remaining entries in mLaunchingProviders 14703 // where we were the only one waiting, so they are no longer of use. 14704 // Look for these and clean up if found. 14705 // XXX Commented out for now. Trying to figure out a way to reproduce 14706 // the actual situation to identify what is actually going on. 14707 if (false) { 14708 for (int i=0; i<mLaunchingProviders.size(); i++) { 14709 ContentProviderRecord cpr = (ContentProviderRecord) 14710 mLaunchingProviders.get(i); 14711 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14712 synchronized (cpr) { 14713 cpr.launchingApp = null; 14714 cpr.notifyAll(); 14715 } 14716 } 14717 } 14718 } 14719 14720 skipCurrentReceiverLocked(app); 14721 14722 // Unregister any receivers. 14723 for (int i=app.receivers.size()-1; i>=0; i--) { 14724 removeReceiverLocked(app.receivers.valueAt(i)); 14725 } 14726 app.receivers.clear(); 14727 14728 // If the app is undergoing backup, tell the backup manager about it 14729 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14730 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14731 + mBackupTarget.appInfo + " died during backup"); 14732 try { 14733 IBackupManager bm = IBackupManager.Stub.asInterface( 14734 ServiceManager.getService(Context.BACKUP_SERVICE)); 14735 bm.agentDisconnected(app.info.packageName); 14736 } catch (RemoteException e) { 14737 // can't happen; backup manager is local 14738 } 14739 } 14740 14741 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14742 ProcessChangeItem item = mPendingProcessChanges.get(i); 14743 if (item.pid == app.pid) { 14744 mPendingProcessChanges.remove(i); 14745 mAvailProcessChanges.add(item); 14746 } 14747 } 14748 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14749 14750 // If the caller is restarting this app, then leave it in its 14751 // current lists and let the caller take care of it. 14752 if (restarting) { 14753 return false; 14754 } 14755 14756 if (!app.persistent || app.isolated) { 14757 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14758 "Removing non-persistent process during cleanup: " + app); 14759 mProcessNames.remove(app.processName, app.uid); 14760 mIsolatedProcesses.remove(app.uid); 14761 if (mHeavyWeightProcess == app) { 14762 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14763 mHeavyWeightProcess.userId, 0)); 14764 mHeavyWeightProcess = null; 14765 } 14766 } else if (!app.removed) { 14767 // This app is persistent, so we need to keep its record around. 14768 // If it is not already on the pending app list, add it there 14769 // and start a new process for it. 14770 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14771 mPersistentStartingProcesses.add(app); 14772 restart = true; 14773 } 14774 } 14775 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14776 "Clean-up removing on hold: " + app); 14777 mProcessesOnHold.remove(app); 14778 14779 if (app == mHomeProcess) { 14780 mHomeProcess = null; 14781 } 14782 if (app == mPreviousProcess) { 14783 mPreviousProcess = null; 14784 } 14785 14786 if (restart && !app.isolated) { 14787 // We have components that still need to be running in the 14788 // process, so re-launch it. 14789 if (index < 0) { 14790 ProcessList.remove(app.pid); 14791 } 14792 mProcessNames.put(app.processName, app.uid, app); 14793 startProcessLocked(app, "restart", app.processName); 14794 return true; 14795 } else if (app.pid > 0 && app.pid != MY_PID) { 14796 // Goodbye! 14797 boolean removed; 14798 synchronized (mPidsSelfLocked) { 14799 mPidsSelfLocked.remove(app.pid); 14800 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14801 } 14802 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14803 if (app.isolated) { 14804 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14805 } 14806 app.setPid(0); 14807 } 14808 return false; 14809 } 14810 14811 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14812 // Look through the content providers we are waiting to have launched, 14813 // and if any run in this process then either schedule a restart of 14814 // the process or kill the client waiting for it if this process has 14815 // gone bad. 14816 int NL = mLaunchingProviders.size(); 14817 boolean restart = false; 14818 for (int i=0; i<NL; i++) { 14819 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14820 if (cpr.launchingApp == app) { 14821 if (!alwaysBad && !app.bad) { 14822 restart = true; 14823 } else { 14824 removeDyingProviderLocked(app, cpr, true); 14825 // cpr should have been removed from mLaunchingProviders 14826 NL = mLaunchingProviders.size(); 14827 i--; 14828 } 14829 } 14830 } 14831 return restart; 14832 } 14833 14834 // ========================================================= 14835 // SERVICES 14836 // ========================================================= 14837 14838 @Override 14839 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14840 int flags) { 14841 enforceNotIsolatedCaller("getServices"); 14842 synchronized (this) { 14843 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14844 } 14845 } 14846 14847 @Override 14848 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14849 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14850 synchronized (this) { 14851 return mServices.getRunningServiceControlPanelLocked(name); 14852 } 14853 } 14854 14855 @Override 14856 public ComponentName startService(IApplicationThread caller, Intent service, 14857 String resolvedType, int userId) { 14858 enforceNotIsolatedCaller("startService"); 14859 // Refuse possible leaked file descriptors 14860 if (service != null && service.hasFileDescriptors() == true) { 14861 throw new IllegalArgumentException("File descriptors passed in Intent"); 14862 } 14863 14864 if (DEBUG_SERVICE) 14865 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14866 synchronized(this) { 14867 final int callingPid = Binder.getCallingPid(); 14868 final int callingUid = Binder.getCallingUid(); 14869 final long origId = Binder.clearCallingIdentity(); 14870 ComponentName res = mServices.startServiceLocked(caller, service, 14871 resolvedType, callingPid, callingUid, userId); 14872 Binder.restoreCallingIdentity(origId); 14873 return res; 14874 } 14875 } 14876 14877 ComponentName startServiceInPackage(int uid, 14878 Intent service, String resolvedType, int userId) { 14879 synchronized(this) { 14880 if (DEBUG_SERVICE) 14881 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14882 final long origId = Binder.clearCallingIdentity(); 14883 ComponentName res = mServices.startServiceLocked(null, service, 14884 resolvedType, -1, uid, userId); 14885 Binder.restoreCallingIdentity(origId); 14886 return res; 14887 } 14888 } 14889 14890 @Override 14891 public int stopService(IApplicationThread caller, Intent service, 14892 String resolvedType, int userId) { 14893 enforceNotIsolatedCaller("stopService"); 14894 // Refuse possible leaked file descriptors 14895 if (service != null && service.hasFileDescriptors() == true) { 14896 throw new IllegalArgumentException("File descriptors passed in Intent"); 14897 } 14898 14899 synchronized(this) { 14900 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14901 } 14902 } 14903 14904 @Override 14905 public IBinder peekService(Intent service, String resolvedType) { 14906 enforceNotIsolatedCaller("peekService"); 14907 // Refuse possible leaked file descriptors 14908 if (service != null && service.hasFileDescriptors() == true) { 14909 throw new IllegalArgumentException("File descriptors passed in Intent"); 14910 } 14911 synchronized(this) { 14912 return mServices.peekServiceLocked(service, resolvedType); 14913 } 14914 } 14915 14916 @Override 14917 public boolean stopServiceToken(ComponentName className, IBinder token, 14918 int startId) { 14919 synchronized(this) { 14920 return mServices.stopServiceTokenLocked(className, token, startId); 14921 } 14922 } 14923 14924 @Override 14925 public void setServiceForeground(ComponentName className, IBinder token, 14926 int id, Notification notification, boolean removeNotification) { 14927 synchronized(this) { 14928 mServices.setServiceForegroundLocked(className, token, id, notification, 14929 removeNotification); 14930 } 14931 } 14932 14933 @Override 14934 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14935 boolean requireFull, String name, String callerPackage) { 14936 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14937 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14938 } 14939 14940 int unsafeConvertIncomingUser(int userId) { 14941 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14942 ? mCurrentUserId : userId; 14943 } 14944 14945 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14946 int allowMode, String name, String callerPackage) { 14947 final int callingUserId = UserHandle.getUserId(callingUid); 14948 if (callingUserId == userId) { 14949 return userId; 14950 } 14951 14952 // Note that we may be accessing mCurrentUserId outside of a lock... 14953 // shouldn't be a big deal, if this is being called outside 14954 // of a locked context there is intrinsically a race with 14955 // the value the caller will receive and someone else changing it. 14956 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14957 // we will switch to the calling user if access to the current user fails. 14958 int targetUserId = unsafeConvertIncomingUser(userId); 14959 14960 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14961 final boolean allow; 14962 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14963 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14964 // If the caller has this permission, they always pass go. And collect $200. 14965 allow = true; 14966 } else if (allowMode == ALLOW_FULL_ONLY) { 14967 // We require full access, sucks to be you. 14968 allow = false; 14969 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14970 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14971 // If the caller does not have either permission, they are always doomed. 14972 allow = false; 14973 } else if (allowMode == ALLOW_NON_FULL) { 14974 // We are blanket allowing non-full access, you lucky caller! 14975 allow = true; 14976 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14977 // We may or may not allow this depending on whether the two users are 14978 // in the same profile. 14979 synchronized (mUserProfileGroupIdsSelfLocked) { 14980 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14981 UserInfo.NO_PROFILE_GROUP_ID); 14982 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14983 UserInfo.NO_PROFILE_GROUP_ID); 14984 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14985 && callingProfile == targetProfile; 14986 } 14987 } else { 14988 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14989 } 14990 if (!allow) { 14991 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14992 // In this case, they would like to just execute as their 14993 // owner user instead of failing. 14994 targetUserId = callingUserId; 14995 } else { 14996 StringBuilder builder = new StringBuilder(128); 14997 builder.append("Permission Denial: "); 14998 builder.append(name); 14999 if (callerPackage != null) { 15000 builder.append(" from "); 15001 builder.append(callerPackage); 15002 } 15003 builder.append(" asks to run as user "); 15004 builder.append(userId); 15005 builder.append(" but is calling from user "); 15006 builder.append(UserHandle.getUserId(callingUid)); 15007 builder.append("; this requires "); 15008 builder.append(INTERACT_ACROSS_USERS_FULL); 15009 if (allowMode != ALLOW_FULL_ONLY) { 15010 builder.append(" or "); 15011 builder.append(INTERACT_ACROSS_USERS); 15012 } 15013 String msg = builder.toString(); 15014 Slog.w(TAG, msg); 15015 throw new SecurityException(msg); 15016 } 15017 } 15018 } 15019 if (!allowAll && targetUserId < 0) { 15020 throw new IllegalArgumentException( 15021 "Call does not support special user #" + targetUserId); 15022 } 15023 // Check shell permission 15024 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15025 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15026 targetUserId)) { 15027 throw new SecurityException("Shell does not have permission to access user " 15028 + targetUserId + "\n " + Debug.getCallers(3)); 15029 } 15030 } 15031 return targetUserId; 15032 } 15033 15034 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15035 String className, int flags) { 15036 boolean result = false; 15037 // For apps that don't have pre-defined UIDs, check for permission 15038 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15039 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15040 if (ActivityManager.checkUidPermission( 15041 INTERACT_ACROSS_USERS, 15042 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15043 ComponentName comp = new ComponentName(aInfo.packageName, className); 15044 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15045 + " requests FLAG_SINGLE_USER, but app does not hold " 15046 + INTERACT_ACROSS_USERS; 15047 Slog.w(TAG, msg); 15048 throw new SecurityException(msg); 15049 } 15050 // Permission passed 15051 result = true; 15052 } 15053 } else if ("system".equals(componentProcessName)) { 15054 result = true; 15055 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15056 // Phone app and persistent apps are allowed to export singleuser providers. 15057 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15058 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15059 } 15060 if (DEBUG_MU) { 15061 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15062 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15063 } 15064 return result; 15065 } 15066 15067 /** 15068 * Checks to see if the caller is in the same app as the singleton 15069 * component, or the component is in a special app. It allows special apps 15070 * to export singleton components but prevents exporting singleton 15071 * components for regular apps. 15072 */ 15073 boolean isValidSingletonCall(int callingUid, int componentUid) { 15074 int componentAppId = UserHandle.getAppId(componentUid); 15075 return UserHandle.isSameApp(callingUid, componentUid) 15076 || componentAppId == Process.SYSTEM_UID 15077 || componentAppId == Process.PHONE_UID 15078 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15079 == PackageManager.PERMISSION_GRANTED; 15080 } 15081 15082 public int bindService(IApplicationThread caller, IBinder token, 15083 Intent service, String resolvedType, 15084 IServiceConnection connection, int flags, int userId) { 15085 enforceNotIsolatedCaller("bindService"); 15086 15087 // Refuse possible leaked file descriptors 15088 if (service != null && service.hasFileDescriptors() == true) { 15089 throw new IllegalArgumentException("File descriptors passed in Intent"); 15090 } 15091 15092 synchronized(this) { 15093 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15094 connection, flags, userId); 15095 } 15096 } 15097 15098 public boolean unbindService(IServiceConnection connection) { 15099 synchronized (this) { 15100 return mServices.unbindServiceLocked(connection); 15101 } 15102 } 15103 15104 public void publishService(IBinder token, Intent intent, IBinder service) { 15105 // Refuse possible leaked file descriptors 15106 if (intent != null && intent.hasFileDescriptors() == true) { 15107 throw new IllegalArgumentException("File descriptors passed in Intent"); 15108 } 15109 15110 synchronized(this) { 15111 if (!(token instanceof ServiceRecord)) { 15112 throw new IllegalArgumentException("Invalid service token"); 15113 } 15114 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15115 } 15116 } 15117 15118 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15119 // Refuse possible leaked file descriptors 15120 if (intent != null && intent.hasFileDescriptors() == true) { 15121 throw new IllegalArgumentException("File descriptors passed in Intent"); 15122 } 15123 15124 synchronized(this) { 15125 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15126 } 15127 } 15128 15129 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15130 synchronized(this) { 15131 if (!(token instanceof ServiceRecord)) { 15132 throw new IllegalArgumentException("Invalid service token"); 15133 } 15134 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15135 } 15136 } 15137 15138 // ========================================================= 15139 // BACKUP AND RESTORE 15140 // ========================================================= 15141 15142 // Cause the target app to be launched if necessary and its backup agent 15143 // instantiated. The backup agent will invoke backupAgentCreated() on the 15144 // activity manager to announce its creation. 15145 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15146 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15147 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15148 15149 synchronized(this) { 15150 // !!! TODO: currently no check here that we're already bound 15151 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15152 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15153 synchronized (stats) { 15154 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15155 } 15156 15157 // Backup agent is now in use, its package can't be stopped. 15158 try { 15159 AppGlobals.getPackageManager().setPackageStoppedState( 15160 app.packageName, false, UserHandle.getUserId(app.uid)); 15161 } catch (RemoteException e) { 15162 } catch (IllegalArgumentException e) { 15163 Slog.w(TAG, "Failed trying to unstop package " 15164 + app.packageName + ": " + e); 15165 } 15166 15167 BackupRecord r = new BackupRecord(ss, app, backupMode); 15168 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15169 ? new ComponentName(app.packageName, app.backupAgentName) 15170 : new ComponentName("android", "FullBackupAgent"); 15171 // startProcessLocked() returns existing proc's record if it's already running 15172 ProcessRecord proc = startProcessLocked(app.processName, app, 15173 false, 0, "backup", hostingName, false, false, false); 15174 if (proc == null) { 15175 Slog.e(TAG, "Unable to start backup agent process " + r); 15176 return false; 15177 } 15178 15179 r.app = proc; 15180 mBackupTarget = r; 15181 mBackupAppName = app.packageName; 15182 15183 // Try not to kill the process during backup 15184 updateOomAdjLocked(proc); 15185 15186 // If the process is already attached, schedule the creation of the backup agent now. 15187 // If it is not yet live, this will be done when it attaches to the framework. 15188 if (proc.thread != null) { 15189 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15190 try { 15191 proc.thread.scheduleCreateBackupAgent(app, 15192 compatibilityInfoForPackageLocked(app), backupMode); 15193 } catch (RemoteException e) { 15194 // Will time out on the backup manager side 15195 } 15196 } else { 15197 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15198 } 15199 // Invariants: at this point, the target app process exists and the application 15200 // is either already running or in the process of coming up. mBackupTarget and 15201 // mBackupAppName describe the app, so that when it binds back to the AM we 15202 // know that it's scheduled for a backup-agent operation. 15203 } 15204 15205 return true; 15206 } 15207 15208 @Override 15209 public void clearPendingBackup() { 15210 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15211 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15212 15213 synchronized (this) { 15214 mBackupTarget = null; 15215 mBackupAppName = null; 15216 } 15217 } 15218 15219 // A backup agent has just come up 15220 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15221 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15222 + " = " + agent); 15223 15224 synchronized(this) { 15225 if (!agentPackageName.equals(mBackupAppName)) { 15226 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15227 return; 15228 } 15229 } 15230 15231 long oldIdent = Binder.clearCallingIdentity(); 15232 try { 15233 IBackupManager bm = IBackupManager.Stub.asInterface( 15234 ServiceManager.getService(Context.BACKUP_SERVICE)); 15235 bm.agentConnected(agentPackageName, agent); 15236 } catch (RemoteException e) { 15237 // can't happen; the backup manager service is local 15238 } catch (Exception e) { 15239 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15240 e.printStackTrace(); 15241 } finally { 15242 Binder.restoreCallingIdentity(oldIdent); 15243 } 15244 } 15245 15246 // done with this agent 15247 public void unbindBackupAgent(ApplicationInfo appInfo) { 15248 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15249 if (appInfo == null) { 15250 Slog.w(TAG, "unbind backup agent for null app"); 15251 return; 15252 } 15253 15254 synchronized(this) { 15255 try { 15256 if (mBackupAppName == null) { 15257 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15258 return; 15259 } 15260 15261 if (!mBackupAppName.equals(appInfo.packageName)) { 15262 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15263 return; 15264 } 15265 15266 // Not backing this app up any more; reset its OOM adjustment 15267 final ProcessRecord proc = mBackupTarget.app; 15268 updateOomAdjLocked(proc); 15269 15270 // If the app crashed during backup, 'thread' will be null here 15271 if (proc.thread != null) { 15272 try { 15273 proc.thread.scheduleDestroyBackupAgent(appInfo, 15274 compatibilityInfoForPackageLocked(appInfo)); 15275 } catch (Exception e) { 15276 Slog.e(TAG, "Exception when unbinding backup agent:"); 15277 e.printStackTrace(); 15278 } 15279 } 15280 } finally { 15281 mBackupTarget = null; 15282 mBackupAppName = null; 15283 } 15284 } 15285 } 15286 // ========================================================= 15287 // BROADCASTS 15288 // ========================================================= 15289 15290 private final List getStickiesLocked(String action, IntentFilter filter, 15291 List cur, int userId) { 15292 final ContentResolver resolver = mContext.getContentResolver(); 15293 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15294 if (stickies == null) { 15295 return cur; 15296 } 15297 final ArrayList<Intent> list = stickies.get(action); 15298 if (list == null) { 15299 return cur; 15300 } 15301 int N = list.size(); 15302 for (int i=0; i<N; i++) { 15303 Intent intent = list.get(i); 15304 if (filter.match(resolver, intent, true, TAG) >= 0) { 15305 if (cur == null) { 15306 cur = new ArrayList<Intent>(); 15307 } 15308 cur.add(intent); 15309 } 15310 } 15311 return cur; 15312 } 15313 15314 boolean isPendingBroadcastProcessLocked(int pid) { 15315 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15316 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15317 } 15318 15319 void skipPendingBroadcastLocked(int pid) { 15320 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15321 for (BroadcastQueue queue : mBroadcastQueues) { 15322 queue.skipPendingBroadcastLocked(pid); 15323 } 15324 } 15325 15326 // The app just attached; send any pending broadcasts that it should receive 15327 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15328 boolean didSomething = false; 15329 for (BroadcastQueue queue : mBroadcastQueues) { 15330 didSomething |= queue.sendPendingBroadcastsLocked(app); 15331 } 15332 return didSomething; 15333 } 15334 15335 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15336 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15337 enforceNotIsolatedCaller("registerReceiver"); 15338 int callingUid; 15339 int callingPid; 15340 synchronized(this) { 15341 ProcessRecord callerApp = null; 15342 if (caller != null) { 15343 callerApp = getRecordForAppLocked(caller); 15344 if (callerApp == null) { 15345 throw new SecurityException( 15346 "Unable to find app for caller " + caller 15347 + " (pid=" + Binder.getCallingPid() 15348 + ") when registering receiver " + receiver); 15349 } 15350 if (callerApp.info.uid != Process.SYSTEM_UID && 15351 !callerApp.pkgList.containsKey(callerPackage) && 15352 !"android".equals(callerPackage)) { 15353 throw new SecurityException("Given caller package " + callerPackage 15354 + " is not running in process " + callerApp); 15355 } 15356 callingUid = callerApp.info.uid; 15357 callingPid = callerApp.pid; 15358 } else { 15359 callerPackage = null; 15360 callingUid = Binder.getCallingUid(); 15361 callingPid = Binder.getCallingPid(); 15362 } 15363 15364 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15365 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15366 15367 List allSticky = null; 15368 15369 // Look for any matching sticky broadcasts... 15370 Iterator actions = filter.actionsIterator(); 15371 if (actions != null) { 15372 while (actions.hasNext()) { 15373 String action = (String)actions.next(); 15374 allSticky = getStickiesLocked(action, filter, allSticky, 15375 UserHandle.USER_ALL); 15376 allSticky = getStickiesLocked(action, filter, allSticky, 15377 UserHandle.getUserId(callingUid)); 15378 } 15379 } else { 15380 allSticky = getStickiesLocked(null, filter, allSticky, 15381 UserHandle.USER_ALL); 15382 allSticky = getStickiesLocked(null, filter, allSticky, 15383 UserHandle.getUserId(callingUid)); 15384 } 15385 15386 // The first sticky in the list is returned directly back to 15387 // the client. 15388 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15389 15390 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15391 + ": " + sticky); 15392 15393 if (receiver == null) { 15394 return sticky; 15395 } 15396 15397 ReceiverList rl 15398 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15399 if (rl == null) { 15400 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15401 userId, receiver); 15402 if (rl.app != null) { 15403 rl.app.receivers.add(rl); 15404 } else { 15405 try { 15406 receiver.asBinder().linkToDeath(rl, 0); 15407 } catch (RemoteException e) { 15408 return sticky; 15409 } 15410 rl.linkedToDeath = true; 15411 } 15412 mRegisteredReceivers.put(receiver.asBinder(), rl); 15413 } else if (rl.uid != callingUid) { 15414 throw new IllegalArgumentException( 15415 "Receiver requested to register for uid " + callingUid 15416 + " was previously registered for uid " + rl.uid); 15417 } else if (rl.pid != callingPid) { 15418 throw new IllegalArgumentException( 15419 "Receiver requested to register for pid " + callingPid 15420 + " was previously registered for pid " + rl.pid); 15421 } else if (rl.userId != userId) { 15422 throw new IllegalArgumentException( 15423 "Receiver requested to register for user " + userId 15424 + " was previously registered for user " + rl.userId); 15425 } 15426 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15427 permission, callingUid, userId); 15428 rl.add(bf); 15429 if (!bf.debugCheck()) { 15430 Slog.w(TAG, "==> For Dynamic broadast"); 15431 } 15432 mReceiverResolver.addFilter(bf); 15433 15434 // Enqueue broadcasts for all existing stickies that match 15435 // this filter. 15436 if (allSticky != null) { 15437 ArrayList receivers = new ArrayList(); 15438 receivers.add(bf); 15439 15440 int N = allSticky.size(); 15441 for (int i=0; i<N; i++) { 15442 Intent intent = (Intent)allSticky.get(i); 15443 BroadcastQueue queue = broadcastQueueForIntent(intent); 15444 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15445 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15446 null, null, false, true, true, -1); 15447 queue.enqueueParallelBroadcastLocked(r); 15448 queue.scheduleBroadcastsLocked(); 15449 } 15450 } 15451 15452 return sticky; 15453 } 15454 } 15455 15456 public void unregisterReceiver(IIntentReceiver receiver) { 15457 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15458 15459 final long origId = Binder.clearCallingIdentity(); 15460 try { 15461 boolean doTrim = false; 15462 15463 synchronized(this) { 15464 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15465 if (rl != null) { 15466 if (rl.curBroadcast != null) { 15467 BroadcastRecord r = rl.curBroadcast; 15468 final boolean doNext = finishReceiverLocked( 15469 receiver.asBinder(), r.resultCode, r.resultData, 15470 r.resultExtras, r.resultAbort); 15471 if (doNext) { 15472 doTrim = true; 15473 r.queue.processNextBroadcast(false); 15474 } 15475 } 15476 15477 if (rl.app != null) { 15478 rl.app.receivers.remove(rl); 15479 } 15480 removeReceiverLocked(rl); 15481 if (rl.linkedToDeath) { 15482 rl.linkedToDeath = false; 15483 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15484 } 15485 } 15486 } 15487 15488 // If we actually concluded any broadcasts, we might now be able 15489 // to trim the recipients' apps from our working set 15490 if (doTrim) { 15491 trimApplications(); 15492 return; 15493 } 15494 15495 } finally { 15496 Binder.restoreCallingIdentity(origId); 15497 } 15498 } 15499 15500 void removeReceiverLocked(ReceiverList rl) { 15501 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15502 int N = rl.size(); 15503 for (int i=0; i<N; i++) { 15504 mReceiverResolver.removeFilter(rl.get(i)); 15505 } 15506 } 15507 15508 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15509 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15510 ProcessRecord r = mLruProcesses.get(i); 15511 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15512 try { 15513 r.thread.dispatchPackageBroadcast(cmd, packages); 15514 } catch (RemoteException ex) { 15515 } 15516 } 15517 } 15518 } 15519 15520 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15521 int callingUid, int[] users) { 15522 List<ResolveInfo> receivers = null; 15523 try { 15524 HashSet<ComponentName> singleUserReceivers = null; 15525 boolean scannedFirstReceivers = false; 15526 for (int user : users) { 15527 // Skip users that have Shell restrictions 15528 if (callingUid == Process.SHELL_UID 15529 && getUserManagerLocked().hasUserRestriction( 15530 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15531 continue; 15532 } 15533 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15534 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15535 if (user != 0 && newReceivers != null) { 15536 // If this is not the primary user, we need to check for 15537 // any receivers that should be filtered out. 15538 for (int i=0; i<newReceivers.size(); i++) { 15539 ResolveInfo ri = newReceivers.get(i); 15540 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15541 newReceivers.remove(i); 15542 i--; 15543 } 15544 } 15545 } 15546 if (newReceivers != null && newReceivers.size() == 0) { 15547 newReceivers = null; 15548 } 15549 if (receivers == null) { 15550 receivers = newReceivers; 15551 } else if (newReceivers != null) { 15552 // We need to concatenate the additional receivers 15553 // found with what we have do far. This would be easy, 15554 // but we also need to de-dup any receivers that are 15555 // singleUser. 15556 if (!scannedFirstReceivers) { 15557 // Collect any single user receivers we had already retrieved. 15558 scannedFirstReceivers = true; 15559 for (int i=0; i<receivers.size(); i++) { 15560 ResolveInfo ri = receivers.get(i); 15561 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15562 ComponentName cn = new ComponentName( 15563 ri.activityInfo.packageName, ri.activityInfo.name); 15564 if (singleUserReceivers == null) { 15565 singleUserReceivers = new HashSet<ComponentName>(); 15566 } 15567 singleUserReceivers.add(cn); 15568 } 15569 } 15570 } 15571 // Add the new results to the existing results, tracking 15572 // and de-dupping single user receivers. 15573 for (int i=0; i<newReceivers.size(); i++) { 15574 ResolveInfo ri = newReceivers.get(i); 15575 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15576 ComponentName cn = new ComponentName( 15577 ri.activityInfo.packageName, ri.activityInfo.name); 15578 if (singleUserReceivers == null) { 15579 singleUserReceivers = new HashSet<ComponentName>(); 15580 } 15581 if (!singleUserReceivers.contains(cn)) { 15582 singleUserReceivers.add(cn); 15583 receivers.add(ri); 15584 } 15585 } else { 15586 receivers.add(ri); 15587 } 15588 } 15589 } 15590 } 15591 } catch (RemoteException ex) { 15592 // pm is in same process, this will never happen. 15593 } 15594 return receivers; 15595 } 15596 15597 private final int broadcastIntentLocked(ProcessRecord callerApp, 15598 String callerPackage, Intent intent, String resolvedType, 15599 IIntentReceiver resultTo, int resultCode, String resultData, 15600 Bundle map, String requiredPermission, int appOp, 15601 boolean ordered, boolean sticky, int callingPid, int callingUid, 15602 int userId) { 15603 intent = new Intent(intent); 15604 15605 // By default broadcasts do not go to stopped apps. 15606 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15607 15608 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15609 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15610 + " ordered=" + ordered + " userid=" + userId); 15611 if ((resultTo != null) && !ordered) { 15612 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15613 } 15614 15615 userId = handleIncomingUser(callingPid, callingUid, userId, 15616 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15617 15618 // Make sure that the user who is receiving this broadcast is started. 15619 // If not, we will just skip it. 15620 15621 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15622 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15623 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15624 Slog.w(TAG, "Skipping broadcast of " + intent 15625 + ": user " + userId + " is stopped"); 15626 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15627 } 15628 } 15629 15630 /* 15631 * Prevent non-system code (defined here to be non-persistent 15632 * processes) from sending protected broadcasts. 15633 */ 15634 int callingAppId = UserHandle.getAppId(callingUid); 15635 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15636 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15637 || callingAppId == Process.NFC_UID || callingUid == 0) { 15638 // Always okay. 15639 } else if (callerApp == null || !callerApp.persistent) { 15640 try { 15641 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15642 intent.getAction())) { 15643 String msg = "Permission Denial: not allowed to send broadcast " 15644 + intent.getAction() + " from pid=" 15645 + callingPid + ", uid=" + callingUid; 15646 Slog.w(TAG, msg); 15647 throw new SecurityException(msg); 15648 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15649 // Special case for compatibility: we don't want apps to send this, 15650 // but historically it has not been protected and apps may be using it 15651 // to poke their own app widget. So, instead of making it protected, 15652 // just limit it to the caller. 15653 if (callerApp == null) { 15654 String msg = "Permission Denial: not allowed to send broadcast " 15655 + intent.getAction() + " from unknown caller."; 15656 Slog.w(TAG, msg); 15657 throw new SecurityException(msg); 15658 } else if (intent.getComponent() != null) { 15659 // They are good enough to send to an explicit component... verify 15660 // it is being sent to the calling app. 15661 if (!intent.getComponent().getPackageName().equals( 15662 callerApp.info.packageName)) { 15663 String msg = "Permission Denial: not allowed to send broadcast " 15664 + intent.getAction() + " to " 15665 + intent.getComponent().getPackageName() + " from " 15666 + callerApp.info.packageName; 15667 Slog.w(TAG, msg); 15668 throw new SecurityException(msg); 15669 } 15670 } else { 15671 // Limit broadcast to their own package. 15672 intent.setPackage(callerApp.info.packageName); 15673 } 15674 } 15675 } catch (RemoteException e) { 15676 Slog.w(TAG, "Remote exception", e); 15677 return ActivityManager.BROADCAST_SUCCESS; 15678 } 15679 } 15680 15681 // Handle special intents: if this broadcast is from the package 15682 // manager about a package being removed, we need to remove all of 15683 // its activities from the history stack. 15684 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15685 intent.getAction()); 15686 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15687 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15688 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15689 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15690 || uidRemoved) { 15691 if (checkComponentPermission( 15692 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15693 callingPid, callingUid, -1, true) 15694 == PackageManager.PERMISSION_GRANTED) { 15695 if (uidRemoved) { 15696 final Bundle intentExtras = intent.getExtras(); 15697 final int uid = intentExtras != null 15698 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15699 if (uid >= 0) { 15700 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15701 synchronized (bs) { 15702 bs.removeUidStatsLocked(uid); 15703 } 15704 mAppOpsService.uidRemoved(uid); 15705 } 15706 } else { 15707 // If resources are unavailable just force stop all 15708 // those packages and flush the attribute cache as well. 15709 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15710 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15711 if (list != null && (list.length > 0)) { 15712 for (String pkg : list) { 15713 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15714 "storage unmount"); 15715 } 15716 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15717 sendPackageBroadcastLocked( 15718 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15719 } 15720 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15721 intent.getAction())) { 15722 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15723 } else { 15724 Uri data = intent.getData(); 15725 String ssp; 15726 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15727 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15728 intent.getAction()); 15729 boolean fullUninstall = removed && 15730 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15731 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15732 forceStopPackageLocked(ssp, UserHandle.getAppId( 15733 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15734 false, fullUninstall, userId, 15735 removed ? "pkg removed" : "pkg changed"); 15736 } 15737 if (removed) { 15738 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15739 new String[] {ssp}, userId); 15740 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15741 mAppOpsService.packageRemoved( 15742 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15743 15744 // Remove all permissions granted from/to this package 15745 removeUriPermissionsForPackageLocked(ssp, userId, true); 15746 } 15747 } 15748 } 15749 } 15750 } 15751 } else { 15752 String msg = "Permission Denial: " + intent.getAction() 15753 + " broadcast from " + callerPackage + " (pid=" + callingPid 15754 + ", uid=" + callingUid + ")" 15755 + " requires " 15756 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15757 Slog.w(TAG, msg); 15758 throw new SecurityException(msg); 15759 } 15760 15761 // Special case for adding a package: by default turn on compatibility 15762 // mode. 15763 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15764 Uri data = intent.getData(); 15765 String ssp; 15766 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15767 mCompatModePackages.handlePackageAddedLocked(ssp, 15768 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15769 } 15770 } 15771 15772 /* 15773 * If this is the time zone changed action, queue up a message that will reset the timezone 15774 * of all currently running processes. This message will get queued up before the broadcast 15775 * happens. 15776 */ 15777 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15778 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15779 } 15780 15781 /* 15782 * If the user set the time, let all running processes know. 15783 */ 15784 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15785 final int is24Hour = intent.getBooleanExtra( 15786 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15787 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15788 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15789 synchronized (stats) { 15790 stats.noteCurrentTimeChangedLocked(); 15791 } 15792 } 15793 15794 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15795 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15796 } 15797 15798 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15799 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15800 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15801 } 15802 15803 // Add to the sticky list if requested. 15804 if (sticky) { 15805 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15806 callingPid, callingUid) 15807 != PackageManager.PERMISSION_GRANTED) { 15808 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15809 + callingPid + ", uid=" + callingUid 15810 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15811 Slog.w(TAG, msg); 15812 throw new SecurityException(msg); 15813 } 15814 if (requiredPermission != null) { 15815 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15816 + " and enforce permission " + requiredPermission); 15817 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15818 } 15819 if (intent.getComponent() != null) { 15820 throw new SecurityException( 15821 "Sticky broadcasts can't target a specific component"); 15822 } 15823 // We use userId directly here, since the "all" target is maintained 15824 // as a separate set of sticky broadcasts. 15825 if (userId != UserHandle.USER_ALL) { 15826 // But first, if this is not a broadcast to all users, then 15827 // make sure it doesn't conflict with an existing broadcast to 15828 // all users. 15829 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15830 UserHandle.USER_ALL); 15831 if (stickies != null) { 15832 ArrayList<Intent> list = stickies.get(intent.getAction()); 15833 if (list != null) { 15834 int N = list.size(); 15835 int i; 15836 for (i=0; i<N; i++) { 15837 if (intent.filterEquals(list.get(i))) { 15838 throw new IllegalArgumentException( 15839 "Sticky broadcast " + intent + " for user " 15840 + userId + " conflicts with existing global broadcast"); 15841 } 15842 } 15843 } 15844 } 15845 } 15846 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15847 if (stickies == null) { 15848 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15849 mStickyBroadcasts.put(userId, stickies); 15850 } 15851 ArrayList<Intent> list = stickies.get(intent.getAction()); 15852 if (list == null) { 15853 list = new ArrayList<Intent>(); 15854 stickies.put(intent.getAction(), list); 15855 } 15856 int N = list.size(); 15857 int i; 15858 for (i=0; i<N; i++) { 15859 if (intent.filterEquals(list.get(i))) { 15860 // This sticky already exists, replace it. 15861 list.set(i, new Intent(intent)); 15862 break; 15863 } 15864 } 15865 if (i >= N) { 15866 list.add(new Intent(intent)); 15867 } 15868 } 15869 15870 int[] users; 15871 if (userId == UserHandle.USER_ALL) { 15872 // Caller wants broadcast to go to all started users. 15873 users = mStartedUserArray; 15874 } else { 15875 // Caller wants broadcast to go to one specific user. 15876 users = new int[] {userId}; 15877 } 15878 15879 // Figure out who all will receive this broadcast. 15880 List receivers = null; 15881 List<BroadcastFilter> registeredReceivers = null; 15882 // Need to resolve the intent to interested receivers... 15883 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15884 == 0) { 15885 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15886 } 15887 if (intent.getComponent() == null) { 15888 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15889 // Query one target user at a time, excluding shell-restricted users 15890 UserManagerService ums = getUserManagerLocked(); 15891 for (int i = 0; i < users.length; i++) { 15892 if (ums.hasUserRestriction( 15893 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15894 continue; 15895 } 15896 List<BroadcastFilter> registeredReceiversForUser = 15897 mReceiverResolver.queryIntent(intent, 15898 resolvedType, false, users[i]); 15899 if (registeredReceivers == null) { 15900 registeredReceivers = registeredReceiversForUser; 15901 } else if (registeredReceiversForUser != null) { 15902 registeredReceivers.addAll(registeredReceiversForUser); 15903 } 15904 } 15905 } else { 15906 registeredReceivers = mReceiverResolver.queryIntent(intent, 15907 resolvedType, false, userId); 15908 } 15909 } 15910 15911 final boolean replacePending = 15912 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15913 15914 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15915 + " replacePending=" + replacePending); 15916 15917 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15918 if (!ordered && NR > 0) { 15919 // If we are not serializing this broadcast, then send the 15920 // registered receivers separately so they don't wait for the 15921 // components to be launched. 15922 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15923 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15924 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15925 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15926 ordered, sticky, false, userId); 15927 if (DEBUG_BROADCAST) Slog.v( 15928 TAG, "Enqueueing parallel broadcast " + r); 15929 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15930 if (!replaced) { 15931 queue.enqueueParallelBroadcastLocked(r); 15932 queue.scheduleBroadcastsLocked(); 15933 } 15934 registeredReceivers = null; 15935 NR = 0; 15936 } 15937 15938 // Merge into one list. 15939 int ir = 0; 15940 if (receivers != null) { 15941 // A special case for PACKAGE_ADDED: do not allow the package 15942 // being added to see this broadcast. This prevents them from 15943 // using this as a back door to get run as soon as they are 15944 // installed. Maybe in the future we want to have a special install 15945 // broadcast or such for apps, but we'd like to deliberately make 15946 // this decision. 15947 String skipPackages[] = null; 15948 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15949 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15950 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15951 Uri data = intent.getData(); 15952 if (data != null) { 15953 String pkgName = data.getSchemeSpecificPart(); 15954 if (pkgName != null) { 15955 skipPackages = new String[] { pkgName }; 15956 } 15957 } 15958 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15959 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15960 } 15961 if (skipPackages != null && (skipPackages.length > 0)) { 15962 for (String skipPackage : skipPackages) { 15963 if (skipPackage != null) { 15964 int NT = receivers.size(); 15965 for (int it=0; it<NT; it++) { 15966 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15967 if (curt.activityInfo.packageName.equals(skipPackage)) { 15968 receivers.remove(it); 15969 it--; 15970 NT--; 15971 } 15972 } 15973 } 15974 } 15975 } 15976 15977 int NT = receivers != null ? receivers.size() : 0; 15978 int it = 0; 15979 ResolveInfo curt = null; 15980 BroadcastFilter curr = null; 15981 while (it < NT && ir < NR) { 15982 if (curt == null) { 15983 curt = (ResolveInfo)receivers.get(it); 15984 } 15985 if (curr == null) { 15986 curr = registeredReceivers.get(ir); 15987 } 15988 if (curr.getPriority() >= curt.priority) { 15989 // Insert this broadcast record into the final list. 15990 receivers.add(it, curr); 15991 ir++; 15992 curr = null; 15993 it++; 15994 NT++; 15995 } else { 15996 // Skip to the next ResolveInfo in the final list. 15997 it++; 15998 curt = null; 15999 } 16000 } 16001 } 16002 while (ir < NR) { 16003 if (receivers == null) { 16004 receivers = new ArrayList(); 16005 } 16006 receivers.add(registeredReceivers.get(ir)); 16007 ir++; 16008 } 16009 16010 if ((receivers != null && receivers.size() > 0) 16011 || resultTo != null) { 16012 BroadcastQueue queue = broadcastQueueForIntent(intent); 16013 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16014 callerPackage, callingPid, callingUid, resolvedType, 16015 requiredPermission, appOp, receivers, resultTo, resultCode, 16016 resultData, map, ordered, sticky, false, userId); 16017 if (DEBUG_BROADCAST) Slog.v( 16018 TAG, "Enqueueing ordered broadcast " + r 16019 + ": prev had " + queue.mOrderedBroadcasts.size()); 16020 if (DEBUG_BROADCAST) { 16021 int seq = r.intent.getIntExtra("seq", -1); 16022 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16023 } 16024 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16025 if (!replaced) { 16026 queue.enqueueOrderedBroadcastLocked(r); 16027 queue.scheduleBroadcastsLocked(); 16028 } 16029 } 16030 16031 return ActivityManager.BROADCAST_SUCCESS; 16032 } 16033 16034 final Intent verifyBroadcastLocked(Intent intent) { 16035 // Refuse possible leaked file descriptors 16036 if (intent != null && intent.hasFileDescriptors() == true) { 16037 throw new IllegalArgumentException("File descriptors passed in Intent"); 16038 } 16039 16040 int flags = intent.getFlags(); 16041 16042 if (!mProcessesReady) { 16043 // if the caller really truly claims to know what they're doing, go 16044 // ahead and allow the broadcast without launching any receivers 16045 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16046 intent = new Intent(intent); 16047 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16048 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16049 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16050 + " before boot completion"); 16051 throw new IllegalStateException("Cannot broadcast before boot completed"); 16052 } 16053 } 16054 16055 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16056 throw new IllegalArgumentException( 16057 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16058 } 16059 16060 return intent; 16061 } 16062 16063 public final int broadcastIntent(IApplicationThread caller, 16064 Intent intent, String resolvedType, IIntentReceiver resultTo, 16065 int resultCode, String resultData, Bundle map, 16066 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16067 enforceNotIsolatedCaller("broadcastIntent"); 16068 synchronized(this) { 16069 intent = verifyBroadcastLocked(intent); 16070 16071 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16072 final int callingPid = Binder.getCallingPid(); 16073 final int callingUid = Binder.getCallingUid(); 16074 final long origId = Binder.clearCallingIdentity(); 16075 int res = broadcastIntentLocked(callerApp, 16076 callerApp != null ? callerApp.info.packageName : null, 16077 intent, resolvedType, resultTo, 16078 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16079 callingPid, callingUid, userId); 16080 Binder.restoreCallingIdentity(origId); 16081 return res; 16082 } 16083 } 16084 16085 int broadcastIntentInPackage(String packageName, int uid, 16086 Intent intent, String resolvedType, IIntentReceiver resultTo, 16087 int resultCode, String resultData, Bundle map, 16088 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16089 synchronized(this) { 16090 intent = verifyBroadcastLocked(intent); 16091 16092 final long origId = Binder.clearCallingIdentity(); 16093 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16094 resultTo, resultCode, resultData, map, requiredPermission, 16095 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16096 Binder.restoreCallingIdentity(origId); 16097 return res; 16098 } 16099 } 16100 16101 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16102 // Refuse possible leaked file descriptors 16103 if (intent != null && intent.hasFileDescriptors() == true) { 16104 throw new IllegalArgumentException("File descriptors passed in Intent"); 16105 } 16106 16107 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16108 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16109 16110 synchronized(this) { 16111 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16112 != PackageManager.PERMISSION_GRANTED) { 16113 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16114 + Binder.getCallingPid() 16115 + ", uid=" + Binder.getCallingUid() 16116 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16117 Slog.w(TAG, msg); 16118 throw new SecurityException(msg); 16119 } 16120 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16121 if (stickies != null) { 16122 ArrayList<Intent> list = stickies.get(intent.getAction()); 16123 if (list != null) { 16124 int N = list.size(); 16125 int i; 16126 for (i=0; i<N; i++) { 16127 if (intent.filterEquals(list.get(i))) { 16128 list.remove(i); 16129 break; 16130 } 16131 } 16132 if (list.size() <= 0) { 16133 stickies.remove(intent.getAction()); 16134 } 16135 } 16136 if (stickies.size() <= 0) { 16137 mStickyBroadcasts.remove(userId); 16138 } 16139 } 16140 } 16141 } 16142 16143 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16144 String resultData, Bundle resultExtras, boolean resultAbort) { 16145 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16146 if (r == null) { 16147 Slog.w(TAG, "finishReceiver called but not found on queue"); 16148 return false; 16149 } 16150 16151 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16152 } 16153 16154 void backgroundServicesFinishedLocked(int userId) { 16155 for (BroadcastQueue queue : mBroadcastQueues) { 16156 queue.backgroundServicesFinishedLocked(userId); 16157 } 16158 } 16159 16160 public void finishReceiver(IBinder who, int resultCode, String resultData, 16161 Bundle resultExtras, boolean resultAbort) { 16162 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16163 16164 // Refuse possible leaked file descriptors 16165 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16166 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16167 } 16168 16169 final long origId = Binder.clearCallingIdentity(); 16170 try { 16171 boolean doNext = false; 16172 BroadcastRecord r; 16173 16174 synchronized(this) { 16175 r = broadcastRecordForReceiverLocked(who); 16176 if (r != null) { 16177 doNext = r.queue.finishReceiverLocked(r, resultCode, 16178 resultData, resultExtras, resultAbort, true); 16179 } 16180 } 16181 16182 if (doNext) { 16183 r.queue.processNextBroadcast(false); 16184 } 16185 trimApplications(); 16186 } finally { 16187 Binder.restoreCallingIdentity(origId); 16188 } 16189 } 16190 16191 // ========================================================= 16192 // INSTRUMENTATION 16193 // ========================================================= 16194 16195 public boolean startInstrumentation(ComponentName className, 16196 String profileFile, int flags, Bundle arguments, 16197 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16198 int userId, String abiOverride) { 16199 enforceNotIsolatedCaller("startInstrumentation"); 16200 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16201 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16202 // Refuse possible leaked file descriptors 16203 if (arguments != null && arguments.hasFileDescriptors()) { 16204 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16205 } 16206 16207 synchronized(this) { 16208 InstrumentationInfo ii = null; 16209 ApplicationInfo ai = null; 16210 try { 16211 ii = mContext.getPackageManager().getInstrumentationInfo( 16212 className, STOCK_PM_FLAGS); 16213 ai = AppGlobals.getPackageManager().getApplicationInfo( 16214 ii.targetPackage, STOCK_PM_FLAGS, userId); 16215 } catch (PackageManager.NameNotFoundException e) { 16216 } catch (RemoteException e) { 16217 } 16218 if (ii == null) { 16219 reportStartInstrumentationFailure(watcher, className, 16220 "Unable to find instrumentation info for: " + className); 16221 return false; 16222 } 16223 if (ai == null) { 16224 reportStartInstrumentationFailure(watcher, className, 16225 "Unable to find instrumentation target package: " + ii.targetPackage); 16226 return false; 16227 } 16228 16229 int match = mContext.getPackageManager().checkSignatures( 16230 ii.targetPackage, ii.packageName); 16231 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16232 String msg = "Permission Denial: starting instrumentation " 16233 + className + " from pid=" 16234 + Binder.getCallingPid() 16235 + ", uid=" + Binder.getCallingPid() 16236 + " not allowed because package " + ii.packageName 16237 + " does not have a signature matching the target " 16238 + ii.targetPackage; 16239 reportStartInstrumentationFailure(watcher, className, msg); 16240 throw new SecurityException(msg); 16241 } 16242 16243 final long origId = Binder.clearCallingIdentity(); 16244 // Instrumentation can kill and relaunch even persistent processes 16245 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16246 "start instr"); 16247 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16248 app.instrumentationClass = className; 16249 app.instrumentationInfo = ai; 16250 app.instrumentationProfileFile = profileFile; 16251 app.instrumentationArguments = arguments; 16252 app.instrumentationWatcher = watcher; 16253 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16254 app.instrumentationResultClass = className; 16255 Binder.restoreCallingIdentity(origId); 16256 } 16257 16258 return true; 16259 } 16260 16261 /** 16262 * Report errors that occur while attempting to start Instrumentation. Always writes the 16263 * error to the logs, but if somebody is watching, send the report there too. This enables 16264 * the "am" command to report errors with more information. 16265 * 16266 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16267 * @param cn The component name of the instrumentation. 16268 * @param report The error report. 16269 */ 16270 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16271 ComponentName cn, String report) { 16272 Slog.w(TAG, report); 16273 try { 16274 if (watcher != null) { 16275 Bundle results = new Bundle(); 16276 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16277 results.putString("Error", report); 16278 watcher.instrumentationStatus(cn, -1, results); 16279 } 16280 } catch (RemoteException e) { 16281 Slog.w(TAG, e); 16282 } 16283 } 16284 16285 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16286 if (app.instrumentationWatcher != null) { 16287 try { 16288 // NOTE: IInstrumentationWatcher *must* be oneway here 16289 app.instrumentationWatcher.instrumentationFinished( 16290 app.instrumentationClass, 16291 resultCode, 16292 results); 16293 } catch (RemoteException e) { 16294 } 16295 } 16296 if (app.instrumentationUiAutomationConnection != null) { 16297 try { 16298 app.instrumentationUiAutomationConnection.shutdown(); 16299 } catch (RemoteException re) { 16300 /* ignore */ 16301 } 16302 // Only a UiAutomation can set this flag and now that 16303 // it is finished we make sure it is reset to its default. 16304 mUserIsMonkey = false; 16305 } 16306 app.instrumentationWatcher = null; 16307 app.instrumentationUiAutomationConnection = null; 16308 app.instrumentationClass = null; 16309 app.instrumentationInfo = null; 16310 app.instrumentationProfileFile = null; 16311 app.instrumentationArguments = null; 16312 16313 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16314 "finished inst"); 16315 } 16316 16317 public void finishInstrumentation(IApplicationThread target, 16318 int resultCode, Bundle results) { 16319 int userId = UserHandle.getCallingUserId(); 16320 // Refuse possible leaked file descriptors 16321 if (results != null && results.hasFileDescriptors()) { 16322 throw new IllegalArgumentException("File descriptors passed in Intent"); 16323 } 16324 16325 synchronized(this) { 16326 ProcessRecord app = getRecordForAppLocked(target); 16327 if (app == null) { 16328 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16329 return; 16330 } 16331 final long origId = Binder.clearCallingIdentity(); 16332 finishInstrumentationLocked(app, resultCode, results); 16333 Binder.restoreCallingIdentity(origId); 16334 } 16335 } 16336 16337 // ========================================================= 16338 // CONFIGURATION 16339 // ========================================================= 16340 16341 public ConfigurationInfo getDeviceConfigurationInfo() { 16342 ConfigurationInfo config = new ConfigurationInfo(); 16343 synchronized (this) { 16344 config.reqTouchScreen = mConfiguration.touchscreen; 16345 config.reqKeyboardType = mConfiguration.keyboard; 16346 config.reqNavigation = mConfiguration.navigation; 16347 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16348 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16349 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16350 } 16351 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16352 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16353 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16354 } 16355 config.reqGlEsVersion = GL_ES_VERSION; 16356 } 16357 return config; 16358 } 16359 16360 ActivityStack getFocusedStack() { 16361 return mStackSupervisor.getFocusedStack(); 16362 } 16363 16364 public Configuration getConfiguration() { 16365 Configuration ci; 16366 synchronized(this) { 16367 ci = new Configuration(mConfiguration); 16368 } 16369 return ci; 16370 } 16371 16372 public void updatePersistentConfiguration(Configuration values) { 16373 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16374 "updateConfiguration()"); 16375 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16376 "updateConfiguration()"); 16377 if (values == null) { 16378 throw new NullPointerException("Configuration must not be null"); 16379 } 16380 16381 synchronized(this) { 16382 final long origId = Binder.clearCallingIdentity(); 16383 updateConfigurationLocked(values, null, true, false); 16384 Binder.restoreCallingIdentity(origId); 16385 } 16386 } 16387 16388 public void updateConfiguration(Configuration values) { 16389 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16390 "updateConfiguration()"); 16391 16392 synchronized(this) { 16393 if (values == null && mWindowManager != null) { 16394 // sentinel: fetch the current configuration from the window manager 16395 values = mWindowManager.computeNewConfiguration(); 16396 } 16397 16398 if (mWindowManager != null) { 16399 mProcessList.applyDisplaySize(mWindowManager); 16400 } 16401 16402 final long origId = Binder.clearCallingIdentity(); 16403 if (values != null) { 16404 Settings.System.clearConfiguration(values); 16405 } 16406 updateConfigurationLocked(values, null, false, false); 16407 Binder.restoreCallingIdentity(origId); 16408 } 16409 } 16410 16411 /** 16412 * Do either or both things: (1) change the current configuration, and (2) 16413 * make sure the given activity is running with the (now) current 16414 * configuration. Returns true if the activity has been left running, or 16415 * false if <var>starting</var> is being destroyed to match the new 16416 * configuration. 16417 * @param persistent TODO 16418 */ 16419 boolean updateConfigurationLocked(Configuration values, 16420 ActivityRecord starting, boolean persistent, boolean initLocale) { 16421 int changes = 0; 16422 16423 if (values != null) { 16424 Configuration newConfig = new Configuration(mConfiguration); 16425 changes = newConfig.updateFrom(values); 16426 if (changes != 0) { 16427 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16428 Slog.i(TAG, "Updating configuration to: " + values); 16429 } 16430 16431 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16432 16433 if (values.locale != null && !initLocale) { 16434 saveLocaleLocked(values.locale, 16435 !values.locale.equals(mConfiguration.locale), 16436 values.userSetLocale); 16437 } 16438 16439 mConfigurationSeq++; 16440 if (mConfigurationSeq <= 0) { 16441 mConfigurationSeq = 1; 16442 } 16443 newConfig.seq = mConfigurationSeq; 16444 mConfiguration = newConfig; 16445 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16446 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16447 //mUsageStatsService.noteStartConfig(newConfig); 16448 16449 final Configuration configCopy = new Configuration(mConfiguration); 16450 16451 // TODO: If our config changes, should we auto dismiss any currently 16452 // showing dialogs? 16453 mShowDialogs = shouldShowDialogs(newConfig); 16454 16455 AttributeCache ac = AttributeCache.instance(); 16456 if (ac != null) { 16457 ac.updateConfiguration(configCopy); 16458 } 16459 16460 // Make sure all resources in our process are updated 16461 // right now, so that anyone who is going to retrieve 16462 // resource values after we return will be sure to get 16463 // the new ones. This is especially important during 16464 // boot, where the first config change needs to guarantee 16465 // all resources have that config before following boot 16466 // code is executed. 16467 mSystemThread.applyConfigurationToResources(configCopy); 16468 16469 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16470 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16471 msg.obj = new Configuration(configCopy); 16472 mHandler.sendMessage(msg); 16473 } 16474 16475 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16476 ProcessRecord app = mLruProcesses.get(i); 16477 try { 16478 if (app.thread != null) { 16479 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16480 + app.processName + " new config " + mConfiguration); 16481 app.thread.scheduleConfigurationChanged(configCopy); 16482 } 16483 } catch (Exception e) { 16484 } 16485 } 16486 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16487 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16488 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16489 | Intent.FLAG_RECEIVER_FOREGROUND); 16490 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16491 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16492 Process.SYSTEM_UID, UserHandle.USER_ALL); 16493 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16494 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16495 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16496 broadcastIntentLocked(null, null, intent, 16497 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16498 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16499 } 16500 } 16501 } 16502 16503 boolean kept = true; 16504 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16505 // mainStack is null during startup. 16506 if (mainStack != null) { 16507 if (changes != 0 && starting == null) { 16508 // If the configuration changed, and the caller is not already 16509 // in the process of starting an activity, then find the top 16510 // activity to check if its configuration needs to change. 16511 starting = mainStack.topRunningActivityLocked(null); 16512 } 16513 16514 if (starting != null) { 16515 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16516 // And we need to make sure at this point that all other activities 16517 // are made visible with the correct configuration. 16518 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16519 } 16520 } 16521 16522 if (values != null && mWindowManager != null) { 16523 mWindowManager.setNewConfiguration(mConfiguration); 16524 } 16525 16526 return kept; 16527 } 16528 16529 /** 16530 * Decide based on the configuration whether we should shouw the ANR, 16531 * crash, etc dialogs. The idea is that if there is no affordnace to 16532 * press the on-screen buttons, we shouldn't show the dialog. 16533 * 16534 * A thought: SystemUI might also want to get told about this, the Power 16535 * dialog / global actions also might want different behaviors. 16536 */ 16537 private static final boolean shouldShowDialogs(Configuration config) { 16538 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16539 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16540 } 16541 16542 /** 16543 * Save the locale. You must be inside a synchronized (this) block. 16544 */ 16545 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16546 if(isDiff) { 16547 SystemProperties.set("user.language", l.getLanguage()); 16548 SystemProperties.set("user.region", l.getCountry()); 16549 } 16550 16551 if(isPersist) { 16552 SystemProperties.set("persist.sys.language", l.getLanguage()); 16553 SystemProperties.set("persist.sys.country", l.getCountry()); 16554 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16555 16556 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16557 } 16558 } 16559 16560 @Override 16561 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16562 synchronized (this) { 16563 ActivityRecord srec = ActivityRecord.forToken(token); 16564 if (srec.task != null && srec.task.stack != null) { 16565 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16566 } 16567 } 16568 return false; 16569 } 16570 16571 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16572 Intent resultData) { 16573 16574 synchronized (this) { 16575 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16576 if (stack != null) { 16577 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16578 } 16579 return false; 16580 } 16581 } 16582 16583 public int getLaunchedFromUid(IBinder activityToken) { 16584 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16585 if (srec == null) { 16586 return -1; 16587 } 16588 return srec.launchedFromUid; 16589 } 16590 16591 public String getLaunchedFromPackage(IBinder activityToken) { 16592 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16593 if (srec == null) { 16594 return null; 16595 } 16596 return srec.launchedFromPackage; 16597 } 16598 16599 // ========================================================= 16600 // LIFETIME MANAGEMENT 16601 // ========================================================= 16602 16603 // Returns which broadcast queue the app is the current [or imminent] receiver 16604 // on, or 'null' if the app is not an active broadcast recipient. 16605 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16606 BroadcastRecord r = app.curReceiver; 16607 if (r != null) { 16608 return r.queue; 16609 } 16610 16611 // It's not the current receiver, but it might be starting up to become one 16612 synchronized (this) { 16613 for (BroadcastQueue queue : mBroadcastQueues) { 16614 r = queue.mPendingBroadcast; 16615 if (r != null && r.curApp == app) { 16616 // found it; report which queue it's in 16617 return queue; 16618 } 16619 } 16620 } 16621 16622 return null; 16623 } 16624 16625 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16626 boolean doingAll, long now) { 16627 if (mAdjSeq == app.adjSeq) { 16628 // This adjustment has already been computed. 16629 return app.curRawAdj; 16630 } 16631 16632 if (app.thread == null) { 16633 app.adjSeq = mAdjSeq; 16634 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16635 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16636 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16637 } 16638 16639 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16640 app.adjSource = null; 16641 app.adjTarget = null; 16642 app.empty = false; 16643 app.cached = false; 16644 16645 final int activitiesSize = app.activities.size(); 16646 16647 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16648 // The max adjustment doesn't allow this app to be anything 16649 // below foreground, so it is not worth doing work for it. 16650 app.adjType = "fixed"; 16651 app.adjSeq = mAdjSeq; 16652 app.curRawAdj = app.maxAdj; 16653 app.foregroundActivities = false; 16654 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16655 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16656 // System processes can do UI, and when they do we want to have 16657 // them trim their memory after the user leaves the UI. To 16658 // facilitate this, here we need to determine whether or not it 16659 // is currently showing UI. 16660 app.systemNoUi = true; 16661 if (app == TOP_APP) { 16662 app.systemNoUi = false; 16663 } else if (activitiesSize > 0) { 16664 for (int j = 0; j < activitiesSize; j++) { 16665 final ActivityRecord r = app.activities.get(j); 16666 if (r.visible) { 16667 app.systemNoUi = false; 16668 } 16669 } 16670 } 16671 if (!app.systemNoUi) { 16672 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16673 } 16674 return (app.curAdj=app.maxAdj); 16675 } 16676 16677 app.systemNoUi = false; 16678 16679 // Determine the importance of the process, starting with most 16680 // important to least, and assign an appropriate OOM adjustment. 16681 int adj; 16682 int schedGroup; 16683 int procState; 16684 boolean foregroundActivities = false; 16685 BroadcastQueue queue; 16686 if (app == TOP_APP) { 16687 // The last app on the list is the foreground app. 16688 adj = ProcessList.FOREGROUND_APP_ADJ; 16689 schedGroup = Process.THREAD_GROUP_DEFAULT; 16690 app.adjType = "top-activity"; 16691 foregroundActivities = true; 16692 procState = ActivityManager.PROCESS_STATE_TOP; 16693 } else if (app.instrumentationClass != null) { 16694 // Don't want to kill running instrumentation. 16695 adj = ProcessList.FOREGROUND_APP_ADJ; 16696 schedGroup = Process.THREAD_GROUP_DEFAULT; 16697 app.adjType = "instrumentation"; 16698 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16699 } else if ((queue = isReceivingBroadcast(app)) != null) { 16700 // An app that is currently receiving a broadcast also 16701 // counts as being in the foreground for OOM killer purposes. 16702 // It's placed in a sched group based on the nature of the 16703 // broadcast as reflected by which queue it's active in. 16704 adj = ProcessList.FOREGROUND_APP_ADJ; 16705 schedGroup = (queue == mFgBroadcastQueue) 16706 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16707 app.adjType = "broadcast"; 16708 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16709 } else if (app.executingServices.size() > 0) { 16710 // An app that is currently executing a service callback also 16711 // counts as being in the foreground. 16712 adj = ProcessList.FOREGROUND_APP_ADJ; 16713 schedGroup = app.execServicesFg ? 16714 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16715 app.adjType = "exec-service"; 16716 procState = ActivityManager.PROCESS_STATE_SERVICE; 16717 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16718 } else { 16719 // As far as we know the process is empty. We may change our mind later. 16720 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16721 // At this point we don't actually know the adjustment. Use the cached adj 16722 // value that the caller wants us to. 16723 adj = cachedAdj; 16724 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16725 app.cached = true; 16726 app.empty = true; 16727 app.adjType = "cch-empty"; 16728 } 16729 16730 // Examine all activities if not already foreground. 16731 if (!foregroundActivities && activitiesSize > 0) { 16732 for (int j = 0; j < activitiesSize; j++) { 16733 final ActivityRecord r = app.activities.get(j); 16734 if (r.app != app) { 16735 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16736 + app + "?!?"); 16737 continue; 16738 } 16739 if (r.visible) { 16740 // App has a visible activity; only upgrade adjustment. 16741 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16742 adj = ProcessList.VISIBLE_APP_ADJ; 16743 app.adjType = "visible"; 16744 } 16745 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16746 procState = ActivityManager.PROCESS_STATE_TOP; 16747 } 16748 schedGroup = Process.THREAD_GROUP_DEFAULT; 16749 app.cached = false; 16750 app.empty = false; 16751 foregroundActivities = true; 16752 break; 16753 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16754 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16755 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16756 app.adjType = "pausing"; 16757 } 16758 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16759 procState = ActivityManager.PROCESS_STATE_TOP; 16760 } 16761 schedGroup = Process.THREAD_GROUP_DEFAULT; 16762 app.cached = false; 16763 app.empty = false; 16764 foregroundActivities = true; 16765 } else if (r.state == ActivityState.STOPPING) { 16766 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16767 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16768 app.adjType = "stopping"; 16769 } 16770 // For the process state, we will at this point consider the 16771 // process to be cached. It will be cached either as an activity 16772 // or empty depending on whether the activity is finishing. We do 16773 // this so that we can treat the process as cached for purposes of 16774 // memory trimming (determing current memory level, trim command to 16775 // send to process) since there can be an arbitrary number of stopping 16776 // processes and they should soon all go into the cached state. 16777 if (!r.finishing) { 16778 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16779 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16780 } 16781 } 16782 app.cached = false; 16783 app.empty = false; 16784 foregroundActivities = true; 16785 } else { 16786 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16787 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16788 app.adjType = "cch-act"; 16789 } 16790 } 16791 } 16792 } 16793 16794 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16795 if (app.foregroundServices) { 16796 // The user is aware of this app, so make it visible. 16797 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16798 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16799 app.cached = false; 16800 app.adjType = "fg-service"; 16801 schedGroup = Process.THREAD_GROUP_DEFAULT; 16802 } else if (app.forcingToForeground != null) { 16803 // The user is aware of this app, so make it visible. 16804 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16805 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16806 app.cached = false; 16807 app.adjType = "force-fg"; 16808 app.adjSource = app.forcingToForeground; 16809 schedGroup = Process.THREAD_GROUP_DEFAULT; 16810 } 16811 } 16812 16813 if (app == mHeavyWeightProcess) { 16814 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16815 // We don't want to kill the current heavy-weight process. 16816 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16817 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16818 app.cached = false; 16819 app.adjType = "heavy"; 16820 } 16821 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16822 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16823 } 16824 } 16825 16826 if (app == mHomeProcess) { 16827 if (adj > ProcessList.HOME_APP_ADJ) { 16828 // This process is hosting what we currently consider to be the 16829 // home app, so we don't want to let it go into the background. 16830 adj = ProcessList.HOME_APP_ADJ; 16831 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16832 app.cached = false; 16833 app.adjType = "home"; 16834 } 16835 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16836 procState = ActivityManager.PROCESS_STATE_HOME; 16837 } 16838 } 16839 16840 if (app == mPreviousProcess && app.activities.size() > 0) { 16841 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16842 // This was the previous process that showed UI to the user. 16843 // We want to try to keep it around more aggressively, to give 16844 // a good experience around switching between two apps. 16845 adj = ProcessList.PREVIOUS_APP_ADJ; 16846 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16847 app.cached = false; 16848 app.adjType = "previous"; 16849 } 16850 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16851 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16852 } 16853 } 16854 16855 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16856 + " reason=" + app.adjType); 16857 16858 // By default, we use the computed adjustment. It may be changed if 16859 // there are applications dependent on our services or providers, but 16860 // this gives us a baseline and makes sure we don't get into an 16861 // infinite recursion. 16862 app.adjSeq = mAdjSeq; 16863 app.curRawAdj = adj; 16864 app.hasStartedServices = false; 16865 16866 if (mBackupTarget != null && app == mBackupTarget.app) { 16867 // If possible we want to avoid killing apps while they're being backed up 16868 if (adj > ProcessList.BACKUP_APP_ADJ) { 16869 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16870 adj = ProcessList.BACKUP_APP_ADJ; 16871 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16872 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16873 } 16874 app.adjType = "backup"; 16875 app.cached = false; 16876 } 16877 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16878 procState = ActivityManager.PROCESS_STATE_BACKUP; 16879 } 16880 } 16881 16882 boolean mayBeTop = false; 16883 16884 for (int is = app.services.size()-1; 16885 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16886 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16887 || procState > ActivityManager.PROCESS_STATE_TOP); 16888 is--) { 16889 ServiceRecord s = app.services.valueAt(is); 16890 if (s.startRequested) { 16891 app.hasStartedServices = true; 16892 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16893 procState = ActivityManager.PROCESS_STATE_SERVICE; 16894 } 16895 if (app.hasShownUi && app != mHomeProcess) { 16896 // If this process has shown some UI, let it immediately 16897 // go to the LRU list because it may be pretty heavy with 16898 // UI stuff. We'll tag it with a label just to help 16899 // debug and understand what is going on. 16900 if (adj > ProcessList.SERVICE_ADJ) { 16901 app.adjType = "cch-started-ui-services"; 16902 } 16903 } else { 16904 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16905 // This service has seen some activity within 16906 // recent memory, so we will keep its process ahead 16907 // of the background processes. 16908 if (adj > ProcessList.SERVICE_ADJ) { 16909 adj = ProcessList.SERVICE_ADJ; 16910 app.adjType = "started-services"; 16911 app.cached = false; 16912 } 16913 } 16914 // If we have let the service slide into the background 16915 // state, still have some text describing what it is doing 16916 // even though the service no longer has an impact. 16917 if (adj > ProcessList.SERVICE_ADJ) { 16918 app.adjType = "cch-started-services"; 16919 } 16920 } 16921 } 16922 for (int conni = s.connections.size()-1; 16923 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16924 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16925 || procState > ActivityManager.PROCESS_STATE_TOP); 16926 conni--) { 16927 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16928 for (int i = 0; 16929 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16930 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16931 || procState > ActivityManager.PROCESS_STATE_TOP); 16932 i++) { 16933 // XXX should compute this based on the max of 16934 // all connected clients. 16935 ConnectionRecord cr = clist.get(i); 16936 if (cr.binding.client == app) { 16937 // Binding to ourself is not interesting. 16938 continue; 16939 } 16940 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16941 ProcessRecord client = cr.binding.client; 16942 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16943 TOP_APP, doingAll, now); 16944 int clientProcState = client.curProcState; 16945 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16946 // If the other app is cached for any reason, for purposes here 16947 // we are going to consider it empty. The specific cached state 16948 // doesn't propagate except under certain conditions. 16949 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16950 } 16951 String adjType = null; 16952 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16953 // Not doing bind OOM management, so treat 16954 // this guy more like a started service. 16955 if (app.hasShownUi && app != mHomeProcess) { 16956 // If this process has shown some UI, let it immediately 16957 // go to the LRU list because it may be pretty heavy with 16958 // UI stuff. We'll tag it with a label just to help 16959 // debug and understand what is going on. 16960 if (adj > clientAdj) { 16961 adjType = "cch-bound-ui-services"; 16962 } 16963 app.cached = false; 16964 clientAdj = adj; 16965 clientProcState = procState; 16966 } else { 16967 if (now >= (s.lastActivity 16968 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16969 // This service has not seen activity within 16970 // recent memory, so allow it to drop to the 16971 // LRU list if there is no other reason to keep 16972 // it around. We'll also tag it with a label just 16973 // to help debug and undertand what is going on. 16974 if (adj > clientAdj) { 16975 adjType = "cch-bound-services"; 16976 } 16977 clientAdj = adj; 16978 } 16979 } 16980 } 16981 if (adj > clientAdj) { 16982 // If this process has recently shown UI, and 16983 // the process that is binding to it is less 16984 // important than being visible, then we don't 16985 // care about the binding as much as we care 16986 // about letting this process get into the LRU 16987 // list to be killed and restarted if needed for 16988 // memory. 16989 if (app.hasShownUi && app != mHomeProcess 16990 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16991 adjType = "cch-bound-ui-services"; 16992 } else { 16993 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16994 |Context.BIND_IMPORTANT)) != 0) { 16995 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16996 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16997 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16998 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16999 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17000 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17001 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17002 adj = clientAdj; 17003 } else { 17004 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17005 adj = ProcessList.VISIBLE_APP_ADJ; 17006 } 17007 } 17008 if (!client.cached) { 17009 app.cached = false; 17010 } 17011 adjType = "service"; 17012 } 17013 } 17014 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17015 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17016 schedGroup = Process.THREAD_GROUP_DEFAULT; 17017 } 17018 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17019 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17020 // Special handling of clients who are in the top state. 17021 // We *may* want to consider this process to be in the 17022 // top state as well, but only if there is not another 17023 // reason for it to be running. Being on the top is a 17024 // special state, meaning you are specifically running 17025 // for the current top app. If the process is already 17026 // running in the background for some other reason, it 17027 // is more important to continue considering it to be 17028 // in the background state. 17029 mayBeTop = true; 17030 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17031 } else { 17032 // Special handling for above-top states (persistent 17033 // processes). These should not bring the current process 17034 // into the top state, since they are not on top. Instead 17035 // give them the best state after that. 17036 clientProcState = 17037 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17038 } 17039 } 17040 } else { 17041 if (clientProcState < 17042 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17043 clientProcState = 17044 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17045 } 17046 } 17047 if (procState > clientProcState) { 17048 procState = clientProcState; 17049 } 17050 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17051 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17052 app.pendingUiClean = true; 17053 } 17054 if (adjType != null) { 17055 app.adjType = adjType; 17056 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17057 .REASON_SERVICE_IN_USE; 17058 app.adjSource = cr.binding.client; 17059 app.adjSourceProcState = clientProcState; 17060 app.adjTarget = s.name; 17061 } 17062 } 17063 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17064 app.treatLikeActivity = true; 17065 } 17066 final ActivityRecord a = cr.activity; 17067 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17068 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17069 (a.visible || a.state == ActivityState.RESUMED 17070 || a.state == ActivityState.PAUSING)) { 17071 adj = ProcessList.FOREGROUND_APP_ADJ; 17072 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17073 schedGroup = Process.THREAD_GROUP_DEFAULT; 17074 } 17075 app.cached = false; 17076 app.adjType = "service"; 17077 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17078 .REASON_SERVICE_IN_USE; 17079 app.adjSource = a; 17080 app.adjSourceProcState = procState; 17081 app.adjTarget = s.name; 17082 } 17083 } 17084 } 17085 } 17086 } 17087 17088 for (int provi = app.pubProviders.size()-1; 17089 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17090 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17091 || procState > ActivityManager.PROCESS_STATE_TOP); 17092 provi--) { 17093 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17094 for (int i = cpr.connections.size()-1; 17095 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17096 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17097 || procState > ActivityManager.PROCESS_STATE_TOP); 17098 i--) { 17099 ContentProviderConnection conn = cpr.connections.get(i); 17100 ProcessRecord client = conn.client; 17101 if (client == app) { 17102 // Being our own client is not interesting. 17103 continue; 17104 } 17105 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17106 int clientProcState = client.curProcState; 17107 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17108 // If the other app is cached for any reason, for purposes here 17109 // we are going to consider it empty. 17110 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17111 } 17112 if (adj > clientAdj) { 17113 if (app.hasShownUi && app != mHomeProcess 17114 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17115 app.adjType = "cch-ui-provider"; 17116 } else { 17117 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17118 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17119 app.adjType = "provider"; 17120 } 17121 app.cached &= client.cached; 17122 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17123 .REASON_PROVIDER_IN_USE; 17124 app.adjSource = client; 17125 app.adjSourceProcState = clientProcState; 17126 app.adjTarget = cpr.name; 17127 } 17128 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17129 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17130 // Special handling of clients who are in the top state. 17131 // We *may* want to consider this process to be in the 17132 // top state as well, but only if there is not another 17133 // reason for it to be running. Being on the top is a 17134 // special state, meaning you are specifically running 17135 // for the current top app. If the process is already 17136 // running in the background for some other reason, it 17137 // is more important to continue considering it to be 17138 // in the background state. 17139 mayBeTop = true; 17140 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17141 } else { 17142 // Special handling for above-top states (persistent 17143 // processes). These should not bring the current process 17144 // into the top state, since they are not on top. Instead 17145 // give them the best state after that. 17146 clientProcState = 17147 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17148 } 17149 } 17150 if (procState > clientProcState) { 17151 procState = clientProcState; 17152 } 17153 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17154 schedGroup = Process.THREAD_GROUP_DEFAULT; 17155 } 17156 } 17157 // If the provider has external (non-framework) process 17158 // dependencies, ensure that its adjustment is at least 17159 // FOREGROUND_APP_ADJ. 17160 if (cpr.hasExternalProcessHandles()) { 17161 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17162 adj = ProcessList.FOREGROUND_APP_ADJ; 17163 schedGroup = Process.THREAD_GROUP_DEFAULT; 17164 app.cached = false; 17165 app.adjType = "provider"; 17166 app.adjTarget = cpr.name; 17167 } 17168 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17169 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17170 } 17171 } 17172 } 17173 17174 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17175 // A client of one of our services or providers is in the top state. We 17176 // *may* want to be in the top state, but not if we are already running in 17177 // the background for some other reason. For the decision here, we are going 17178 // to pick out a few specific states that we want to remain in when a client 17179 // is top (states that tend to be longer-term) and otherwise allow it to go 17180 // to the top state. 17181 switch (procState) { 17182 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17183 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17184 case ActivityManager.PROCESS_STATE_SERVICE: 17185 // These all are longer-term states, so pull them up to the top 17186 // of the background states, but not all the way to the top state. 17187 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17188 break; 17189 default: 17190 // Otherwise, top is a better choice, so take it. 17191 procState = ActivityManager.PROCESS_STATE_TOP; 17192 break; 17193 } 17194 } 17195 17196 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17197 if (app.hasClientActivities) { 17198 // This is a cached process, but with client activities. Mark it so. 17199 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17200 app.adjType = "cch-client-act"; 17201 } else if (app.treatLikeActivity) { 17202 // This is a cached process, but somebody wants us to treat it like it has 17203 // an activity, okay! 17204 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17205 app.adjType = "cch-as-act"; 17206 } 17207 } 17208 17209 if (adj == ProcessList.SERVICE_ADJ) { 17210 if (doingAll) { 17211 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17212 mNewNumServiceProcs++; 17213 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17214 if (!app.serviceb) { 17215 // This service isn't far enough down on the LRU list to 17216 // normally be a B service, but if we are low on RAM and it 17217 // is large we want to force it down since we would prefer to 17218 // keep launcher over it. 17219 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17220 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17221 app.serviceHighRam = true; 17222 app.serviceb = true; 17223 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17224 } else { 17225 mNewNumAServiceProcs++; 17226 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17227 } 17228 } else { 17229 app.serviceHighRam = false; 17230 } 17231 } 17232 if (app.serviceb) { 17233 adj = ProcessList.SERVICE_B_ADJ; 17234 } 17235 } 17236 17237 app.curRawAdj = adj; 17238 17239 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17240 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17241 if (adj > app.maxAdj) { 17242 adj = app.maxAdj; 17243 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17244 schedGroup = Process.THREAD_GROUP_DEFAULT; 17245 } 17246 } 17247 17248 // Do final modification to adj. Everything we do between here and applying 17249 // the final setAdj must be done in this function, because we will also use 17250 // it when computing the final cached adj later. Note that we don't need to 17251 // worry about this for max adj above, since max adj will always be used to 17252 // keep it out of the cached vaues. 17253 app.curAdj = app.modifyRawOomAdj(adj); 17254 app.curSchedGroup = schedGroup; 17255 app.curProcState = procState; 17256 app.foregroundActivities = foregroundActivities; 17257 17258 return app.curRawAdj; 17259 } 17260 17261 /** 17262 * Schedule PSS collection of a process. 17263 */ 17264 void requestPssLocked(ProcessRecord proc, int procState) { 17265 if (mPendingPssProcesses.contains(proc)) { 17266 return; 17267 } 17268 if (mPendingPssProcesses.size() == 0) { 17269 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17270 } 17271 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17272 proc.pssProcState = procState; 17273 mPendingPssProcesses.add(proc); 17274 } 17275 17276 /** 17277 * Schedule PSS collection of all processes. 17278 */ 17279 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17280 if (!always) { 17281 if (now < (mLastFullPssTime + 17282 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17283 return; 17284 } 17285 } 17286 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17287 mLastFullPssTime = now; 17288 mFullPssPending = true; 17289 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17290 mPendingPssProcesses.clear(); 17291 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17292 ProcessRecord app = mLruProcesses.get(i); 17293 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17294 app.pssProcState = app.setProcState; 17295 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17296 isSleeping(), now); 17297 mPendingPssProcesses.add(app); 17298 } 17299 } 17300 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17301 } 17302 17303 /** 17304 * Ask a given process to GC right now. 17305 */ 17306 final void performAppGcLocked(ProcessRecord app) { 17307 try { 17308 app.lastRequestedGc = SystemClock.uptimeMillis(); 17309 if (app.thread != null) { 17310 if (app.reportLowMemory) { 17311 app.reportLowMemory = false; 17312 app.thread.scheduleLowMemory(); 17313 } else { 17314 app.thread.processInBackground(); 17315 } 17316 } 17317 } catch (Exception e) { 17318 // whatever. 17319 } 17320 } 17321 17322 /** 17323 * Returns true if things are idle enough to perform GCs. 17324 */ 17325 private final boolean canGcNowLocked() { 17326 boolean processingBroadcasts = false; 17327 for (BroadcastQueue q : mBroadcastQueues) { 17328 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17329 processingBroadcasts = true; 17330 } 17331 } 17332 return !processingBroadcasts 17333 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17334 } 17335 17336 /** 17337 * Perform GCs on all processes that are waiting for it, but only 17338 * if things are idle. 17339 */ 17340 final void performAppGcsLocked() { 17341 final int N = mProcessesToGc.size(); 17342 if (N <= 0) { 17343 return; 17344 } 17345 if (canGcNowLocked()) { 17346 while (mProcessesToGc.size() > 0) { 17347 ProcessRecord proc = mProcessesToGc.remove(0); 17348 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17349 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17350 <= SystemClock.uptimeMillis()) { 17351 // To avoid spamming the system, we will GC processes one 17352 // at a time, waiting a few seconds between each. 17353 performAppGcLocked(proc); 17354 scheduleAppGcsLocked(); 17355 return; 17356 } else { 17357 // It hasn't been long enough since we last GCed this 17358 // process... put it in the list to wait for its time. 17359 addProcessToGcListLocked(proc); 17360 break; 17361 } 17362 } 17363 } 17364 17365 scheduleAppGcsLocked(); 17366 } 17367 } 17368 17369 /** 17370 * If all looks good, perform GCs on all processes waiting for them. 17371 */ 17372 final void performAppGcsIfAppropriateLocked() { 17373 if (canGcNowLocked()) { 17374 performAppGcsLocked(); 17375 return; 17376 } 17377 // Still not idle, wait some more. 17378 scheduleAppGcsLocked(); 17379 } 17380 17381 /** 17382 * Schedule the execution of all pending app GCs. 17383 */ 17384 final void scheduleAppGcsLocked() { 17385 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17386 17387 if (mProcessesToGc.size() > 0) { 17388 // Schedule a GC for the time to the next process. 17389 ProcessRecord proc = mProcessesToGc.get(0); 17390 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17391 17392 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17393 long now = SystemClock.uptimeMillis(); 17394 if (when < (now+GC_TIMEOUT)) { 17395 when = now + GC_TIMEOUT; 17396 } 17397 mHandler.sendMessageAtTime(msg, when); 17398 } 17399 } 17400 17401 /** 17402 * Add a process to the array of processes waiting to be GCed. Keeps the 17403 * list in sorted order by the last GC time. The process can't already be 17404 * on the list. 17405 */ 17406 final void addProcessToGcListLocked(ProcessRecord proc) { 17407 boolean added = false; 17408 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17409 if (mProcessesToGc.get(i).lastRequestedGc < 17410 proc.lastRequestedGc) { 17411 added = true; 17412 mProcessesToGc.add(i+1, proc); 17413 break; 17414 } 17415 } 17416 if (!added) { 17417 mProcessesToGc.add(0, proc); 17418 } 17419 } 17420 17421 /** 17422 * Set up to ask a process to GC itself. This will either do it 17423 * immediately, or put it on the list of processes to gc the next 17424 * time things are idle. 17425 */ 17426 final void scheduleAppGcLocked(ProcessRecord app) { 17427 long now = SystemClock.uptimeMillis(); 17428 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17429 return; 17430 } 17431 if (!mProcessesToGc.contains(app)) { 17432 addProcessToGcListLocked(app); 17433 scheduleAppGcsLocked(); 17434 } 17435 } 17436 17437 final void checkExcessivePowerUsageLocked(boolean doKills) { 17438 updateCpuStatsNow(); 17439 17440 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17441 boolean doWakeKills = doKills; 17442 boolean doCpuKills = doKills; 17443 if (mLastPowerCheckRealtime == 0) { 17444 doWakeKills = false; 17445 } 17446 if (mLastPowerCheckUptime == 0) { 17447 doCpuKills = false; 17448 } 17449 if (stats.isScreenOn()) { 17450 doWakeKills = false; 17451 } 17452 final long curRealtime = SystemClock.elapsedRealtime(); 17453 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17454 final long curUptime = SystemClock.uptimeMillis(); 17455 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17456 mLastPowerCheckRealtime = curRealtime; 17457 mLastPowerCheckUptime = curUptime; 17458 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17459 doWakeKills = false; 17460 } 17461 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17462 doCpuKills = false; 17463 } 17464 int i = mLruProcesses.size(); 17465 while (i > 0) { 17466 i--; 17467 ProcessRecord app = mLruProcesses.get(i); 17468 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17469 long wtime; 17470 synchronized (stats) { 17471 wtime = stats.getProcessWakeTime(app.info.uid, 17472 app.pid, curRealtime); 17473 } 17474 long wtimeUsed = wtime - app.lastWakeTime; 17475 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17476 if (DEBUG_POWER) { 17477 StringBuilder sb = new StringBuilder(128); 17478 sb.append("Wake for "); 17479 app.toShortString(sb); 17480 sb.append(": over "); 17481 TimeUtils.formatDuration(realtimeSince, sb); 17482 sb.append(" used "); 17483 TimeUtils.formatDuration(wtimeUsed, sb); 17484 sb.append(" ("); 17485 sb.append((wtimeUsed*100)/realtimeSince); 17486 sb.append("%)"); 17487 Slog.i(TAG, sb.toString()); 17488 sb.setLength(0); 17489 sb.append("CPU for "); 17490 app.toShortString(sb); 17491 sb.append(": over "); 17492 TimeUtils.formatDuration(uptimeSince, sb); 17493 sb.append(" used "); 17494 TimeUtils.formatDuration(cputimeUsed, sb); 17495 sb.append(" ("); 17496 sb.append((cputimeUsed*100)/uptimeSince); 17497 sb.append("%)"); 17498 Slog.i(TAG, sb.toString()); 17499 } 17500 // If a process has held a wake lock for more 17501 // than 50% of the time during this period, 17502 // that sounds bad. Kill! 17503 if (doWakeKills && realtimeSince > 0 17504 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17505 synchronized (stats) { 17506 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17507 realtimeSince, wtimeUsed); 17508 } 17509 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17510 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17511 } else if (doCpuKills && uptimeSince > 0 17512 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17513 synchronized (stats) { 17514 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17515 uptimeSince, cputimeUsed); 17516 } 17517 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17518 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17519 } else { 17520 app.lastWakeTime = wtime; 17521 app.lastCpuTime = app.curCpuTime; 17522 } 17523 } 17524 } 17525 } 17526 17527 private final boolean applyOomAdjLocked(ProcessRecord app, 17528 ProcessRecord TOP_APP, boolean doingAll, long now) { 17529 boolean success = true; 17530 17531 if (app.curRawAdj != app.setRawAdj) { 17532 app.setRawAdj = app.curRawAdj; 17533 } 17534 17535 int changes = 0; 17536 17537 if (app.curAdj != app.setAdj) { 17538 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17539 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17540 TAG, "Set " + app.pid + " " + app.processName + 17541 " adj " + app.curAdj + ": " + app.adjType); 17542 app.setAdj = app.curAdj; 17543 } 17544 17545 if (app.setSchedGroup != app.curSchedGroup) { 17546 app.setSchedGroup = app.curSchedGroup; 17547 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17548 "Setting process group of " + app.processName 17549 + " to " + app.curSchedGroup); 17550 if (app.waitingToKill != null && 17551 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17552 app.kill(app.waitingToKill, true); 17553 success = false; 17554 } else { 17555 if (true) { 17556 long oldId = Binder.clearCallingIdentity(); 17557 try { 17558 Process.setProcessGroup(app.pid, app.curSchedGroup); 17559 } catch (Exception e) { 17560 Slog.w(TAG, "Failed setting process group of " + app.pid 17561 + " to " + app.curSchedGroup); 17562 e.printStackTrace(); 17563 } finally { 17564 Binder.restoreCallingIdentity(oldId); 17565 } 17566 } else { 17567 if (app.thread != null) { 17568 try { 17569 app.thread.setSchedulingGroup(app.curSchedGroup); 17570 } catch (RemoteException e) { 17571 } 17572 } 17573 } 17574 Process.setSwappiness(app.pid, 17575 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17576 } 17577 } 17578 if (app.repForegroundActivities != app.foregroundActivities) { 17579 app.repForegroundActivities = app.foregroundActivities; 17580 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17581 } 17582 if (app.repProcState != app.curProcState) { 17583 app.repProcState = app.curProcState; 17584 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17585 if (app.thread != null) { 17586 try { 17587 if (false) { 17588 //RuntimeException h = new RuntimeException("here"); 17589 Slog.i(TAG, "Sending new process state " + app.repProcState 17590 + " to " + app /*, h*/); 17591 } 17592 app.thread.setProcessState(app.repProcState); 17593 } catch (RemoteException e) { 17594 } 17595 } 17596 } 17597 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17598 app.setProcState)) { 17599 app.lastStateTime = now; 17600 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17601 isSleeping(), now); 17602 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17603 + ProcessList.makeProcStateString(app.setProcState) + " to " 17604 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17605 + (app.nextPssTime-now) + ": " + app); 17606 } else { 17607 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17608 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17609 requestPssLocked(app, app.setProcState); 17610 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17611 isSleeping(), now); 17612 } else if (false && DEBUG_PSS) { 17613 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17614 } 17615 } 17616 if (app.setProcState != app.curProcState) { 17617 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17618 "Proc state change of " + app.processName 17619 + " to " + app.curProcState); 17620 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17621 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17622 if (setImportant && !curImportant) { 17623 // This app is no longer something we consider important enough to allow to 17624 // use arbitrary amounts of battery power. Note 17625 // its current wake lock time to later know to kill it if 17626 // it is not behaving well. 17627 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17628 synchronized (stats) { 17629 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17630 app.pid, SystemClock.elapsedRealtime()); 17631 } 17632 app.lastCpuTime = app.curCpuTime; 17633 17634 } 17635 app.setProcState = app.curProcState; 17636 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17637 app.notCachedSinceIdle = false; 17638 } 17639 if (!doingAll) { 17640 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17641 } else { 17642 app.procStateChanged = true; 17643 } 17644 } 17645 17646 if (changes != 0) { 17647 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17648 int i = mPendingProcessChanges.size()-1; 17649 ProcessChangeItem item = null; 17650 while (i >= 0) { 17651 item = mPendingProcessChanges.get(i); 17652 if (item.pid == app.pid) { 17653 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17654 break; 17655 } 17656 i--; 17657 } 17658 if (i < 0) { 17659 // No existing item in pending changes; need a new one. 17660 final int NA = mAvailProcessChanges.size(); 17661 if (NA > 0) { 17662 item = mAvailProcessChanges.remove(NA-1); 17663 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17664 } else { 17665 item = new ProcessChangeItem(); 17666 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17667 } 17668 item.changes = 0; 17669 item.pid = app.pid; 17670 item.uid = app.info.uid; 17671 if (mPendingProcessChanges.size() == 0) { 17672 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17673 "*** Enqueueing dispatch processes changed!"); 17674 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17675 } 17676 mPendingProcessChanges.add(item); 17677 } 17678 item.changes |= changes; 17679 item.processState = app.repProcState; 17680 item.foregroundActivities = app.repForegroundActivities; 17681 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17682 + Integer.toHexString(System.identityHashCode(item)) 17683 + " " + app.toShortString() + ": changes=" + item.changes 17684 + " procState=" + item.processState 17685 + " foreground=" + item.foregroundActivities 17686 + " type=" + app.adjType + " source=" + app.adjSource 17687 + " target=" + app.adjTarget); 17688 } 17689 17690 return success; 17691 } 17692 17693 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17694 if (proc.thread != null) { 17695 if (proc.baseProcessTracker != null) { 17696 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17697 } 17698 if (proc.repProcState >= 0) { 17699 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17700 proc.repProcState); 17701 } 17702 } 17703 } 17704 17705 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17706 ProcessRecord TOP_APP, boolean doingAll, long now) { 17707 if (app.thread == null) { 17708 return false; 17709 } 17710 17711 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17712 17713 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17714 } 17715 17716 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17717 boolean oomAdj) { 17718 if (isForeground != proc.foregroundServices) { 17719 proc.foregroundServices = isForeground; 17720 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17721 proc.info.uid); 17722 if (isForeground) { 17723 if (curProcs == null) { 17724 curProcs = new ArrayList<ProcessRecord>(); 17725 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17726 } 17727 if (!curProcs.contains(proc)) { 17728 curProcs.add(proc); 17729 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17730 proc.info.packageName, proc.info.uid); 17731 } 17732 } else { 17733 if (curProcs != null) { 17734 if (curProcs.remove(proc)) { 17735 mBatteryStatsService.noteEvent( 17736 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17737 proc.info.packageName, proc.info.uid); 17738 if (curProcs.size() <= 0) { 17739 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17740 } 17741 } 17742 } 17743 } 17744 if (oomAdj) { 17745 updateOomAdjLocked(); 17746 } 17747 } 17748 } 17749 17750 private final ActivityRecord resumedAppLocked() { 17751 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17752 String pkg; 17753 int uid; 17754 if (act != null) { 17755 pkg = act.packageName; 17756 uid = act.info.applicationInfo.uid; 17757 } else { 17758 pkg = null; 17759 uid = -1; 17760 } 17761 // Has the UID or resumed package name changed? 17762 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17763 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17764 if (mCurResumedPackage != null) { 17765 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17766 mCurResumedPackage, mCurResumedUid); 17767 } 17768 mCurResumedPackage = pkg; 17769 mCurResumedUid = uid; 17770 if (mCurResumedPackage != null) { 17771 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17772 mCurResumedPackage, mCurResumedUid); 17773 } 17774 } 17775 return act; 17776 } 17777 17778 final boolean updateOomAdjLocked(ProcessRecord app) { 17779 final ActivityRecord TOP_ACT = resumedAppLocked(); 17780 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17781 final boolean wasCached = app.cached; 17782 17783 mAdjSeq++; 17784 17785 // This is the desired cached adjusment we want to tell it to use. 17786 // If our app is currently cached, we know it, and that is it. Otherwise, 17787 // we don't know it yet, and it needs to now be cached we will then 17788 // need to do a complete oom adj. 17789 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17790 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17791 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17792 SystemClock.uptimeMillis()); 17793 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17794 // Changed to/from cached state, so apps after it in the LRU 17795 // list may also be changed. 17796 updateOomAdjLocked(); 17797 } 17798 return success; 17799 } 17800 17801 final void updateOomAdjLocked() { 17802 final ActivityRecord TOP_ACT = resumedAppLocked(); 17803 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17804 final long now = SystemClock.uptimeMillis(); 17805 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17806 final int N = mLruProcesses.size(); 17807 17808 if (false) { 17809 RuntimeException e = new RuntimeException(); 17810 e.fillInStackTrace(); 17811 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17812 } 17813 17814 mAdjSeq++; 17815 mNewNumServiceProcs = 0; 17816 mNewNumAServiceProcs = 0; 17817 17818 final int emptyProcessLimit; 17819 final int cachedProcessLimit; 17820 if (mProcessLimit <= 0) { 17821 emptyProcessLimit = cachedProcessLimit = 0; 17822 } else if (mProcessLimit == 1) { 17823 emptyProcessLimit = 1; 17824 cachedProcessLimit = 0; 17825 } else { 17826 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17827 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17828 } 17829 17830 // Let's determine how many processes we have running vs. 17831 // how many slots we have for background processes; we may want 17832 // to put multiple processes in a slot of there are enough of 17833 // them. 17834 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17835 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17836 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17837 if (numEmptyProcs > cachedProcessLimit) { 17838 // If there are more empty processes than our limit on cached 17839 // processes, then use the cached process limit for the factor. 17840 // This ensures that the really old empty processes get pushed 17841 // down to the bottom, so if we are running low on memory we will 17842 // have a better chance at keeping around more cached processes 17843 // instead of a gazillion empty processes. 17844 numEmptyProcs = cachedProcessLimit; 17845 } 17846 int emptyFactor = numEmptyProcs/numSlots; 17847 if (emptyFactor < 1) emptyFactor = 1; 17848 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17849 if (cachedFactor < 1) cachedFactor = 1; 17850 int stepCached = 0; 17851 int stepEmpty = 0; 17852 int numCached = 0; 17853 int numEmpty = 0; 17854 int numTrimming = 0; 17855 17856 mNumNonCachedProcs = 0; 17857 mNumCachedHiddenProcs = 0; 17858 17859 // First update the OOM adjustment for each of the 17860 // application processes based on their current state. 17861 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17862 int nextCachedAdj = curCachedAdj+1; 17863 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17864 int nextEmptyAdj = curEmptyAdj+2; 17865 for (int i=N-1; i>=0; i--) { 17866 ProcessRecord app = mLruProcesses.get(i); 17867 if (!app.killedByAm && app.thread != null) { 17868 app.procStateChanged = false; 17869 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17870 17871 // If we haven't yet assigned the final cached adj 17872 // to the process, do that now. 17873 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17874 switch (app.curProcState) { 17875 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17876 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17877 // This process is a cached process holding activities... 17878 // assign it the next cached value for that type, and then 17879 // step that cached level. 17880 app.curRawAdj = curCachedAdj; 17881 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17882 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17883 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17884 + ")"); 17885 if (curCachedAdj != nextCachedAdj) { 17886 stepCached++; 17887 if (stepCached >= cachedFactor) { 17888 stepCached = 0; 17889 curCachedAdj = nextCachedAdj; 17890 nextCachedAdj += 2; 17891 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17892 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17893 } 17894 } 17895 } 17896 break; 17897 default: 17898 // For everything else, assign next empty cached process 17899 // level and bump that up. Note that this means that 17900 // long-running services that have dropped down to the 17901 // cached level will be treated as empty (since their process 17902 // state is still as a service), which is what we want. 17903 app.curRawAdj = curEmptyAdj; 17904 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17905 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17906 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17907 + ")"); 17908 if (curEmptyAdj != nextEmptyAdj) { 17909 stepEmpty++; 17910 if (stepEmpty >= emptyFactor) { 17911 stepEmpty = 0; 17912 curEmptyAdj = nextEmptyAdj; 17913 nextEmptyAdj += 2; 17914 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17915 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17916 } 17917 } 17918 } 17919 break; 17920 } 17921 } 17922 17923 applyOomAdjLocked(app, TOP_APP, true, now); 17924 17925 // Count the number of process types. 17926 switch (app.curProcState) { 17927 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17928 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17929 mNumCachedHiddenProcs++; 17930 numCached++; 17931 if (numCached > cachedProcessLimit) { 17932 app.kill("cached #" + numCached, true); 17933 } 17934 break; 17935 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17936 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17937 && app.lastActivityTime < oldTime) { 17938 app.kill("empty for " 17939 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17940 / 1000) + "s", true); 17941 } else { 17942 numEmpty++; 17943 if (numEmpty > emptyProcessLimit) { 17944 app.kill("empty #" + numEmpty, true); 17945 } 17946 } 17947 break; 17948 default: 17949 mNumNonCachedProcs++; 17950 break; 17951 } 17952 17953 if (app.isolated && app.services.size() <= 0) { 17954 // If this is an isolated process, and there are no 17955 // services running in it, then the process is no longer 17956 // needed. We agressively kill these because we can by 17957 // definition not re-use the same process again, and it is 17958 // good to avoid having whatever code was running in them 17959 // left sitting around after no longer needed. 17960 app.kill("isolated not needed", true); 17961 } 17962 17963 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17964 && !app.killedByAm) { 17965 numTrimming++; 17966 } 17967 } 17968 } 17969 17970 mNumServiceProcs = mNewNumServiceProcs; 17971 17972 // Now determine the memory trimming level of background processes. 17973 // Unfortunately we need to start at the back of the list to do this 17974 // properly. We only do this if the number of background apps we 17975 // are managing to keep around is less than half the maximum we desire; 17976 // if we are keeping a good number around, we'll let them use whatever 17977 // memory they want. 17978 final int numCachedAndEmpty = numCached + numEmpty; 17979 int memFactor; 17980 if (numCached <= ProcessList.TRIM_CACHED_APPS 17981 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17982 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17983 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17984 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17985 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17986 } else { 17987 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17988 } 17989 } else { 17990 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17991 } 17992 // We always allow the memory level to go up (better). We only allow it to go 17993 // down if we are in a state where that is allowed, *and* the total number of processes 17994 // has gone down since last time. 17995 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17996 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17997 + " last=" + mLastNumProcesses); 17998 if (memFactor > mLastMemoryLevel) { 17999 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18000 memFactor = mLastMemoryLevel; 18001 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18002 } 18003 } 18004 mLastMemoryLevel = memFactor; 18005 mLastNumProcesses = mLruProcesses.size(); 18006 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18007 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18008 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18009 if (mLowRamStartTime == 0) { 18010 mLowRamStartTime = now; 18011 } 18012 int step = 0; 18013 int fgTrimLevel; 18014 switch (memFactor) { 18015 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18016 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18017 break; 18018 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18019 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18020 break; 18021 default: 18022 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18023 break; 18024 } 18025 int factor = numTrimming/3; 18026 int minFactor = 2; 18027 if (mHomeProcess != null) minFactor++; 18028 if (mPreviousProcess != null) minFactor++; 18029 if (factor < minFactor) factor = minFactor; 18030 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18031 for (int i=N-1; i>=0; i--) { 18032 ProcessRecord app = mLruProcesses.get(i); 18033 if (allChanged || app.procStateChanged) { 18034 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18035 app.procStateChanged = false; 18036 } 18037 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18038 && !app.killedByAm) { 18039 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18040 try { 18041 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18042 "Trimming memory of " + app.processName 18043 + " to " + curLevel); 18044 app.thread.scheduleTrimMemory(curLevel); 18045 } catch (RemoteException e) { 18046 } 18047 if (false) { 18048 // For now we won't do this; our memory trimming seems 18049 // to be good enough at this point that destroying 18050 // activities causes more harm than good. 18051 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18052 && app != mHomeProcess && app != mPreviousProcess) { 18053 // Need to do this on its own message because the stack may not 18054 // be in a consistent state at this point. 18055 // For these apps we will also finish their activities 18056 // to help them free memory. 18057 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18058 } 18059 } 18060 } 18061 app.trimMemoryLevel = curLevel; 18062 step++; 18063 if (step >= factor) { 18064 step = 0; 18065 switch (curLevel) { 18066 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18067 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18068 break; 18069 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18070 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18071 break; 18072 } 18073 } 18074 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18075 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18076 && app.thread != null) { 18077 try { 18078 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18079 "Trimming memory of heavy-weight " + app.processName 18080 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18081 app.thread.scheduleTrimMemory( 18082 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18083 } catch (RemoteException e) { 18084 } 18085 } 18086 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18087 } else { 18088 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18089 || app.systemNoUi) && app.pendingUiClean) { 18090 // If this application is now in the background and it 18091 // had done UI, then give it the special trim level to 18092 // have it free UI resources. 18093 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18094 if (app.trimMemoryLevel < level && app.thread != null) { 18095 try { 18096 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18097 "Trimming memory of bg-ui " + app.processName 18098 + " to " + level); 18099 app.thread.scheduleTrimMemory(level); 18100 } catch (RemoteException e) { 18101 } 18102 } 18103 app.pendingUiClean = false; 18104 } 18105 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18106 try { 18107 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18108 "Trimming memory of fg " + app.processName 18109 + " to " + fgTrimLevel); 18110 app.thread.scheduleTrimMemory(fgTrimLevel); 18111 } catch (RemoteException e) { 18112 } 18113 } 18114 app.trimMemoryLevel = fgTrimLevel; 18115 } 18116 } 18117 } else { 18118 if (mLowRamStartTime != 0) { 18119 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18120 mLowRamStartTime = 0; 18121 } 18122 for (int i=N-1; i>=0; i--) { 18123 ProcessRecord app = mLruProcesses.get(i); 18124 if (allChanged || app.procStateChanged) { 18125 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18126 app.procStateChanged = false; 18127 } 18128 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18129 || app.systemNoUi) && app.pendingUiClean) { 18130 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18131 && app.thread != null) { 18132 try { 18133 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18134 "Trimming memory of ui hidden " + app.processName 18135 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18136 app.thread.scheduleTrimMemory( 18137 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18138 } catch (RemoteException e) { 18139 } 18140 } 18141 app.pendingUiClean = false; 18142 } 18143 app.trimMemoryLevel = 0; 18144 } 18145 } 18146 18147 if (mAlwaysFinishActivities) { 18148 // Need to do this on its own message because the stack may not 18149 // be in a consistent state at this point. 18150 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18151 } 18152 18153 if (allChanged) { 18154 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18155 } 18156 18157 if (mProcessStats.shouldWriteNowLocked(now)) { 18158 mHandler.post(new Runnable() { 18159 @Override public void run() { 18160 synchronized (ActivityManagerService.this) { 18161 mProcessStats.writeStateAsyncLocked(); 18162 } 18163 } 18164 }); 18165 } 18166 18167 if (DEBUG_OOM_ADJ) { 18168 if (false) { 18169 RuntimeException here = new RuntimeException("here"); 18170 here.fillInStackTrace(); 18171 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18172 } else { 18173 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18174 } 18175 } 18176 } 18177 18178 final void trimApplications() { 18179 synchronized (this) { 18180 int i; 18181 18182 // First remove any unused application processes whose package 18183 // has been removed. 18184 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18185 final ProcessRecord app = mRemovedProcesses.get(i); 18186 if (app.activities.size() == 0 18187 && app.curReceiver == null && app.services.size() == 0) { 18188 Slog.i( 18189 TAG, "Exiting empty application process " 18190 + app.processName + " (" 18191 + (app.thread != null ? app.thread.asBinder() : null) 18192 + ")\n"); 18193 if (app.pid > 0 && app.pid != MY_PID) { 18194 app.kill("empty", false); 18195 } else { 18196 try { 18197 app.thread.scheduleExit(); 18198 } catch (Exception e) { 18199 // Ignore exceptions. 18200 } 18201 } 18202 cleanUpApplicationRecordLocked(app, false, true, -1); 18203 mRemovedProcesses.remove(i); 18204 18205 if (app.persistent) { 18206 addAppLocked(app.info, false, null /* ABI override */); 18207 } 18208 } 18209 } 18210 18211 // Now update the oom adj for all processes. 18212 updateOomAdjLocked(); 18213 } 18214 } 18215 18216 /** This method sends the specified signal to each of the persistent apps */ 18217 public void signalPersistentProcesses(int sig) throws RemoteException { 18218 if (sig != Process.SIGNAL_USR1) { 18219 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18220 } 18221 18222 synchronized (this) { 18223 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18224 != PackageManager.PERMISSION_GRANTED) { 18225 throw new SecurityException("Requires permission " 18226 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18227 } 18228 18229 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18230 ProcessRecord r = mLruProcesses.get(i); 18231 if (r.thread != null && r.persistent) { 18232 Process.sendSignal(r.pid, sig); 18233 } 18234 } 18235 } 18236 } 18237 18238 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18239 if (proc == null || proc == mProfileProc) { 18240 proc = mProfileProc; 18241 profileType = mProfileType; 18242 clearProfilerLocked(); 18243 } 18244 if (proc == null) { 18245 return; 18246 } 18247 try { 18248 proc.thread.profilerControl(false, null, profileType); 18249 } catch (RemoteException e) { 18250 throw new IllegalStateException("Process disappeared"); 18251 } 18252 } 18253 18254 private void clearProfilerLocked() { 18255 if (mProfileFd != null) { 18256 try { 18257 mProfileFd.close(); 18258 } catch (IOException e) { 18259 } 18260 } 18261 mProfileApp = null; 18262 mProfileProc = null; 18263 mProfileFile = null; 18264 mProfileType = 0; 18265 mAutoStopProfiler = false; 18266 mSamplingInterval = 0; 18267 } 18268 18269 public boolean profileControl(String process, int userId, boolean start, 18270 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18271 18272 try { 18273 synchronized (this) { 18274 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18275 // its own permission. 18276 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18277 != PackageManager.PERMISSION_GRANTED) { 18278 throw new SecurityException("Requires permission " 18279 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18280 } 18281 18282 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18283 throw new IllegalArgumentException("null profile info or fd"); 18284 } 18285 18286 ProcessRecord proc = null; 18287 if (process != null) { 18288 proc = findProcessLocked(process, userId, "profileControl"); 18289 } 18290 18291 if (start && (proc == null || proc.thread == null)) { 18292 throw new IllegalArgumentException("Unknown process: " + process); 18293 } 18294 18295 if (start) { 18296 stopProfilerLocked(null, 0); 18297 setProfileApp(proc.info, proc.processName, profilerInfo); 18298 mProfileProc = proc; 18299 mProfileType = profileType; 18300 ParcelFileDescriptor fd = profilerInfo.profileFd; 18301 try { 18302 fd = fd.dup(); 18303 } catch (IOException e) { 18304 fd = null; 18305 } 18306 profilerInfo.profileFd = fd; 18307 proc.thread.profilerControl(start, profilerInfo, profileType); 18308 fd = null; 18309 mProfileFd = null; 18310 } else { 18311 stopProfilerLocked(proc, profileType); 18312 if (profilerInfo != null && profilerInfo.profileFd != null) { 18313 try { 18314 profilerInfo.profileFd.close(); 18315 } catch (IOException e) { 18316 } 18317 } 18318 } 18319 18320 return true; 18321 } 18322 } catch (RemoteException e) { 18323 throw new IllegalStateException("Process disappeared"); 18324 } finally { 18325 if (profilerInfo != null && profilerInfo.profileFd != null) { 18326 try { 18327 profilerInfo.profileFd.close(); 18328 } catch (IOException e) { 18329 } 18330 } 18331 } 18332 } 18333 18334 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18335 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18336 userId, true, ALLOW_FULL_ONLY, callName, null); 18337 ProcessRecord proc = null; 18338 try { 18339 int pid = Integer.parseInt(process); 18340 synchronized (mPidsSelfLocked) { 18341 proc = mPidsSelfLocked.get(pid); 18342 } 18343 } catch (NumberFormatException e) { 18344 } 18345 18346 if (proc == null) { 18347 ArrayMap<String, SparseArray<ProcessRecord>> all 18348 = mProcessNames.getMap(); 18349 SparseArray<ProcessRecord> procs = all.get(process); 18350 if (procs != null && procs.size() > 0) { 18351 proc = procs.valueAt(0); 18352 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18353 for (int i=1; i<procs.size(); i++) { 18354 ProcessRecord thisProc = procs.valueAt(i); 18355 if (thisProc.userId == userId) { 18356 proc = thisProc; 18357 break; 18358 } 18359 } 18360 } 18361 } 18362 } 18363 18364 return proc; 18365 } 18366 18367 public boolean dumpHeap(String process, int userId, boolean managed, 18368 String path, ParcelFileDescriptor fd) throws RemoteException { 18369 18370 try { 18371 synchronized (this) { 18372 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18373 // its own permission (same as profileControl). 18374 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18375 != PackageManager.PERMISSION_GRANTED) { 18376 throw new SecurityException("Requires permission " 18377 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18378 } 18379 18380 if (fd == null) { 18381 throw new IllegalArgumentException("null fd"); 18382 } 18383 18384 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18385 if (proc == null || proc.thread == null) { 18386 throw new IllegalArgumentException("Unknown process: " + process); 18387 } 18388 18389 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18390 if (!isDebuggable) { 18391 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18392 throw new SecurityException("Process not debuggable: " + proc); 18393 } 18394 } 18395 18396 proc.thread.dumpHeap(managed, path, fd); 18397 fd = null; 18398 return true; 18399 } 18400 } catch (RemoteException e) { 18401 throw new IllegalStateException("Process disappeared"); 18402 } finally { 18403 if (fd != null) { 18404 try { 18405 fd.close(); 18406 } catch (IOException e) { 18407 } 18408 } 18409 } 18410 } 18411 18412 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18413 public void monitor() { 18414 synchronized (this) { } 18415 } 18416 18417 void onCoreSettingsChange(Bundle settings) { 18418 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18419 ProcessRecord processRecord = mLruProcesses.get(i); 18420 try { 18421 if (processRecord.thread != null) { 18422 processRecord.thread.setCoreSettings(settings); 18423 } 18424 } catch (RemoteException re) { 18425 /* ignore */ 18426 } 18427 } 18428 } 18429 18430 // Multi-user methods 18431 18432 /** 18433 * Start user, if its not already running, but don't bring it to foreground. 18434 */ 18435 @Override 18436 public boolean startUserInBackground(final int userId) { 18437 return startUser(userId, /* foreground */ false); 18438 } 18439 18440 /** 18441 * Start user, if its not already running, and bring it to foreground. 18442 */ 18443 boolean startUserInForeground(final int userId, Dialog dlg) { 18444 boolean result = startUser(userId, /* foreground */ true); 18445 dlg.dismiss(); 18446 return result; 18447 } 18448 18449 /** 18450 * Refreshes the list of users related to the current user when either a 18451 * user switch happens or when a new related user is started in the 18452 * background. 18453 */ 18454 private void updateCurrentProfileIdsLocked() { 18455 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18456 mCurrentUserId, false /* enabledOnly */); 18457 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18458 for (int i = 0; i < currentProfileIds.length; i++) { 18459 currentProfileIds[i] = profiles.get(i).id; 18460 } 18461 mCurrentProfileIds = currentProfileIds; 18462 18463 synchronized (mUserProfileGroupIdsSelfLocked) { 18464 mUserProfileGroupIdsSelfLocked.clear(); 18465 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18466 for (int i = 0; i < users.size(); i++) { 18467 UserInfo user = users.get(i); 18468 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18469 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18470 } 18471 } 18472 } 18473 } 18474 18475 private Set getProfileIdsLocked(int userId) { 18476 Set userIds = new HashSet<Integer>(); 18477 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18478 userId, false /* enabledOnly */); 18479 for (UserInfo user : profiles) { 18480 userIds.add(Integer.valueOf(user.id)); 18481 } 18482 return userIds; 18483 } 18484 18485 @Override 18486 public boolean switchUser(final int userId) { 18487 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18488 String userName; 18489 synchronized (this) { 18490 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18491 if (userInfo == null) { 18492 Slog.w(TAG, "No user info for user #" + userId); 18493 return false; 18494 } 18495 if (userInfo.isManagedProfile()) { 18496 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18497 return false; 18498 } 18499 userName = userInfo.name; 18500 mTargetUserId = userId; 18501 } 18502 mHandler.removeMessages(START_USER_SWITCH_MSG); 18503 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18504 return true; 18505 } 18506 18507 private void showUserSwitchDialog(int userId, String userName) { 18508 // The dialog will show and then initiate the user switch by calling startUserInForeground 18509 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18510 true /* above system */); 18511 d.show(); 18512 } 18513 18514 private boolean startUser(final int userId, final boolean foreground) { 18515 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18516 != PackageManager.PERMISSION_GRANTED) { 18517 String msg = "Permission Denial: switchUser() from pid=" 18518 + Binder.getCallingPid() 18519 + ", uid=" + Binder.getCallingUid() 18520 + " requires " + INTERACT_ACROSS_USERS_FULL; 18521 Slog.w(TAG, msg); 18522 throw new SecurityException(msg); 18523 } 18524 18525 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18526 18527 final long ident = Binder.clearCallingIdentity(); 18528 try { 18529 synchronized (this) { 18530 final int oldUserId = mCurrentUserId; 18531 if (oldUserId == userId) { 18532 return true; 18533 } 18534 18535 mStackSupervisor.setLockTaskModeLocked(null, false); 18536 18537 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18538 if (userInfo == null) { 18539 Slog.w(TAG, "No user info for user #" + userId); 18540 return false; 18541 } 18542 if (foreground && userInfo.isManagedProfile()) { 18543 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18544 return false; 18545 } 18546 18547 if (foreground) { 18548 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18549 R.anim.screen_user_enter); 18550 } 18551 18552 boolean needStart = false; 18553 18554 // If the user we are switching to is not currently started, then 18555 // we need to start it now. 18556 if (mStartedUsers.get(userId) == null) { 18557 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18558 updateStartedUserArrayLocked(); 18559 needStart = true; 18560 } 18561 18562 final Integer userIdInt = Integer.valueOf(userId); 18563 mUserLru.remove(userIdInt); 18564 mUserLru.add(userIdInt); 18565 18566 if (foreground) { 18567 mCurrentUserId = userId; 18568 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18569 updateCurrentProfileIdsLocked(); 18570 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18571 // Once the internal notion of the active user has switched, we lock the device 18572 // with the option to show the user switcher on the keyguard. 18573 mWindowManager.lockNow(null); 18574 } else { 18575 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18576 updateCurrentProfileIdsLocked(); 18577 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18578 mUserLru.remove(currentUserIdInt); 18579 mUserLru.add(currentUserIdInt); 18580 } 18581 18582 final UserStartedState uss = mStartedUsers.get(userId); 18583 18584 // Make sure user is in the started state. If it is currently 18585 // stopping, we need to knock that off. 18586 if (uss.mState == UserStartedState.STATE_STOPPING) { 18587 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18588 // so we can just fairly silently bring the user back from 18589 // the almost-dead. 18590 uss.mState = UserStartedState.STATE_RUNNING; 18591 updateStartedUserArrayLocked(); 18592 needStart = true; 18593 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18594 // This means ACTION_SHUTDOWN has been sent, so we will 18595 // need to treat this as a new boot of the user. 18596 uss.mState = UserStartedState.STATE_BOOTING; 18597 updateStartedUserArrayLocked(); 18598 needStart = true; 18599 } 18600 18601 if (uss.mState == UserStartedState.STATE_BOOTING) { 18602 // Booting up a new user, need to tell system services about it. 18603 // Note that this is on the same handler as scheduling of broadcasts, 18604 // which is important because it needs to go first. 18605 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18606 } 18607 18608 if (foreground) { 18609 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18610 oldUserId)); 18611 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18612 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18613 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18614 oldUserId, userId, uss)); 18615 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18616 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18617 } 18618 18619 if (needStart) { 18620 // Send USER_STARTED broadcast 18621 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18623 | Intent.FLAG_RECEIVER_FOREGROUND); 18624 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18625 broadcastIntentLocked(null, null, intent, 18626 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18627 false, false, MY_PID, Process.SYSTEM_UID, userId); 18628 } 18629 18630 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18631 if (userId != UserHandle.USER_OWNER) { 18632 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18633 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18634 broadcastIntentLocked(null, null, intent, null, 18635 new IIntentReceiver.Stub() { 18636 public void performReceive(Intent intent, int resultCode, 18637 String data, Bundle extras, boolean ordered, 18638 boolean sticky, int sendingUser) { 18639 onUserInitialized(uss, foreground, oldUserId, userId); 18640 } 18641 }, 0, null, null, null, AppOpsManager.OP_NONE, 18642 true, false, MY_PID, Process.SYSTEM_UID, 18643 userId); 18644 uss.initializing = true; 18645 } else { 18646 getUserManagerLocked().makeInitialized(userInfo.id); 18647 } 18648 } 18649 18650 if (foreground) { 18651 if (!uss.initializing) { 18652 moveUserToForeground(uss, oldUserId, userId); 18653 } 18654 } else { 18655 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18656 } 18657 18658 if (needStart) { 18659 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18660 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18661 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18662 broadcastIntentLocked(null, null, intent, 18663 null, new IIntentReceiver.Stub() { 18664 @Override 18665 public void performReceive(Intent intent, int resultCode, String data, 18666 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18667 throws RemoteException { 18668 } 18669 }, 0, null, null, 18670 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18671 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18672 } 18673 } 18674 } finally { 18675 Binder.restoreCallingIdentity(ident); 18676 } 18677 18678 return true; 18679 } 18680 18681 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18682 long ident = Binder.clearCallingIdentity(); 18683 try { 18684 Intent intent; 18685 if (oldUserId >= 0) { 18686 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18687 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18688 int count = profiles.size(); 18689 for (int i = 0; i < count; i++) { 18690 int profileUserId = profiles.get(i).id; 18691 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18692 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18693 | Intent.FLAG_RECEIVER_FOREGROUND); 18694 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18695 broadcastIntentLocked(null, null, intent, 18696 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18697 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18698 } 18699 } 18700 if (newUserId >= 0) { 18701 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18702 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18703 int count = profiles.size(); 18704 for (int i = 0; i < count; i++) { 18705 int profileUserId = profiles.get(i).id; 18706 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18707 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18708 | Intent.FLAG_RECEIVER_FOREGROUND); 18709 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18710 broadcastIntentLocked(null, null, intent, 18711 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18712 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18713 } 18714 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18715 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18716 | Intent.FLAG_RECEIVER_FOREGROUND); 18717 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18718 broadcastIntentLocked(null, null, intent, 18719 null, null, 0, null, null, 18720 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18721 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18722 } 18723 } finally { 18724 Binder.restoreCallingIdentity(ident); 18725 } 18726 } 18727 18728 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18729 final int newUserId) { 18730 final int N = mUserSwitchObservers.beginBroadcast(); 18731 if (N > 0) { 18732 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18733 int mCount = 0; 18734 @Override 18735 public void sendResult(Bundle data) throws RemoteException { 18736 synchronized (ActivityManagerService.this) { 18737 if (mCurUserSwitchCallback == this) { 18738 mCount++; 18739 if (mCount == N) { 18740 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18741 } 18742 } 18743 } 18744 } 18745 }; 18746 synchronized (this) { 18747 uss.switching = true; 18748 mCurUserSwitchCallback = callback; 18749 } 18750 for (int i=0; i<N; i++) { 18751 try { 18752 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18753 newUserId, callback); 18754 } catch (RemoteException e) { 18755 } 18756 } 18757 } else { 18758 synchronized (this) { 18759 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18760 } 18761 } 18762 mUserSwitchObservers.finishBroadcast(); 18763 } 18764 18765 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18766 synchronized (this) { 18767 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18768 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18769 } 18770 } 18771 18772 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18773 mCurUserSwitchCallback = null; 18774 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18775 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18776 oldUserId, newUserId, uss)); 18777 } 18778 18779 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18780 synchronized (this) { 18781 if (foreground) { 18782 moveUserToForeground(uss, oldUserId, newUserId); 18783 } 18784 } 18785 18786 completeSwitchAndInitalize(uss, newUserId, true, false); 18787 } 18788 18789 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18790 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18791 if (homeInFront) { 18792 startHomeActivityLocked(newUserId); 18793 } else { 18794 mStackSupervisor.resumeTopActivitiesLocked(); 18795 } 18796 EventLogTags.writeAmSwitchUser(newUserId); 18797 getUserManagerLocked().userForeground(newUserId); 18798 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18799 } 18800 18801 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18802 completeSwitchAndInitalize(uss, newUserId, false, true); 18803 } 18804 18805 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18806 boolean clearInitializing, boolean clearSwitching) { 18807 boolean unfrozen = false; 18808 synchronized (this) { 18809 if (clearInitializing) { 18810 uss.initializing = false; 18811 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18812 } 18813 if (clearSwitching) { 18814 uss.switching = false; 18815 } 18816 if (!uss.switching && !uss.initializing) { 18817 mWindowManager.stopFreezingScreen(); 18818 unfrozen = true; 18819 } 18820 } 18821 if (unfrozen) { 18822 final int N = mUserSwitchObservers.beginBroadcast(); 18823 for (int i=0; i<N; i++) { 18824 try { 18825 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18826 } catch (RemoteException e) { 18827 } 18828 } 18829 mUserSwitchObservers.finishBroadcast(); 18830 } 18831 } 18832 18833 void scheduleStartProfilesLocked() { 18834 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18835 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18836 DateUtils.SECOND_IN_MILLIS); 18837 } 18838 } 18839 18840 void startProfilesLocked() { 18841 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18842 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18843 mCurrentUserId, false /* enabledOnly */); 18844 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18845 for (UserInfo user : profiles) { 18846 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18847 && user.id != mCurrentUserId) { 18848 toStart.add(user); 18849 } 18850 } 18851 final int n = toStart.size(); 18852 int i = 0; 18853 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18854 startUserInBackground(toStart.get(i).id); 18855 } 18856 if (i < n) { 18857 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18858 } 18859 } 18860 18861 void finishUserBoot(UserStartedState uss) { 18862 synchronized (this) { 18863 if (uss.mState == UserStartedState.STATE_BOOTING 18864 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18865 uss.mState = UserStartedState.STATE_RUNNING; 18866 final int userId = uss.mHandle.getIdentifier(); 18867 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18868 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18869 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18870 broadcastIntentLocked(null, null, intent, 18871 null, null, 0, null, null, 18872 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18873 true, false, MY_PID, Process.SYSTEM_UID, userId); 18874 } 18875 } 18876 } 18877 18878 void finishUserSwitch(UserStartedState uss) { 18879 synchronized (this) { 18880 finishUserBoot(uss); 18881 18882 startProfilesLocked(); 18883 18884 int num = mUserLru.size(); 18885 int i = 0; 18886 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18887 Integer oldUserId = mUserLru.get(i); 18888 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18889 if (oldUss == null) { 18890 // Shouldn't happen, but be sane if it does. 18891 mUserLru.remove(i); 18892 num--; 18893 continue; 18894 } 18895 if (oldUss.mState == UserStartedState.STATE_STOPPING 18896 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18897 // This user is already stopping, doesn't count. 18898 num--; 18899 i++; 18900 continue; 18901 } 18902 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18903 // Owner and current can't be stopped, but count as running. 18904 i++; 18905 continue; 18906 } 18907 // This is a user to be stopped. 18908 stopUserLocked(oldUserId, null); 18909 num--; 18910 i++; 18911 } 18912 } 18913 } 18914 18915 @Override 18916 public int stopUser(final int userId, final IStopUserCallback callback) { 18917 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18918 != PackageManager.PERMISSION_GRANTED) { 18919 String msg = "Permission Denial: switchUser() from pid=" 18920 + Binder.getCallingPid() 18921 + ", uid=" + Binder.getCallingUid() 18922 + " requires " + INTERACT_ACROSS_USERS_FULL; 18923 Slog.w(TAG, msg); 18924 throw new SecurityException(msg); 18925 } 18926 if (userId <= 0) { 18927 throw new IllegalArgumentException("Can't stop primary user " + userId); 18928 } 18929 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18930 synchronized (this) { 18931 return stopUserLocked(userId, callback); 18932 } 18933 } 18934 18935 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18936 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18937 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18938 return ActivityManager.USER_OP_IS_CURRENT; 18939 } 18940 18941 final UserStartedState uss = mStartedUsers.get(userId); 18942 if (uss == null) { 18943 // User is not started, nothing to do... but we do need to 18944 // callback if requested. 18945 if (callback != null) { 18946 mHandler.post(new Runnable() { 18947 @Override 18948 public void run() { 18949 try { 18950 callback.userStopped(userId); 18951 } catch (RemoteException e) { 18952 } 18953 } 18954 }); 18955 } 18956 return ActivityManager.USER_OP_SUCCESS; 18957 } 18958 18959 if (callback != null) { 18960 uss.mStopCallbacks.add(callback); 18961 } 18962 18963 if (uss.mState != UserStartedState.STATE_STOPPING 18964 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18965 uss.mState = UserStartedState.STATE_STOPPING; 18966 updateStartedUserArrayLocked(); 18967 18968 long ident = Binder.clearCallingIdentity(); 18969 try { 18970 // We are going to broadcast ACTION_USER_STOPPING and then 18971 // once that is done send a final ACTION_SHUTDOWN and then 18972 // stop the user. 18973 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18974 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18975 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18976 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18977 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18978 // This is the result receiver for the final shutdown broadcast. 18979 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18980 @Override 18981 public void performReceive(Intent intent, int resultCode, String data, 18982 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18983 finishUserStop(uss); 18984 } 18985 }; 18986 // This is the result receiver for the initial stopping broadcast. 18987 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18988 @Override 18989 public void performReceive(Intent intent, int resultCode, String data, 18990 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18991 // On to the next. 18992 synchronized (ActivityManagerService.this) { 18993 if (uss.mState != UserStartedState.STATE_STOPPING) { 18994 // Whoops, we are being started back up. Abort, abort! 18995 return; 18996 } 18997 uss.mState = UserStartedState.STATE_SHUTDOWN; 18998 } 18999 mBatteryStatsService.noteEvent( 19000 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19001 Integer.toString(userId), userId); 19002 mSystemServiceManager.stopUser(userId); 19003 broadcastIntentLocked(null, null, shutdownIntent, 19004 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19005 true, false, MY_PID, Process.SYSTEM_UID, userId); 19006 } 19007 }; 19008 // Kick things off. 19009 broadcastIntentLocked(null, null, stoppingIntent, 19010 null, stoppingReceiver, 0, null, null, 19011 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19012 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19013 } finally { 19014 Binder.restoreCallingIdentity(ident); 19015 } 19016 } 19017 19018 return ActivityManager.USER_OP_SUCCESS; 19019 } 19020 19021 void finishUserStop(UserStartedState uss) { 19022 final int userId = uss.mHandle.getIdentifier(); 19023 boolean stopped; 19024 ArrayList<IStopUserCallback> callbacks; 19025 synchronized (this) { 19026 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19027 if (mStartedUsers.get(userId) != uss) { 19028 stopped = false; 19029 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19030 stopped = false; 19031 } else { 19032 stopped = true; 19033 // User can no longer run. 19034 mStartedUsers.remove(userId); 19035 mUserLru.remove(Integer.valueOf(userId)); 19036 updateStartedUserArrayLocked(); 19037 19038 // Clean up all state and processes associated with the user. 19039 // Kill all the processes for the user. 19040 forceStopUserLocked(userId, "finish user"); 19041 } 19042 19043 // Explicitly remove the old information in mRecentTasks. 19044 removeRecentTasksForUserLocked(userId); 19045 } 19046 19047 for (int i=0; i<callbacks.size(); i++) { 19048 try { 19049 if (stopped) callbacks.get(i).userStopped(userId); 19050 else callbacks.get(i).userStopAborted(userId); 19051 } catch (RemoteException e) { 19052 } 19053 } 19054 19055 if (stopped) { 19056 mSystemServiceManager.cleanupUser(userId); 19057 synchronized (this) { 19058 mStackSupervisor.removeUserLocked(userId); 19059 } 19060 } 19061 } 19062 19063 @Override 19064 public UserInfo getCurrentUser() { 19065 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19066 != PackageManager.PERMISSION_GRANTED) && ( 19067 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19068 != PackageManager.PERMISSION_GRANTED)) { 19069 String msg = "Permission Denial: getCurrentUser() from pid=" 19070 + Binder.getCallingPid() 19071 + ", uid=" + Binder.getCallingUid() 19072 + " requires " + INTERACT_ACROSS_USERS; 19073 Slog.w(TAG, msg); 19074 throw new SecurityException(msg); 19075 } 19076 synchronized (this) { 19077 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19078 return getUserManagerLocked().getUserInfo(userId); 19079 } 19080 } 19081 19082 int getCurrentUserIdLocked() { 19083 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19084 } 19085 19086 @Override 19087 public boolean isUserRunning(int userId, boolean orStopped) { 19088 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19089 != PackageManager.PERMISSION_GRANTED) { 19090 String msg = "Permission Denial: isUserRunning() from pid=" 19091 + Binder.getCallingPid() 19092 + ", uid=" + Binder.getCallingUid() 19093 + " requires " + INTERACT_ACROSS_USERS; 19094 Slog.w(TAG, msg); 19095 throw new SecurityException(msg); 19096 } 19097 synchronized (this) { 19098 return isUserRunningLocked(userId, orStopped); 19099 } 19100 } 19101 19102 boolean isUserRunningLocked(int userId, boolean orStopped) { 19103 UserStartedState state = mStartedUsers.get(userId); 19104 if (state == null) { 19105 return false; 19106 } 19107 if (orStopped) { 19108 return true; 19109 } 19110 return state.mState != UserStartedState.STATE_STOPPING 19111 && state.mState != UserStartedState.STATE_SHUTDOWN; 19112 } 19113 19114 @Override 19115 public int[] getRunningUserIds() { 19116 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19117 != PackageManager.PERMISSION_GRANTED) { 19118 String msg = "Permission Denial: isUserRunning() from pid=" 19119 + Binder.getCallingPid() 19120 + ", uid=" + Binder.getCallingUid() 19121 + " requires " + INTERACT_ACROSS_USERS; 19122 Slog.w(TAG, msg); 19123 throw new SecurityException(msg); 19124 } 19125 synchronized (this) { 19126 return mStartedUserArray; 19127 } 19128 } 19129 19130 private void updateStartedUserArrayLocked() { 19131 int num = 0; 19132 for (int i=0; i<mStartedUsers.size(); i++) { 19133 UserStartedState uss = mStartedUsers.valueAt(i); 19134 // This list does not include stopping users. 19135 if (uss.mState != UserStartedState.STATE_STOPPING 19136 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19137 num++; 19138 } 19139 } 19140 mStartedUserArray = new int[num]; 19141 num = 0; 19142 for (int i=0; i<mStartedUsers.size(); i++) { 19143 UserStartedState uss = mStartedUsers.valueAt(i); 19144 if (uss.mState != UserStartedState.STATE_STOPPING 19145 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19146 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19147 num++; 19148 } 19149 } 19150 } 19151 19152 @Override 19153 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19154 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19155 != PackageManager.PERMISSION_GRANTED) { 19156 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19157 + Binder.getCallingPid() 19158 + ", uid=" + Binder.getCallingUid() 19159 + " requires " + INTERACT_ACROSS_USERS_FULL; 19160 Slog.w(TAG, msg); 19161 throw new SecurityException(msg); 19162 } 19163 19164 mUserSwitchObservers.register(observer); 19165 } 19166 19167 @Override 19168 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19169 mUserSwitchObservers.unregister(observer); 19170 } 19171 19172 private boolean userExists(int userId) { 19173 if (userId == 0) { 19174 return true; 19175 } 19176 UserManagerService ums = getUserManagerLocked(); 19177 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19178 } 19179 19180 int[] getUsersLocked() { 19181 UserManagerService ums = getUserManagerLocked(); 19182 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19183 } 19184 19185 UserManagerService getUserManagerLocked() { 19186 if (mUserManager == null) { 19187 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19188 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19189 } 19190 return mUserManager; 19191 } 19192 19193 private int applyUserId(int uid, int userId) { 19194 return UserHandle.getUid(userId, uid); 19195 } 19196 19197 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19198 if (info == null) return null; 19199 ApplicationInfo newInfo = new ApplicationInfo(info); 19200 newInfo.uid = applyUserId(info.uid, userId); 19201 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19202 + info.packageName; 19203 return newInfo; 19204 } 19205 19206 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19207 if (aInfo == null 19208 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19209 return aInfo; 19210 } 19211 19212 ActivityInfo info = new ActivityInfo(aInfo); 19213 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19214 return info; 19215 } 19216 19217 private final class LocalService extends ActivityManagerInternal { 19218 @Override 19219 public void goingToSleep() { 19220 ActivityManagerService.this.goingToSleep(); 19221 } 19222 19223 @Override 19224 public void wakingUp() { 19225 ActivityManagerService.this.wakingUp(); 19226 } 19227 19228 @Override 19229 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19230 String processName, String abiOverride, int uid, Runnable crashHandler) { 19231 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19232 processName, abiOverride, uid, crashHandler); 19233 } 19234 } 19235 19236 /** 19237 * An implementation of IAppTask, that allows an app to manage its own tasks via 19238 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19239 * only the process that calls getAppTasks() can call the AppTask methods. 19240 */ 19241 class AppTaskImpl extends IAppTask.Stub { 19242 private int mTaskId; 19243 private int mCallingUid; 19244 19245 public AppTaskImpl(int taskId, int callingUid) { 19246 mTaskId = taskId; 19247 mCallingUid = callingUid; 19248 } 19249 19250 private void checkCaller() { 19251 if (mCallingUid != Binder.getCallingUid()) { 19252 throw new SecurityException("Caller " + mCallingUid 19253 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19254 } 19255 } 19256 19257 @Override 19258 public void finishAndRemoveTask() { 19259 checkCaller(); 19260 19261 synchronized (ActivityManagerService.this) { 19262 long origId = Binder.clearCallingIdentity(); 19263 try { 19264 if (!removeTaskByIdLocked(mTaskId, false)) { 19265 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19266 } 19267 } finally { 19268 Binder.restoreCallingIdentity(origId); 19269 } 19270 } 19271 } 19272 19273 @Override 19274 public ActivityManager.RecentTaskInfo getTaskInfo() { 19275 checkCaller(); 19276 19277 synchronized (ActivityManagerService.this) { 19278 long origId = Binder.clearCallingIdentity(); 19279 try { 19280 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19281 if (tr == null) { 19282 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19283 } 19284 return createRecentTaskInfoFromTaskRecord(tr); 19285 } finally { 19286 Binder.restoreCallingIdentity(origId); 19287 } 19288 } 19289 } 19290 19291 @Override 19292 public void moveToFront() { 19293 checkCaller(); 19294 19295 final TaskRecord tr; 19296 synchronized (ActivityManagerService.this) { 19297 tr = recentTaskForIdLocked(mTaskId); 19298 if (tr == null) { 19299 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19300 } 19301 if (tr.getRootActivity() != null) { 19302 moveTaskToFrontLocked(tr.taskId, 0, null); 19303 return; 19304 } 19305 } 19306 19307 startActivityFromRecentsInner(tr.taskId, null); 19308 } 19309 19310 @Override 19311 public int startActivity(IBinder whoThread, String callingPackage, 19312 Intent intent, String resolvedType, Bundle options) { 19313 checkCaller(); 19314 19315 int callingUser = UserHandle.getCallingUserId(); 19316 TaskRecord tr; 19317 IApplicationThread appThread; 19318 synchronized (ActivityManagerService.this) { 19319 tr = recentTaskForIdLocked(mTaskId); 19320 if (tr == null) { 19321 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19322 } 19323 appThread = ApplicationThreadNative.asInterface(whoThread); 19324 if (appThread == null) { 19325 throw new IllegalArgumentException("Bad app thread " + appThread); 19326 } 19327 } 19328 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19329 resolvedType, null, null, null, null, 0, 0, null, null, 19330 null, options, callingUser, null, tr); 19331 } 19332 19333 @Override 19334 public void setExcludeFromRecents(boolean exclude) { 19335 checkCaller(); 19336 19337 synchronized (ActivityManagerService.this) { 19338 long origId = Binder.clearCallingIdentity(); 19339 try { 19340 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19341 if (tr == null) { 19342 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19343 } 19344 Intent intent = tr.getBaseIntent(); 19345 if (exclude) { 19346 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19347 } else { 19348 intent.setFlags(intent.getFlags() 19349 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19350 } 19351 } finally { 19352 Binder.restoreCallingIdentity(origId); 19353 } 19354 } 19355 } 19356 } 19357} 19358