ActivityManagerService.java revision 308fa0548b8be4d8cca7ba55846d6f61b36f1a7d
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.os.BackgroundThread; 65import com.android.internal.os.BatteryStatsImpl; 66import com.android.internal.os.ProcessCpuTracker; 67import com.android.internal.os.TransferPipe; 68import com.android.internal.os.Zygote; 69import com.android.internal.util.FastPrintWriter; 70import com.android.internal.util.FastXmlSerializer; 71import com.android.internal.util.MemInfoReader; 72import com.android.internal.util.Preconditions; 73import com.android.server.AppOpsService; 74import com.android.server.AttributeCache; 75import com.android.server.IntentResolver; 76import com.android.server.LocalServices; 77import com.android.server.ServiceThread; 78import com.android.server.SystemService; 79import com.android.server.SystemServiceManager; 80import com.android.server.Watchdog; 81import com.android.server.am.ActivityStack.ActivityState; 82import com.android.server.firewall.IntentFirewall; 83import com.android.server.pm.Installer; 84import com.android.server.pm.UserManagerService; 85import com.android.server.statusbar.StatusBarManagerInternal; 86import com.android.server.wm.AppTransition; 87import com.android.server.wm.WindowManagerService; 88import com.google.android.collect.Lists; 89import com.google.android.collect.Maps; 90 91import libcore.io.IoUtils; 92 93import org.xmlpull.v1.XmlPullParser; 94import org.xmlpull.v1.XmlPullParserException; 95import org.xmlpull.v1.XmlSerializer; 96 97import android.app.Activity; 98import android.app.ActivityManager; 99import android.app.ActivityManager.RunningTaskInfo; 100import android.app.ActivityManager.StackInfo; 101import android.app.ActivityManagerInternal; 102import android.app.ActivityManagerNative; 103import android.app.ActivityOptions; 104import android.app.ActivityThread; 105import android.app.AlertDialog; 106import android.app.AppGlobals; 107import android.app.ApplicationErrorReport; 108import android.app.Dialog; 109import android.app.IActivityController; 110import android.app.IApplicationThread; 111import android.app.IInstrumentationWatcher; 112import android.app.INotificationManager; 113import android.app.IProcessObserver; 114import android.app.IServiceConnection; 115import android.app.IStopUserCallback; 116import android.app.IUiAutomationConnection; 117import android.app.IUserSwitchObserver; 118import android.app.Instrumentation; 119import android.app.Notification; 120import android.app.NotificationManager; 121import android.app.PendingIntent; 122import android.app.backup.IBackupManager; 123import android.content.ActivityNotFoundException; 124import android.content.BroadcastReceiver; 125import android.content.ClipData; 126import android.content.ComponentCallbacks2; 127import android.content.ComponentName; 128import android.content.ContentProvider; 129import android.content.ContentResolver; 130import android.content.Context; 131import android.content.DialogInterface; 132import android.content.IContentProvider; 133import android.content.IIntentReceiver; 134import android.content.IIntentSender; 135import android.content.Intent; 136import android.content.IntentFilter; 137import android.content.IntentSender; 138import android.content.pm.ActivityInfo; 139import android.content.pm.ApplicationInfo; 140import android.content.pm.ConfigurationInfo; 141import android.content.pm.IPackageDataObserver; 142import android.content.pm.IPackageManager; 143import android.content.pm.InstrumentationInfo; 144import android.content.pm.PackageInfo; 145import android.content.pm.PackageManager; 146import android.content.pm.ParceledListSlice; 147import android.content.pm.UserInfo; 148import android.content.pm.PackageManager.NameNotFoundException; 149import android.content.pm.PathPermission; 150import android.content.pm.ProviderInfo; 151import android.content.pm.ResolveInfo; 152import android.content.pm.ServiceInfo; 153import android.content.res.CompatibilityInfo; 154import android.content.res.Configuration; 155import android.net.Proxy; 156import android.net.ProxyInfo; 157import android.net.Uri; 158import android.os.Binder; 159import android.os.Build; 160import android.os.Bundle; 161import android.os.Debug; 162import android.os.DropBoxManager; 163import android.os.Environment; 164import android.os.FactoryTest; 165import android.os.FileObserver; 166import android.os.FileUtils; 167import android.os.Handler; 168import android.os.IBinder; 169import android.os.IPermissionController; 170import android.os.IRemoteCallback; 171import android.os.IUserManager; 172import android.os.Looper; 173import android.os.Message; 174import android.os.Parcel; 175import android.os.ParcelFileDescriptor; 176import android.os.PowerManagerInternal; 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 final IBinder token; 843 public final int pid; 844 public final int uid; 845 846 Identity(IBinder _token, int _pid, int _uid) { 847 token = _token; 848 pid = _pid; 849 uid = _uid; 850 } 851 } 852 853 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 854 855 /** 856 * All information we have collected about the runtime performance of 857 * any user id that can impact battery performance. 858 */ 859 final BatteryStatsService mBatteryStatsService; 860 861 /** 862 * Information about component usage 863 */ 864 UsageStatsManagerInternal mUsageStatsService; 865 866 /** 867 * Information about and control over application operations 868 */ 869 final AppOpsService mAppOpsService; 870 871 /** 872 * Save recent tasks information across reboots. 873 */ 874 final TaskPersister mTaskPersister; 875 876 /** 877 * Current configuration information. HistoryRecord objects are given 878 * a reference to this object to indicate which configuration they are 879 * currently running in, so this object must be kept immutable. 880 */ 881 Configuration mConfiguration = new Configuration(); 882 883 /** 884 * Current sequencing integer of the configuration, for skipping old 885 * configurations. 886 */ 887 int mConfigurationSeq = 0; 888 889 /** 890 * Hardware-reported OpenGLES version. 891 */ 892 final int GL_ES_VERSION; 893 894 /** 895 * List of initialization arguments to pass to all processes when binding applications to them. 896 * For example, references to the commonly used services. 897 */ 898 HashMap<String, IBinder> mAppBindArgs; 899 900 /** 901 * Temporary to avoid allocations. Protected by main lock. 902 */ 903 final StringBuilder mStringBuilder = new StringBuilder(256); 904 905 /** 906 * Used to control how we initialize the service. 907 */ 908 ComponentName mTopComponent; 909 String mTopAction = Intent.ACTION_MAIN; 910 String mTopData; 911 boolean mProcessesReady = false; 912 boolean mSystemReady = false; 913 boolean mBooting = false; 914 boolean mCallFinishBooting = false; 915 boolean mBootAnimationComplete = false; 916 boolean mWaitingUpdate = false; 917 boolean mDidUpdate = false; 918 boolean mOnBattery = false; 919 boolean mLaunchWarningShown = false; 920 921 Context mContext; 922 923 int mFactoryTest; 924 925 boolean mCheckedForSetup; 926 927 /** 928 * The time at which we will allow normal application switches again, 929 * after a call to {@link #stopAppSwitches()}. 930 */ 931 long mAppSwitchesAllowedTime; 932 933 /** 934 * This is set to true after the first switch after mAppSwitchesAllowedTime 935 * is set; any switches after that will clear the time. 936 */ 937 boolean mDidAppSwitch; 938 939 /** 940 * Last time (in realtime) at which we checked for power usage. 941 */ 942 long mLastPowerCheckRealtime; 943 944 /** 945 * Last time (in uptime) at which we checked for power usage. 946 */ 947 long mLastPowerCheckUptime; 948 949 /** 950 * Set while we are wanting to sleep, to prevent any 951 * activities from being started/resumed. 952 */ 953 private boolean mSleeping = false; 954 955 /** 956 * Set while we are running a voice interaction. This overrides 957 * sleeping while it is active. 958 */ 959 private boolean mRunningVoice = false; 960 961 /** 962 * State of external calls telling us if the device is awake or asleep. 963 */ 964 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 965 966 static final int LOCK_SCREEN_HIDDEN = 0; 967 static final int LOCK_SCREEN_LEAVING = 1; 968 static final int LOCK_SCREEN_SHOWN = 2; 969 /** 970 * State of external call telling us if the lock screen is shown. 971 */ 972 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 973 974 /** 975 * Set if we are shutting down the system, similar to sleeping. 976 */ 977 boolean mShuttingDown = false; 978 979 /** 980 * Current sequence id for oom_adj computation traversal. 981 */ 982 int mAdjSeq = 0; 983 984 /** 985 * Current sequence id for process LRU updating. 986 */ 987 int mLruSeq = 0; 988 989 /** 990 * Keep track of the non-cached/empty process we last found, to help 991 * determine how to distribute cached/empty processes next time. 992 */ 993 int mNumNonCachedProcs = 0; 994 995 /** 996 * Keep track of the number of cached hidden procs, to balance oom adj 997 * distribution between those and empty procs. 998 */ 999 int mNumCachedHiddenProcs = 0; 1000 1001 /** 1002 * Keep track of the number of service processes we last found, to 1003 * determine on the next iteration which should be B services. 1004 */ 1005 int mNumServiceProcs = 0; 1006 int mNewNumAServiceProcs = 0; 1007 int mNewNumServiceProcs = 0; 1008 1009 /** 1010 * Allow the current computed overall memory level of the system to go down? 1011 * This is set to false when we are killing processes for reasons other than 1012 * memory management, so that the now smaller process list will not be taken as 1013 * an indication that memory is tighter. 1014 */ 1015 boolean mAllowLowerMemLevel = false; 1016 1017 /** 1018 * The last computed memory level, for holding when we are in a state that 1019 * processes are going away for other reasons. 1020 */ 1021 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1022 1023 /** 1024 * The last total number of process we have, to determine if changes actually look 1025 * like a shrinking number of process due to lower RAM. 1026 */ 1027 int mLastNumProcesses; 1028 1029 /** 1030 * The uptime of the last time we performed idle maintenance. 1031 */ 1032 long mLastIdleTime = SystemClock.uptimeMillis(); 1033 1034 /** 1035 * Total time spent with RAM that has been added in the past since the last idle time. 1036 */ 1037 long mLowRamTimeSinceLastIdle = 0; 1038 1039 /** 1040 * If RAM is currently low, when that horrible situation started. 1041 */ 1042 long mLowRamStartTime = 0; 1043 1044 /** 1045 * For reporting to battery stats the current top application. 1046 */ 1047 private String mCurResumedPackage = null; 1048 private int mCurResumedUid = -1; 1049 1050 /** 1051 * For reporting to battery stats the apps currently running foreground 1052 * service. The ProcessMap is package/uid tuples; each of these contain 1053 * an array of the currently foreground processes. 1054 */ 1055 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1056 = new ProcessMap<ArrayList<ProcessRecord>>(); 1057 1058 /** 1059 * This is set if we had to do a delayed dexopt of an app before launching 1060 * it, to increase the ANR timeouts in that case. 1061 */ 1062 boolean mDidDexOpt; 1063 1064 /** 1065 * Set if the systemServer made a call to enterSafeMode. 1066 */ 1067 boolean mSafeMode; 1068 1069 String mDebugApp = null; 1070 boolean mWaitForDebugger = false; 1071 boolean mDebugTransient = false; 1072 String mOrigDebugApp = null; 1073 boolean mOrigWaitForDebugger = false; 1074 boolean mAlwaysFinishActivities = false; 1075 IActivityController mController = null; 1076 String mProfileApp = null; 1077 ProcessRecord mProfileProc = null; 1078 String mProfileFile; 1079 ParcelFileDescriptor mProfileFd; 1080 int mSamplingInterval = 0; 1081 boolean mAutoStopProfiler = false; 1082 int mProfileType = 0; 1083 String mOpenGlTraceApp = null; 1084 1085 static class ProcessChangeItem { 1086 static final int CHANGE_ACTIVITIES = 1<<0; 1087 static final int CHANGE_PROCESS_STATE = 1<<1; 1088 int changes; 1089 int uid; 1090 int pid; 1091 int processState; 1092 boolean foregroundActivities; 1093 } 1094 1095 final RemoteCallbackList<IProcessObserver> mProcessObservers 1096 = new RemoteCallbackList<IProcessObserver>(); 1097 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1098 1099 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1100 = new ArrayList<ProcessChangeItem>(); 1101 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1102 = new ArrayList<ProcessChangeItem>(); 1103 1104 /** 1105 * Runtime CPU use collection thread. This object's lock is used to 1106 * perform synchronization with the thread (notifying it to run). 1107 */ 1108 final Thread mProcessCpuThread; 1109 1110 /** 1111 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1112 * Must acquire this object's lock when accessing it. 1113 * NOTE: this lock will be held while doing long operations (trawling 1114 * through all processes in /proc), so it should never be acquired by 1115 * any critical paths such as when holding the main activity manager lock. 1116 */ 1117 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1118 MONITOR_THREAD_CPU_USAGE); 1119 final AtomicLong mLastCpuTime = new AtomicLong(0); 1120 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1121 1122 long mLastWriteTime = 0; 1123 1124 /** 1125 * Used to retain an update lock when the foreground activity is in 1126 * immersive mode. 1127 */ 1128 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1129 1130 /** 1131 * Set to true after the system has finished booting. 1132 */ 1133 boolean mBooted = false; 1134 1135 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1136 int mProcessLimitOverride = -1; 1137 1138 WindowManagerService mWindowManager; 1139 1140 final ActivityThread mSystemThread; 1141 1142 // Holds the current foreground user's id 1143 int mCurrentUserId = 0; 1144 // Holds the target user's id during a user switch 1145 int mTargetUserId = UserHandle.USER_NULL; 1146 // If there are multiple profiles for the current user, their ids are here 1147 // Currently only the primary user can have managed profiles 1148 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1149 1150 /** 1151 * Mapping from each known user ID to the profile group ID it is associated with. 1152 */ 1153 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1154 1155 private UserManagerService mUserManager; 1156 1157 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1158 final ProcessRecord mApp; 1159 final int mPid; 1160 final IApplicationThread mAppThread; 1161 1162 AppDeathRecipient(ProcessRecord app, int pid, 1163 IApplicationThread thread) { 1164 if (localLOGV) Slog.v( 1165 TAG, "New death recipient " + this 1166 + " for thread " + thread.asBinder()); 1167 mApp = app; 1168 mPid = pid; 1169 mAppThread = thread; 1170 } 1171 1172 @Override 1173 public void binderDied() { 1174 if (localLOGV) Slog.v( 1175 TAG, "Death received in " + this 1176 + " for thread " + mAppThread.asBinder()); 1177 synchronized(ActivityManagerService.this) { 1178 appDiedLocked(mApp, mPid, mAppThread); 1179 } 1180 } 1181 } 1182 1183 static final int SHOW_ERROR_MSG = 1; 1184 static final int SHOW_NOT_RESPONDING_MSG = 2; 1185 static final int SHOW_FACTORY_ERROR_MSG = 3; 1186 static final int UPDATE_CONFIGURATION_MSG = 4; 1187 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1188 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1189 static final int SERVICE_TIMEOUT_MSG = 12; 1190 static final int UPDATE_TIME_ZONE = 13; 1191 static final int SHOW_UID_ERROR_MSG = 14; 1192 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1193 static final int PROC_START_TIMEOUT_MSG = 20; 1194 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1195 static final int KILL_APPLICATION_MSG = 22; 1196 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1197 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1198 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1199 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1200 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1201 static final int CLEAR_DNS_CACHE_MSG = 28; 1202 static final int UPDATE_HTTP_PROXY_MSG = 29; 1203 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1204 static final int DISPATCH_PROCESSES_CHANGED = 31; 1205 static final int DISPATCH_PROCESS_DIED = 32; 1206 static final int REPORT_MEM_USAGE_MSG = 33; 1207 static final int REPORT_USER_SWITCH_MSG = 34; 1208 static final int CONTINUE_USER_SWITCH_MSG = 35; 1209 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1210 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1211 static final int PERSIST_URI_GRANTS_MSG = 38; 1212 static final int REQUEST_ALL_PSS_MSG = 39; 1213 static final int START_PROFILES_MSG = 40; 1214 static final int UPDATE_TIME = 41; 1215 static final int SYSTEM_USER_START_MSG = 42; 1216 static final int SYSTEM_USER_CURRENT_MSG = 43; 1217 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1218 static final int FINISH_BOOTING_MSG = 45; 1219 static final int START_USER_SWITCH_MSG = 46; 1220 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1221 static final int DISMISS_DIALOG_MSG = 48; 1222 1223 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1224 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1225 static final int FIRST_COMPAT_MODE_MSG = 300; 1226 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1227 1228 CompatModeDialog mCompatModeDialog; 1229 long mLastMemUsageReportTime = 0; 1230 1231 /** 1232 * Flag whether the current user is a "monkey", i.e. whether 1233 * the UI is driven by a UI automation tool. 1234 */ 1235 private boolean mUserIsMonkey; 1236 1237 /** Flag whether the device has a Recents UI */ 1238 boolean mHasRecents; 1239 1240 /** The dimensions of the thumbnails in the Recents UI. */ 1241 int mThumbnailWidth; 1242 int mThumbnailHeight; 1243 1244 final ServiceThread mHandlerThread; 1245 final MainHandler mHandler; 1246 1247 final class MainHandler extends Handler { 1248 public MainHandler(Looper looper) { 1249 super(looper, null, true); 1250 } 1251 1252 @Override 1253 public void handleMessage(Message msg) { 1254 switch (msg.what) { 1255 case SHOW_ERROR_MSG: { 1256 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1257 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1258 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1259 synchronized (ActivityManagerService.this) { 1260 ProcessRecord proc = (ProcessRecord)data.get("app"); 1261 AppErrorResult res = (AppErrorResult) data.get("result"); 1262 if (proc != null && proc.crashDialog != null) { 1263 Slog.e(TAG, "App already has crash dialog: " + proc); 1264 if (res != null) { 1265 res.set(0); 1266 } 1267 return; 1268 } 1269 boolean isBackground = (UserHandle.getAppId(proc.uid) 1270 >= Process.FIRST_APPLICATION_UID 1271 && proc.pid != MY_PID); 1272 for (int userId : mCurrentProfileIds) { 1273 isBackground &= (proc.userId != userId); 1274 } 1275 if (isBackground && !showBackground) { 1276 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1277 if (res != null) { 1278 res.set(0); 1279 } 1280 return; 1281 } 1282 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1283 Dialog d = new AppErrorDialog(mContext, 1284 ActivityManagerService.this, res, proc); 1285 d.show(); 1286 proc.crashDialog = d; 1287 } else { 1288 // The device is asleep, so just pretend that the user 1289 // saw a crash dialog and hit "force quit". 1290 if (res != null) { 1291 res.set(0); 1292 } 1293 } 1294 } 1295 1296 ensureBootCompleted(); 1297 } break; 1298 case SHOW_NOT_RESPONDING_MSG: { 1299 synchronized (ActivityManagerService.this) { 1300 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1301 ProcessRecord proc = (ProcessRecord)data.get("app"); 1302 if (proc != null && proc.anrDialog != null) { 1303 Slog.e(TAG, "App already has anr dialog: " + proc); 1304 return; 1305 } 1306 1307 Intent intent = new Intent("android.intent.action.ANR"); 1308 if (!mProcessesReady) { 1309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1310 | Intent.FLAG_RECEIVER_FOREGROUND); 1311 } 1312 broadcastIntentLocked(null, null, intent, 1313 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1314 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1315 1316 if (mShowDialogs) { 1317 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1318 mContext, proc, (ActivityRecord)data.get("activity"), 1319 msg.arg1 != 0); 1320 d.show(); 1321 proc.anrDialog = d; 1322 } else { 1323 // Just kill the app if there is no dialog to be shown. 1324 killAppAtUsersRequest(proc, null); 1325 } 1326 } 1327 1328 ensureBootCompleted(); 1329 } break; 1330 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1331 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1332 synchronized (ActivityManagerService.this) { 1333 ProcessRecord proc = (ProcessRecord) data.get("app"); 1334 if (proc == null) { 1335 Slog.e(TAG, "App not found when showing strict mode dialog."); 1336 break; 1337 } 1338 if (proc.crashDialog != null) { 1339 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1340 return; 1341 } 1342 AppErrorResult res = (AppErrorResult) data.get("result"); 1343 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1344 Dialog d = new StrictModeViolationDialog(mContext, 1345 ActivityManagerService.this, res, proc); 1346 d.show(); 1347 proc.crashDialog = d; 1348 } else { 1349 // The device is asleep, so just pretend that the user 1350 // saw a crash dialog and hit "force quit". 1351 res.set(0); 1352 } 1353 } 1354 ensureBootCompleted(); 1355 } break; 1356 case SHOW_FACTORY_ERROR_MSG: { 1357 Dialog d = new FactoryErrorDialog( 1358 mContext, msg.getData().getCharSequence("msg")); 1359 d.show(); 1360 ensureBootCompleted(); 1361 } break; 1362 case UPDATE_CONFIGURATION_MSG: { 1363 final ContentResolver resolver = mContext.getContentResolver(); 1364 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1365 } break; 1366 case GC_BACKGROUND_PROCESSES_MSG: { 1367 synchronized (ActivityManagerService.this) { 1368 performAppGcsIfAppropriateLocked(); 1369 } 1370 } break; 1371 case WAIT_FOR_DEBUGGER_MSG: { 1372 synchronized (ActivityManagerService.this) { 1373 ProcessRecord app = (ProcessRecord)msg.obj; 1374 if (msg.arg1 != 0) { 1375 if (!app.waitedForDebugger) { 1376 Dialog d = new AppWaitingForDebuggerDialog( 1377 ActivityManagerService.this, 1378 mContext, app); 1379 app.waitDialog = d; 1380 app.waitedForDebugger = true; 1381 d.show(); 1382 } 1383 } else { 1384 if (app.waitDialog != null) { 1385 app.waitDialog.dismiss(); 1386 app.waitDialog = null; 1387 } 1388 } 1389 } 1390 } break; 1391 case SERVICE_TIMEOUT_MSG: { 1392 if (mDidDexOpt) { 1393 mDidDexOpt = false; 1394 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1395 nmsg.obj = msg.obj; 1396 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1397 return; 1398 } 1399 mServices.serviceTimeout((ProcessRecord)msg.obj); 1400 } break; 1401 case UPDATE_TIME_ZONE: { 1402 synchronized (ActivityManagerService.this) { 1403 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1404 ProcessRecord r = mLruProcesses.get(i); 1405 if (r.thread != null) { 1406 try { 1407 r.thread.updateTimeZone(); 1408 } catch (RemoteException ex) { 1409 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1410 } 1411 } 1412 } 1413 } 1414 } break; 1415 case CLEAR_DNS_CACHE_MSG: { 1416 synchronized (ActivityManagerService.this) { 1417 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1418 ProcessRecord r = mLruProcesses.get(i); 1419 if (r.thread != null) { 1420 try { 1421 r.thread.clearDnsCache(); 1422 } catch (RemoteException ex) { 1423 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1424 } 1425 } 1426 } 1427 } 1428 } break; 1429 case UPDATE_HTTP_PROXY_MSG: { 1430 ProxyInfo proxy = (ProxyInfo)msg.obj; 1431 String host = ""; 1432 String port = ""; 1433 String exclList = ""; 1434 Uri pacFileUrl = Uri.EMPTY; 1435 if (proxy != null) { 1436 host = proxy.getHost(); 1437 port = Integer.toString(proxy.getPort()); 1438 exclList = proxy.getExclusionListAsString(); 1439 pacFileUrl = proxy.getPacFileUrl(); 1440 } 1441 synchronized (ActivityManagerService.this) { 1442 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1443 ProcessRecord r = mLruProcesses.get(i); 1444 if (r.thread != null) { 1445 try { 1446 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1447 } catch (RemoteException ex) { 1448 Slog.w(TAG, "Failed to update http proxy for: " + 1449 r.info.processName); 1450 } 1451 } 1452 } 1453 } 1454 } break; 1455 case SHOW_UID_ERROR_MSG: { 1456 if (mShowDialogs) { 1457 AlertDialog d = new BaseErrorDialog(mContext); 1458 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1459 d.setCancelable(false); 1460 d.setTitle(mContext.getText(R.string.android_system_label)); 1461 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1462 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1463 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1464 d.show(); 1465 } 1466 } break; 1467 case SHOW_FINGERPRINT_ERROR_MSG: { 1468 if (mShowDialogs) { 1469 AlertDialog d = new BaseErrorDialog(mContext); 1470 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1471 d.setCancelable(false); 1472 d.setTitle(mContext.getText(R.string.android_system_label)); 1473 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1474 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1475 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1476 d.show(); 1477 } 1478 } break; 1479 case PROC_START_TIMEOUT_MSG: { 1480 if (mDidDexOpt) { 1481 mDidDexOpt = false; 1482 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1483 nmsg.obj = msg.obj; 1484 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1485 return; 1486 } 1487 ProcessRecord app = (ProcessRecord)msg.obj; 1488 synchronized (ActivityManagerService.this) { 1489 processStartTimedOutLocked(app); 1490 } 1491 } break; 1492 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1493 synchronized (ActivityManagerService.this) { 1494 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1495 } 1496 } break; 1497 case KILL_APPLICATION_MSG: { 1498 synchronized (ActivityManagerService.this) { 1499 int appid = msg.arg1; 1500 boolean restart = (msg.arg2 == 1); 1501 Bundle bundle = (Bundle)msg.obj; 1502 String pkg = bundle.getString("pkg"); 1503 String reason = bundle.getString("reason"); 1504 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1505 false, UserHandle.USER_ALL, reason); 1506 } 1507 } break; 1508 case FINALIZE_PENDING_INTENT_MSG: { 1509 ((PendingIntentRecord)msg.obj).completeFinalize(); 1510 } break; 1511 case POST_HEAVY_NOTIFICATION_MSG: { 1512 INotificationManager inm = NotificationManager.getService(); 1513 if (inm == null) { 1514 return; 1515 } 1516 1517 ActivityRecord root = (ActivityRecord)msg.obj; 1518 ProcessRecord process = root.app; 1519 if (process == null) { 1520 return; 1521 } 1522 1523 try { 1524 Context context = mContext.createPackageContext(process.info.packageName, 0); 1525 String text = mContext.getString(R.string.heavy_weight_notification, 1526 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1527 Notification notification = new Notification(); 1528 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1529 notification.when = 0; 1530 notification.flags = Notification.FLAG_ONGOING_EVENT; 1531 notification.tickerText = text; 1532 notification.defaults = 0; // please be quiet 1533 notification.sound = null; 1534 notification.vibrate = null; 1535 notification.color = mContext.getResources().getColor( 1536 com.android.internal.R.color.system_notification_accent_color); 1537 notification.setLatestEventInfo(context, text, 1538 mContext.getText(R.string.heavy_weight_notification_detail), 1539 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1540 PendingIntent.FLAG_CANCEL_CURRENT, null, 1541 new UserHandle(root.userId))); 1542 1543 try { 1544 int[] outId = new int[1]; 1545 inm.enqueueNotificationWithTag("android", "android", null, 1546 R.string.heavy_weight_notification, 1547 notification, outId, root.userId); 1548 } catch (RuntimeException e) { 1549 Slog.w(ActivityManagerService.TAG, 1550 "Error showing notification for heavy-weight app", e); 1551 } catch (RemoteException e) { 1552 } 1553 } catch (NameNotFoundException e) { 1554 Slog.w(TAG, "Unable to create context for heavy notification", e); 1555 } 1556 } break; 1557 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1558 INotificationManager inm = NotificationManager.getService(); 1559 if (inm == null) { 1560 return; 1561 } 1562 try { 1563 inm.cancelNotificationWithTag("android", null, 1564 R.string.heavy_weight_notification, msg.arg1); 1565 } catch (RuntimeException e) { 1566 Slog.w(ActivityManagerService.TAG, 1567 "Error canceling notification for service", e); 1568 } catch (RemoteException e) { 1569 } 1570 } break; 1571 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1572 synchronized (ActivityManagerService.this) { 1573 checkExcessivePowerUsageLocked(true); 1574 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1575 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1576 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1577 } 1578 } break; 1579 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1580 synchronized (ActivityManagerService.this) { 1581 ActivityRecord ar = (ActivityRecord)msg.obj; 1582 if (mCompatModeDialog != null) { 1583 if (mCompatModeDialog.mAppInfo.packageName.equals( 1584 ar.info.applicationInfo.packageName)) { 1585 return; 1586 } 1587 mCompatModeDialog.dismiss(); 1588 mCompatModeDialog = null; 1589 } 1590 if (ar != null && false) { 1591 if (mCompatModePackages.getPackageAskCompatModeLocked( 1592 ar.packageName)) { 1593 int mode = mCompatModePackages.computeCompatModeLocked( 1594 ar.info.applicationInfo); 1595 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1596 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1597 mCompatModeDialog = new CompatModeDialog( 1598 ActivityManagerService.this, mContext, 1599 ar.info.applicationInfo); 1600 mCompatModeDialog.show(); 1601 } 1602 } 1603 } 1604 } 1605 break; 1606 } 1607 case DISPATCH_PROCESSES_CHANGED: { 1608 dispatchProcessesChanged(); 1609 break; 1610 } 1611 case DISPATCH_PROCESS_DIED: { 1612 final int pid = msg.arg1; 1613 final int uid = msg.arg2; 1614 dispatchProcessDied(pid, uid); 1615 break; 1616 } 1617 case REPORT_MEM_USAGE_MSG: { 1618 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1619 Thread thread = new Thread() { 1620 @Override public void run() { 1621 reportMemUsage(memInfos); 1622 } 1623 }; 1624 thread.start(); 1625 break; 1626 } 1627 case START_USER_SWITCH_MSG: { 1628 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1629 break; 1630 } 1631 case REPORT_USER_SWITCH_MSG: { 1632 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1633 break; 1634 } 1635 case CONTINUE_USER_SWITCH_MSG: { 1636 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1637 break; 1638 } 1639 case USER_SWITCH_TIMEOUT_MSG: { 1640 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1641 break; 1642 } 1643 case IMMERSIVE_MODE_LOCK_MSG: { 1644 final boolean nextState = (msg.arg1 != 0); 1645 if (mUpdateLock.isHeld() != nextState) { 1646 if (DEBUG_IMMERSIVE) { 1647 final ActivityRecord r = (ActivityRecord) msg.obj; 1648 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1649 } 1650 if (nextState) { 1651 mUpdateLock.acquire(); 1652 } else { 1653 mUpdateLock.release(); 1654 } 1655 } 1656 break; 1657 } 1658 case PERSIST_URI_GRANTS_MSG: { 1659 writeGrantedUriPermissions(); 1660 break; 1661 } 1662 case REQUEST_ALL_PSS_MSG: { 1663 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1664 break; 1665 } 1666 case START_PROFILES_MSG: { 1667 synchronized (ActivityManagerService.this) { 1668 startProfilesLocked(); 1669 } 1670 break; 1671 } 1672 case UPDATE_TIME: { 1673 synchronized (ActivityManagerService.this) { 1674 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1675 ProcessRecord r = mLruProcesses.get(i); 1676 if (r.thread != null) { 1677 try { 1678 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1679 } catch (RemoteException ex) { 1680 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1681 } 1682 } 1683 } 1684 } 1685 break; 1686 } 1687 case SYSTEM_USER_START_MSG: { 1688 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1689 Integer.toString(msg.arg1), msg.arg1); 1690 mSystemServiceManager.startUser(msg.arg1); 1691 break; 1692 } 1693 case SYSTEM_USER_CURRENT_MSG: { 1694 mBatteryStatsService.noteEvent( 1695 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1696 Integer.toString(msg.arg2), msg.arg2); 1697 mBatteryStatsService.noteEvent( 1698 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1699 Integer.toString(msg.arg1), msg.arg1); 1700 mSystemServiceManager.switchUser(msg.arg1); 1701 break; 1702 } 1703 case ENTER_ANIMATION_COMPLETE_MSG: { 1704 synchronized (ActivityManagerService.this) { 1705 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1706 if (r != null && r.app != null && r.app.thread != null) { 1707 try { 1708 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1709 } catch (RemoteException e) { 1710 } 1711 } 1712 } 1713 break; 1714 } 1715 case FINISH_BOOTING_MSG: { 1716 if (msg.arg1 != 0) { 1717 finishBooting(); 1718 } 1719 if (msg.arg2 != 0) { 1720 enableScreenAfterBoot(); 1721 } 1722 break; 1723 } 1724 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1725 try { 1726 Locale l = (Locale) msg.obj; 1727 IBinder service = ServiceManager.getService("mount"); 1728 IMountService mountService = IMountService.Stub.asInterface(service); 1729 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1730 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1731 } catch (RemoteException e) { 1732 Log.e(TAG, "Error storing locale for decryption UI", e); 1733 } 1734 break; 1735 } 1736 case DISMISS_DIALOG_MSG: { 1737 final Dialog d = (Dialog) msg.obj; 1738 d.dismiss(); 1739 break; 1740 } 1741 } 1742 } 1743 }; 1744 1745 static final int COLLECT_PSS_BG_MSG = 1; 1746 1747 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1748 @Override 1749 public void handleMessage(Message msg) { 1750 switch (msg.what) { 1751 case COLLECT_PSS_BG_MSG: { 1752 long start = SystemClock.uptimeMillis(); 1753 MemInfoReader memInfo = null; 1754 synchronized (ActivityManagerService.this) { 1755 if (mFullPssPending) { 1756 mFullPssPending = false; 1757 memInfo = new MemInfoReader(); 1758 } 1759 } 1760 if (memInfo != null) { 1761 updateCpuStatsNow(); 1762 long nativeTotalPss = 0; 1763 synchronized (mProcessCpuTracker) { 1764 final int N = mProcessCpuTracker.countStats(); 1765 for (int j=0; j<N; j++) { 1766 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1767 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1768 // This is definitely an application process; skip it. 1769 continue; 1770 } 1771 synchronized (mPidsSelfLocked) { 1772 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1773 // This is one of our own processes; skip it. 1774 continue; 1775 } 1776 } 1777 nativeTotalPss += Debug.getPss(st.pid, null); 1778 } 1779 } 1780 memInfo.readMemInfo(); 1781 synchronized (ActivityManagerService.this) { 1782 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1783 + (SystemClock.uptimeMillis()-start) + "ms"); 1784 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1785 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1786 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1787 } 1788 } 1789 1790 int i = 0; 1791 int num = 0; 1792 long[] tmp = new long[1]; 1793 do { 1794 ProcessRecord proc; 1795 int procState; 1796 int pid; 1797 synchronized (ActivityManagerService.this) { 1798 if (i >= mPendingPssProcesses.size()) { 1799 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1800 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1801 mPendingPssProcesses.clear(); 1802 return; 1803 } 1804 proc = mPendingPssProcesses.get(i); 1805 procState = proc.pssProcState; 1806 if (proc.thread != null && procState == proc.setProcState) { 1807 pid = proc.pid; 1808 } else { 1809 proc = null; 1810 pid = 0; 1811 } 1812 i++; 1813 } 1814 if (proc != null) { 1815 long pss = Debug.getPss(pid, tmp); 1816 synchronized (ActivityManagerService.this) { 1817 if (proc.thread != null && proc.setProcState == procState 1818 && proc.pid == pid) { 1819 num++; 1820 proc.lastPssTime = SystemClock.uptimeMillis(); 1821 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1822 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1823 + ": " + pss + " lastPss=" + proc.lastPss 1824 + " state=" + ProcessList.makeProcStateString(procState)); 1825 if (proc.initialIdlePss == 0) { 1826 proc.initialIdlePss = pss; 1827 } 1828 proc.lastPss = pss; 1829 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1830 proc.lastCachedPss = pss; 1831 } 1832 } 1833 } 1834 } 1835 } while (true); 1836 } 1837 } 1838 } 1839 }; 1840 1841 public void setSystemProcess() { 1842 try { 1843 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1844 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1845 ServiceManager.addService("meminfo", new MemBinder(this)); 1846 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1847 ServiceManager.addService("dbinfo", new DbBinder(this)); 1848 if (MONITOR_CPU_USAGE) { 1849 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1850 } 1851 ServiceManager.addService("permission", new PermissionController(this)); 1852 1853 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1854 "android", STOCK_PM_FLAGS); 1855 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1856 1857 synchronized (this) { 1858 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1859 app.persistent = true; 1860 app.pid = MY_PID; 1861 app.maxAdj = ProcessList.SYSTEM_ADJ; 1862 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1863 mProcessNames.put(app.processName, app.uid, app); 1864 synchronized (mPidsSelfLocked) { 1865 mPidsSelfLocked.put(app.pid, app); 1866 } 1867 updateLruProcessLocked(app, false, null); 1868 updateOomAdjLocked(); 1869 } 1870 } catch (PackageManager.NameNotFoundException e) { 1871 throw new RuntimeException( 1872 "Unable to find android system package", e); 1873 } 1874 } 1875 1876 public void setWindowManager(WindowManagerService wm) { 1877 mWindowManager = wm; 1878 mStackSupervisor.setWindowManager(wm); 1879 } 1880 1881 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1882 mUsageStatsService = usageStatsManager; 1883 } 1884 1885 public void startObservingNativeCrashes() { 1886 final NativeCrashListener ncl = new NativeCrashListener(this); 1887 ncl.start(); 1888 } 1889 1890 public IAppOpsService getAppOpsService() { 1891 return mAppOpsService; 1892 } 1893 1894 static class MemBinder extends Binder { 1895 ActivityManagerService mActivityManagerService; 1896 MemBinder(ActivityManagerService activityManagerService) { 1897 mActivityManagerService = activityManagerService; 1898 } 1899 1900 @Override 1901 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1902 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1903 != PackageManager.PERMISSION_GRANTED) { 1904 pw.println("Permission Denial: can't dump meminfo from from pid=" 1905 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1906 + " without permission " + android.Manifest.permission.DUMP); 1907 return; 1908 } 1909 1910 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1911 } 1912 } 1913 1914 static class GraphicsBinder extends Binder { 1915 ActivityManagerService mActivityManagerService; 1916 GraphicsBinder(ActivityManagerService activityManagerService) { 1917 mActivityManagerService = activityManagerService; 1918 } 1919 1920 @Override 1921 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1922 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1923 != PackageManager.PERMISSION_GRANTED) { 1924 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1925 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1926 + " without permission " + android.Manifest.permission.DUMP); 1927 return; 1928 } 1929 1930 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1931 } 1932 } 1933 1934 static class DbBinder extends Binder { 1935 ActivityManagerService mActivityManagerService; 1936 DbBinder(ActivityManagerService activityManagerService) { 1937 mActivityManagerService = activityManagerService; 1938 } 1939 1940 @Override 1941 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1942 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1943 != PackageManager.PERMISSION_GRANTED) { 1944 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1945 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1946 + " without permission " + android.Manifest.permission.DUMP); 1947 return; 1948 } 1949 1950 mActivityManagerService.dumpDbInfo(fd, pw, args); 1951 } 1952 } 1953 1954 static class CpuBinder extends Binder { 1955 ActivityManagerService mActivityManagerService; 1956 CpuBinder(ActivityManagerService activityManagerService) { 1957 mActivityManagerService = activityManagerService; 1958 } 1959 1960 @Override 1961 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1962 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1963 != PackageManager.PERMISSION_GRANTED) { 1964 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1965 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1966 + " without permission " + android.Manifest.permission.DUMP); 1967 return; 1968 } 1969 1970 synchronized (mActivityManagerService.mProcessCpuTracker) { 1971 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1972 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1973 SystemClock.uptimeMillis())); 1974 } 1975 } 1976 } 1977 1978 public static final class Lifecycle extends SystemService { 1979 private final ActivityManagerService mService; 1980 1981 public Lifecycle(Context context) { 1982 super(context); 1983 mService = new ActivityManagerService(context); 1984 } 1985 1986 @Override 1987 public void onStart() { 1988 mService.start(); 1989 } 1990 1991 public ActivityManagerService getService() { 1992 return mService; 1993 } 1994 } 1995 1996 // Note: This method is invoked on the main thread but may need to attach various 1997 // handlers to other threads. So take care to be explicit about the looper. 1998 public ActivityManagerService(Context systemContext) { 1999 mContext = systemContext; 2000 mFactoryTest = FactoryTest.getMode(); 2001 mSystemThread = ActivityThread.currentActivityThread(); 2002 2003 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2004 2005 mHandlerThread = new ServiceThread(TAG, 2006 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2007 mHandlerThread.start(); 2008 mHandler = new MainHandler(mHandlerThread.getLooper()); 2009 2010 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2011 "foreground", BROADCAST_FG_TIMEOUT, false); 2012 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2013 "background", BROADCAST_BG_TIMEOUT, true); 2014 mBroadcastQueues[0] = mFgBroadcastQueue; 2015 mBroadcastQueues[1] = mBgBroadcastQueue; 2016 2017 mServices = new ActiveServices(this); 2018 mProviderMap = new ProviderMap(this); 2019 2020 // TODO: Move creation of battery stats service outside of activity manager service. 2021 File dataDir = Environment.getDataDirectory(); 2022 File systemDir = new File(dataDir, "system"); 2023 systemDir.mkdirs(); 2024 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2025 mBatteryStatsService.getActiveStatistics().readLocked(); 2026 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2027 mOnBattery = DEBUG_POWER ? true 2028 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2029 mBatteryStatsService.getActiveStatistics().setCallback(this); 2030 2031 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2032 2033 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2034 2035 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2036 2037 // User 0 is the first and only user that runs at boot. 2038 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2039 mUserLru.add(Integer.valueOf(0)); 2040 updateStartedUserArrayLocked(); 2041 2042 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2043 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2044 2045 mConfiguration.setToDefaults(); 2046 mConfiguration.setLocale(Locale.getDefault()); 2047 2048 mConfigurationSeq = mConfiguration.seq = 1; 2049 mProcessCpuTracker.init(); 2050 2051 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2052 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2053 mStackSupervisor = new ActivityStackSupervisor(this); 2054 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2055 2056 mProcessCpuThread = new Thread("CpuTracker") { 2057 @Override 2058 public void run() { 2059 while (true) { 2060 try { 2061 try { 2062 synchronized(this) { 2063 final long now = SystemClock.uptimeMillis(); 2064 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2065 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2066 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2067 // + ", write delay=" + nextWriteDelay); 2068 if (nextWriteDelay < nextCpuDelay) { 2069 nextCpuDelay = nextWriteDelay; 2070 } 2071 if (nextCpuDelay > 0) { 2072 mProcessCpuMutexFree.set(true); 2073 this.wait(nextCpuDelay); 2074 } 2075 } 2076 } catch (InterruptedException e) { 2077 } 2078 updateCpuStatsNow(); 2079 } catch (Exception e) { 2080 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2081 } 2082 } 2083 } 2084 }; 2085 2086 Watchdog.getInstance().addMonitor(this); 2087 Watchdog.getInstance().addThread(mHandler); 2088 } 2089 2090 public void setSystemServiceManager(SystemServiceManager mgr) { 2091 mSystemServiceManager = mgr; 2092 } 2093 2094 public void setInstaller(Installer installer) { 2095 mInstaller = installer; 2096 } 2097 2098 private void start() { 2099 Process.removeAllProcessGroups(); 2100 mProcessCpuThread.start(); 2101 2102 mBatteryStatsService.publish(mContext); 2103 mAppOpsService.publish(mContext); 2104 Slog.d("AppOps", "AppOpsService published"); 2105 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2106 } 2107 2108 public void initPowerManagement() { 2109 mStackSupervisor.initPowerManagement(); 2110 mBatteryStatsService.initPowerManagement(); 2111 } 2112 2113 @Override 2114 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2115 throws RemoteException { 2116 if (code == SYSPROPS_TRANSACTION) { 2117 // We need to tell all apps about the system property change. 2118 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2119 synchronized(this) { 2120 final int NP = mProcessNames.getMap().size(); 2121 for (int ip=0; ip<NP; ip++) { 2122 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2123 final int NA = apps.size(); 2124 for (int ia=0; ia<NA; ia++) { 2125 ProcessRecord app = apps.valueAt(ia); 2126 if (app.thread != null) { 2127 procs.add(app.thread.asBinder()); 2128 } 2129 } 2130 } 2131 } 2132 2133 int N = procs.size(); 2134 for (int i=0; i<N; i++) { 2135 Parcel data2 = Parcel.obtain(); 2136 try { 2137 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2138 } catch (RemoteException e) { 2139 } 2140 data2.recycle(); 2141 } 2142 } 2143 try { 2144 return super.onTransact(code, data, reply, flags); 2145 } catch (RuntimeException e) { 2146 // The activity manager only throws security exceptions, so let's 2147 // log all others. 2148 if (!(e instanceof SecurityException)) { 2149 Slog.wtf(TAG, "Activity Manager Crash", e); 2150 } 2151 throw e; 2152 } 2153 } 2154 2155 void updateCpuStats() { 2156 final long now = SystemClock.uptimeMillis(); 2157 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2158 return; 2159 } 2160 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2161 synchronized (mProcessCpuThread) { 2162 mProcessCpuThread.notify(); 2163 } 2164 } 2165 } 2166 2167 void updateCpuStatsNow() { 2168 synchronized (mProcessCpuTracker) { 2169 mProcessCpuMutexFree.set(false); 2170 final long now = SystemClock.uptimeMillis(); 2171 boolean haveNewCpuStats = false; 2172 2173 if (MONITOR_CPU_USAGE && 2174 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2175 mLastCpuTime.set(now); 2176 haveNewCpuStats = true; 2177 mProcessCpuTracker.update(); 2178 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2179 //Slog.i(TAG, "Total CPU usage: " 2180 // + mProcessCpu.getTotalCpuPercent() + "%"); 2181 2182 // Slog the cpu usage if the property is set. 2183 if ("true".equals(SystemProperties.get("events.cpu"))) { 2184 int user = mProcessCpuTracker.getLastUserTime(); 2185 int system = mProcessCpuTracker.getLastSystemTime(); 2186 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2187 int irq = mProcessCpuTracker.getLastIrqTime(); 2188 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2189 int idle = mProcessCpuTracker.getLastIdleTime(); 2190 2191 int total = user + system + iowait + irq + softIrq + idle; 2192 if (total == 0) total = 1; 2193 2194 EventLog.writeEvent(EventLogTags.CPU, 2195 ((user+system+iowait+irq+softIrq) * 100) / total, 2196 (user * 100) / total, 2197 (system * 100) / total, 2198 (iowait * 100) / total, 2199 (irq * 100) / total, 2200 (softIrq * 100) / total); 2201 } 2202 } 2203 2204 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2205 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2206 synchronized(bstats) { 2207 synchronized(mPidsSelfLocked) { 2208 if (haveNewCpuStats) { 2209 if (mOnBattery) { 2210 int perc = bstats.startAddingCpuLocked(); 2211 int totalUTime = 0; 2212 int totalSTime = 0; 2213 final int N = mProcessCpuTracker.countStats(); 2214 for (int i=0; i<N; i++) { 2215 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2216 if (!st.working) { 2217 continue; 2218 } 2219 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2220 int otherUTime = (st.rel_utime*perc)/100; 2221 int otherSTime = (st.rel_stime*perc)/100; 2222 totalUTime += otherUTime; 2223 totalSTime += otherSTime; 2224 if (pr != null) { 2225 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2226 if (ps == null || !ps.isActive()) { 2227 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2228 pr.info.uid, pr.processName); 2229 } 2230 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2231 st.rel_stime-otherSTime); 2232 ps.addSpeedStepTimes(cpuSpeedTimes); 2233 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2234 } else { 2235 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2236 if (ps == null || !ps.isActive()) { 2237 st.batteryStats = ps = bstats.getProcessStatsLocked( 2238 bstats.mapUid(st.uid), st.name); 2239 } 2240 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2241 st.rel_stime-otherSTime); 2242 ps.addSpeedStepTimes(cpuSpeedTimes); 2243 } 2244 } 2245 bstats.finishAddingCpuLocked(perc, totalUTime, 2246 totalSTime, cpuSpeedTimes); 2247 } 2248 } 2249 } 2250 2251 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2252 mLastWriteTime = now; 2253 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2254 } 2255 } 2256 } 2257 } 2258 2259 @Override 2260 public void batteryNeedsCpuUpdate() { 2261 updateCpuStatsNow(); 2262 } 2263 2264 @Override 2265 public void batteryPowerChanged(boolean onBattery) { 2266 // When plugging in, update the CPU stats first before changing 2267 // the plug state. 2268 updateCpuStatsNow(); 2269 synchronized (this) { 2270 synchronized(mPidsSelfLocked) { 2271 mOnBattery = DEBUG_POWER ? true : onBattery; 2272 } 2273 } 2274 } 2275 2276 /** 2277 * Initialize the application bind args. These are passed to each 2278 * process when the bindApplication() IPC is sent to the process. They're 2279 * lazily setup to make sure the services are running when they're asked for. 2280 */ 2281 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2282 if (mAppBindArgs == null) { 2283 mAppBindArgs = new HashMap<>(); 2284 2285 // Isolated processes won't get this optimization, so that we don't 2286 // violate the rules about which services they have access to. 2287 if (!isolated) { 2288 // Setup the application init args 2289 mAppBindArgs.put("package", ServiceManager.getService("package")); 2290 mAppBindArgs.put("window", ServiceManager.getService("window")); 2291 mAppBindArgs.put(Context.ALARM_SERVICE, 2292 ServiceManager.getService(Context.ALARM_SERVICE)); 2293 } 2294 } 2295 return mAppBindArgs; 2296 } 2297 2298 final void setFocusedActivityLocked(ActivityRecord r) { 2299 if (mFocusedActivity != r) { 2300 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2301 mFocusedActivity = r; 2302 if (r.task != null && r.task.voiceInteractor != null) { 2303 startRunningVoiceLocked(); 2304 } else { 2305 finishRunningVoiceLocked(); 2306 } 2307 mStackSupervisor.setFocusedStack(r); 2308 if (r != null) { 2309 mWindowManager.setFocusedApp(r.appToken, true); 2310 } 2311 applyUpdateLockStateLocked(r); 2312 } 2313 } 2314 2315 final void clearFocusedActivity(ActivityRecord r) { 2316 if (mFocusedActivity == r) { 2317 mFocusedActivity = null; 2318 } 2319 } 2320 2321 @Override 2322 public void setFocusedStack(int stackId) { 2323 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2324 synchronized (ActivityManagerService.this) { 2325 ActivityStack stack = mStackSupervisor.getStack(stackId); 2326 if (stack != null) { 2327 ActivityRecord r = stack.topRunningActivityLocked(null); 2328 if (r != null) { 2329 setFocusedActivityLocked(r); 2330 } 2331 } 2332 } 2333 } 2334 2335 @Override 2336 public void notifyActivityDrawn(IBinder token) { 2337 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2338 synchronized (this) { 2339 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2340 if (r != null) { 2341 r.task.stack.notifyActivityDrawnLocked(r); 2342 } 2343 } 2344 } 2345 2346 final void applyUpdateLockStateLocked(ActivityRecord r) { 2347 // Modifications to the UpdateLock state are done on our handler, outside 2348 // the activity manager's locks. The new state is determined based on the 2349 // state *now* of the relevant activity record. The object is passed to 2350 // the handler solely for logging detail, not to be consulted/modified. 2351 final boolean nextState = r != null && r.immersive; 2352 mHandler.sendMessage( 2353 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2354 } 2355 2356 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2357 Message msg = Message.obtain(); 2358 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2359 msg.obj = r.task.askedCompatMode ? null : r; 2360 mHandler.sendMessage(msg); 2361 } 2362 2363 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2364 String what, Object obj, ProcessRecord srcApp) { 2365 app.lastActivityTime = now; 2366 2367 if (app.activities.size() > 0) { 2368 // Don't want to touch dependent processes that are hosting activities. 2369 return index; 2370 } 2371 2372 int lrui = mLruProcesses.lastIndexOf(app); 2373 if (lrui < 0) { 2374 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2375 + what + " " + obj + " from " + srcApp); 2376 return index; 2377 } 2378 2379 if (lrui >= index) { 2380 // Don't want to cause this to move dependent processes *back* in the 2381 // list as if they were less frequently used. 2382 return index; 2383 } 2384 2385 if (lrui >= mLruProcessActivityStart) { 2386 // Don't want to touch dependent processes that are hosting activities. 2387 return index; 2388 } 2389 2390 mLruProcesses.remove(lrui); 2391 if (index > 0) { 2392 index--; 2393 } 2394 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2395 + " in LRU list: " + app); 2396 mLruProcesses.add(index, app); 2397 return index; 2398 } 2399 2400 final void removeLruProcessLocked(ProcessRecord app) { 2401 int lrui = mLruProcesses.lastIndexOf(app); 2402 if (lrui >= 0) { 2403 if (!app.killed) { 2404 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2405 Process.killProcessQuiet(app.pid); 2406 Process.killProcessGroup(app.info.uid, app.pid); 2407 } 2408 if (lrui <= mLruProcessActivityStart) { 2409 mLruProcessActivityStart--; 2410 } 2411 if (lrui <= mLruProcessServiceStart) { 2412 mLruProcessServiceStart--; 2413 } 2414 mLruProcesses.remove(lrui); 2415 } 2416 } 2417 2418 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2419 ProcessRecord client) { 2420 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2421 || app.treatLikeActivity; 2422 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2423 if (!activityChange && hasActivity) { 2424 // The process has activities, so we are only allowing activity-based adjustments 2425 // to move it. It should be kept in the front of the list with other 2426 // processes that have activities, and we don't want those to change their 2427 // order except due to activity operations. 2428 return; 2429 } 2430 2431 mLruSeq++; 2432 final long now = SystemClock.uptimeMillis(); 2433 app.lastActivityTime = now; 2434 2435 // First a quick reject: if the app is already at the position we will 2436 // put it, then there is nothing to do. 2437 if (hasActivity) { 2438 final int N = mLruProcesses.size(); 2439 if (N > 0 && mLruProcesses.get(N-1) == app) { 2440 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2441 return; 2442 } 2443 } else { 2444 if (mLruProcessServiceStart > 0 2445 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2446 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2447 return; 2448 } 2449 } 2450 2451 int lrui = mLruProcesses.lastIndexOf(app); 2452 2453 if (app.persistent && lrui >= 0) { 2454 // We don't care about the position of persistent processes, as long as 2455 // they are in the list. 2456 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2457 return; 2458 } 2459 2460 /* In progress: compute new position first, so we can avoid doing work 2461 if the process is not actually going to move. Not yet working. 2462 int addIndex; 2463 int nextIndex; 2464 boolean inActivity = false, inService = false; 2465 if (hasActivity) { 2466 // Process has activities, put it at the very tipsy-top. 2467 addIndex = mLruProcesses.size(); 2468 nextIndex = mLruProcessServiceStart; 2469 inActivity = true; 2470 } else if (hasService) { 2471 // Process has services, put it at the top of the service list. 2472 addIndex = mLruProcessActivityStart; 2473 nextIndex = mLruProcessServiceStart; 2474 inActivity = true; 2475 inService = true; 2476 } else { 2477 // Process not otherwise of interest, it goes to the top of the non-service area. 2478 addIndex = mLruProcessServiceStart; 2479 if (client != null) { 2480 int clientIndex = mLruProcesses.lastIndexOf(client); 2481 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2482 + app); 2483 if (clientIndex >= 0 && addIndex > clientIndex) { 2484 addIndex = clientIndex; 2485 } 2486 } 2487 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2488 } 2489 2490 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2491 + mLruProcessActivityStart + "): " + app); 2492 */ 2493 2494 if (lrui >= 0) { 2495 if (lrui < mLruProcessActivityStart) { 2496 mLruProcessActivityStart--; 2497 } 2498 if (lrui < mLruProcessServiceStart) { 2499 mLruProcessServiceStart--; 2500 } 2501 /* 2502 if (addIndex > lrui) { 2503 addIndex--; 2504 } 2505 if (nextIndex > lrui) { 2506 nextIndex--; 2507 } 2508 */ 2509 mLruProcesses.remove(lrui); 2510 } 2511 2512 /* 2513 mLruProcesses.add(addIndex, app); 2514 if (inActivity) { 2515 mLruProcessActivityStart++; 2516 } 2517 if (inService) { 2518 mLruProcessActivityStart++; 2519 } 2520 */ 2521 2522 int nextIndex; 2523 if (hasActivity) { 2524 final int N = mLruProcesses.size(); 2525 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2526 // Process doesn't have activities, but has clients with 2527 // activities... move it up, but one below the top (the top 2528 // should always have a real activity). 2529 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2530 mLruProcesses.add(N-1, app); 2531 // To keep it from spamming the LRU list (by making a bunch of clients), 2532 // we will push down any other entries owned by the app. 2533 final int uid = app.info.uid; 2534 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2535 ProcessRecord subProc = mLruProcesses.get(i); 2536 if (subProc.info.uid == uid) { 2537 // We want to push this one down the list. If the process after 2538 // it is for the same uid, however, don't do so, because we don't 2539 // want them internally to be re-ordered. 2540 if (mLruProcesses.get(i-1).info.uid != uid) { 2541 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2542 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2543 ProcessRecord tmp = mLruProcesses.get(i); 2544 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2545 mLruProcesses.set(i-1, tmp); 2546 i--; 2547 } 2548 } else { 2549 // A gap, we can stop here. 2550 break; 2551 } 2552 } 2553 } else { 2554 // Process has activities, put it at the very tipsy-top. 2555 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2556 mLruProcesses.add(app); 2557 } 2558 nextIndex = mLruProcessServiceStart; 2559 } else if (hasService) { 2560 // Process has services, put it at the top of the service list. 2561 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2562 mLruProcesses.add(mLruProcessActivityStart, app); 2563 nextIndex = mLruProcessServiceStart; 2564 mLruProcessActivityStart++; 2565 } else { 2566 // Process not otherwise of interest, it goes to the top of the non-service area. 2567 int index = mLruProcessServiceStart; 2568 if (client != null) { 2569 // If there is a client, don't allow the process to be moved up higher 2570 // in the list than that client. 2571 int clientIndex = mLruProcesses.lastIndexOf(client); 2572 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2573 + " when updating " + app); 2574 if (clientIndex <= lrui) { 2575 // Don't allow the client index restriction to push it down farther in the 2576 // list than it already is. 2577 clientIndex = lrui; 2578 } 2579 if (clientIndex >= 0 && index > clientIndex) { 2580 index = clientIndex; 2581 } 2582 } 2583 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2584 mLruProcesses.add(index, app); 2585 nextIndex = index-1; 2586 mLruProcessActivityStart++; 2587 mLruProcessServiceStart++; 2588 } 2589 2590 // If the app is currently using a content provider or service, 2591 // bump those processes as well. 2592 for (int j=app.connections.size()-1; j>=0; j--) { 2593 ConnectionRecord cr = app.connections.valueAt(j); 2594 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2595 && cr.binding.service.app != null 2596 && cr.binding.service.app.lruSeq != mLruSeq 2597 && !cr.binding.service.app.persistent) { 2598 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2599 "service connection", cr, app); 2600 } 2601 } 2602 for (int j=app.conProviders.size()-1; j>=0; j--) { 2603 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2604 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2605 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2606 "provider reference", cpr, app); 2607 } 2608 } 2609 } 2610 2611 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2612 if (uid == Process.SYSTEM_UID) { 2613 // The system gets to run in any process. If there are multiple 2614 // processes with the same uid, just pick the first (this 2615 // should never happen). 2616 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2617 if (procs == null) return null; 2618 final int N = procs.size(); 2619 for (int i = 0; i < N; i++) { 2620 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2621 } 2622 } 2623 ProcessRecord proc = mProcessNames.get(processName, uid); 2624 if (false && proc != null && !keepIfLarge 2625 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2626 && proc.lastCachedPss >= 4000) { 2627 // Turn this condition on to cause killing to happen regularly, for testing. 2628 if (proc.baseProcessTracker != null) { 2629 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2630 } 2631 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2632 } else if (proc != null && !keepIfLarge 2633 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2634 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2635 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2636 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2637 if (proc.baseProcessTracker != null) { 2638 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2639 } 2640 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2641 } 2642 } 2643 return proc; 2644 } 2645 2646 void ensurePackageDexOpt(String packageName) { 2647 IPackageManager pm = AppGlobals.getPackageManager(); 2648 try { 2649 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2650 mDidDexOpt = true; 2651 } 2652 } catch (RemoteException e) { 2653 } 2654 } 2655 2656 boolean isNextTransitionForward() { 2657 int transit = mWindowManager.getPendingAppTransition(); 2658 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2659 || transit == AppTransition.TRANSIT_TASK_OPEN 2660 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2661 } 2662 2663 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2664 String processName, String abiOverride, int uid, Runnable crashHandler) { 2665 synchronized(this) { 2666 ApplicationInfo info = new ApplicationInfo(); 2667 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2668 // For isolated processes, the former contains the parent's uid and the latter the 2669 // actual uid of the isolated process. 2670 // In the special case introduced by this method (which is, starting an isolated 2671 // process directly from the SystemServer without an actual parent app process) the 2672 // closest thing to a parent's uid is SYSTEM_UID. 2673 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2674 // the |isolated| logic in the ProcessRecord constructor. 2675 info.uid = Process.SYSTEM_UID; 2676 info.processName = processName; 2677 info.className = entryPoint; 2678 info.packageName = "android"; 2679 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2680 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2681 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2682 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2683 crashHandler); 2684 return proc != null ? proc.pid : 0; 2685 } 2686 } 2687 2688 final ProcessRecord startProcessLocked(String processName, 2689 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2690 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2691 boolean isolated, boolean keepIfLarge) { 2692 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2693 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2694 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2695 null /* crashHandler */); 2696 } 2697 2698 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2699 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2700 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2701 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2702 long startTime = SystemClock.elapsedRealtime(); 2703 ProcessRecord app; 2704 if (!isolated) { 2705 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2706 checkTime(startTime, "startProcess: after getProcessRecord"); 2707 } else { 2708 // If this is an isolated process, it can't re-use an existing process. 2709 app = null; 2710 } 2711 // We don't have to do anything more if: 2712 // (1) There is an existing application record; and 2713 // (2) The caller doesn't think it is dead, OR there is no thread 2714 // object attached to it so we know it couldn't have crashed; and 2715 // (3) There is a pid assigned to it, so it is either starting or 2716 // already running. 2717 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2718 + " app=" + app + " knownToBeDead=" + knownToBeDead 2719 + " thread=" + (app != null ? app.thread : null) 2720 + " pid=" + (app != null ? app.pid : -1)); 2721 if (app != null && app.pid > 0) { 2722 if (!knownToBeDead || app.thread == null) { 2723 // We already have the app running, or are waiting for it to 2724 // come up (we have a pid but not yet its thread), so keep it. 2725 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2726 // If this is a new package in the process, add the package to the list 2727 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2728 checkTime(startTime, "startProcess: done, added package to proc"); 2729 return app; 2730 } 2731 2732 // An application record is attached to a previous process, 2733 // clean it up now. 2734 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2735 checkTime(startTime, "startProcess: bad proc running, killing"); 2736 Process.killProcessGroup(app.info.uid, app.pid); 2737 handleAppDiedLocked(app, true, true); 2738 checkTime(startTime, "startProcess: done killing old proc"); 2739 } 2740 2741 String hostingNameStr = hostingName != null 2742 ? hostingName.flattenToShortString() : null; 2743 2744 if (!isolated) { 2745 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2746 // If we are in the background, then check to see if this process 2747 // is bad. If so, we will just silently fail. 2748 if (mBadProcesses.get(info.processName, info.uid) != null) { 2749 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2750 + "/" + info.processName); 2751 return null; 2752 } 2753 } else { 2754 // When the user is explicitly starting a process, then clear its 2755 // crash count so that we won't make it bad until they see at 2756 // least one crash dialog again, and make the process good again 2757 // if it had been bad. 2758 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2759 + "/" + info.processName); 2760 mProcessCrashTimes.remove(info.processName, info.uid); 2761 if (mBadProcesses.get(info.processName, info.uid) != null) { 2762 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2763 UserHandle.getUserId(info.uid), info.uid, 2764 info.processName); 2765 mBadProcesses.remove(info.processName, info.uid); 2766 if (app != null) { 2767 app.bad = false; 2768 } 2769 } 2770 } 2771 } 2772 2773 if (app == null) { 2774 checkTime(startTime, "startProcess: creating new process record"); 2775 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2776 app.crashHandler = crashHandler; 2777 if (app == null) { 2778 Slog.w(TAG, "Failed making new process record for " 2779 + processName + "/" + info.uid + " isolated=" + isolated); 2780 return null; 2781 } 2782 mProcessNames.put(processName, app.uid, app); 2783 if (isolated) { 2784 mIsolatedProcesses.put(app.uid, app); 2785 } 2786 checkTime(startTime, "startProcess: done creating new process record"); 2787 } else { 2788 // If this is a new package in the process, add the package to the list 2789 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2790 checkTime(startTime, "startProcess: added package to existing proc"); 2791 } 2792 2793 // If the system is not ready yet, then hold off on starting this 2794 // process until it is. 2795 if (!mProcessesReady 2796 && !isAllowedWhileBooting(info) 2797 && !allowWhileBooting) { 2798 if (!mProcessesOnHold.contains(app)) { 2799 mProcessesOnHold.add(app); 2800 } 2801 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2802 checkTime(startTime, "startProcess: returning with proc on hold"); 2803 return app; 2804 } 2805 2806 checkTime(startTime, "startProcess: stepping in to startProcess"); 2807 startProcessLocked( 2808 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2809 checkTime(startTime, "startProcess: done starting proc!"); 2810 return (app.pid != 0) ? app : null; 2811 } 2812 2813 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2814 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2815 } 2816 2817 private final void startProcessLocked(ProcessRecord app, 2818 String hostingType, String hostingNameStr) { 2819 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2820 null /* entryPoint */, null /* entryPointArgs */); 2821 } 2822 2823 private final void startProcessLocked(ProcessRecord app, String hostingType, 2824 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2825 long startTime = SystemClock.elapsedRealtime(); 2826 if (app.pid > 0 && app.pid != MY_PID) { 2827 checkTime(startTime, "startProcess: removing from pids map"); 2828 synchronized (mPidsSelfLocked) { 2829 mPidsSelfLocked.remove(app.pid); 2830 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2831 } 2832 checkTime(startTime, "startProcess: done removing from pids map"); 2833 app.setPid(0); 2834 } 2835 2836 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2837 "startProcessLocked removing on hold: " + app); 2838 mProcessesOnHold.remove(app); 2839 2840 checkTime(startTime, "startProcess: starting to update cpu stats"); 2841 updateCpuStats(); 2842 checkTime(startTime, "startProcess: done updating cpu stats"); 2843 2844 try { 2845 int uid = app.uid; 2846 2847 int[] gids = null; 2848 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2849 if (!app.isolated) { 2850 int[] permGids = null; 2851 try { 2852 checkTime(startTime, "startProcess: getting gids from package manager"); 2853 final PackageManager pm = mContext.getPackageManager(); 2854 permGids = pm.getPackageGids(app.info.packageName); 2855 2856 if (Environment.isExternalStorageEmulated()) { 2857 checkTime(startTime, "startProcess: checking external storage perm"); 2858 if (pm.checkPermission( 2859 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2860 app.info.packageName) == PERMISSION_GRANTED) { 2861 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2862 } else { 2863 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2864 } 2865 } 2866 } catch (PackageManager.NameNotFoundException e) { 2867 Slog.w(TAG, "Unable to retrieve gids", e); 2868 } 2869 2870 /* 2871 * Add shared application and profile GIDs so applications can share some 2872 * resources like shared libraries and access user-wide resources 2873 */ 2874 if (permGids == null) { 2875 gids = new int[2]; 2876 } else { 2877 gids = new int[permGids.length + 2]; 2878 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2879 } 2880 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2881 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2882 } 2883 checkTime(startTime, "startProcess: building args"); 2884 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2885 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2886 && mTopComponent != null 2887 && app.processName.equals(mTopComponent.getPackageName())) { 2888 uid = 0; 2889 } 2890 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2891 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2892 uid = 0; 2893 } 2894 } 2895 int debugFlags = 0; 2896 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2897 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2898 // Also turn on CheckJNI for debuggable apps. It's quite 2899 // awkward to turn on otherwise. 2900 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2901 } 2902 // Run the app in safe mode if its manifest requests so or the 2903 // system is booted in safe mode. 2904 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2905 mSafeMode == true) { 2906 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2907 } 2908 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2909 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2910 } 2911 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2912 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2913 } 2914 if ("1".equals(SystemProperties.get("debug.assert"))) { 2915 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2916 } 2917 2918 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2919 if (requiredAbi == null) { 2920 requiredAbi = Build.SUPPORTED_ABIS[0]; 2921 } 2922 2923 String instructionSet = null; 2924 if (app.info.primaryCpuAbi != null) { 2925 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2926 } 2927 2928 // Start the process. It will either succeed and return a result containing 2929 // the PID of the new process, or else throw a RuntimeException. 2930 boolean isActivityProcess = (entryPoint == null); 2931 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2932 checkTime(startTime, "startProcess: asking zygote to start proc"); 2933 Process.ProcessStartResult startResult = Process.start(entryPoint, 2934 app.processName, uid, uid, gids, debugFlags, mountExternal, 2935 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2936 app.info.dataDir, entryPointArgs); 2937 checkTime(startTime, "startProcess: returned from zygote!"); 2938 2939 if (app.isolated) { 2940 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2941 } 2942 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2943 checkTime(startTime, "startProcess: done updating battery stats"); 2944 2945 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2946 UserHandle.getUserId(uid), startResult.pid, uid, 2947 app.processName, hostingType, 2948 hostingNameStr != null ? hostingNameStr : ""); 2949 2950 if (app.persistent) { 2951 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2952 } 2953 2954 checkTime(startTime, "startProcess: building log message"); 2955 StringBuilder buf = mStringBuilder; 2956 buf.setLength(0); 2957 buf.append("Start proc "); 2958 buf.append(app.processName); 2959 if (!isActivityProcess) { 2960 buf.append(" ["); 2961 buf.append(entryPoint); 2962 buf.append("]"); 2963 } 2964 buf.append(" for "); 2965 buf.append(hostingType); 2966 if (hostingNameStr != null) { 2967 buf.append(" "); 2968 buf.append(hostingNameStr); 2969 } 2970 buf.append(": pid="); 2971 buf.append(startResult.pid); 2972 buf.append(" uid="); 2973 buf.append(uid); 2974 buf.append(" gids={"); 2975 if (gids != null) { 2976 for (int gi=0; gi<gids.length; gi++) { 2977 if (gi != 0) buf.append(", "); 2978 buf.append(gids[gi]); 2979 2980 } 2981 } 2982 buf.append("}"); 2983 if (requiredAbi != null) { 2984 buf.append(" abi="); 2985 buf.append(requiredAbi); 2986 } 2987 Slog.i(TAG, buf.toString()); 2988 app.setPid(startResult.pid); 2989 app.usingWrapper = startResult.usingWrapper; 2990 app.removed = false; 2991 app.killed = false; 2992 app.killedByAm = false; 2993 checkTime(startTime, "startProcess: starting to update pids map"); 2994 synchronized (mPidsSelfLocked) { 2995 this.mPidsSelfLocked.put(startResult.pid, app); 2996 if (isActivityProcess) { 2997 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2998 msg.obj = app; 2999 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3000 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3001 } 3002 } 3003 checkTime(startTime, "startProcess: done updating pids map"); 3004 } catch (RuntimeException e) { 3005 // XXX do better error recovery. 3006 app.setPid(0); 3007 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3008 if (app.isolated) { 3009 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3010 } 3011 Slog.e(TAG, "Failure starting process " + app.processName, e); 3012 } 3013 } 3014 3015 void updateUsageStats(ActivityRecord component, boolean resumed) { 3016 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3017 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3018 if (resumed) { 3019 if (mUsageStatsService != null) { 3020 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3021 UsageEvents.Event.MOVE_TO_FOREGROUND); 3022 } 3023 synchronized (stats) { 3024 stats.noteActivityResumedLocked(component.app.uid); 3025 } 3026 } else { 3027 if (mUsageStatsService != null) { 3028 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3029 UsageEvents.Event.MOVE_TO_BACKGROUND); 3030 } 3031 synchronized (stats) { 3032 stats.noteActivityPausedLocked(component.app.uid); 3033 } 3034 } 3035 } 3036 3037 Intent getHomeIntent() { 3038 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3039 intent.setComponent(mTopComponent); 3040 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3041 intent.addCategory(Intent.CATEGORY_HOME); 3042 } 3043 return intent; 3044 } 3045 3046 boolean startHomeActivityLocked(int userId) { 3047 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3048 && mTopAction == null) { 3049 // We are running in factory test mode, but unable to find 3050 // the factory test app, so just sit around displaying the 3051 // error message and don't try to start anything. 3052 return false; 3053 } 3054 Intent intent = getHomeIntent(); 3055 ActivityInfo aInfo = 3056 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3057 if (aInfo != null) { 3058 intent.setComponent(new ComponentName( 3059 aInfo.applicationInfo.packageName, aInfo.name)); 3060 // Don't do this if the home app is currently being 3061 // instrumented. 3062 aInfo = new ActivityInfo(aInfo); 3063 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3064 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3065 aInfo.applicationInfo.uid, true); 3066 if (app == null || app.instrumentationClass == null) { 3067 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3068 mStackSupervisor.startHomeActivity(intent, aInfo); 3069 } 3070 } 3071 3072 return true; 3073 } 3074 3075 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3076 ActivityInfo ai = null; 3077 ComponentName comp = intent.getComponent(); 3078 try { 3079 if (comp != null) { 3080 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3081 } else { 3082 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3083 intent, 3084 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3085 flags, userId); 3086 3087 if (info != null) { 3088 ai = info.activityInfo; 3089 } 3090 } 3091 } catch (RemoteException e) { 3092 // ignore 3093 } 3094 3095 return ai; 3096 } 3097 3098 /** 3099 * Starts the "new version setup screen" if appropriate. 3100 */ 3101 void startSetupActivityLocked() { 3102 // Only do this once per boot. 3103 if (mCheckedForSetup) { 3104 return; 3105 } 3106 3107 // We will show this screen if the current one is a different 3108 // version than the last one shown, and we are not running in 3109 // low-level factory test mode. 3110 final ContentResolver resolver = mContext.getContentResolver(); 3111 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3112 Settings.Global.getInt(resolver, 3113 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3114 mCheckedForSetup = true; 3115 3116 // See if we should be showing the platform update setup UI. 3117 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3118 List<ResolveInfo> ris = mContext.getPackageManager() 3119 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3120 3121 // We don't allow third party apps to replace this. 3122 ResolveInfo ri = null; 3123 for (int i=0; ris != null && i<ris.size(); i++) { 3124 if ((ris.get(i).activityInfo.applicationInfo.flags 3125 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3126 ri = ris.get(i); 3127 break; 3128 } 3129 } 3130 3131 if (ri != null) { 3132 String vers = ri.activityInfo.metaData != null 3133 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3134 : null; 3135 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3136 vers = ri.activityInfo.applicationInfo.metaData.getString( 3137 Intent.METADATA_SETUP_VERSION); 3138 } 3139 String lastVers = Settings.Secure.getString( 3140 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3141 if (vers != null && !vers.equals(lastVers)) { 3142 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3143 intent.setComponent(new ComponentName( 3144 ri.activityInfo.packageName, ri.activityInfo.name)); 3145 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3146 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3147 null); 3148 } 3149 } 3150 } 3151 } 3152 3153 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3154 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3155 } 3156 3157 void enforceNotIsolatedCaller(String caller) { 3158 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3159 throw new SecurityException("Isolated process not allowed to call " + caller); 3160 } 3161 } 3162 3163 void enforceShellRestriction(String restriction, int userHandle) { 3164 if (Binder.getCallingUid() == Process.SHELL_UID) { 3165 if (userHandle < 0 3166 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3167 throw new SecurityException("Shell does not have permission to access user " 3168 + userHandle); 3169 } 3170 } 3171 } 3172 3173 @Override 3174 public int getFrontActivityScreenCompatMode() { 3175 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3176 synchronized (this) { 3177 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3178 } 3179 } 3180 3181 @Override 3182 public void setFrontActivityScreenCompatMode(int mode) { 3183 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3184 "setFrontActivityScreenCompatMode"); 3185 synchronized (this) { 3186 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3187 } 3188 } 3189 3190 @Override 3191 public int getPackageScreenCompatMode(String packageName) { 3192 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3193 synchronized (this) { 3194 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3195 } 3196 } 3197 3198 @Override 3199 public void setPackageScreenCompatMode(String packageName, int mode) { 3200 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3201 "setPackageScreenCompatMode"); 3202 synchronized (this) { 3203 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3204 } 3205 } 3206 3207 @Override 3208 public boolean getPackageAskScreenCompat(String packageName) { 3209 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3210 synchronized (this) { 3211 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3212 } 3213 } 3214 3215 @Override 3216 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3217 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3218 "setPackageAskScreenCompat"); 3219 synchronized (this) { 3220 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3221 } 3222 } 3223 3224 private void dispatchProcessesChanged() { 3225 int N; 3226 synchronized (this) { 3227 N = mPendingProcessChanges.size(); 3228 if (mActiveProcessChanges.length < N) { 3229 mActiveProcessChanges = new ProcessChangeItem[N]; 3230 } 3231 mPendingProcessChanges.toArray(mActiveProcessChanges); 3232 mAvailProcessChanges.addAll(mPendingProcessChanges); 3233 mPendingProcessChanges.clear(); 3234 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3235 } 3236 3237 int i = mProcessObservers.beginBroadcast(); 3238 while (i > 0) { 3239 i--; 3240 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3241 if (observer != null) { 3242 try { 3243 for (int j=0; j<N; j++) { 3244 ProcessChangeItem item = mActiveProcessChanges[j]; 3245 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3246 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3247 + item.pid + " uid=" + item.uid + ": " 3248 + item.foregroundActivities); 3249 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3250 item.foregroundActivities); 3251 } 3252 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3253 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3254 + item.pid + " uid=" + item.uid + ": " + item.processState); 3255 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3256 } 3257 } 3258 } catch (RemoteException e) { 3259 } 3260 } 3261 } 3262 mProcessObservers.finishBroadcast(); 3263 } 3264 3265 private void dispatchProcessDied(int pid, int uid) { 3266 int i = mProcessObservers.beginBroadcast(); 3267 while (i > 0) { 3268 i--; 3269 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3270 if (observer != null) { 3271 try { 3272 observer.onProcessDied(pid, uid); 3273 } catch (RemoteException e) { 3274 } 3275 } 3276 } 3277 mProcessObservers.finishBroadcast(); 3278 } 3279 3280 @Override 3281 public final int startActivity(IApplicationThread caller, String callingPackage, 3282 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3283 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3284 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3285 resultWho, requestCode, startFlags, profilerInfo, options, 3286 UserHandle.getCallingUserId()); 3287 } 3288 3289 @Override 3290 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3291 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3292 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3293 enforceNotIsolatedCaller("startActivity"); 3294 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3295 false, ALLOW_FULL_ONLY, "startActivity", null); 3296 // TODO: Switch to user app stacks here. 3297 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3298 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3299 profilerInfo, null, null, options, userId, null, null); 3300 } 3301 3302 @Override 3303 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3304 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3305 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3306 3307 // This is very dangerous -- it allows you to perform a start activity (including 3308 // permission grants) as any app that may launch one of your own activities. So 3309 // we will only allow this to be done from activities that are part of the core framework, 3310 // and then only when they are running as the system. 3311 final ActivityRecord sourceRecord; 3312 final int targetUid; 3313 final String targetPackage; 3314 synchronized (this) { 3315 if (resultTo == null) { 3316 throw new SecurityException("Must be called from an activity"); 3317 } 3318 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3319 if (sourceRecord == null) { 3320 throw new SecurityException("Called with bad activity token: " + resultTo); 3321 } 3322 if (!sourceRecord.info.packageName.equals("android")) { 3323 throw new SecurityException( 3324 "Must be called from an activity that is declared in the android package"); 3325 } 3326 if (sourceRecord.app == null) { 3327 throw new SecurityException("Called without a process attached to activity"); 3328 } 3329 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3330 // This is still okay, as long as this activity is running under the 3331 // uid of the original calling activity. 3332 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3333 throw new SecurityException( 3334 "Calling activity in uid " + sourceRecord.app.uid 3335 + " must be system uid or original calling uid " 3336 + sourceRecord.launchedFromUid); 3337 } 3338 } 3339 targetUid = sourceRecord.launchedFromUid; 3340 targetPackage = sourceRecord.launchedFromPackage; 3341 } 3342 3343 if (userId == UserHandle.USER_NULL) { 3344 userId = UserHandle.getUserId(sourceRecord.app.uid); 3345 } 3346 3347 // TODO: Switch to user app stacks here. 3348 try { 3349 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3350 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3351 null, null, options, userId, null, null); 3352 return ret; 3353 } catch (SecurityException e) { 3354 // XXX need to figure out how to propagate to original app. 3355 // A SecurityException here is generally actually a fault of the original 3356 // calling activity (such as a fairly granting permissions), so propagate it 3357 // back to them. 3358 /* 3359 StringBuilder msg = new StringBuilder(); 3360 msg.append("While launching"); 3361 msg.append(intent.toString()); 3362 msg.append(": "); 3363 msg.append(e.getMessage()); 3364 */ 3365 throw e; 3366 } 3367 } 3368 3369 @Override 3370 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3371 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3372 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3373 enforceNotIsolatedCaller("startActivityAndWait"); 3374 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3375 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3376 WaitResult res = new WaitResult(); 3377 // TODO: Switch to user app stacks here. 3378 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3379 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3380 options, userId, null, null); 3381 return res; 3382 } 3383 3384 @Override 3385 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3386 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3387 int startFlags, Configuration config, Bundle options, int userId) { 3388 enforceNotIsolatedCaller("startActivityWithConfig"); 3389 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3390 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3391 // TODO: Switch to user app stacks here. 3392 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3393 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3394 null, null, config, options, userId, null, null); 3395 return ret; 3396 } 3397 3398 @Override 3399 public int startActivityIntentSender(IApplicationThread caller, 3400 IntentSender intent, Intent fillInIntent, String resolvedType, 3401 IBinder resultTo, String resultWho, int requestCode, 3402 int flagsMask, int flagsValues, Bundle options) { 3403 enforceNotIsolatedCaller("startActivityIntentSender"); 3404 // Refuse possible leaked file descriptors 3405 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3406 throw new IllegalArgumentException("File descriptors passed in Intent"); 3407 } 3408 3409 IIntentSender sender = intent.getTarget(); 3410 if (!(sender instanceof PendingIntentRecord)) { 3411 throw new IllegalArgumentException("Bad PendingIntent object"); 3412 } 3413 3414 PendingIntentRecord pir = (PendingIntentRecord)sender; 3415 3416 synchronized (this) { 3417 // If this is coming from the currently resumed activity, it is 3418 // effectively saying that app switches are allowed at this point. 3419 final ActivityStack stack = getFocusedStack(); 3420 if (stack.mResumedActivity != null && 3421 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3422 mAppSwitchesAllowedTime = 0; 3423 } 3424 } 3425 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3426 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3427 return ret; 3428 } 3429 3430 @Override 3431 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3432 Intent intent, String resolvedType, IVoiceInteractionSession session, 3433 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3434 Bundle options, int userId) { 3435 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3436 != PackageManager.PERMISSION_GRANTED) { 3437 String msg = "Permission Denial: startVoiceActivity() from pid=" 3438 + Binder.getCallingPid() 3439 + ", uid=" + Binder.getCallingUid() 3440 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3441 Slog.w(TAG, msg); 3442 throw new SecurityException(msg); 3443 } 3444 if (session == null || interactor == null) { 3445 throw new NullPointerException("null session or interactor"); 3446 } 3447 userId = handleIncomingUser(callingPid, callingUid, userId, 3448 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3449 // TODO: Switch to user app stacks here. 3450 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3451 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3452 null, options, userId, null, null); 3453 } 3454 3455 @Override 3456 public boolean startNextMatchingActivity(IBinder callingActivity, 3457 Intent intent, Bundle options) { 3458 // Refuse possible leaked file descriptors 3459 if (intent != null && intent.hasFileDescriptors() == true) { 3460 throw new IllegalArgumentException("File descriptors passed in Intent"); 3461 } 3462 3463 synchronized (this) { 3464 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3465 if (r == null) { 3466 ActivityOptions.abort(options); 3467 return false; 3468 } 3469 if (r.app == null || r.app.thread == null) { 3470 // The caller is not running... d'oh! 3471 ActivityOptions.abort(options); 3472 return false; 3473 } 3474 intent = new Intent(intent); 3475 // The caller is not allowed to change the data. 3476 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3477 // And we are resetting to find the next component... 3478 intent.setComponent(null); 3479 3480 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3481 3482 ActivityInfo aInfo = null; 3483 try { 3484 List<ResolveInfo> resolves = 3485 AppGlobals.getPackageManager().queryIntentActivities( 3486 intent, r.resolvedType, 3487 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3488 UserHandle.getCallingUserId()); 3489 3490 // Look for the original activity in the list... 3491 final int N = resolves != null ? resolves.size() : 0; 3492 for (int i=0; i<N; i++) { 3493 ResolveInfo rInfo = resolves.get(i); 3494 if (rInfo.activityInfo.packageName.equals(r.packageName) 3495 && rInfo.activityInfo.name.equals(r.info.name)) { 3496 // We found the current one... the next matching is 3497 // after it. 3498 i++; 3499 if (i<N) { 3500 aInfo = resolves.get(i).activityInfo; 3501 } 3502 if (debug) { 3503 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3504 + "/" + r.info.name); 3505 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3506 + "/" + aInfo.name); 3507 } 3508 break; 3509 } 3510 } 3511 } catch (RemoteException e) { 3512 } 3513 3514 if (aInfo == null) { 3515 // Nobody who is next! 3516 ActivityOptions.abort(options); 3517 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3518 return false; 3519 } 3520 3521 intent.setComponent(new ComponentName( 3522 aInfo.applicationInfo.packageName, aInfo.name)); 3523 intent.setFlags(intent.getFlags()&~( 3524 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3525 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3526 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3527 Intent.FLAG_ACTIVITY_NEW_TASK)); 3528 3529 // Okay now we need to start the new activity, replacing the 3530 // currently running activity. This is a little tricky because 3531 // we want to start the new one as if the current one is finished, 3532 // but not finish the current one first so that there is no flicker. 3533 // And thus... 3534 final boolean wasFinishing = r.finishing; 3535 r.finishing = true; 3536 3537 // Propagate reply information over to the new activity. 3538 final ActivityRecord resultTo = r.resultTo; 3539 final String resultWho = r.resultWho; 3540 final int requestCode = r.requestCode; 3541 r.resultTo = null; 3542 if (resultTo != null) { 3543 resultTo.removeResultsLocked(r, resultWho, requestCode); 3544 } 3545 3546 final long origId = Binder.clearCallingIdentity(); 3547 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3548 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3549 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3550 -1, r.launchedFromUid, 0, options, false, null, null, null); 3551 Binder.restoreCallingIdentity(origId); 3552 3553 r.finishing = wasFinishing; 3554 if (res != ActivityManager.START_SUCCESS) { 3555 return false; 3556 } 3557 return true; 3558 } 3559 } 3560 3561 @Override 3562 public final int startActivityFromRecents(int taskId, Bundle options) { 3563 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3564 String msg = "Permission Denial: startActivityFromRecents called without " + 3565 START_TASKS_FROM_RECENTS; 3566 Slog.w(TAG, msg); 3567 throw new SecurityException(msg); 3568 } 3569 return startActivityFromRecentsInner(taskId, options); 3570 } 3571 3572 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3573 final TaskRecord task; 3574 final int callingUid; 3575 final String callingPackage; 3576 final Intent intent; 3577 final int userId; 3578 synchronized (this) { 3579 task = recentTaskForIdLocked(taskId); 3580 if (task == null) { 3581 throw new IllegalArgumentException("Task " + taskId + " not found."); 3582 } 3583 callingUid = task.mCallingUid; 3584 callingPackage = task.mCallingPackage; 3585 intent = task.intent; 3586 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3587 userId = task.userId; 3588 } 3589 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3590 options, userId, null, task); 3591 } 3592 3593 final int startActivityInPackage(int uid, String callingPackage, 3594 Intent intent, String resolvedType, IBinder resultTo, 3595 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3596 IActivityContainer container, TaskRecord inTask) { 3597 3598 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3599 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3600 3601 // TODO: Switch to user app stacks here. 3602 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3603 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3604 null, null, null, options, userId, container, inTask); 3605 return ret; 3606 } 3607 3608 @Override 3609 public final int startActivities(IApplicationThread caller, String callingPackage, 3610 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3611 int userId) { 3612 enforceNotIsolatedCaller("startActivities"); 3613 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3614 false, ALLOW_FULL_ONLY, "startActivity", null); 3615 // TODO: Switch to user app stacks here. 3616 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3617 resolvedTypes, resultTo, options, userId); 3618 return ret; 3619 } 3620 3621 final int startActivitiesInPackage(int uid, String callingPackage, 3622 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3623 Bundle options, int userId) { 3624 3625 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3626 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3627 // TODO: Switch to user app stacks here. 3628 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3629 resultTo, options, userId); 3630 return ret; 3631 } 3632 3633 //explicitly remove thd old information in mRecentTasks when removing existing user. 3634 private void removeRecentTasksForUserLocked(int userId) { 3635 if(userId <= 0) { 3636 Slog.i(TAG, "Can't remove recent task on user " + userId); 3637 return; 3638 } 3639 3640 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3641 TaskRecord tr = mRecentTasks.get(i); 3642 if (tr.userId == userId) { 3643 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3644 + " when finishing user" + userId); 3645 mRecentTasks.remove(i); 3646 tr.removedFromRecents(mTaskPersister); 3647 } 3648 } 3649 3650 // Remove tasks from persistent storage. 3651 mTaskPersister.wakeup(null, true); 3652 } 3653 3654 // Sort by taskId 3655 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3656 @Override 3657 public int compare(TaskRecord lhs, TaskRecord rhs) { 3658 return rhs.taskId - lhs.taskId; 3659 } 3660 }; 3661 3662 // Extract the affiliates of the chain containing mRecentTasks[start]. 3663 private int processNextAffiliateChain(int start) { 3664 final TaskRecord startTask = mRecentTasks.get(start); 3665 final int affiliateId = startTask.mAffiliatedTaskId; 3666 3667 // Quick identification of isolated tasks. I.e. those not launched behind. 3668 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3669 startTask.mNextAffiliate == null) { 3670 // There is still a slim chance that there are other tasks that point to this task 3671 // and that the chain is so messed up that this task no longer points to them but 3672 // the gain of this optimization outweighs the risk. 3673 startTask.inRecents = true; 3674 return start + 1; 3675 } 3676 3677 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3678 mTmpRecents.clear(); 3679 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3680 final TaskRecord task = mRecentTasks.get(i); 3681 if (task.mAffiliatedTaskId == affiliateId) { 3682 mRecentTasks.remove(i); 3683 mTmpRecents.add(task); 3684 } 3685 } 3686 3687 // Sort them all by taskId. That is the order they were create in and that order will 3688 // always be correct. 3689 Collections.sort(mTmpRecents, mTaskRecordComparator); 3690 3691 // Go through and fix up the linked list. 3692 // The first one is the end of the chain and has no next. 3693 final TaskRecord first = mTmpRecents.get(0); 3694 first.inRecents = true; 3695 if (first.mNextAffiliate != null) { 3696 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3697 first.setNextAffiliate(null); 3698 mTaskPersister.wakeup(first, false); 3699 } 3700 // Everything in the middle is doubly linked from next to prev. 3701 final int tmpSize = mTmpRecents.size(); 3702 for (int i = 0; i < tmpSize - 1; ++i) { 3703 final TaskRecord next = mTmpRecents.get(i); 3704 final TaskRecord prev = mTmpRecents.get(i + 1); 3705 if (next.mPrevAffiliate != prev) { 3706 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3707 " setting prev=" + prev); 3708 next.setPrevAffiliate(prev); 3709 mTaskPersister.wakeup(next, false); 3710 } 3711 if (prev.mNextAffiliate != next) { 3712 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3713 " setting next=" + next); 3714 prev.setNextAffiliate(next); 3715 mTaskPersister.wakeup(prev, false); 3716 } 3717 prev.inRecents = true; 3718 } 3719 // The last one is the beginning of the list and has no prev. 3720 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3721 if (last.mPrevAffiliate != null) { 3722 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3723 last.setPrevAffiliate(null); 3724 mTaskPersister.wakeup(last, false); 3725 } 3726 3727 // Insert the group back into mRecentTasks at start. 3728 mRecentTasks.addAll(start, mTmpRecents); 3729 3730 // Let the caller know where we left off. 3731 return start + tmpSize; 3732 } 3733 3734 /** 3735 * Update the recent tasks lists: make sure tasks should still be here (their 3736 * applications / activities still exist), update their availability, fixup ordering 3737 * of affiliations. 3738 */ 3739 void cleanupRecentTasksLocked(int userId) { 3740 if (mRecentTasks == null) { 3741 // Happens when called from the packagemanager broadcast before boot. 3742 return; 3743 } 3744 3745 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3746 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3747 final IPackageManager pm = AppGlobals.getPackageManager(); 3748 final ActivityInfo dummyAct = new ActivityInfo(); 3749 final ApplicationInfo dummyApp = new ApplicationInfo(); 3750 3751 int N = mRecentTasks.size(); 3752 3753 int[] users = userId == UserHandle.USER_ALL 3754 ? getUsersLocked() : new int[] { userId }; 3755 for (int user : users) { 3756 for (int i = 0; i < N; i++) { 3757 TaskRecord task = mRecentTasks.get(i); 3758 if (task.userId != user) { 3759 // Only look at tasks for the user ID of interest. 3760 continue; 3761 } 3762 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3763 // This situation is broken, and we should just get rid of it now. 3764 mRecentTasks.remove(i); 3765 task.removedFromRecents(mTaskPersister); 3766 i--; 3767 N--; 3768 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3769 continue; 3770 } 3771 // Check whether this activity is currently available. 3772 if (task.realActivity != null) { 3773 ActivityInfo ai = availActCache.get(task.realActivity); 3774 if (ai == null) { 3775 try { 3776 ai = pm.getActivityInfo(task.realActivity, 3777 PackageManager.GET_UNINSTALLED_PACKAGES 3778 | PackageManager.GET_DISABLED_COMPONENTS, user); 3779 } catch (RemoteException e) { 3780 // Will never happen. 3781 continue; 3782 } 3783 if (ai == null) { 3784 ai = dummyAct; 3785 } 3786 availActCache.put(task.realActivity, ai); 3787 } 3788 if (ai == dummyAct) { 3789 // This could be either because the activity no longer exists, or the 3790 // app is temporarily gone. For the former we want to remove the recents 3791 // entry; for the latter we want to mark it as unavailable. 3792 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3793 if (app == null) { 3794 try { 3795 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3796 PackageManager.GET_UNINSTALLED_PACKAGES 3797 | PackageManager.GET_DISABLED_COMPONENTS, user); 3798 } catch (RemoteException e) { 3799 // Will never happen. 3800 continue; 3801 } 3802 if (app == null) { 3803 app = dummyApp; 3804 } 3805 availAppCache.put(task.realActivity.getPackageName(), app); 3806 } 3807 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3808 // Doesn't exist any more! Good-bye. 3809 mRecentTasks.remove(i); 3810 task.removedFromRecents(mTaskPersister); 3811 i--; 3812 N--; 3813 Slog.w(TAG, "Removing no longer valid recent: " + task); 3814 continue; 3815 } else { 3816 // Otherwise just not available for now. 3817 if (task.isAvailable) { 3818 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3819 + task); 3820 } 3821 task.isAvailable = false; 3822 } 3823 } else { 3824 if (!ai.enabled || !ai.applicationInfo.enabled 3825 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3826 if (task.isAvailable) { 3827 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3828 + task + " (enabled=" + ai.enabled + "/" 3829 + ai.applicationInfo.enabled + " flags=" 3830 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3831 } 3832 task.isAvailable = false; 3833 } else { 3834 if (!task.isAvailable) { 3835 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3836 + task); 3837 } 3838 task.isAvailable = true; 3839 } 3840 } 3841 } 3842 } 3843 } 3844 3845 // Verify the affiliate chain for each task. 3846 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3847 } 3848 3849 mTmpRecents.clear(); 3850 // mRecentTasks is now in sorted, affiliated order. 3851 } 3852 3853 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3854 int N = mRecentTasks.size(); 3855 TaskRecord top = task; 3856 int topIndex = taskIndex; 3857 while (top.mNextAffiliate != null && topIndex > 0) { 3858 top = top.mNextAffiliate; 3859 topIndex--; 3860 } 3861 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3862 + topIndex + " from intial " + taskIndex); 3863 // Find the end of the chain, doing a sanity check along the way. 3864 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3865 int endIndex = topIndex; 3866 TaskRecord prev = top; 3867 while (endIndex < N) { 3868 TaskRecord cur = mRecentTasks.get(endIndex); 3869 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3870 + endIndex + " " + cur); 3871 if (cur == top) { 3872 // Verify start of the chain. 3873 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3874 Slog.wtf(TAG, "Bad chain @" + endIndex 3875 + ": first task has next affiliate: " + prev); 3876 sane = false; 3877 break; 3878 } 3879 } else { 3880 // Verify middle of the chain's next points back to the one before. 3881 if (cur.mNextAffiliate != prev 3882 || cur.mNextAffiliateTaskId != prev.taskId) { 3883 Slog.wtf(TAG, "Bad chain @" + endIndex 3884 + ": middle task " + cur + " @" + endIndex 3885 + " has bad next affiliate " 3886 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3887 + ", expected " + prev); 3888 sane = false; 3889 break; 3890 } 3891 } 3892 if (cur.mPrevAffiliateTaskId == -1) { 3893 // Chain ends here. 3894 if (cur.mPrevAffiliate != null) { 3895 Slog.wtf(TAG, "Bad chain @" + endIndex 3896 + ": last task " + cur + " has previous affiliate " 3897 + cur.mPrevAffiliate); 3898 sane = false; 3899 } 3900 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3901 break; 3902 } else { 3903 // Verify middle of the chain's prev points to a valid item. 3904 if (cur.mPrevAffiliate == null) { 3905 Slog.wtf(TAG, "Bad chain @" + endIndex 3906 + ": task " + cur + " has previous affiliate " 3907 + cur.mPrevAffiliate + " but should be id " 3908 + cur.mPrevAffiliate); 3909 sane = false; 3910 break; 3911 } 3912 } 3913 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3914 Slog.wtf(TAG, "Bad chain @" + endIndex 3915 + ": task " + cur + " has affiliated id " 3916 + cur.mAffiliatedTaskId + " but should be " 3917 + task.mAffiliatedTaskId); 3918 sane = false; 3919 break; 3920 } 3921 prev = cur; 3922 endIndex++; 3923 if (endIndex >= N) { 3924 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3925 + ": last task " + prev); 3926 sane = false; 3927 break; 3928 } 3929 } 3930 if (sane) { 3931 if (endIndex < taskIndex) { 3932 Slog.wtf(TAG, "Bad chain @" + endIndex 3933 + ": did not extend to task " + task + " @" + taskIndex); 3934 sane = false; 3935 } 3936 } 3937 if (sane) { 3938 // All looks good, we can just move all of the affiliated tasks 3939 // to the top. 3940 for (int i=topIndex; i<=endIndex; i++) { 3941 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3942 + " from " + i + " to " + (i-topIndex)); 3943 TaskRecord cur = mRecentTasks.remove(i); 3944 mRecentTasks.add(i-topIndex, cur); 3945 } 3946 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3947 + " to " + endIndex); 3948 return true; 3949 } 3950 3951 // Whoops, couldn't do it. 3952 return false; 3953 } 3954 3955 final void addRecentTaskLocked(TaskRecord task) { 3956 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3957 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3958 3959 int N = mRecentTasks.size(); 3960 // Quick case: check if the top-most recent task is the same. 3961 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3962 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 3963 return; 3964 } 3965 // Another quick case: check if this is part of a set of affiliated 3966 // tasks that are at the top. 3967 if (isAffiliated && N > 0 && task.inRecents 3968 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 3969 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 3970 + " at top when adding " + task); 3971 return; 3972 } 3973 // Another quick case: never add voice sessions. 3974 if (task.voiceSession != null) { 3975 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 3976 return; 3977 } 3978 3979 boolean needAffiliationFix = false; 3980 3981 // Slightly less quick case: the task is already in recents, so all we need 3982 // to do is move it. 3983 if (task.inRecents) { 3984 int taskIndex = mRecentTasks.indexOf(task); 3985 if (taskIndex >= 0) { 3986 if (!isAffiliated) { 3987 // Simple case: this is not an affiliated task, so we just move it to the front. 3988 mRecentTasks.remove(taskIndex); 3989 mRecentTasks.add(0, task); 3990 notifyTaskPersisterLocked(task, false); 3991 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 3992 + " from " + taskIndex); 3993 return; 3994 } else { 3995 // More complicated: need to keep all affiliated tasks together. 3996 if (moveAffiliatedTasksToFront(task, taskIndex)) { 3997 // All went well. 3998 return; 3999 } 4000 4001 // Uh oh... something bad in the affiliation chain, try to rebuild 4002 // everything and then go through our general path of adding a new task. 4003 needAffiliationFix = true; 4004 } 4005 } else { 4006 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4007 needAffiliationFix = true; 4008 } 4009 } 4010 4011 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4012 trimRecentsForTask(task, true); 4013 4014 N = mRecentTasks.size(); 4015 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4016 final TaskRecord tr = mRecentTasks.remove(N - 1); 4017 tr.removedFromRecents(mTaskPersister); 4018 N--; 4019 } 4020 task.inRecents = true; 4021 if (!isAffiliated || needAffiliationFix) { 4022 // If this is a simple non-affiliated task, or we had some failure trying to 4023 // handle it as part of an affilated task, then just place it at the top. 4024 mRecentTasks.add(0, task); 4025 } else if (isAffiliated) { 4026 // If this is a new affiliated task, then move all of the affiliated tasks 4027 // to the front and insert this new one. 4028 TaskRecord other = task.mNextAffiliate; 4029 if (other == null) { 4030 other = task.mPrevAffiliate; 4031 } 4032 if (other != null) { 4033 int otherIndex = mRecentTasks.indexOf(other); 4034 if (otherIndex >= 0) { 4035 // Insert new task at appropriate location. 4036 int taskIndex; 4037 if (other == task.mNextAffiliate) { 4038 // We found the index of our next affiliation, which is who is 4039 // before us in the list, so add after that point. 4040 taskIndex = otherIndex+1; 4041 } else { 4042 // We found the index of our previous affiliation, which is who is 4043 // after us in the list, so add at their position. 4044 taskIndex = otherIndex; 4045 } 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4047 + taskIndex + ": " + task); 4048 mRecentTasks.add(taskIndex, task); 4049 4050 // Now move everything to the front. 4051 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4052 // All went well. 4053 return; 4054 } 4055 4056 // Uh oh... something bad in the affiliation chain, try to rebuild 4057 // everything and then go through our general path of adding a new task. 4058 needAffiliationFix = true; 4059 } else { 4060 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4061 + other); 4062 needAffiliationFix = true; 4063 } 4064 } else { 4065 if (DEBUG_RECENTS) Slog.d(TAG, 4066 "addRecent: adding affiliated task without next/prev:" + task); 4067 needAffiliationFix = true; 4068 } 4069 } 4070 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4071 4072 if (needAffiliationFix) { 4073 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4074 cleanupRecentTasksLocked(task.userId); 4075 } 4076 } 4077 4078 /** 4079 * If needed, remove oldest existing entries in recents that are for the same kind 4080 * of task as the given one. 4081 */ 4082 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4083 int N = mRecentTasks.size(); 4084 final Intent intent = task.intent; 4085 final boolean document = intent != null && intent.isDocument(); 4086 4087 int maxRecents = task.maxRecents - 1; 4088 for (int i=0; i<N; i++) { 4089 final TaskRecord tr = mRecentTasks.get(i); 4090 if (task != tr) { 4091 if (task.userId != tr.userId) { 4092 continue; 4093 } 4094 if (i > MAX_RECENT_BITMAPS) { 4095 tr.freeLastThumbnail(); 4096 } 4097 final Intent trIntent = tr.intent; 4098 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4099 (intent == null || !intent.filterEquals(trIntent))) { 4100 continue; 4101 } 4102 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4103 if (document && trIsDocument) { 4104 // These are the same document activity (not necessarily the same doc). 4105 if (maxRecents > 0) { 4106 --maxRecents; 4107 continue; 4108 } 4109 // Hit the maximum number of documents for this task. Fall through 4110 // and remove this document from recents. 4111 } else if (document || trIsDocument) { 4112 // Only one of these is a document. Not the droid we're looking for. 4113 continue; 4114 } 4115 } 4116 4117 if (!doTrim) { 4118 // If the caller is not actually asking for a trim, just tell them we reached 4119 // a point where the trim would happen. 4120 return i; 4121 } 4122 4123 // Either task and tr are the same or, their affinities match or their intents match 4124 // and neither of them is a document, or they are documents using the same activity 4125 // and their maxRecents has been reached. 4126 tr.disposeThumbnail(); 4127 mRecentTasks.remove(i); 4128 if (task != tr) { 4129 tr.removedFromRecents(mTaskPersister); 4130 } 4131 i--; 4132 N--; 4133 if (task.intent == null) { 4134 // If the new recent task we are adding is not fully 4135 // specified, then replace it with the existing recent task. 4136 task = tr; 4137 } 4138 notifyTaskPersisterLocked(tr, false); 4139 } 4140 4141 return -1; 4142 } 4143 4144 @Override 4145 public void reportActivityFullyDrawn(IBinder token) { 4146 synchronized (this) { 4147 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4148 if (r == null) { 4149 return; 4150 } 4151 r.reportFullyDrawnLocked(); 4152 } 4153 } 4154 4155 @Override 4156 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4157 synchronized (this) { 4158 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4159 if (r == null) { 4160 return; 4161 } 4162 final long origId = Binder.clearCallingIdentity(); 4163 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4164 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4165 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4166 if (config != null) { 4167 r.frozenBeforeDestroy = true; 4168 if (!updateConfigurationLocked(config, r, false, false)) { 4169 mStackSupervisor.resumeTopActivitiesLocked(); 4170 } 4171 } 4172 Binder.restoreCallingIdentity(origId); 4173 } 4174 } 4175 4176 @Override 4177 public int getRequestedOrientation(IBinder token) { 4178 synchronized (this) { 4179 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4180 if (r == null) { 4181 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4182 } 4183 return mWindowManager.getAppOrientation(r.appToken); 4184 } 4185 } 4186 4187 /** 4188 * This is the internal entry point for handling Activity.finish(). 4189 * 4190 * @param token The Binder token referencing the Activity we want to finish. 4191 * @param resultCode Result code, if any, from this Activity. 4192 * @param resultData Result data (Intent), if any, from this Activity. 4193 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4194 * the root Activity in the task. 4195 * 4196 * @return Returns true if the activity successfully finished, or false if it is still running. 4197 */ 4198 @Override 4199 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4200 boolean finishTask) { 4201 // Refuse possible leaked file descriptors 4202 if (resultData != null && resultData.hasFileDescriptors() == true) { 4203 throw new IllegalArgumentException("File descriptors passed in Intent"); 4204 } 4205 4206 synchronized(this) { 4207 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4208 if (r == null) { 4209 return true; 4210 } 4211 // Keep track of the root activity of the task before we finish it 4212 TaskRecord tr = r.task; 4213 ActivityRecord rootR = tr.getRootActivity(); 4214 if (rootR == null) { 4215 Slog.w(TAG, "Finishing task with all activities already finished"); 4216 } 4217 // Do not allow task to finish in Lock Task mode. 4218 if (tr == mStackSupervisor.mLockTaskModeTask) { 4219 if (rootR == r) { 4220 Slog.i(TAG, "Not finishing task in lock task mode"); 4221 mStackSupervisor.showLockTaskToast(); 4222 return false; 4223 } 4224 } 4225 if (mController != null) { 4226 // Find the first activity that is not finishing. 4227 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4228 if (next != null) { 4229 // ask watcher if this is allowed 4230 boolean resumeOK = true; 4231 try { 4232 resumeOK = mController.activityResuming(next.packageName); 4233 } catch (RemoteException e) { 4234 mController = null; 4235 Watchdog.getInstance().setActivityController(null); 4236 } 4237 4238 if (!resumeOK) { 4239 Slog.i(TAG, "Not finishing activity because controller resumed"); 4240 return false; 4241 } 4242 } 4243 } 4244 final long origId = Binder.clearCallingIdentity(); 4245 try { 4246 boolean res; 4247 if (finishTask && r == rootR) { 4248 // If requested, remove the task that is associated to this activity only if it 4249 // was the root activity in the task. The result code and data is ignored 4250 // because we don't support returning them across task boundaries. 4251 res = removeTaskByIdLocked(tr.taskId, false); 4252 if (!res) { 4253 Slog.i(TAG, "Removing task failed to finish activity"); 4254 } 4255 } else { 4256 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4257 resultData, "app-request", true); 4258 if (!res) { 4259 Slog.i(TAG, "Failed to finish by app-request"); 4260 } 4261 } 4262 return res; 4263 } finally { 4264 Binder.restoreCallingIdentity(origId); 4265 } 4266 } 4267 } 4268 4269 @Override 4270 public final void finishHeavyWeightApp() { 4271 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4272 != PackageManager.PERMISSION_GRANTED) { 4273 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4274 + Binder.getCallingPid() 4275 + ", uid=" + Binder.getCallingUid() 4276 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4277 Slog.w(TAG, msg); 4278 throw new SecurityException(msg); 4279 } 4280 4281 synchronized(this) { 4282 if (mHeavyWeightProcess == null) { 4283 return; 4284 } 4285 4286 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4287 mHeavyWeightProcess.activities); 4288 for (int i=0; i<activities.size(); i++) { 4289 ActivityRecord r = activities.get(i); 4290 if (!r.finishing) { 4291 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4292 null, "finish-heavy", true); 4293 } 4294 } 4295 4296 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4297 mHeavyWeightProcess.userId, 0)); 4298 mHeavyWeightProcess = null; 4299 } 4300 } 4301 4302 @Override 4303 public void crashApplication(int uid, int initialPid, String packageName, 4304 String message) { 4305 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4306 != PackageManager.PERMISSION_GRANTED) { 4307 String msg = "Permission Denial: crashApplication() from pid=" 4308 + Binder.getCallingPid() 4309 + ", uid=" + Binder.getCallingUid() 4310 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4311 Slog.w(TAG, msg); 4312 throw new SecurityException(msg); 4313 } 4314 4315 synchronized(this) { 4316 ProcessRecord proc = null; 4317 4318 // Figure out which process to kill. We don't trust that initialPid 4319 // still has any relation to current pids, so must scan through the 4320 // list. 4321 synchronized (mPidsSelfLocked) { 4322 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4323 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4324 if (p.uid != uid) { 4325 continue; 4326 } 4327 if (p.pid == initialPid) { 4328 proc = p; 4329 break; 4330 } 4331 if (p.pkgList.containsKey(packageName)) { 4332 proc = p; 4333 } 4334 } 4335 } 4336 4337 if (proc == null) { 4338 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4339 + " initialPid=" + initialPid 4340 + " packageName=" + packageName); 4341 return; 4342 } 4343 4344 if (proc.thread != null) { 4345 if (proc.pid == Process.myPid()) { 4346 Log.w(TAG, "crashApplication: trying to crash self!"); 4347 return; 4348 } 4349 long ident = Binder.clearCallingIdentity(); 4350 try { 4351 proc.thread.scheduleCrash(message); 4352 } catch (RemoteException e) { 4353 } 4354 Binder.restoreCallingIdentity(ident); 4355 } 4356 } 4357 } 4358 4359 @Override 4360 public final void finishSubActivity(IBinder token, String resultWho, 4361 int requestCode) { 4362 synchronized(this) { 4363 final long origId = Binder.clearCallingIdentity(); 4364 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4365 if (r != null) { 4366 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4367 } 4368 Binder.restoreCallingIdentity(origId); 4369 } 4370 } 4371 4372 @Override 4373 public boolean finishActivityAffinity(IBinder token) { 4374 synchronized(this) { 4375 final long origId = Binder.clearCallingIdentity(); 4376 try { 4377 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4378 4379 ActivityRecord rootR = r.task.getRootActivity(); 4380 // Do not allow task to finish in Lock Task mode. 4381 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4382 if (rootR == r) { 4383 mStackSupervisor.showLockTaskToast(); 4384 return false; 4385 } 4386 } 4387 boolean res = false; 4388 if (r != null) { 4389 res = r.task.stack.finishActivityAffinityLocked(r); 4390 } 4391 return res; 4392 } finally { 4393 Binder.restoreCallingIdentity(origId); 4394 } 4395 } 4396 } 4397 4398 @Override 4399 public void finishVoiceTask(IVoiceInteractionSession session) { 4400 synchronized(this) { 4401 final long origId = Binder.clearCallingIdentity(); 4402 try { 4403 mStackSupervisor.finishVoiceTask(session); 4404 } finally { 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 4409 } 4410 4411 @Override 4412 public boolean releaseActivityInstance(IBinder token) { 4413 synchronized(this) { 4414 final long origId = Binder.clearCallingIdentity(); 4415 try { 4416 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4417 if (r.task == null || r.task.stack == null) { 4418 return false; 4419 } 4420 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4421 } finally { 4422 Binder.restoreCallingIdentity(origId); 4423 } 4424 } 4425 } 4426 4427 @Override 4428 public void releaseSomeActivities(IApplicationThread appInt) { 4429 synchronized(this) { 4430 final long origId = Binder.clearCallingIdentity(); 4431 try { 4432 ProcessRecord app = getRecordForAppLocked(appInt); 4433 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4434 } finally { 4435 Binder.restoreCallingIdentity(origId); 4436 } 4437 } 4438 } 4439 4440 @Override 4441 public boolean willActivityBeVisible(IBinder token) { 4442 synchronized(this) { 4443 ActivityStack stack = ActivityRecord.getStackLocked(token); 4444 if (stack != null) { 4445 return stack.willActivityBeVisibleLocked(token); 4446 } 4447 return false; 4448 } 4449 } 4450 4451 @Override 4452 public void overridePendingTransition(IBinder token, String packageName, 4453 int enterAnim, int exitAnim) { 4454 synchronized(this) { 4455 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4456 if (self == null) { 4457 return; 4458 } 4459 4460 final long origId = Binder.clearCallingIdentity(); 4461 4462 if (self.state == ActivityState.RESUMED 4463 || self.state == ActivityState.PAUSING) { 4464 mWindowManager.overridePendingAppTransition(packageName, 4465 enterAnim, exitAnim, null); 4466 } 4467 4468 Binder.restoreCallingIdentity(origId); 4469 } 4470 } 4471 4472 /** 4473 * Main function for removing an existing process from the activity manager 4474 * as a result of that process going away. Clears out all connections 4475 * to the process. 4476 */ 4477 private final void handleAppDiedLocked(ProcessRecord app, 4478 boolean restarting, boolean allowRestart) { 4479 int pid = app.pid; 4480 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4481 if (!kept && !restarting) { 4482 removeLruProcessLocked(app); 4483 if (pid > 0) { 4484 ProcessList.remove(pid); 4485 } 4486 } 4487 4488 if (mProfileProc == app) { 4489 clearProfilerLocked(); 4490 } 4491 4492 // Remove this application's activities from active lists. 4493 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4494 4495 app.activities.clear(); 4496 4497 if (app.instrumentationClass != null) { 4498 Slog.w(TAG, "Crash of app " + app.processName 4499 + " running instrumentation " + app.instrumentationClass); 4500 Bundle info = new Bundle(); 4501 info.putString("shortMsg", "Process crashed."); 4502 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4503 } 4504 4505 if (!restarting) { 4506 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4507 // If there was nothing to resume, and we are not already 4508 // restarting this process, but there is a visible activity that 4509 // is hosted by the process... then make sure all visible 4510 // activities are running, taking care of restarting this 4511 // process. 4512 if (hasVisibleActivities) { 4513 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4514 } 4515 } 4516 } 4517 } 4518 4519 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4520 IBinder threadBinder = thread.asBinder(); 4521 // Find the application record. 4522 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4523 ProcessRecord rec = mLruProcesses.get(i); 4524 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4525 return i; 4526 } 4527 } 4528 return -1; 4529 } 4530 4531 final ProcessRecord getRecordForAppLocked( 4532 IApplicationThread thread) { 4533 if (thread == null) { 4534 return null; 4535 } 4536 4537 int appIndex = getLRURecordIndexForAppLocked(thread); 4538 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4539 } 4540 4541 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4542 // If there are no longer any background processes running, 4543 // and the app that died was not running instrumentation, 4544 // then tell everyone we are now low on memory. 4545 boolean haveBg = false; 4546 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4547 ProcessRecord rec = mLruProcesses.get(i); 4548 if (rec.thread != null 4549 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4550 haveBg = true; 4551 break; 4552 } 4553 } 4554 4555 if (!haveBg) { 4556 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4557 if (doReport) { 4558 long now = SystemClock.uptimeMillis(); 4559 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4560 doReport = false; 4561 } else { 4562 mLastMemUsageReportTime = now; 4563 } 4564 } 4565 final ArrayList<ProcessMemInfo> memInfos 4566 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4567 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4568 long now = SystemClock.uptimeMillis(); 4569 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4570 ProcessRecord rec = mLruProcesses.get(i); 4571 if (rec == dyingProc || rec.thread == null) { 4572 continue; 4573 } 4574 if (doReport) { 4575 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4576 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4577 } 4578 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4579 // The low memory report is overriding any current 4580 // state for a GC request. Make sure to do 4581 // heavy/important/visible/foreground processes first. 4582 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4583 rec.lastRequestedGc = 0; 4584 } else { 4585 rec.lastRequestedGc = rec.lastLowMemory; 4586 } 4587 rec.reportLowMemory = true; 4588 rec.lastLowMemory = now; 4589 mProcessesToGc.remove(rec); 4590 addProcessToGcListLocked(rec); 4591 } 4592 } 4593 if (doReport) { 4594 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4595 mHandler.sendMessage(msg); 4596 } 4597 scheduleAppGcsLocked(); 4598 } 4599 } 4600 4601 final void appDiedLocked(ProcessRecord app) { 4602 appDiedLocked(app, app.pid, app.thread); 4603 } 4604 4605 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4606 // First check if this ProcessRecord is actually active for the pid. 4607 synchronized (mPidsSelfLocked) { 4608 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4609 if (curProc != app) { 4610 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4611 return; 4612 } 4613 } 4614 4615 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4616 synchronized (stats) { 4617 stats.noteProcessDiedLocked(app.info.uid, pid); 4618 } 4619 4620 Process.killProcessQuiet(pid); 4621 Process.killProcessGroup(app.info.uid, pid); 4622 app.killed = true; 4623 4624 // Clean up already done if the process has been re-started. 4625 if (app.pid == pid && app.thread != null && 4626 app.thread.asBinder() == thread.asBinder()) { 4627 boolean doLowMem = app.instrumentationClass == null; 4628 boolean doOomAdj = doLowMem; 4629 if (!app.killedByAm) { 4630 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4631 + ") has died"); 4632 mAllowLowerMemLevel = true; 4633 } else { 4634 // Note that we always want to do oom adj to update our state with the 4635 // new number of procs. 4636 mAllowLowerMemLevel = false; 4637 doLowMem = false; 4638 } 4639 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4640 if (DEBUG_CLEANUP) Slog.v( 4641 TAG, "Dying app: " + app + ", pid: " + pid 4642 + ", thread: " + thread.asBinder()); 4643 handleAppDiedLocked(app, false, true); 4644 4645 if (doOomAdj) { 4646 updateOomAdjLocked(); 4647 } 4648 if (doLowMem) { 4649 doLowMemReportIfNeededLocked(app); 4650 } 4651 } else if (app.pid != pid) { 4652 // A new process has already been started. 4653 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4654 + ") has died and restarted (pid " + app.pid + ")."); 4655 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4656 } else if (DEBUG_PROCESSES) { 4657 Slog.d(TAG, "Received spurious death notification for thread " 4658 + thread.asBinder()); 4659 } 4660 } 4661 4662 /** 4663 * If a stack trace dump file is configured, dump process stack traces. 4664 * @param clearTraces causes the dump file to be erased prior to the new 4665 * traces being written, if true; when false, the new traces will be 4666 * appended to any existing file content. 4667 * @param firstPids of dalvik VM processes to dump stack traces for first 4668 * @param lastPids of dalvik VM processes to dump stack traces for last 4669 * @param nativeProcs optional list of native process names to dump stack crawls 4670 * @return file containing stack traces, or null if no dump file is configured 4671 */ 4672 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4673 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4674 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4675 if (tracesPath == null || tracesPath.length() == 0) { 4676 return null; 4677 } 4678 4679 File tracesFile = new File(tracesPath); 4680 try { 4681 File tracesDir = tracesFile.getParentFile(); 4682 if (!tracesDir.exists()) { 4683 tracesDir.mkdirs(); 4684 if (!SELinux.restorecon(tracesDir)) { 4685 return null; 4686 } 4687 } 4688 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4689 4690 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4691 tracesFile.createNewFile(); 4692 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4693 } catch (IOException e) { 4694 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4695 return null; 4696 } 4697 4698 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4699 return tracesFile; 4700 } 4701 4702 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4703 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4704 // Use a FileObserver to detect when traces finish writing. 4705 // The order of traces is considered important to maintain for legibility. 4706 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4707 @Override 4708 public synchronized void onEvent(int event, String path) { notify(); } 4709 }; 4710 4711 try { 4712 observer.startWatching(); 4713 4714 // First collect all of the stacks of the most important pids. 4715 if (firstPids != null) { 4716 try { 4717 int num = firstPids.size(); 4718 for (int i = 0; i < num; i++) { 4719 synchronized (observer) { 4720 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4721 observer.wait(200); // Wait for write-close, give up after 200msec 4722 } 4723 } 4724 } catch (InterruptedException e) { 4725 Slog.wtf(TAG, e); 4726 } 4727 } 4728 4729 // Next collect the stacks of the native pids 4730 if (nativeProcs != null) { 4731 int[] pids = Process.getPidsForCommands(nativeProcs); 4732 if (pids != null) { 4733 for (int pid : pids) { 4734 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4735 } 4736 } 4737 } 4738 4739 // Lastly, measure CPU usage. 4740 if (processCpuTracker != null) { 4741 processCpuTracker.init(); 4742 System.gc(); 4743 processCpuTracker.update(); 4744 try { 4745 synchronized (processCpuTracker) { 4746 processCpuTracker.wait(500); // measure over 1/2 second. 4747 } 4748 } catch (InterruptedException e) { 4749 } 4750 processCpuTracker.update(); 4751 4752 // We'll take the stack crawls of just the top apps using CPU. 4753 final int N = processCpuTracker.countWorkingStats(); 4754 int numProcs = 0; 4755 for (int i=0; i<N && numProcs<5; i++) { 4756 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4757 if (lastPids.indexOfKey(stats.pid) >= 0) { 4758 numProcs++; 4759 try { 4760 synchronized (observer) { 4761 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4762 observer.wait(200); // Wait for write-close, give up after 200msec 4763 } 4764 } catch (InterruptedException e) { 4765 Slog.wtf(TAG, e); 4766 } 4767 4768 } 4769 } 4770 } 4771 } finally { 4772 observer.stopWatching(); 4773 } 4774 } 4775 4776 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4777 if (true || IS_USER_BUILD) { 4778 return; 4779 } 4780 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4781 if (tracesPath == null || tracesPath.length() == 0) { 4782 return; 4783 } 4784 4785 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4786 StrictMode.allowThreadDiskWrites(); 4787 try { 4788 final File tracesFile = new File(tracesPath); 4789 final File tracesDir = tracesFile.getParentFile(); 4790 final File tracesTmp = new File(tracesDir, "__tmp__"); 4791 try { 4792 if (!tracesDir.exists()) { 4793 tracesDir.mkdirs(); 4794 if (!SELinux.restorecon(tracesDir.getPath())) { 4795 return; 4796 } 4797 } 4798 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4799 4800 if (tracesFile.exists()) { 4801 tracesTmp.delete(); 4802 tracesFile.renameTo(tracesTmp); 4803 } 4804 StringBuilder sb = new StringBuilder(); 4805 Time tobj = new Time(); 4806 tobj.set(System.currentTimeMillis()); 4807 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4808 sb.append(": "); 4809 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4810 sb.append(" since "); 4811 sb.append(msg); 4812 FileOutputStream fos = new FileOutputStream(tracesFile); 4813 fos.write(sb.toString().getBytes()); 4814 if (app == null) { 4815 fos.write("\n*** No application process!".getBytes()); 4816 } 4817 fos.close(); 4818 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4819 } catch (IOException e) { 4820 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4821 return; 4822 } 4823 4824 if (app != null) { 4825 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4826 firstPids.add(app.pid); 4827 dumpStackTraces(tracesPath, firstPids, null, null, null); 4828 } 4829 4830 File lastTracesFile = null; 4831 File curTracesFile = null; 4832 for (int i=9; i>=0; i--) { 4833 String name = String.format(Locale.US, "slow%02d.txt", i); 4834 curTracesFile = new File(tracesDir, name); 4835 if (curTracesFile.exists()) { 4836 if (lastTracesFile != null) { 4837 curTracesFile.renameTo(lastTracesFile); 4838 } else { 4839 curTracesFile.delete(); 4840 } 4841 } 4842 lastTracesFile = curTracesFile; 4843 } 4844 tracesFile.renameTo(curTracesFile); 4845 if (tracesTmp.exists()) { 4846 tracesTmp.renameTo(tracesFile); 4847 } 4848 } finally { 4849 StrictMode.setThreadPolicy(oldPolicy); 4850 } 4851 } 4852 4853 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4854 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4855 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4856 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4857 4858 if (mController != null) { 4859 try { 4860 // 0 == continue, -1 = kill process immediately 4861 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4862 if (res < 0 && app.pid != MY_PID) { 4863 app.kill("anr", true); 4864 } 4865 } catch (RemoteException e) { 4866 mController = null; 4867 Watchdog.getInstance().setActivityController(null); 4868 } 4869 } 4870 4871 long anrTime = SystemClock.uptimeMillis(); 4872 if (MONITOR_CPU_USAGE) { 4873 updateCpuStatsNow(); 4874 } 4875 4876 synchronized (this) { 4877 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4878 if (mShuttingDown) { 4879 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4880 return; 4881 } else if (app.notResponding) { 4882 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4883 return; 4884 } else if (app.crashing) { 4885 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4886 return; 4887 } 4888 4889 // In case we come through here for the same app before completing 4890 // this one, mark as anring now so we will bail out. 4891 app.notResponding = true; 4892 4893 // Log the ANR to the event log. 4894 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4895 app.processName, app.info.flags, annotation); 4896 4897 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4898 firstPids.add(app.pid); 4899 4900 int parentPid = app.pid; 4901 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4902 if (parentPid != app.pid) firstPids.add(parentPid); 4903 4904 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4905 4906 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4907 ProcessRecord r = mLruProcesses.get(i); 4908 if (r != null && r.thread != null) { 4909 int pid = r.pid; 4910 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4911 if (r.persistent) { 4912 firstPids.add(pid); 4913 } else { 4914 lastPids.put(pid, Boolean.TRUE); 4915 } 4916 } 4917 } 4918 } 4919 } 4920 4921 // Log the ANR to the main log. 4922 StringBuilder info = new StringBuilder(); 4923 info.setLength(0); 4924 info.append("ANR in ").append(app.processName); 4925 if (activity != null && activity.shortComponentName != null) { 4926 info.append(" (").append(activity.shortComponentName).append(")"); 4927 } 4928 info.append("\n"); 4929 info.append("PID: ").append(app.pid).append("\n"); 4930 if (annotation != null) { 4931 info.append("Reason: ").append(annotation).append("\n"); 4932 } 4933 if (parent != null && parent != activity) { 4934 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4935 } 4936 4937 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4938 4939 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4940 NATIVE_STACKS_OF_INTEREST); 4941 4942 String cpuInfo = null; 4943 if (MONITOR_CPU_USAGE) { 4944 updateCpuStatsNow(); 4945 synchronized (mProcessCpuTracker) { 4946 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4947 } 4948 info.append(processCpuTracker.printCurrentLoad()); 4949 info.append(cpuInfo); 4950 } 4951 4952 info.append(processCpuTracker.printCurrentState(anrTime)); 4953 4954 Slog.e(TAG, info.toString()); 4955 if (tracesFile == null) { 4956 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4957 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4958 } 4959 4960 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4961 cpuInfo, tracesFile, null); 4962 4963 if (mController != null) { 4964 try { 4965 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4966 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4967 if (res != 0) { 4968 if (res < 0 && app.pid != MY_PID) { 4969 app.kill("anr", true); 4970 } else { 4971 synchronized (this) { 4972 mServices.scheduleServiceTimeoutLocked(app); 4973 } 4974 } 4975 return; 4976 } 4977 } catch (RemoteException e) { 4978 mController = null; 4979 Watchdog.getInstance().setActivityController(null); 4980 } 4981 } 4982 4983 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4984 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4985 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4986 4987 synchronized (this) { 4988 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4989 app.kill("bg anr", true); 4990 return; 4991 } 4992 4993 // Set the app's notResponding state, and look up the errorReportReceiver 4994 makeAppNotRespondingLocked(app, 4995 activity != null ? activity.shortComponentName : null, 4996 annotation != null ? "ANR " + annotation : "ANR", 4997 info.toString()); 4998 4999 // Bring up the infamous App Not Responding dialog 5000 Message msg = Message.obtain(); 5001 HashMap<String, Object> map = new HashMap<String, Object>(); 5002 msg.what = SHOW_NOT_RESPONDING_MSG; 5003 msg.obj = map; 5004 msg.arg1 = aboveSystem ? 1 : 0; 5005 map.put("app", app); 5006 if (activity != null) { 5007 map.put("activity", activity); 5008 } 5009 5010 mHandler.sendMessage(msg); 5011 } 5012 } 5013 5014 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5015 if (!mLaunchWarningShown) { 5016 mLaunchWarningShown = true; 5017 mHandler.post(new Runnable() { 5018 @Override 5019 public void run() { 5020 synchronized (ActivityManagerService.this) { 5021 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5022 d.show(); 5023 mHandler.postDelayed(new Runnable() { 5024 @Override 5025 public void run() { 5026 synchronized (ActivityManagerService.this) { 5027 d.dismiss(); 5028 mLaunchWarningShown = false; 5029 } 5030 } 5031 }, 4000); 5032 } 5033 } 5034 }); 5035 } 5036 } 5037 5038 @Override 5039 public boolean clearApplicationUserData(final String packageName, 5040 final IPackageDataObserver observer, int userId) { 5041 enforceNotIsolatedCaller("clearApplicationUserData"); 5042 int uid = Binder.getCallingUid(); 5043 int pid = Binder.getCallingPid(); 5044 userId = handleIncomingUser(pid, uid, 5045 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5046 long callingId = Binder.clearCallingIdentity(); 5047 try { 5048 IPackageManager pm = AppGlobals.getPackageManager(); 5049 int pkgUid = -1; 5050 synchronized(this) { 5051 try { 5052 pkgUid = pm.getPackageUid(packageName, userId); 5053 } catch (RemoteException e) { 5054 } 5055 if (pkgUid == -1) { 5056 Slog.w(TAG, "Invalid packageName: " + packageName); 5057 if (observer != null) { 5058 try { 5059 observer.onRemoveCompleted(packageName, false); 5060 } catch (RemoteException e) { 5061 Slog.i(TAG, "Observer no longer exists."); 5062 } 5063 } 5064 return false; 5065 } 5066 if (uid == pkgUid || checkComponentPermission( 5067 android.Manifest.permission.CLEAR_APP_USER_DATA, 5068 pid, uid, -1, true) 5069 == PackageManager.PERMISSION_GRANTED) { 5070 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5071 } else { 5072 throw new SecurityException("PID " + pid + " does not have permission " 5073 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5074 + " of package " + packageName); 5075 } 5076 5077 // Remove all tasks match the cleared application package and user 5078 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5079 final TaskRecord tr = mRecentTasks.get(i); 5080 final String taskPackageName = 5081 tr.getBaseIntent().getComponent().getPackageName(); 5082 if (tr.userId != userId) continue; 5083 if (!taskPackageName.equals(packageName)) continue; 5084 removeTaskByIdLocked(tr.taskId, false); 5085 } 5086 } 5087 5088 try { 5089 // Clear application user data 5090 pm.clearApplicationUserData(packageName, observer, userId); 5091 5092 synchronized(this) { 5093 // Remove all permissions granted from/to this package 5094 removeUriPermissionsForPackageLocked(packageName, userId, true); 5095 } 5096 5097 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5098 Uri.fromParts("package", packageName, null)); 5099 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5100 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5101 null, null, 0, null, null, null, false, false, userId); 5102 } catch (RemoteException e) { 5103 } 5104 } finally { 5105 Binder.restoreCallingIdentity(callingId); 5106 } 5107 return true; 5108 } 5109 5110 @Override 5111 public void killBackgroundProcesses(final String packageName, int userId) { 5112 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5113 != PackageManager.PERMISSION_GRANTED && 5114 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5115 != PackageManager.PERMISSION_GRANTED) { 5116 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5117 + Binder.getCallingPid() 5118 + ", uid=" + Binder.getCallingUid() 5119 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5120 Slog.w(TAG, msg); 5121 throw new SecurityException(msg); 5122 } 5123 5124 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5125 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5126 long callingId = Binder.clearCallingIdentity(); 5127 try { 5128 IPackageManager pm = AppGlobals.getPackageManager(); 5129 synchronized(this) { 5130 int appId = -1; 5131 try { 5132 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5133 } catch (RemoteException e) { 5134 } 5135 if (appId == -1) { 5136 Slog.w(TAG, "Invalid packageName: " + packageName); 5137 return; 5138 } 5139 killPackageProcessesLocked(packageName, appId, userId, 5140 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5141 } 5142 } finally { 5143 Binder.restoreCallingIdentity(callingId); 5144 } 5145 } 5146 5147 @Override 5148 public void killAllBackgroundProcesses() { 5149 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5150 != PackageManager.PERMISSION_GRANTED) { 5151 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5152 + Binder.getCallingPid() 5153 + ", uid=" + Binder.getCallingUid() 5154 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5155 Slog.w(TAG, msg); 5156 throw new SecurityException(msg); 5157 } 5158 5159 long callingId = Binder.clearCallingIdentity(); 5160 try { 5161 synchronized(this) { 5162 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5163 final int NP = mProcessNames.getMap().size(); 5164 for (int ip=0; ip<NP; ip++) { 5165 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5166 final int NA = apps.size(); 5167 for (int ia=0; ia<NA; ia++) { 5168 ProcessRecord app = apps.valueAt(ia); 5169 if (app.persistent) { 5170 // we don't kill persistent processes 5171 continue; 5172 } 5173 if (app.removed) { 5174 procs.add(app); 5175 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5176 app.removed = true; 5177 procs.add(app); 5178 } 5179 } 5180 } 5181 5182 int N = procs.size(); 5183 for (int i=0; i<N; i++) { 5184 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5185 } 5186 mAllowLowerMemLevel = true; 5187 updateOomAdjLocked(); 5188 doLowMemReportIfNeededLocked(null); 5189 } 5190 } finally { 5191 Binder.restoreCallingIdentity(callingId); 5192 } 5193 } 5194 5195 @Override 5196 public void forceStopPackage(final String packageName, int userId) { 5197 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5198 != PackageManager.PERMISSION_GRANTED) { 5199 String msg = "Permission Denial: forceStopPackage() from pid=" 5200 + Binder.getCallingPid() 5201 + ", uid=" + Binder.getCallingUid() 5202 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5203 Slog.w(TAG, msg); 5204 throw new SecurityException(msg); 5205 } 5206 final int callingPid = Binder.getCallingPid(); 5207 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5208 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5209 long callingId = Binder.clearCallingIdentity(); 5210 try { 5211 IPackageManager pm = AppGlobals.getPackageManager(); 5212 synchronized(this) { 5213 int[] users = userId == UserHandle.USER_ALL 5214 ? getUsersLocked() : new int[] { userId }; 5215 for (int user : users) { 5216 int pkgUid = -1; 5217 try { 5218 pkgUid = pm.getPackageUid(packageName, user); 5219 } catch (RemoteException e) { 5220 } 5221 if (pkgUid == -1) { 5222 Slog.w(TAG, "Invalid packageName: " + packageName); 5223 continue; 5224 } 5225 try { 5226 pm.setPackageStoppedState(packageName, true, user); 5227 } catch (RemoteException e) { 5228 } catch (IllegalArgumentException e) { 5229 Slog.w(TAG, "Failed trying to unstop package " 5230 + packageName + ": " + e); 5231 } 5232 if (isUserRunningLocked(user, false)) { 5233 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5234 } 5235 } 5236 } 5237 } finally { 5238 Binder.restoreCallingIdentity(callingId); 5239 } 5240 } 5241 5242 @Override 5243 public void addPackageDependency(String packageName) { 5244 synchronized (this) { 5245 int callingPid = Binder.getCallingPid(); 5246 if (callingPid == Process.myPid()) { 5247 // Yeah, um, no. 5248 Slog.w(TAG, "Can't addPackageDependency on system process"); 5249 return; 5250 } 5251 ProcessRecord proc; 5252 synchronized (mPidsSelfLocked) { 5253 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5254 } 5255 if (proc != null) { 5256 if (proc.pkgDeps == null) { 5257 proc.pkgDeps = new ArraySet<String>(1); 5258 } 5259 proc.pkgDeps.add(packageName); 5260 } 5261 } 5262 } 5263 5264 /* 5265 * The pkg name and app id have to be specified. 5266 */ 5267 @Override 5268 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5269 if (pkg == null) { 5270 return; 5271 } 5272 // Make sure the uid is valid. 5273 if (appid < 0) { 5274 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5275 return; 5276 } 5277 int callerUid = Binder.getCallingUid(); 5278 // Only the system server can kill an application 5279 if (callerUid == Process.SYSTEM_UID) { 5280 // Post an aysnc message to kill the application 5281 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5282 msg.arg1 = appid; 5283 msg.arg2 = 0; 5284 Bundle bundle = new Bundle(); 5285 bundle.putString("pkg", pkg); 5286 bundle.putString("reason", reason); 5287 msg.obj = bundle; 5288 mHandler.sendMessage(msg); 5289 } else { 5290 throw new SecurityException(callerUid + " cannot kill pkg: " + 5291 pkg); 5292 } 5293 } 5294 5295 @Override 5296 public void closeSystemDialogs(String reason) { 5297 enforceNotIsolatedCaller("closeSystemDialogs"); 5298 5299 final int pid = Binder.getCallingPid(); 5300 final int uid = Binder.getCallingUid(); 5301 final long origId = Binder.clearCallingIdentity(); 5302 try { 5303 synchronized (this) { 5304 // Only allow this from foreground processes, so that background 5305 // applications can't abuse it to prevent system UI from being shown. 5306 if (uid >= Process.FIRST_APPLICATION_UID) { 5307 ProcessRecord proc; 5308 synchronized (mPidsSelfLocked) { 5309 proc = mPidsSelfLocked.get(pid); 5310 } 5311 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5312 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5313 + " from background process " + proc); 5314 return; 5315 } 5316 } 5317 closeSystemDialogsLocked(reason); 5318 } 5319 } finally { 5320 Binder.restoreCallingIdentity(origId); 5321 } 5322 } 5323 5324 void closeSystemDialogsLocked(String reason) { 5325 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5326 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5327 | Intent.FLAG_RECEIVER_FOREGROUND); 5328 if (reason != null) { 5329 intent.putExtra("reason", reason); 5330 } 5331 mWindowManager.closeSystemDialogs(reason); 5332 5333 mStackSupervisor.closeSystemDialogsLocked(); 5334 5335 broadcastIntentLocked(null, null, intent, null, 5336 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5337 Process.SYSTEM_UID, UserHandle.USER_ALL); 5338 } 5339 5340 @Override 5341 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5342 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5343 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5344 for (int i=pids.length-1; i>=0; i--) { 5345 ProcessRecord proc; 5346 int oomAdj; 5347 synchronized (this) { 5348 synchronized (mPidsSelfLocked) { 5349 proc = mPidsSelfLocked.get(pids[i]); 5350 oomAdj = proc != null ? proc.setAdj : 0; 5351 } 5352 } 5353 infos[i] = new Debug.MemoryInfo(); 5354 Debug.getMemoryInfo(pids[i], infos[i]); 5355 if (proc != null) { 5356 synchronized (this) { 5357 if (proc.thread != null && proc.setAdj == oomAdj) { 5358 // Record this for posterity if the process has been stable. 5359 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5360 infos[i].getTotalUss(), false, proc.pkgList); 5361 } 5362 } 5363 } 5364 } 5365 return infos; 5366 } 5367 5368 @Override 5369 public long[] getProcessPss(int[] pids) { 5370 enforceNotIsolatedCaller("getProcessPss"); 5371 long[] pss = new long[pids.length]; 5372 for (int i=pids.length-1; i>=0; i--) { 5373 ProcessRecord proc; 5374 int oomAdj; 5375 synchronized (this) { 5376 synchronized (mPidsSelfLocked) { 5377 proc = mPidsSelfLocked.get(pids[i]); 5378 oomAdj = proc != null ? proc.setAdj : 0; 5379 } 5380 } 5381 long[] tmpUss = new long[1]; 5382 pss[i] = Debug.getPss(pids[i], tmpUss); 5383 if (proc != null) { 5384 synchronized (this) { 5385 if (proc.thread != null && proc.setAdj == oomAdj) { 5386 // Record this for posterity if the process has been stable. 5387 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5388 } 5389 } 5390 } 5391 } 5392 return pss; 5393 } 5394 5395 @Override 5396 public void killApplicationProcess(String processName, int uid) { 5397 if (processName == null) { 5398 return; 5399 } 5400 5401 int callerUid = Binder.getCallingUid(); 5402 // Only the system server can kill an application 5403 if (callerUid == Process.SYSTEM_UID) { 5404 synchronized (this) { 5405 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5406 if (app != null && app.thread != null) { 5407 try { 5408 app.thread.scheduleSuicide(); 5409 } catch (RemoteException e) { 5410 // If the other end already died, then our work here is done. 5411 } 5412 } else { 5413 Slog.w(TAG, "Process/uid not found attempting kill of " 5414 + processName + " / " + uid); 5415 } 5416 } 5417 } else { 5418 throw new SecurityException(callerUid + " cannot kill app process: " + 5419 processName); 5420 } 5421 } 5422 5423 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5424 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5425 false, true, false, false, UserHandle.getUserId(uid), reason); 5426 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5427 Uri.fromParts("package", packageName, null)); 5428 if (!mProcessesReady) { 5429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5430 | Intent.FLAG_RECEIVER_FOREGROUND); 5431 } 5432 intent.putExtra(Intent.EXTRA_UID, uid); 5433 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5434 broadcastIntentLocked(null, null, intent, 5435 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5436 false, false, 5437 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5438 } 5439 5440 private void forceStopUserLocked(int userId, String reason) { 5441 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5442 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5444 | Intent.FLAG_RECEIVER_FOREGROUND); 5445 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5446 broadcastIntentLocked(null, null, intent, 5447 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5448 false, false, 5449 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5450 } 5451 5452 private final boolean killPackageProcessesLocked(String packageName, int appId, 5453 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5454 boolean doit, boolean evenPersistent, String reason) { 5455 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5456 5457 // Remove all processes this package may have touched: all with the 5458 // same UID (except for the system or root user), and all whose name 5459 // matches the package name. 5460 final int NP = mProcessNames.getMap().size(); 5461 for (int ip=0; ip<NP; ip++) { 5462 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5463 final int NA = apps.size(); 5464 for (int ia=0; ia<NA; ia++) { 5465 ProcessRecord app = apps.valueAt(ia); 5466 if (app.persistent && !evenPersistent) { 5467 // we don't kill persistent processes 5468 continue; 5469 } 5470 if (app.removed) { 5471 if (doit) { 5472 procs.add(app); 5473 } 5474 continue; 5475 } 5476 5477 // Skip process if it doesn't meet our oom adj requirement. 5478 if (app.setAdj < minOomAdj) { 5479 continue; 5480 } 5481 5482 // If no package is specified, we call all processes under the 5483 // give user id. 5484 if (packageName == null) { 5485 if (app.userId != userId) { 5486 continue; 5487 } 5488 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5489 continue; 5490 } 5491 // Package has been specified, we want to hit all processes 5492 // that match it. We need to qualify this by the processes 5493 // that are running under the specified app and user ID. 5494 } else { 5495 final boolean isDep = app.pkgDeps != null 5496 && app.pkgDeps.contains(packageName); 5497 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5498 continue; 5499 } 5500 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5501 continue; 5502 } 5503 if (!app.pkgList.containsKey(packageName) && !isDep) { 5504 continue; 5505 } 5506 } 5507 5508 // Process has passed all conditions, kill it! 5509 if (!doit) { 5510 return true; 5511 } 5512 app.removed = true; 5513 procs.add(app); 5514 } 5515 } 5516 5517 int N = procs.size(); 5518 for (int i=0; i<N; i++) { 5519 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5520 } 5521 updateOomAdjLocked(); 5522 return N > 0; 5523 } 5524 5525 private final boolean forceStopPackageLocked(String name, int appId, 5526 boolean callerWillRestart, boolean purgeCache, boolean doit, 5527 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5528 int i; 5529 int N; 5530 5531 if (userId == UserHandle.USER_ALL && name == null) { 5532 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5533 } 5534 5535 if (appId < 0 && name != null) { 5536 try { 5537 appId = UserHandle.getAppId( 5538 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5539 } catch (RemoteException e) { 5540 } 5541 } 5542 5543 if (doit) { 5544 if (name != null) { 5545 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5546 + " user=" + userId + ": " + reason); 5547 } else { 5548 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5549 } 5550 5551 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5552 for (int ip=pmap.size()-1; ip>=0; ip--) { 5553 SparseArray<Long> ba = pmap.valueAt(ip); 5554 for (i=ba.size()-1; i>=0; i--) { 5555 boolean remove = false; 5556 final int entUid = ba.keyAt(i); 5557 if (name != null) { 5558 if (userId == UserHandle.USER_ALL) { 5559 if (UserHandle.getAppId(entUid) == appId) { 5560 remove = true; 5561 } 5562 } else { 5563 if (entUid == UserHandle.getUid(userId, appId)) { 5564 remove = true; 5565 } 5566 } 5567 } else if (UserHandle.getUserId(entUid) == userId) { 5568 remove = true; 5569 } 5570 if (remove) { 5571 ba.removeAt(i); 5572 } 5573 } 5574 if (ba.size() == 0) { 5575 pmap.removeAt(ip); 5576 } 5577 } 5578 } 5579 5580 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5581 -100, callerWillRestart, true, doit, evenPersistent, 5582 name == null ? ("stop user " + userId) : ("stop " + name)); 5583 5584 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5585 if (!doit) { 5586 return true; 5587 } 5588 didSomething = true; 5589 } 5590 5591 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5592 if (!doit) { 5593 return true; 5594 } 5595 didSomething = true; 5596 } 5597 5598 if (name == null) { 5599 // Remove all sticky broadcasts from this user. 5600 mStickyBroadcasts.remove(userId); 5601 } 5602 5603 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5604 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5605 userId, providers)) { 5606 if (!doit) { 5607 return true; 5608 } 5609 didSomething = true; 5610 } 5611 N = providers.size(); 5612 for (i=0; i<N; i++) { 5613 removeDyingProviderLocked(null, providers.get(i), true); 5614 } 5615 5616 // Remove transient permissions granted from/to this package/user 5617 removeUriPermissionsForPackageLocked(name, userId, false); 5618 5619 if (name == null || uninstalling) { 5620 // Remove pending intents. For now we only do this when force 5621 // stopping users, because we have some problems when doing this 5622 // for packages -- app widgets are not currently cleaned up for 5623 // such packages, so they can be left with bad pending intents. 5624 if (mIntentSenderRecords.size() > 0) { 5625 Iterator<WeakReference<PendingIntentRecord>> it 5626 = mIntentSenderRecords.values().iterator(); 5627 while (it.hasNext()) { 5628 WeakReference<PendingIntentRecord> wpir = it.next(); 5629 if (wpir == null) { 5630 it.remove(); 5631 continue; 5632 } 5633 PendingIntentRecord pir = wpir.get(); 5634 if (pir == null) { 5635 it.remove(); 5636 continue; 5637 } 5638 if (name == null) { 5639 // Stopping user, remove all objects for the user. 5640 if (pir.key.userId != userId) { 5641 // Not the same user, skip it. 5642 continue; 5643 } 5644 } else { 5645 if (UserHandle.getAppId(pir.uid) != appId) { 5646 // Different app id, skip it. 5647 continue; 5648 } 5649 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5650 // Different user, skip it. 5651 continue; 5652 } 5653 if (!pir.key.packageName.equals(name)) { 5654 // Different package, skip it. 5655 continue; 5656 } 5657 } 5658 if (!doit) { 5659 return true; 5660 } 5661 didSomething = true; 5662 it.remove(); 5663 pir.canceled = true; 5664 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5665 pir.key.activity.pendingResults.remove(pir.ref); 5666 } 5667 } 5668 } 5669 } 5670 5671 if (doit) { 5672 if (purgeCache && name != null) { 5673 AttributeCache ac = AttributeCache.instance(); 5674 if (ac != null) { 5675 ac.removePackage(name); 5676 } 5677 } 5678 if (mBooted) { 5679 mStackSupervisor.resumeTopActivitiesLocked(); 5680 mStackSupervisor.scheduleIdleLocked(); 5681 } 5682 } 5683 5684 return didSomething; 5685 } 5686 5687 private final boolean removeProcessLocked(ProcessRecord app, 5688 boolean callerWillRestart, boolean allowRestart, String reason) { 5689 final String name = app.processName; 5690 final int uid = app.uid; 5691 if (DEBUG_PROCESSES) Slog.d( 5692 TAG, "Force removing proc " + app.toShortString() + " (" + name 5693 + "/" + uid + ")"); 5694 5695 mProcessNames.remove(name, uid); 5696 mIsolatedProcesses.remove(app.uid); 5697 if (mHeavyWeightProcess == app) { 5698 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5699 mHeavyWeightProcess.userId, 0)); 5700 mHeavyWeightProcess = null; 5701 } 5702 boolean needRestart = false; 5703 if (app.pid > 0 && app.pid != MY_PID) { 5704 int pid = app.pid; 5705 synchronized (mPidsSelfLocked) { 5706 mPidsSelfLocked.remove(pid); 5707 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5708 } 5709 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5710 if (app.isolated) { 5711 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5712 } 5713 app.kill(reason, true); 5714 handleAppDiedLocked(app, true, allowRestart); 5715 removeLruProcessLocked(app); 5716 5717 if (app.persistent && !app.isolated) { 5718 if (!callerWillRestart) { 5719 addAppLocked(app.info, false, null /* ABI override */); 5720 } else { 5721 needRestart = true; 5722 } 5723 } 5724 } else { 5725 mRemovedProcesses.add(app); 5726 } 5727 5728 return needRestart; 5729 } 5730 5731 private final void processStartTimedOutLocked(ProcessRecord app) { 5732 final int pid = app.pid; 5733 boolean gone = false; 5734 synchronized (mPidsSelfLocked) { 5735 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5736 if (knownApp != null && knownApp.thread == null) { 5737 mPidsSelfLocked.remove(pid); 5738 gone = true; 5739 } 5740 } 5741 5742 if (gone) { 5743 Slog.w(TAG, "Process " + app + " failed to attach"); 5744 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5745 pid, app.uid, app.processName); 5746 mProcessNames.remove(app.processName, app.uid); 5747 mIsolatedProcesses.remove(app.uid); 5748 if (mHeavyWeightProcess == app) { 5749 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5750 mHeavyWeightProcess.userId, 0)); 5751 mHeavyWeightProcess = null; 5752 } 5753 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5754 if (app.isolated) { 5755 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5756 } 5757 // Take care of any launching providers waiting for this process. 5758 checkAppInLaunchingProvidersLocked(app, true); 5759 // Take care of any services that are waiting for the process. 5760 mServices.processStartTimedOutLocked(app); 5761 app.kill("start timeout", true); 5762 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5763 Slog.w(TAG, "Unattached app died before backup, skipping"); 5764 try { 5765 IBackupManager bm = IBackupManager.Stub.asInterface( 5766 ServiceManager.getService(Context.BACKUP_SERVICE)); 5767 bm.agentDisconnected(app.info.packageName); 5768 } catch (RemoteException e) { 5769 // Can't happen; the backup manager is local 5770 } 5771 } 5772 if (isPendingBroadcastProcessLocked(pid)) { 5773 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5774 skipPendingBroadcastLocked(pid); 5775 } 5776 } else { 5777 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5778 } 5779 } 5780 5781 private final boolean attachApplicationLocked(IApplicationThread thread, 5782 int pid) { 5783 5784 // Find the application record that is being attached... either via 5785 // the pid if we are running in multiple processes, or just pull the 5786 // next app record if we are emulating process with anonymous threads. 5787 ProcessRecord app; 5788 if (pid != MY_PID && pid >= 0) { 5789 synchronized (mPidsSelfLocked) { 5790 app = mPidsSelfLocked.get(pid); 5791 } 5792 } else { 5793 app = null; 5794 } 5795 5796 if (app == null) { 5797 Slog.w(TAG, "No pending application record for pid " + pid 5798 + " (IApplicationThread " + thread + "); dropping process"); 5799 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5800 if (pid > 0 && pid != MY_PID) { 5801 Process.killProcessQuiet(pid); 5802 //TODO: Process.killProcessGroup(app.info.uid, pid); 5803 } else { 5804 try { 5805 thread.scheduleExit(); 5806 } catch (Exception e) { 5807 // Ignore exceptions. 5808 } 5809 } 5810 return false; 5811 } 5812 5813 // If this application record is still attached to a previous 5814 // process, clean it up now. 5815 if (app.thread != null) { 5816 handleAppDiedLocked(app, true, true); 5817 } 5818 5819 // Tell the process all about itself. 5820 5821 if (localLOGV) Slog.v( 5822 TAG, "Binding process pid " + pid + " to record " + app); 5823 5824 final String processName = app.processName; 5825 try { 5826 AppDeathRecipient adr = new AppDeathRecipient( 5827 app, pid, thread); 5828 thread.asBinder().linkToDeath(adr, 0); 5829 app.deathRecipient = adr; 5830 } catch (RemoteException e) { 5831 app.resetPackageList(mProcessStats); 5832 startProcessLocked(app, "link fail", processName); 5833 return false; 5834 } 5835 5836 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5837 5838 app.makeActive(thread, mProcessStats); 5839 app.curAdj = app.setAdj = -100; 5840 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5841 app.forcingToForeground = null; 5842 updateProcessForegroundLocked(app, false, false); 5843 app.hasShownUi = false; 5844 app.debugging = false; 5845 app.cached = false; 5846 5847 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5848 5849 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5850 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5851 5852 if (!normalMode) { 5853 Slog.i(TAG, "Launching preboot mode app: " + app); 5854 } 5855 5856 if (localLOGV) Slog.v( 5857 TAG, "New app record " + app 5858 + " thread=" + thread.asBinder() + " pid=" + pid); 5859 try { 5860 int testMode = IApplicationThread.DEBUG_OFF; 5861 if (mDebugApp != null && mDebugApp.equals(processName)) { 5862 testMode = mWaitForDebugger 5863 ? IApplicationThread.DEBUG_WAIT 5864 : IApplicationThread.DEBUG_ON; 5865 app.debugging = true; 5866 if (mDebugTransient) { 5867 mDebugApp = mOrigDebugApp; 5868 mWaitForDebugger = mOrigWaitForDebugger; 5869 } 5870 } 5871 String profileFile = app.instrumentationProfileFile; 5872 ParcelFileDescriptor profileFd = null; 5873 int samplingInterval = 0; 5874 boolean profileAutoStop = false; 5875 if (mProfileApp != null && mProfileApp.equals(processName)) { 5876 mProfileProc = app; 5877 profileFile = mProfileFile; 5878 profileFd = mProfileFd; 5879 samplingInterval = mSamplingInterval; 5880 profileAutoStop = mAutoStopProfiler; 5881 } 5882 boolean enableOpenGlTrace = false; 5883 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5884 enableOpenGlTrace = true; 5885 mOpenGlTraceApp = null; 5886 } 5887 5888 // If the app is being launched for restore or full backup, set it up specially 5889 boolean isRestrictedBackupMode = false; 5890 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5891 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5892 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5893 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5894 } 5895 5896 ensurePackageDexOpt(app.instrumentationInfo != null 5897 ? app.instrumentationInfo.packageName 5898 : app.info.packageName); 5899 if (app.instrumentationClass != null) { 5900 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5901 } 5902 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5903 + processName + " with config " + mConfiguration); 5904 ApplicationInfo appInfo = app.instrumentationInfo != null 5905 ? app.instrumentationInfo : app.info; 5906 app.compat = compatibilityInfoForPackageLocked(appInfo); 5907 if (profileFd != null) { 5908 profileFd = profileFd.dup(); 5909 } 5910 ProfilerInfo profilerInfo = profileFile == null ? null 5911 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5912 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5913 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5914 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5915 isRestrictedBackupMode || !normalMode, app.persistent, 5916 new Configuration(mConfiguration), app.compat, 5917 getCommonServicesLocked(app.isolated), 5918 mCoreSettingsObserver.getCoreSettingsLocked()); 5919 updateLruProcessLocked(app, false, null); 5920 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5921 } catch (Exception e) { 5922 // todo: Yikes! What should we do? For now we will try to 5923 // start another process, but that could easily get us in 5924 // an infinite loop of restarting processes... 5925 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5926 5927 app.resetPackageList(mProcessStats); 5928 app.unlinkDeathRecipient(); 5929 startProcessLocked(app, "bind fail", processName); 5930 return false; 5931 } 5932 5933 // Remove this record from the list of starting applications. 5934 mPersistentStartingProcesses.remove(app); 5935 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5936 "Attach application locked removing on hold: " + app); 5937 mProcessesOnHold.remove(app); 5938 5939 boolean badApp = false; 5940 boolean didSomething = false; 5941 5942 // See if the top visible activity is waiting to run in this process... 5943 if (normalMode) { 5944 try { 5945 if (mStackSupervisor.attachApplicationLocked(app)) { 5946 didSomething = true; 5947 } 5948 } catch (Exception e) { 5949 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5950 badApp = true; 5951 } 5952 } 5953 5954 // Find any services that should be running in this process... 5955 if (!badApp) { 5956 try { 5957 didSomething |= mServices.attachApplicationLocked(app, processName); 5958 } catch (Exception e) { 5959 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5960 badApp = true; 5961 } 5962 } 5963 5964 // Check if a next-broadcast receiver is in this process... 5965 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5966 try { 5967 didSomething |= sendPendingBroadcastsLocked(app); 5968 } catch (Exception e) { 5969 // If the app died trying to launch the receiver we declare it 'bad' 5970 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 5971 badApp = true; 5972 } 5973 } 5974 5975 // Check whether the next backup agent is in this process... 5976 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5977 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5978 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5979 try { 5980 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5981 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5982 mBackupTarget.backupMode); 5983 } catch (Exception e) { 5984 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 5985 badApp = true; 5986 } 5987 } 5988 5989 if (badApp) { 5990 app.kill("error during init", true); 5991 handleAppDiedLocked(app, false, true); 5992 return false; 5993 } 5994 5995 if (!didSomething) { 5996 updateOomAdjLocked(); 5997 } 5998 5999 return true; 6000 } 6001 6002 @Override 6003 public final void attachApplication(IApplicationThread thread) { 6004 synchronized (this) { 6005 int callingPid = Binder.getCallingPid(); 6006 final long origId = Binder.clearCallingIdentity(); 6007 attachApplicationLocked(thread, callingPid); 6008 Binder.restoreCallingIdentity(origId); 6009 } 6010 } 6011 6012 @Override 6013 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6014 final long origId = Binder.clearCallingIdentity(); 6015 synchronized (this) { 6016 ActivityStack stack = ActivityRecord.getStackLocked(token); 6017 if (stack != null) { 6018 ActivityRecord r = 6019 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6020 if (stopProfiling) { 6021 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6022 try { 6023 mProfileFd.close(); 6024 } catch (IOException e) { 6025 } 6026 clearProfilerLocked(); 6027 } 6028 } 6029 } 6030 } 6031 Binder.restoreCallingIdentity(origId); 6032 } 6033 6034 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6035 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6036 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6037 } 6038 6039 void enableScreenAfterBoot() { 6040 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6041 SystemClock.uptimeMillis()); 6042 mWindowManager.enableScreenAfterBoot(); 6043 6044 synchronized (this) { 6045 updateEventDispatchingLocked(); 6046 } 6047 } 6048 6049 @Override 6050 public void showBootMessage(final CharSequence msg, final boolean always) { 6051 enforceNotIsolatedCaller("showBootMessage"); 6052 mWindowManager.showBootMessage(msg, always); 6053 } 6054 6055 @Override 6056 public void keyguardWaitingForActivityDrawn() { 6057 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6058 final long token = Binder.clearCallingIdentity(); 6059 try { 6060 synchronized (this) { 6061 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6062 mWindowManager.keyguardWaitingForActivityDrawn(); 6063 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6064 mLockScreenShown = LOCK_SCREEN_LEAVING; 6065 updateSleepIfNeededLocked(); 6066 } 6067 } 6068 } finally { 6069 Binder.restoreCallingIdentity(token); 6070 } 6071 } 6072 6073 final void finishBooting() { 6074 synchronized (this) { 6075 if (!mBootAnimationComplete) { 6076 mCallFinishBooting = true; 6077 return; 6078 } 6079 mCallFinishBooting = false; 6080 } 6081 6082 ArraySet<String> completedIsas = new ArraySet<String>(); 6083 for (String abi : Build.SUPPORTED_ABIS) { 6084 Process.establishZygoteConnectionForAbi(abi); 6085 final String instructionSet = VMRuntime.getInstructionSet(abi); 6086 if (!completedIsas.contains(instructionSet)) { 6087 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6088 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6089 } 6090 completedIsas.add(instructionSet); 6091 } 6092 } 6093 6094 IntentFilter pkgFilter = new IntentFilter(); 6095 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6096 pkgFilter.addDataScheme("package"); 6097 mContext.registerReceiver(new BroadcastReceiver() { 6098 @Override 6099 public void onReceive(Context context, Intent intent) { 6100 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6101 if (pkgs != null) { 6102 for (String pkg : pkgs) { 6103 synchronized (ActivityManagerService.this) { 6104 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6105 0, "finished booting")) { 6106 setResultCode(Activity.RESULT_OK); 6107 return; 6108 } 6109 } 6110 } 6111 } 6112 } 6113 }, pkgFilter); 6114 6115 // Let system services know. 6116 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6117 6118 synchronized (this) { 6119 // Ensure that any processes we had put on hold are now started 6120 // up. 6121 final int NP = mProcessesOnHold.size(); 6122 if (NP > 0) { 6123 ArrayList<ProcessRecord> procs = 6124 new ArrayList<ProcessRecord>(mProcessesOnHold); 6125 for (int ip=0; ip<NP; ip++) { 6126 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6127 + procs.get(ip)); 6128 startProcessLocked(procs.get(ip), "on-hold", null); 6129 } 6130 } 6131 6132 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6133 // Start looking for apps that are abusing wake locks. 6134 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6135 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6136 // Tell anyone interested that we are done booting! 6137 SystemProperties.set("sys.boot_completed", "1"); 6138 6139 // And trigger dev.bootcomplete if we are not showing encryption progress 6140 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6141 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6142 SystemProperties.set("dev.bootcomplete", "1"); 6143 } 6144 for (int i=0; i<mStartedUsers.size(); i++) { 6145 UserStartedState uss = mStartedUsers.valueAt(i); 6146 if (uss.mState == UserStartedState.STATE_BOOTING) { 6147 uss.mState = UserStartedState.STATE_RUNNING; 6148 final int userId = mStartedUsers.keyAt(i); 6149 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6150 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6151 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6152 broadcastIntentLocked(null, null, intent, null, 6153 new IIntentReceiver.Stub() { 6154 @Override 6155 public void performReceive(Intent intent, int resultCode, 6156 String data, Bundle extras, boolean ordered, 6157 boolean sticky, int sendingUser) { 6158 synchronized (ActivityManagerService.this) { 6159 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6160 true, false); 6161 } 6162 } 6163 }, 6164 0, null, null, 6165 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6166 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6167 userId); 6168 } 6169 } 6170 scheduleStartProfilesLocked(); 6171 } 6172 } 6173 } 6174 6175 @Override 6176 public void bootAnimationComplete() { 6177 final boolean callFinishBooting; 6178 synchronized (this) { 6179 callFinishBooting = mCallFinishBooting; 6180 mBootAnimationComplete = true; 6181 } 6182 if (callFinishBooting) { 6183 finishBooting(); 6184 } 6185 } 6186 6187 final void ensureBootCompleted() { 6188 boolean booting; 6189 boolean enableScreen; 6190 synchronized (this) { 6191 booting = mBooting; 6192 mBooting = false; 6193 enableScreen = !mBooted; 6194 mBooted = true; 6195 } 6196 6197 if (booting) { 6198 finishBooting(); 6199 } 6200 6201 if (enableScreen) { 6202 enableScreenAfterBoot(); 6203 } 6204 } 6205 6206 @Override 6207 public final void activityResumed(IBinder token) { 6208 final long origId = Binder.clearCallingIdentity(); 6209 synchronized(this) { 6210 ActivityStack stack = ActivityRecord.getStackLocked(token); 6211 if (stack != null) { 6212 ActivityRecord.activityResumedLocked(token); 6213 } 6214 } 6215 Binder.restoreCallingIdentity(origId); 6216 } 6217 6218 @Override 6219 public final void activityPaused(IBinder token) { 6220 final long origId = Binder.clearCallingIdentity(); 6221 synchronized(this) { 6222 ActivityStack stack = ActivityRecord.getStackLocked(token); 6223 if (stack != null) { 6224 stack.activityPausedLocked(token, false); 6225 } 6226 } 6227 Binder.restoreCallingIdentity(origId); 6228 } 6229 6230 @Override 6231 public final void activityStopped(IBinder token, Bundle icicle, 6232 PersistableBundle persistentState, CharSequence description) { 6233 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6234 6235 // Refuse possible leaked file descriptors 6236 if (icicle != null && icicle.hasFileDescriptors()) { 6237 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6238 } 6239 6240 final long origId = Binder.clearCallingIdentity(); 6241 6242 synchronized (this) { 6243 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6244 if (r != null) { 6245 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6246 } 6247 } 6248 6249 trimApplications(); 6250 6251 Binder.restoreCallingIdentity(origId); 6252 } 6253 6254 @Override 6255 public final void activityDestroyed(IBinder token) { 6256 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6257 synchronized (this) { 6258 ActivityStack stack = ActivityRecord.getStackLocked(token); 6259 if (stack != null) { 6260 stack.activityDestroyedLocked(token); 6261 } 6262 } 6263 } 6264 6265 @Override 6266 public final void backgroundResourcesReleased(IBinder token) { 6267 final long origId = Binder.clearCallingIdentity(); 6268 try { 6269 synchronized (this) { 6270 ActivityStack stack = ActivityRecord.getStackLocked(token); 6271 if (stack != null) { 6272 stack.backgroundResourcesReleased(); 6273 } 6274 } 6275 } finally { 6276 Binder.restoreCallingIdentity(origId); 6277 } 6278 } 6279 6280 @Override 6281 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6282 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6283 } 6284 6285 @Override 6286 public final void notifyEnterAnimationComplete(IBinder token) { 6287 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6288 } 6289 6290 @Override 6291 public String getCallingPackage(IBinder token) { 6292 synchronized (this) { 6293 ActivityRecord r = getCallingRecordLocked(token); 6294 return r != null ? r.info.packageName : null; 6295 } 6296 } 6297 6298 @Override 6299 public ComponentName getCallingActivity(IBinder token) { 6300 synchronized (this) { 6301 ActivityRecord r = getCallingRecordLocked(token); 6302 return r != null ? r.intent.getComponent() : null; 6303 } 6304 } 6305 6306 private ActivityRecord getCallingRecordLocked(IBinder token) { 6307 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6308 if (r == null) { 6309 return null; 6310 } 6311 return r.resultTo; 6312 } 6313 6314 @Override 6315 public ComponentName getActivityClassForToken(IBinder token) { 6316 synchronized(this) { 6317 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6318 if (r == null) { 6319 return null; 6320 } 6321 return r.intent.getComponent(); 6322 } 6323 } 6324 6325 @Override 6326 public String getPackageForToken(IBinder token) { 6327 synchronized(this) { 6328 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6329 if (r == null) { 6330 return null; 6331 } 6332 return r.packageName; 6333 } 6334 } 6335 6336 @Override 6337 public IIntentSender getIntentSender(int type, 6338 String packageName, IBinder token, String resultWho, 6339 int requestCode, Intent[] intents, String[] resolvedTypes, 6340 int flags, Bundle options, int userId) { 6341 enforceNotIsolatedCaller("getIntentSender"); 6342 // Refuse possible leaked file descriptors 6343 if (intents != null) { 6344 if (intents.length < 1) { 6345 throw new IllegalArgumentException("Intents array length must be >= 1"); 6346 } 6347 for (int i=0; i<intents.length; i++) { 6348 Intent intent = intents[i]; 6349 if (intent != null) { 6350 if (intent.hasFileDescriptors()) { 6351 throw new IllegalArgumentException("File descriptors passed in Intent"); 6352 } 6353 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6354 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6355 throw new IllegalArgumentException( 6356 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6357 } 6358 intents[i] = new Intent(intent); 6359 } 6360 } 6361 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6362 throw new IllegalArgumentException( 6363 "Intent array length does not match resolvedTypes length"); 6364 } 6365 } 6366 if (options != null) { 6367 if (options.hasFileDescriptors()) { 6368 throw new IllegalArgumentException("File descriptors passed in options"); 6369 } 6370 } 6371 6372 synchronized(this) { 6373 int callingUid = Binder.getCallingUid(); 6374 int origUserId = userId; 6375 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6376 type == ActivityManager.INTENT_SENDER_BROADCAST, 6377 ALLOW_NON_FULL, "getIntentSender", null); 6378 if (origUserId == UserHandle.USER_CURRENT) { 6379 // We don't want to evaluate this until the pending intent is 6380 // actually executed. However, we do want to always do the 6381 // security checking for it above. 6382 userId = UserHandle.USER_CURRENT; 6383 } 6384 try { 6385 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6386 int uid = AppGlobals.getPackageManager() 6387 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6388 if (!UserHandle.isSameApp(callingUid, uid)) { 6389 String msg = "Permission Denial: getIntentSender() from pid=" 6390 + Binder.getCallingPid() 6391 + ", uid=" + Binder.getCallingUid() 6392 + ", (need uid=" + uid + ")" 6393 + " is not allowed to send as package " + packageName; 6394 Slog.w(TAG, msg); 6395 throw new SecurityException(msg); 6396 } 6397 } 6398 6399 return getIntentSenderLocked(type, packageName, callingUid, userId, 6400 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6401 6402 } catch (RemoteException e) { 6403 throw new SecurityException(e); 6404 } 6405 } 6406 } 6407 6408 IIntentSender getIntentSenderLocked(int type, String packageName, 6409 int callingUid, int userId, IBinder token, String resultWho, 6410 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6411 Bundle options) { 6412 if (DEBUG_MU) 6413 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6414 ActivityRecord activity = null; 6415 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6416 activity = ActivityRecord.isInStackLocked(token); 6417 if (activity == null) { 6418 return null; 6419 } 6420 if (activity.finishing) { 6421 return null; 6422 } 6423 } 6424 6425 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6426 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6427 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6428 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6429 |PendingIntent.FLAG_UPDATE_CURRENT); 6430 6431 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6432 type, packageName, activity, resultWho, 6433 requestCode, intents, resolvedTypes, flags, options, userId); 6434 WeakReference<PendingIntentRecord> ref; 6435 ref = mIntentSenderRecords.get(key); 6436 PendingIntentRecord rec = ref != null ? ref.get() : null; 6437 if (rec != null) { 6438 if (!cancelCurrent) { 6439 if (updateCurrent) { 6440 if (rec.key.requestIntent != null) { 6441 rec.key.requestIntent.replaceExtras(intents != null ? 6442 intents[intents.length - 1] : null); 6443 } 6444 if (intents != null) { 6445 intents[intents.length-1] = rec.key.requestIntent; 6446 rec.key.allIntents = intents; 6447 rec.key.allResolvedTypes = resolvedTypes; 6448 } else { 6449 rec.key.allIntents = null; 6450 rec.key.allResolvedTypes = null; 6451 } 6452 } 6453 return rec; 6454 } 6455 rec.canceled = true; 6456 mIntentSenderRecords.remove(key); 6457 } 6458 if (noCreate) { 6459 return rec; 6460 } 6461 rec = new PendingIntentRecord(this, key, callingUid); 6462 mIntentSenderRecords.put(key, rec.ref); 6463 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6464 if (activity.pendingResults == null) { 6465 activity.pendingResults 6466 = new HashSet<WeakReference<PendingIntentRecord>>(); 6467 } 6468 activity.pendingResults.add(rec.ref); 6469 } 6470 return rec; 6471 } 6472 6473 @Override 6474 public void cancelIntentSender(IIntentSender sender) { 6475 if (!(sender instanceof PendingIntentRecord)) { 6476 return; 6477 } 6478 synchronized(this) { 6479 PendingIntentRecord rec = (PendingIntentRecord)sender; 6480 try { 6481 int uid = AppGlobals.getPackageManager() 6482 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6483 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6484 String msg = "Permission Denial: cancelIntentSender() from pid=" 6485 + Binder.getCallingPid() 6486 + ", uid=" + Binder.getCallingUid() 6487 + " is not allowed to cancel packges " 6488 + rec.key.packageName; 6489 Slog.w(TAG, msg); 6490 throw new SecurityException(msg); 6491 } 6492 } catch (RemoteException e) { 6493 throw new SecurityException(e); 6494 } 6495 cancelIntentSenderLocked(rec, true); 6496 } 6497 } 6498 6499 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6500 rec.canceled = true; 6501 mIntentSenderRecords.remove(rec.key); 6502 if (cleanActivity && rec.key.activity != null) { 6503 rec.key.activity.pendingResults.remove(rec.ref); 6504 } 6505 } 6506 6507 @Override 6508 public String getPackageForIntentSender(IIntentSender pendingResult) { 6509 if (!(pendingResult instanceof PendingIntentRecord)) { 6510 return null; 6511 } 6512 try { 6513 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6514 return res.key.packageName; 6515 } catch (ClassCastException e) { 6516 } 6517 return null; 6518 } 6519 6520 @Override 6521 public int getUidForIntentSender(IIntentSender sender) { 6522 if (sender instanceof PendingIntentRecord) { 6523 try { 6524 PendingIntentRecord res = (PendingIntentRecord)sender; 6525 return res.uid; 6526 } catch (ClassCastException e) { 6527 } 6528 } 6529 return -1; 6530 } 6531 6532 @Override 6533 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6534 if (!(pendingResult instanceof PendingIntentRecord)) { 6535 return false; 6536 } 6537 try { 6538 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6539 if (res.key.allIntents == null) { 6540 return false; 6541 } 6542 for (int i=0; i<res.key.allIntents.length; i++) { 6543 Intent intent = res.key.allIntents[i]; 6544 if (intent.getPackage() != null && intent.getComponent() != null) { 6545 return false; 6546 } 6547 } 6548 return true; 6549 } catch (ClassCastException e) { 6550 } 6551 return false; 6552 } 6553 6554 @Override 6555 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6556 if (!(pendingResult instanceof PendingIntentRecord)) { 6557 return false; 6558 } 6559 try { 6560 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6561 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6562 return true; 6563 } 6564 return false; 6565 } catch (ClassCastException e) { 6566 } 6567 return false; 6568 } 6569 6570 @Override 6571 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6572 if (!(pendingResult instanceof PendingIntentRecord)) { 6573 return null; 6574 } 6575 try { 6576 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6577 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6578 } catch (ClassCastException e) { 6579 } 6580 return null; 6581 } 6582 6583 @Override 6584 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6585 if (!(pendingResult instanceof PendingIntentRecord)) { 6586 return null; 6587 } 6588 try { 6589 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6590 Intent intent = res.key.requestIntent; 6591 if (intent != null) { 6592 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6593 || res.lastTagPrefix.equals(prefix))) { 6594 return res.lastTag; 6595 } 6596 res.lastTagPrefix = prefix; 6597 StringBuilder sb = new StringBuilder(128); 6598 if (prefix != null) { 6599 sb.append(prefix); 6600 } 6601 if (intent.getAction() != null) { 6602 sb.append(intent.getAction()); 6603 } else if (intent.getComponent() != null) { 6604 intent.getComponent().appendShortString(sb); 6605 } else { 6606 sb.append("?"); 6607 } 6608 return res.lastTag = sb.toString(); 6609 } 6610 } catch (ClassCastException e) { 6611 } 6612 return null; 6613 } 6614 6615 @Override 6616 public void setProcessLimit(int max) { 6617 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6618 "setProcessLimit()"); 6619 synchronized (this) { 6620 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6621 mProcessLimitOverride = max; 6622 } 6623 trimApplications(); 6624 } 6625 6626 @Override 6627 public int getProcessLimit() { 6628 synchronized (this) { 6629 return mProcessLimitOverride; 6630 } 6631 } 6632 6633 void foregroundTokenDied(ForegroundToken token) { 6634 synchronized (ActivityManagerService.this) { 6635 synchronized (mPidsSelfLocked) { 6636 ForegroundToken cur 6637 = mForegroundProcesses.get(token.pid); 6638 if (cur != token) { 6639 return; 6640 } 6641 mForegroundProcesses.remove(token.pid); 6642 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6643 if (pr == null) { 6644 return; 6645 } 6646 pr.forcingToForeground = null; 6647 updateProcessForegroundLocked(pr, false, false); 6648 } 6649 updateOomAdjLocked(); 6650 } 6651 } 6652 6653 @Override 6654 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6655 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6656 "setProcessForeground()"); 6657 synchronized(this) { 6658 boolean changed = false; 6659 6660 synchronized (mPidsSelfLocked) { 6661 ProcessRecord pr = mPidsSelfLocked.get(pid); 6662 if (pr == null && isForeground) { 6663 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6664 return; 6665 } 6666 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6667 if (oldToken != null) { 6668 oldToken.token.unlinkToDeath(oldToken, 0); 6669 mForegroundProcesses.remove(pid); 6670 if (pr != null) { 6671 pr.forcingToForeground = null; 6672 } 6673 changed = true; 6674 } 6675 if (isForeground && token != null) { 6676 ForegroundToken newToken = new ForegroundToken() { 6677 @Override 6678 public void binderDied() { 6679 foregroundTokenDied(this); 6680 } 6681 }; 6682 newToken.pid = pid; 6683 newToken.token = token; 6684 try { 6685 token.linkToDeath(newToken, 0); 6686 mForegroundProcesses.put(pid, newToken); 6687 pr.forcingToForeground = token; 6688 changed = true; 6689 } catch (RemoteException e) { 6690 // If the process died while doing this, we will later 6691 // do the cleanup with the process death link. 6692 } 6693 } 6694 } 6695 6696 if (changed) { 6697 updateOomAdjLocked(); 6698 } 6699 } 6700 } 6701 6702 // ========================================================= 6703 // PERMISSIONS 6704 // ========================================================= 6705 6706 static class PermissionController extends IPermissionController.Stub { 6707 ActivityManagerService mActivityManagerService; 6708 PermissionController(ActivityManagerService activityManagerService) { 6709 mActivityManagerService = activityManagerService; 6710 } 6711 6712 @Override 6713 public boolean checkPermission(String permission, int pid, int uid) { 6714 return mActivityManagerService.checkPermission(permission, pid, 6715 uid) == PackageManager.PERMISSION_GRANTED; 6716 } 6717 } 6718 6719 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6720 @Override 6721 public int checkComponentPermission(String permission, int pid, int uid, 6722 int owningUid, boolean exported) { 6723 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6724 owningUid, exported); 6725 } 6726 6727 @Override 6728 public Object getAMSLock() { 6729 return ActivityManagerService.this; 6730 } 6731 } 6732 6733 /** 6734 * This can be called with or without the global lock held. 6735 */ 6736 int checkComponentPermission(String permission, int pid, int uid, 6737 int owningUid, boolean exported) { 6738 if (pid == MY_PID) { 6739 return PackageManager.PERMISSION_GRANTED; 6740 } 6741 return ActivityManager.checkComponentPermission(permission, uid, 6742 owningUid, exported); 6743 } 6744 6745 /** 6746 * As the only public entry point for permissions checking, this method 6747 * can enforce the semantic that requesting a check on a null global 6748 * permission is automatically denied. (Internally a null permission 6749 * string is used when calling {@link #checkComponentPermission} in cases 6750 * when only uid-based security is needed.) 6751 * 6752 * This can be called with or without the global lock held. 6753 */ 6754 @Override 6755 public int checkPermission(String permission, int pid, int uid) { 6756 if (permission == null) { 6757 return PackageManager.PERMISSION_DENIED; 6758 } 6759 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6760 } 6761 6762 @Override 6763 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6764 if (permission == null) { 6765 return PackageManager.PERMISSION_DENIED; 6766 } 6767 6768 // We might be performing an operation on behalf of an indirect binder 6769 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6770 // client identity accordingly before proceeding. 6771 Identity tlsIdentity = sCallerIdentity.get(); 6772 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6773 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6774 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6775 uid = tlsIdentity.uid; 6776 pid = tlsIdentity.pid; 6777 } 6778 6779 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6780 } 6781 6782 /** 6783 * Binder IPC calls go through the public entry point. 6784 * This can be called with or without the global lock held. 6785 */ 6786 int checkCallingPermission(String permission) { 6787 return checkPermission(permission, 6788 Binder.getCallingPid(), 6789 UserHandle.getAppId(Binder.getCallingUid())); 6790 } 6791 6792 /** 6793 * This can be called with or without the global lock held. 6794 */ 6795 void enforceCallingPermission(String permission, String func) { 6796 if (checkCallingPermission(permission) 6797 == PackageManager.PERMISSION_GRANTED) { 6798 return; 6799 } 6800 6801 String msg = "Permission Denial: " + func + " from pid=" 6802 + Binder.getCallingPid() 6803 + ", uid=" + Binder.getCallingUid() 6804 + " requires " + permission; 6805 Slog.w(TAG, msg); 6806 throw new SecurityException(msg); 6807 } 6808 6809 /** 6810 * Determine if UID is holding permissions required to access {@link Uri} in 6811 * the given {@link ProviderInfo}. Final permission checking is always done 6812 * in {@link ContentProvider}. 6813 */ 6814 private final boolean checkHoldingPermissionsLocked( 6815 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6816 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6817 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6818 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6819 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6820 != PERMISSION_GRANTED) { 6821 return false; 6822 } 6823 } 6824 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6825 } 6826 6827 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6828 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6829 if (pi.applicationInfo.uid == uid) { 6830 return true; 6831 } else if (!pi.exported) { 6832 return false; 6833 } 6834 6835 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6836 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6837 try { 6838 // check if target holds top-level <provider> permissions 6839 if (!readMet && pi.readPermission != null && considerUidPermissions 6840 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6841 readMet = true; 6842 } 6843 if (!writeMet && pi.writePermission != null && considerUidPermissions 6844 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6845 writeMet = true; 6846 } 6847 6848 // track if unprotected read/write is allowed; any denied 6849 // <path-permission> below removes this ability 6850 boolean allowDefaultRead = pi.readPermission == null; 6851 boolean allowDefaultWrite = pi.writePermission == null; 6852 6853 // check if target holds any <path-permission> that match uri 6854 final PathPermission[] pps = pi.pathPermissions; 6855 if (pps != null) { 6856 final String path = grantUri.uri.getPath(); 6857 int i = pps.length; 6858 while (i > 0 && (!readMet || !writeMet)) { 6859 i--; 6860 PathPermission pp = pps[i]; 6861 if (pp.match(path)) { 6862 if (!readMet) { 6863 final String pprperm = pp.getReadPermission(); 6864 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6865 + pprperm + " for " + pp.getPath() 6866 + ": match=" + pp.match(path) 6867 + " check=" + pm.checkUidPermission(pprperm, uid)); 6868 if (pprperm != null) { 6869 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6870 == PERMISSION_GRANTED) { 6871 readMet = true; 6872 } else { 6873 allowDefaultRead = false; 6874 } 6875 } 6876 } 6877 if (!writeMet) { 6878 final String ppwperm = pp.getWritePermission(); 6879 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6880 + ppwperm + " for " + pp.getPath() 6881 + ": match=" + pp.match(path) 6882 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6883 if (ppwperm != null) { 6884 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6885 == PERMISSION_GRANTED) { 6886 writeMet = true; 6887 } else { 6888 allowDefaultWrite = false; 6889 } 6890 } 6891 } 6892 } 6893 } 6894 } 6895 6896 // grant unprotected <provider> read/write, if not blocked by 6897 // <path-permission> above 6898 if (allowDefaultRead) readMet = true; 6899 if (allowDefaultWrite) writeMet = true; 6900 6901 } catch (RemoteException e) { 6902 return false; 6903 } 6904 6905 return readMet && writeMet; 6906 } 6907 6908 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6909 ProviderInfo pi = null; 6910 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6911 if (cpr != null) { 6912 pi = cpr.info; 6913 } else { 6914 try { 6915 pi = AppGlobals.getPackageManager().resolveContentProvider( 6916 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6917 } catch (RemoteException ex) { 6918 } 6919 } 6920 return pi; 6921 } 6922 6923 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6924 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6925 if (targetUris != null) { 6926 return targetUris.get(grantUri); 6927 } 6928 return null; 6929 } 6930 6931 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6932 String targetPkg, int targetUid, GrantUri grantUri) { 6933 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6934 if (targetUris == null) { 6935 targetUris = Maps.newArrayMap(); 6936 mGrantedUriPermissions.put(targetUid, targetUris); 6937 } 6938 6939 UriPermission perm = targetUris.get(grantUri); 6940 if (perm == null) { 6941 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6942 targetUris.put(grantUri, perm); 6943 } 6944 6945 return perm; 6946 } 6947 6948 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6949 final int modeFlags) { 6950 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6951 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6952 : UriPermission.STRENGTH_OWNED; 6953 6954 // Root gets to do everything. 6955 if (uid == 0) { 6956 return true; 6957 } 6958 6959 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6960 if (perms == null) return false; 6961 6962 // First look for exact match 6963 final UriPermission exactPerm = perms.get(grantUri); 6964 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6965 return true; 6966 } 6967 6968 // No exact match, look for prefixes 6969 final int N = perms.size(); 6970 for (int i = 0; i < N; i++) { 6971 final UriPermission perm = perms.valueAt(i); 6972 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6973 && perm.getStrength(modeFlags) >= minStrength) { 6974 return true; 6975 } 6976 } 6977 6978 return false; 6979 } 6980 6981 /** 6982 * @param uri This uri must NOT contain an embedded userId. 6983 * @param userId The userId in which the uri is to be resolved. 6984 */ 6985 @Override 6986 public int checkUriPermission(Uri uri, int pid, int uid, 6987 final int modeFlags, int userId, IBinder callerToken) { 6988 enforceNotIsolatedCaller("checkUriPermission"); 6989 6990 // Another redirected-binder-call permissions check as in 6991 // {@link checkPermissionWithToken}. 6992 Identity tlsIdentity = sCallerIdentity.get(); 6993 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6994 uid = tlsIdentity.uid; 6995 pid = tlsIdentity.pid; 6996 } 6997 6998 // Our own process gets to do everything. 6999 if (pid == MY_PID) { 7000 return PackageManager.PERMISSION_GRANTED; 7001 } 7002 synchronized (this) { 7003 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7004 ? PackageManager.PERMISSION_GRANTED 7005 : PackageManager.PERMISSION_DENIED; 7006 } 7007 } 7008 7009 /** 7010 * Check if the targetPkg can be granted permission to access uri by 7011 * the callingUid using the given modeFlags. Throws a security exception 7012 * if callingUid is not allowed to do this. Returns the uid of the target 7013 * if the URI permission grant should be performed; returns -1 if it is not 7014 * needed (for example targetPkg already has permission to access the URI). 7015 * If you already know the uid of the target, you can supply it in 7016 * lastTargetUid else set that to -1. 7017 */ 7018 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7019 final int modeFlags, int lastTargetUid) { 7020 if (!Intent.isAccessUriMode(modeFlags)) { 7021 return -1; 7022 } 7023 7024 if (targetPkg != null) { 7025 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7026 "Checking grant " + targetPkg + " permission to " + grantUri); 7027 } 7028 7029 final IPackageManager pm = AppGlobals.getPackageManager(); 7030 7031 // If this is not a content: uri, we can't do anything with it. 7032 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7033 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7034 "Can't grant URI permission for non-content URI: " + grantUri); 7035 return -1; 7036 } 7037 7038 final String authority = grantUri.uri.getAuthority(); 7039 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7040 if (pi == null) { 7041 Slog.w(TAG, "No content provider found for permission check: " + 7042 grantUri.uri.toSafeString()); 7043 return -1; 7044 } 7045 7046 int targetUid = lastTargetUid; 7047 if (targetUid < 0 && targetPkg != null) { 7048 try { 7049 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7050 if (targetUid < 0) { 7051 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7052 "Can't grant URI permission no uid for: " + targetPkg); 7053 return -1; 7054 } 7055 } catch (RemoteException ex) { 7056 return -1; 7057 } 7058 } 7059 7060 if (targetUid >= 0) { 7061 // First... does the target actually need this permission? 7062 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7063 // No need to grant the target this permission. 7064 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7065 "Target " + targetPkg + " already has full permission to " + grantUri); 7066 return -1; 7067 } 7068 } else { 7069 // First... there is no target package, so can anyone access it? 7070 boolean allowed = pi.exported; 7071 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7072 if (pi.readPermission != null) { 7073 allowed = false; 7074 } 7075 } 7076 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7077 if (pi.writePermission != null) { 7078 allowed = false; 7079 } 7080 } 7081 if (allowed) { 7082 return -1; 7083 } 7084 } 7085 7086 /* There is a special cross user grant if: 7087 * - The target is on another user. 7088 * - Apps on the current user can access the uri without any uid permissions. 7089 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7090 * grant uri permissions. 7091 */ 7092 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7093 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7094 modeFlags, false /*without considering the uid permissions*/); 7095 7096 // Second... is the provider allowing granting of URI permissions? 7097 if (!specialCrossUserGrant) { 7098 if (!pi.grantUriPermissions) { 7099 throw new SecurityException("Provider " + pi.packageName 7100 + "/" + pi.name 7101 + " does not allow granting of Uri permissions (uri " 7102 + grantUri + ")"); 7103 } 7104 if (pi.uriPermissionPatterns != null) { 7105 final int N = pi.uriPermissionPatterns.length; 7106 boolean allowed = false; 7107 for (int i=0; i<N; i++) { 7108 if (pi.uriPermissionPatterns[i] != null 7109 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7110 allowed = true; 7111 break; 7112 } 7113 } 7114 if (!allowed) { 7115 throw new SecurityException("Provider " + pi.packageName 7116 + "/" + pi.name 7117 + " does not allow granting of permission to path of Uri " 7118 + grantUri); 7119 } 7120 } 7121 } 7122 7123 // Third... does the caller itself have permission to access 7124 // this uri? 7125 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7126 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7127 // Require they hold a strong enough Uri permission 7128 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7129 throw new SecurityException("Uid " + callingUid 7130 + " does not have permission to uri " + grantUri); 7131 } 7132 } 7133 } 7134 return targetUid; 7135 } 7136 7137 /** 7138 * @param uri This uri must NOT contain an embedded userId. 7139 * @param userId The userId in which the uri is to be resolved. 7140 */ 7141 @Override 7142 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7143 final int modeFlags, int userId) { 7144 enforceNotIsolatedCaller("checkGrantUriPermission"); 7145 synchronized(this) { 7146 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7147 new GrantUri(userId, uri, false), modeFlags, -1); 7148 } 7149 } 7150 7151 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7152 final int modeFlags, UriPermissionOwner owner) { 7153 if (!Intent.isAccessUriMode(modeFlags)) { 7154 return; 7155 } 7156 7157 // So here we are: the caller has the assumed permission 7158 // to the uri, and the target doesn't. Let's now give this to 7159 // the target. 7160 7161 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7162 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7163 7164 final String authority = grantUri.uri.getAuthority(); 7165 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7166 if (pi == null) { 7167 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7168 return; 7169 } 7170 7171 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7172 grantUri.prefix = true; 7173 } 7174 final UriPermission perm = findOrCreateUriPermissionLocked( 7175 pi.packageName, targetPkg, targetUid, grantUri); 7176 perm.grantModes(modeFlags, owner); 7177 } 7178 7179 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7180 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7181 if (targetPkg == null) { 7182 throw new NullPointerException("targetPkg"); 7183 } 7184 int targetUid; 7185 final IPackageManager pm = AppGlobals.getPackageManager(); 7186 try { 7187 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7188 } catch (RemoteException ex) { 7189 return; 7190 } 7191 7192 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7193 targetUid); 7194 if (targetUid < 0) { 7195 return; 7196 } 7197 7198 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7199 owner); 7200 } 7201 7202 static class NeededUriGrants extends ArrayList<GrantUri> { 7203 final String targetPkg; 7204 final int targetUid; 7205 final int flags; 7206 7207 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7208 this.targetPkg = targetPkg; 7209 this.targetUid = targetUid; 7210 this.flags = flags; 7211 } 7212 } 7213 7214 /** 7215 * Like checkGrantUriPermissionLocked, but takes an Intent. 7216 */ 7217 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7218 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7219 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7220 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7221 + " clip=" + (intent != null ? intent.getClipData() : null) 7222 + " from " + intent + "; flags=0x" 7223 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7224 7225 if (targetPkg == null) { 7226 throw new NullPointerException("targetPkg"); 7227 } 7228 7229 if (intent == null) { 7230 return null; 7231 } 7232 Uri data = intent.getData(); 7233 ClipData clip = intent.getClipData(); 7234 if (data == null && clip == null) { 7235 return null; 7236 } 7237 // Default userId for uris in the intent (if they don't specify it themselves) 7238 int contentUserHint = intent.getContentUserHint(); 7239 if (contentUserHint == UserHandle.USER_CURRENT) { 7240 contentUserHint = UserHandle.getUserId(callingUid); 7241 } 7242 final IPackageManager pm = AppGlobals.getPackageManager(); 7243 int targetUid; 7244 if (needed != null) { 7245 targetUid = needed.targetUid; 7246 } else { 7247 try { 7248 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7249 } catch (RemoteException ex) { 7250 return null; 7251 } 7252 if (targetUid < 0) { 7253 if (DEBUG_URI_PERMISSION) { 7254 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7255 + " on user " + targetUserId); 7256 } 7257 return null; 7258 } 7259 } 7260 if (data != null) { 7261 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7262 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7263 targetUid); 7264 if (targetUid > 0) { 7265 if (needed == null) { 7266 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7267 } 7268 needed.add(grantUri); 7269 } 7270 } 7271 if (clip != null) { 7272 for (int i=0; i<clip.getItemCount(); i++) { 7273 Uri uri = clip.getItemAt(i).getUri(); 7274 if (uri != null) { 7275 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7276 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7277 targetUid); 7278 if (targetUid > 0) { 7279 if (needed == null) { 7280 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7281 } 7282 needed.add(grantUri); 7283 } 7284 } else { 7285 Intent clipIntent = clip.getItemAt(i).getIntent(); 7286 if (clipIntent != null) { 7287 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7288 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7289 if (newNeeded != null) { 7290 needed = newNeeded; 7291 } 7292 } 7293 } 7294 } 7295 } 7296 7297 return needed; 7298 } 7299 7300 /** 7301 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7302 */ 7303 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7304 UriPermissionOwner owner) { 7305 if (needed != null) { 7306 for (int i=0; i<needed.size(); i++) { 7307 GrantUri grantUri = needed.get(i); 7308 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7309 grantUri, needed.flags, owner); 7310 } 7311 } 7312 } 7313 7314 void grantUriPermissionFromIntentLocked(int callingUid, 7315 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7316 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7317 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7318 if (needed == null) { 7319 return; 7320 } 7321 7322 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7323 } 7324 7325 /** 7326 * @param uri This uri must NOT contain an embedded userId. 7327 * @param userId The userId in which the uri is to be resolved. 7328 */ 7329 @Override 7330 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7331 final int modeFlags, int userId) { 7332 enforceNotIsolatedCaller("grantUriPermission"); 7333 GrantUri grantUri = new GrantUri(userId, uri, false); 7334 synchronized(this) { 7335 final ProcessRecord r = getRecordForAppLocked(caller); 7336 if (r == null) { 7337 throw new SecurityException("Unable to find app for caller " 7338 + caller 7339 + " when granting permission to uri " + grantUri); 7340 } 7341 if (targetPkg == null) { 7342 throw new IllegalArgumentException("null target"); 7343 } 7344 if (grantUri == null) { 7345 throw new IllegalArgumentException("null uri"); 7346 } 7347 7348 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7349 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7350 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7351 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7352 7353 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7354 UserHandle.getUserId(r.uid)); 7355 } 7356 } 7357 7358 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7359 if (perm.modeFlags == 0) { 7360 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7361 perm.targetUid); 7362 if (perms != null) { 7363 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7364 "Removing " + perm.targetUid + " permission to " + perm.uri); 7365 7366 perms.remove(perm.uri); 7367 if (perms.isEmpty()) { 7368 mGrantedUriPermissions.remove(perm.targetUid); 7369 } 7370 } 7371 } 7372 } 7373 7374 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7375 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7376 7377 final IPackageManager pm = AppGlobals.getPackageManager(); 7378 final String authority = grantUri.uri.getAuthority(); 7379 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7380 if (pi == null) { 7381 Slog.w(TAG, "No content provider found for permission revoke: " 7382 + grantUri.toSafeString()); 7383 return; 7384 } 7385 7386 // Does the caller have this permission on the URI? 7387 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7388 // If they don't have direct access to the URI, then revoke any 7389 // ownerless URI permissions that have been granted to them. 7390 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7391 if (perms != null) { 7392 boolean persistChanged = false; 7393 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7394 final UriPermission perm = it.next(); 7395 if (perm.uri.sourceUserId == grantUri.sourceUserId 7396 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7397 if (DEBUG_URI_PERMISSION) 7398 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7399 " permission to " + perm.uri); 7400 persistChanged |= perm.revokeModes( 7401 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7402 if (perm.modeFlags == 0) { 7403 it.remove(); 7404 } 7405 } 7406 } 7407 if (perms.isEmpty()) { 7408 mGrantedUriPermissions.remove(callingUid); 7409 } 7410 if (persistChanged) { 7411 schedulePersistUriGrants(); 7412 } 7413 } 7414 return; 7415 } 7416 7417 boolean persistChanged = false; 7418 7419 // Go through all of the permissions and remove any that match. 7420 int N = mGrantedUriPermissions.size(); 7421 for (int i = 0; i < N; i++) { 7422 final int targetUid = mGrantedUriPermissions.keyAt(i); 7423 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7424 7425 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7426 final UriPermission perm = it.next(); 7427 if (perm.uri.sourceUserId == grantUri.sourceUserId 7428 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7429 if (DEBUG_URI_PERMISSION) 7430 Slog.v(TAG, 7431 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7432 persistChanged |= perm.revokeModes( 7433 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7434 if (perm.modeFlags == 0) { 7435 it.remove(); 7436 } 7437 } 7438 } 7439 7440 if (perms.isEmpty()) { 7441 mGrantedUriPermissions.remove(targetUid); 7442 N--; 7443 i--; 7444 } 7445 } 7446 7447 if (persistChanged) { 7448 schedulePersistUriGrants(); 7449 } 7450 } 7451 7452 /** 7453 * @param uri This uri must NOT contain an embedded userId. 7454 * @param userId The userId in which the uri is to be resolved. 7455 */ 7456 @Override 7457 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7458 int userId) { 7459 enforceNotIsolatedCaller("revokeUriPermission"); 7460 synchronized(this) { 7461 final ProcessRecord r = getRecordForAppLocked(caller); 7462 if (r == null) { 7463 throw new SecurityException("Unable to find app for caller " 7464 + caller 7465 + " when revoking permission to uri " + uri); 7466 } 7467 if (uri == null) { 7468 Slog.w(TAG, "revokeUriPermission: null uri"); 7469 return; 7470 } 7471 7472 if (!Intent.isAccessUriMode(modeFlags)) { 7473 return; 7474 } 7475 7476 final IPackageManager pm = AppGlobals.getPackageManager(); 7477 final String authority = uri.getAuthority(); 7478 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7479 if (pi == null) { 7480 Slog.w(TAG, "No content provider found for permission revoke: " 7481 + uri.toSafeString()); 7482 return; 7483 } 7484 7485 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7486 } 7487 } 7488 7489 /** 7490 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7491 * given package. 7492 * 7493 * @param packageName Package name to match, or {@code null} to apply to all 7494 * packages. 7495 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7496 * to all users. 7497 * @param persistable If persistable grants should be removed. 7498 */ 7499 private void removeUriPermissionsForPackageLocked( 7500 String packageName, int userHandle, boolean persistable) { 7501 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7502 throw new IllegalArgumentException("Must narrow by either package or user"); 7503 } 7504 7505 boolean persistChanged = false; 7506 7507 int N = mGrantedUriPermissions.size(); 7508 for (int i = 0; i < N; i++) { 7509 final int targetUid = mGrantedUriPermissions.keyAt(i); 7510 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7511 7512 // Only inspect grants matching user 7513 if (userHandle == UserHandle.USER_ALL 7514 || userHandle == UserHandle.getUserId(targetUid)) { 7515 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7516 final UriPermission perm = it.next(); 7517 7518 // Only inspect grants matching package 7519 if (packageName == null || perm.sourcePkg.equals(packageName) 7520 || perm.targetPkg.equals(packageName)) { 7521 persistChanged |= perm.revokeModes(persistable 7522 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7523 7524 // Only remove when no modes remain; any persisted grants 7525 // will keep this alive. 7526 if (perm.modeFlags == 0) { 7527 it.remove(); 7528 } 7529 } 7530 } 7531 7532 if (perms.isEmpty()) { 7533 mGrantedUriPermissions.remove(targetUid); 7534 N--; 7535 i--; 7536 } 7537 } 7538 } 7539 7540 if (persistChanged) { 7541 schedulePersistUriGrants(); 7542 } 7543 } 7544 7545 @Override 7546 public IBinder newUriPermissionOwner(String name) { 7547 enforceNotIsolatedCaller("newUriPermissionOwner"); 7548 synchronized(this) { 7549 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7550 return owner.getExternalTokenLocked(); 7551 } 7552 } 7553 7554 /** 7555 * @param uri This uri must NOT contain an embedded userId. 7556 * @param sourceUserId The userId in which the uri is to be resolved. 7557 * @param targetUserId The userId of the app that receives the grant. 7558 */ 7559 @Override 7560 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7561 final int modeFlags, int sourceUserId, int targetUserId) { 7562 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7563 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7564 synchronized(this) { 7565 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7566 if (owner == null) { 7567 throw new IllegalArgumentException("Unknown owner: " + token); 7568 } 7569 if (fromUid != Binder.getCallingUid()) { 7570 if (Binder.getCallingUid() != Process.myUid()) { 7571 // Only system code can grant URI permissions on behalf 7572 // of other users. 7573 throw new SecurityException("nice try"); 7574 } 7575 } 7576 if (targetPkg == null) { 7577 throw new IllegalArgumentException("null target"); 7578 } 7579 if (uri == null) { 7580 throw new IllegalArgumentException("null uri"); 7581 } 7582 7583 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7584 modeFlags, owner, targetUserId); 7585 } 7586 } 7587 7588 /** 7589 * @param uri This uri must NOT contain an embedded userId. 7590 * @param userId The userId in which the uri is to be resolved. 7591 */ 7592 @Override 7593 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7594 synchronized(this) { 7595 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7596 if (owner == null) { 7597 throw new IllegalArgumentException("Unknown owner: " + token); 7598 } 7599 7600 if (uri == null) { 7601 owner.removeUriPermissionsLocked(mode); 7602 } else { 7603 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7604 } 7605 } 7606 } 7607 7608 private void schedulePersistUriGrants() { 7609 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7610 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7611 10 * DateUtils.SECOND_IN_MILLIS); 7612 } 7613 } 7614 7615 private void writeGrantedUriPermissions() { 7616 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7617 7618 // Snapshot permissions so we can persist without lock 7619 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7620 synchronized (this) { 7621 final int size = mGrantedUriPermissions.size(); 7622 for (int i = 0; i < size; i++) { 7623 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7624 for (UriPermission perm : perms.values()) { 7625 if (perm.persistedModeFlags != 0) { 7626 persist.add(perm.snapshot()); 7627 } 7628 } 7629 } 7630 } 7631 7632 FileOutputStream fos = null; 7633 try { 7634 fos = mGrantFile.startWrite(); 7635 7636 XmlSerializer out = new FastXmlSerializer(); 7637 out.setOutput(fos, "utf-8"); 7638 out.startDocument(null, true); 7639 out.startTag(null, TAG_URI_GRANTS); 7640 for (UriPermission.Snapshot perm : persist) { 7641 out.startTag(null, TAG_URI_GRANT); 7642 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7643 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7644 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7645 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7646 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7647 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7648 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7649 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7650 out.endTag(null, TAG_URI_GRANT); 7651 } 7652 out.endTag(null, TAG_URI_GRANTS); 7653 out.endDocument(); 7654 7655 mGrantFile.finishWrite(fos); 7656 } catch (IOException e) { 7657 if (fos != null) { 7658 mGrantFile.failWrite(fos); 7659 } 7660 } 7661 } 7662 7663 private void readGrantedUriPermissionsLocked() { 7664 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7665 7666 final long now = System.currentTimeMillis(); 7667 7668 FileInputStream fis = null; 7669 try { 7670 fis = mGrantFile.openRead(); 7671 final XmlPullParser in = Xml.newPullParser(); 7672 in.setInput(fis, null); 7673 7674 int type; 7675 while ((type = in.next()) != END_DOCUMENT) { 7676 final String tag = in.getName(); 7677 if (type == START_TAG) { 7678 if (TAG_URI_GRANT.equals(tag)) { 7679 final int sourceUserId; 7680 final int targetUserId; 7681 final int userHandle = readIntAttribute(in, 7682 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7683 if (userHandle != UserHandle.USER_NULL) { 7684 // For backwards compatibility. 7685 sourceUserId = userHandle; 7686 targetUserId = userHandle; 7687 } else { 7688 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7689 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7690 } 7691 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7692 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7693 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7694 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7695 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7696 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7697 7698 // Sanity check that provider still belongs to source package 7699 final ProviderInfo pi = getProviderInfoLocked( 7700 uri.getAuthority(), sourceUserId); 7701 if (pi != null && sourcePkg.equals(pi.packageName)) { 7702 int targetUid = -1; 7703 try { 7704 targetUid = AppGlobals.getPackageManager() 7705 .getPackageUid(targetPkg, targetUserId); 7706 } catch (RemoteException e) { 7707 } 7708 if (targetUid != -1) { 7709 final UriPermission perm = findOrCreateUriPermissionLocked( 7710 sourcePkg, targetPkg, targetUid, 7711 new GrantUri(sourceUserId, uri, prefix)); 7712 perm.initPersistedModes(modeFlags, createdTime); 7713 } 7714 } else { 7715 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7716 + " but instead found " + pi); 7717 } 7718 } 7719 } 7720 } 7721 } catch (FileNotFoundException e) { 7722 // Missing grants is okay 7723 } catch (IOException e) { 7724 Slog.wtf(TAG, "Failed reading Uri grants", e); 7725 } catch (XmlPullParserException e) { 7726 Slog.wtf(TAG, "Failed reading Uri grants", e); 7727 } finally { 7728 IoUtils.closeQuietly(fis); 7729 } 7730 } 7731 7732 /** 7733 * @param uri This uri must NOT contain an embedded userId. 7734 * @param userId The userId in which the uri is to be resolved. 7735 */ 7736 @Override 7737 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7738 enforceNotIsolatedCaller("takePersistableUriPermission"); 7739 7740 Preconditions.checkFlagsArgument(modeFlags, 7741 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7742 7743 synchronized (this) { 7744 final int callingUid = Binder.getCallingUid(); 7745 boolean persistChanged = false; 7746 GrantUri grantUri = new GrantUri(userId, uri, false); 7747 7748 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7749 new GrantUri(userId, uri, false)); 7750 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7751 new GrantUri(userId, uri, true)); 7752 7753 final boolean exactValid = (exactPerm != null) 7754 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7755 final boolean prefixValid = (prefixPerm != null) 7756 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7757 7758 if (!(exactValid || prefixValid)) { 7759 throw new SecurityException("No persistable permission grants found for UID " 7760 + callingUid + " and Uri " + grantUri.toSafeString()); 7761 } 7762 7763 if (exactValid) { 7764 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7765 } 7766 if (prefixValid) { 7767 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7768 } 7769 7770 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7771 7772 if (persistChanged) { 7773 schedulePersistUriGrants(); 7774 } 7775 } 7776 } 7777 7778 /** 7779 * @param uri This uri must NOT contain an embedded userId. 7780 * @param userId The userId in which the uri is to be resolved. 7781 */ 7782 @Override 7783 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7784 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7785 7786 Preconditions.checkFlagsArgument(modeFlags, 7787 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7788 7789 synchronized (this) { 7790 final int callingUid = Binder.getCallingUid(); 7791 boolean persistChanged = false; 7792 7793 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7794 new GrantUri(userId, uri, false)); 7795 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7796 new GrantUri(userId, uri, true)); 7797 if (exactPerm == null && prefixPerm == null) { 7798 throw new SecurityException("No permission grants found for UID " + callingUid 7799 + " and Uri " + uri.toSafeString()); 7800 } 7801 7802 if (exactPerm != null) { 7803 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7804 removeUriPermissionIfNeededLocked(exactPerm); 7805 } 7806 if (prefixPerm != null) { 7807 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7808 removeUriPermissionIfNeededLocked(prefixPerm); 7809 } 7810 7811 if (persistChanged) { 7812 schedulePersistUriGrants(); 7813 } 7814 } 7815 } 7816 7817 /** 7818 * Prune any older {@link UriPermission} for the given UID until outstanding 7819 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7820 * 7821 * @return if any mutations occured that require persisting. 7822 */ 7823 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7824 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7825 if (perms == null) return false; 7826 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7827 7828 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7829 for (UriPermission perm : perms.values()) { 7830 if (perm.persistedModeFlags != 0) { 7831 persisted.add(perm); 7832 } 7833 } 7834 7835 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7836 if (trimCount <= 0) return false; 7837 7838 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7839 for (int i = 0; i < trimCount; i++) { 7840 final UriPermission perm = persisted.get(i); 7841 7842 if (DEBUG_URI_PERMISSION) { 7843 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7844 } 7845 7846 perm.releasePersistableModes(~0); 7847 removeUriPermissionIfNeededLocked(perm); 7848 } 7849 7850 return true; 7851 } 7852 7853 @Override 7854 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7855 String packageName, boolean incoming) { 7856 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7857 Preconditions.checkNotNull(packageName, "packageName"); 7858 7859 final int callingUid = Binder.getCallingUid(); 7860 final IPackageManager pm = AppGlobals.getPackageManager(); 7861 try { 7862 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7863 if (packageUid != callingUid) { 7864 throw new SecurityException( 7865 "Package " + packageName + " does not belong to calling UID " + callingUid); 7866 } 7867 } catch (RemoteException e) { 7868 throw new SecurityException("Failed to verify package name ownership"); 7869 } 7870 7871 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7872 synchronized (this) { 7873 if (incoming) { 7874 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7875 callingUid); 7876 if (perms == null) { 7877 Slog.w(TAG, "No permission grants found for " + packageName); 7878 } else { 7879 for (UriPermission perm : perms.values()) { 7880 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7881 result.add(perm.buildPersistedPublicApiObject()); 7882 } 7883 } 7884 } 7885 } else { 7886 final int size = mGrantedUriPermissions.size(); 7887 for (int i = 0; i < size; i++) { 7888 final ArrayMap<GrantUri, UriPermission> perms = 7889 mGrantedUriPermissions.valueAt(i); 7890 for (UriPermission perm : perms.values()) { 7891 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7892 result.add(perm.buildPersistedPublicApiObject()); 7893 } 7894 } 7895 } 7896 } 7897 } 7898 return new ParceledListSlice<android.content.UriPermission>(result); 7899 } 7900 7901 @Override 7902 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7903 synchronized (this) { 7904 ProcessRecord app = 7905 who != null ? getRecordForAppLocked(who) : null; 7906 if (app == null) return; 7907 7908 Message msg = Message.obtain(); 7909 msg.what = WAIT_FOR_DEBUGGER_MSG; 7910 msg.obj = app; 7911 msg.arg1 = waiting ? 1 : 0; 7912 mHandler.sendMessage(msg); 7913 } 7914 } 7915 7916 @Override 7917 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7918 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7919 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7920 outInfo.availMem = Process.getFreeMemory(); 7921 outInfo.totalMem = Process.getTotalMemory(); 7922 outInfo.threshold = homeAppMem; 7923 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7924 outInfo.hiddenAppThreshold = cachedAppMem; 7925 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7926 ProcessList.SERVICE_ADJ); 7927 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7928 ProcessList.VISIBLE_APP_ADJ); 7929 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7930 ProcessList.FOREGROUND_APP_ADJ); 7931 } 7932 7933 // ========================================================= 7934 // TASK MANAGEMENT 7935 // ========================================================= 7936 7937 @Override 7938 public List<IAppTask> getAppTasks(String callingPackage) { 7939 int callingUid = Binder.getCallingUid(); 7940 long ident = Binder.clearCallingIdentity(); 7941 7942 synchronized(this) { 7943 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7944 try { 7945 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7946 7947 final int N = mRecentTasks.size(); 7948 for (int i = 0; i < N; i++) { 7949 TaskRecord tr = mRecentTasks.get(i); 7950 // Skip tasks that do not match the caller. We don't need to verify 7951 // callingPackage, because we are also limiting to callingUid and know 7952 // that will limit to the correct security sandbox. 7953 if (tr.effectiveUid != callingUid) { 7954 continue; 7955 } 7956 Intent intent = tr.getBaseIntent(); 7957 if (intent == null || 7958 !callingPackage.equals(intent.getComponent().getPackageName())) { 7959 continue; 7960 } 7961 ActivityManager.RecentTaskInfo taskInfo = 7962 createRecentTaskInfoFromTaskRecord(tr); 7963 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7964 list.add(taskImpl); 7965 } 7966 } finally { 7967 Binder.restoreCallingIdentity(ident); 7968 } 7969 return list; 7970 } 7971 } 7972 7973 @Override 7974 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7975 final int callingUid = Binder.getCallingUid(); 7976 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7977 7978 synchronized(this) { 7979 if (localLOGV) Slog.v( 7980 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7981 7982 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 7983 callingUid); 7984 7985 // TODO: Improve with MRU list from all ActivityStacks. 7986 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7987 } 7988 7989 return list; 7990 } 7991 7992 TaskRecord getMostRecentTask() { 7993 return mRecentTasks.get(0); 7994 } 7995 7996 /** 7997 * Creates a new RecentTaskInfo from a TaskRecord. 7998 */ 7999 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8000 // Update the task description to reflect any changes in the task stack 8001 tr.updateTaskDescription(); 8002 8003 // Compose the recent task info 8004 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8005 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8006 rti.persistentId = tr.taskId; 8007 rti.baseIntent = new Intent(tr.getBaseIntent()); 8008 rti.origActivity = tr.origActivity; 8009 rti.description = tr.lastDescription; 8010 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8011 rti.userId = tr.userId; 8012 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8013 rti.firstActiveTime = tr.firstActiveTime; 8014 rti.lastActiveTime = tr.lastActiveTime; 8015 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8016 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8017 return rti; 8018 } 8019 8020 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8021 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8022 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8023 if (!allowed) { 8024 if (checkPermission(android.Manifest.permission.GET_TASKS, 8025 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8026 // Temporary compatibility: some existing apps on the system image may 8027 // still be requesting the old permission and not switched to the new 8028 // one; if so, we'll still allow them full access. This means we need 8029 // to see if they are holding the old permission and are a system app. 8030 try { 8031 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8032 allowed = true; 8033 Slog.w(TAG, caller + ": caller " + callingUid 8034 + " is using old GET_TASKS but privileged; allowing"); 8035 } 8036 } catch (RemoteException e) { 8037 } 8038 } 8039 } 8040 if (!allowed) { 8041 Slog.w(TAG, caller + ": caller " + callingUid 8042 + " does not hold GET_TASKS; limiting output"); 8043 } 8044 return allowed; 8045 } 8046 8047 @Override 8048 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8049 final int callingUid = Binder.getCallingUid(); 8050 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8051 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8052 8053 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8054 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8055 synchronized (this) { 8056 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8057 callingUid); 8058 final boolean detailed = checkCallingPermission( 8059 android.Manifest.permission.GET_DETAILED_TASKS) 8060 == PackageManager.PERMISSION_GRANTED; 8061 8062 final int N = mRecentTasks.size(); 8063 ArrayList<ActivityManager.RecentTaskInfo> res 8064 = new ArrayList<ActivityManager.RecentTaskInfo>( 8065 maxNum < N ? maxNum : N); 8066 8067 final Set<Integer> includedUsers; 8068 if (includeProfiles) { 8069 includedUsers = getProfileIdsLocked(userId); 8070 } else { 8071 includedUsers = new HashSet<Integer>(); 8072 } 8073 includedUsers.add(Integer.valueOf(userId)); 8074 8075 for (int i=0; i<N && maxNum > 0; i++) { 8076 TaskRecord tr = mRecentTasks.get(i); 8077 // Only add calling user or related users recent tasks 8078 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8079 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8080 continue; 8081 } 8082 8083 // Return the entry if desired by the caller. We always return 8084 // the first entry, because callers always expect this to be the 8085 // foreground app. We may filter others if the caller has 8086 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8087 // we should exclude the entry. 8088 8089 if (i == 0 8090 || withExcluded 8091 || (tr.intent == null) 8092 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8093 == 0)) { 8094 if (!allowed) { 8095 // If the caller doesn't have the GET_TASKS permission, then only 8096 // allow them to see a small subset of tasks -- their own and home. 8097 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8098 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8099 continue; 8100 } 8101 } 8102 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8103 if (tr.stack != null && tr.stack.isHomeStack()) { 8104 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8105 continue; 8106 } 8107 } 8108 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8109 // Don't include auto remove tasks that are finished or finishing. 8110 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8111 + tr); 8112 continue; 8113 } 8114 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8115 && !tr.isAvailable) { 8116 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8117 continue; 8118 } 8119 8120 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8121 if (!detailed) { 8122 rti.baseIntent.replaceExtras((Bundle)null); 8123 } 8124 8125 res.add(rti); 8126 maxNum--; 8127 } 8128 } 8129 return res; 8130 } 8131 } 8132 8133 private TaskRecord taskForIdLocked(int id) { 8134 final TaskRecord task = recentTaskForIdLocked(id); 8135 if (task != null) { 8136 return task; 8137 } 8138 8139 // Don't give up. Sometimes it just hasn't made it to recents yet. 8140 return mStackSupervisor.anyTaskForIdLocked(id); 8141 } 8142 8143 private TaskRecord recentTaskForIdLocked(int id) { 8144 final int N = mRecentTasks.size(); 8145 for (int i=0; i<N; i++) { 8146 TaskRecord tr = mRecentTasks.get(i); 8147 if (tr.taskId == id) { 8148 return tr; 8149 } 8150 } 8151 return null; 8152 } 8153 8154 @Override 8155 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8156 synchronized (this) { 8157 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8158 "getTaskThumbnail()"); 8159 TaskRecord tr = recentTaskForIdLocked(id); 8160 if (tr != null) { 8161 return tr.getTaskThumbnailLocked(); 8162 } 8163 } 8164 return null; 8165 } 8166 8167 @Override 8168 public int addAppTask(IBinder activityToken, Intent intent, 8169 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8170 final int callingUid = Binder.getCallingUid(); 8171 final long callingIdent = Binder.clearCallingIdentity(); 8172 8173 try { 8174 synchronized (this) { 8175 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8176 if (r == null) { 8177 throw new IllegalArgumentException("Activity does not exist; token=" 8178 + activityToken); 8179 } 8180 ComponentName comp = intent.getComponent(); 8181 if (comp == null) { 8182 throw new IllegalArgumentException("Intent " + intent 8183 + " must specify explicit component"); 8184 } 8185 if (thumbnail.getWidth() != mThumbnailWidth 8186 || thumbnail.getHeight() != mThumbnailHeight) { 8187 throw new IllegalArgumentException("Bad thumbnail size: got " 8188 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8189 + mThumbnailWidth + "x" + mThumbnailHeight); 8190 } 8191 if (intent.getSelector() != null) { 8192 intent.setSelector(null); 8193 } 8194 if (intent.getSourceBounds() != null) { 8195 intent.setSourceBounds(null); 8196 } 8197 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8198 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8199 // The caller has added this as an auto-remove task... that makes no 8200 // sense, so turn off auto-remove. 8201 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8202 } 8203 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8204 // Must be a new task. 8205 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8206 } 8207 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8208 mLastAddedTaskActivity = null; 8209 } 8210 ActivityInfo ainfo = mLastAddedTaskActivity; 8211 if (ainfo == null) { 8212 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8213 comp, 0, UserHandle.getUserId(callingUid)); 8214 if (ainfo.applicationInfo.uid != callingUid) { 8215 throw new SecurityException( 8216 "Can't add task for another application: target uid=" 8217 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8218 } 8219 } 8220 8221 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8222 intent, description); 8223 8224 int trimIdx = trimRecentsForTask(task, false); 8225 if (trimIdx >= 0) { 8226 // If this would have caused a trim, then we'll abort because that 8227 // means it would be added at the end of the list but then just removed. 8228 return -1; 8229 } 8230 8231 final int N = mRecentTasks.size(); 8232 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8233 final TaskRecord tr = mRecentTasks.remove(N - 1); 8234 tr.removedFromRecents(mTaskPersister); 8235 } 8236 8237 task.inRecents = true; 8238 mRecentTasks.add(task); 8239 r.task.stack.addTask(task, false, false); 8240 8241 task.setLastThumbnail(thumbnail); 8242 task.freeLastThumbnail(); 8243 8244 return task.taskId; 8245 } 8246 } finally { 8247 Binder.restoreCallingIdentity(callingIdent); 8248 } 8249 } 8250 8251 @Override 8252 public Point getAppTaskThumbnailSize() { 8253 synchronized (this) { 8254 return new Point(mThumbnailWidth, mThumbnailHeight); 8255 } 8256 } 8257 8258 @Override 8259 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8260 synchronized (this) { 8261 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8262 if (r != null) { 8263 r.setTaskDescription(td); 8264 r.task.updateTaskDescription(); 8265 } 8266 } 8267 } 8268 8269 @Override 8270 public Bitmap getTaskDescriptionIcon(String filename) { 8271 if (!FileUtils.isValidExtFilename(filename) 8272 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8273 throw new IllegalArgumentException("Bad filename: " + filename); 8274 } 8275 return mTaskPersister.getTaskDescriptionIcon(filename); 8276 } 8277 8278 @Override 8279 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8280 throws RemoteException { 8281 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8282 opts.getCustomInPlaceResId() == 0) { 8283 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8284 "with valid animation"); 8285 } 8286 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8287 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8288 opts.getCustomInPlaceResId()); 8289 mWindowManager.executeAppTransition(); 8290 } 8291 8292 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8293 mRecentTasks.remove(tr); 8294 tr.removedFromRecents(mTaskPersister); 8295 ComponentName component = tr.getBaseIntent().getComponent(); 8296 if (component == null) { 8297 Slog.w(TAG, "No component for base intent of task: " + tr); 8298 return; 8299 } 8300 8301 if (!killProcess) { 8302 return; 8303 } 8304 8305 // Determine if the process(es) for this task should be killed. 8306 final String pkg = component.getPackageName(); 8307 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8308 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8309 for (int i = 0; i < pmap.size(); i++) { 8310 8311 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8312 for (int j = 0; j < uids.size(); j++) { 8313 ProcessRecord proc = uids.valueAt(j); 8314 if (proc.userId != tr.userId) { 8315 // Don't kill process for a different user. 8316 continue; 8317 } 8318 if (proc == mHomeProcess) { 8319 // Don't kill the home process along with tasks from the same package. 8320 continue; 8321 } 8322 if (!proc.pkgList.containsKey(pkg)) { 8323 // Don't kill process that is not associated with this task. 8324 continue; 8325 } 8326 8327 for (int k = 0; k < proc.activities.size(); k++) { 8328 TaskRecord otherTask = proc.activities.get(k).task; 8329 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8330 // Don't kill process(es) that has an activity in a different task that is 8331 // also in recents. 8332 return; 8333 } 8334 } 8335 8336 // Add process to kill list. 8337 procsToKill.add(proc); 8338 } 8339 } 8340 8341 // Find any running services associated with this app and stop if needed. 8342 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8343 8344 // Kill the running processes. 8345 for (int i = 0; i < procsToKill.size(); i++) { 8346 ProcessRecord pr = procsToKill.get(i); 8347 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8348 pr.kill("remove task", true); 8349 } else { 8350 pr.waitingToKill = "remove task"; 8351 } 8352 } 8353 } 8354 8355 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8356 // Remove all tasks with activities in the specified package from the list of recent tasks 8357 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8358 TaskRecord tr = mRecentTasks.get(i); 8359 if (tr.userId != userId) continue; 8360 8361 ComponentName cn = tr.intent.getComponent(); 8362 if (cn != null && cn.getPackageName().equals(packageName)) { 8363 // If the package name matches, remove the task. 8364 removeTaskByIdLocked(tr.taskId, true); 8365 } 8366 } 8367 } 8368 8369 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8370 final IPackageManager pm = AppGlobals.getPackageManager(); 8371 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8372 8373 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8374 TaskRecord tr = mRecentTasks.get(i); 8375 if (tr.userId != userId) continue; 8376 8377 ComponentName cn = tr.intent.getComponent(); 8378 if (cn != null && cn.getPackageName().equals(packageName)) { 8379 // Skip if component still exists in the package. 8380 if (componentsKnownToExist.contains(cn)) continue; 8381 8382 try { 8383 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8384 if (info != null) { 8385 componentsKnownToExist.add(cn); 8386 } else { 8387 removeTaskByIdLocked(tr.taskId, false); 8388 } 8389 } catch (RemoteException e) { 8390 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8391 } 8392 } 8393 } 8394 } 8395 8396 /** 8397 * Removes the task with the specified task id. 8398 * 8399 * @param taskId Identifier of the task to be removed. 8400 * @param killProcess Kill any process associated with the task if possible. 8401 * @return Returns true if the given task was found and removed. 8402 */ 8403 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8404 TaskRecord tr = taskForIdLocked(taskId); 8405 if (tr != null) { 8406 tr.removeTaskActivitiesLocked(); 8407 cleanUpRemovedTaskLocked(tr, killProcess); 8408 if (tr.isPersistable) { 8409 notifyTaskPersisterLocked(null, true); 8410 } 8411 return true; 8412 } 8413 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8414 return false; 8415 } 8416 8417 @Override 8418 public boolean removeTask(int taskId) { 8419 synchronized (this) { 8420 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8421 "removeTask()"); 8422 long ident = Binder.clearCallingIdentity(); 8423 try { 8424 return removeTaskByIdLocked(taskId, true); 8425 } finally { 8426 Binder.restoreCallingIdentity(ident); 8427 } 8428 } 8429 } 8430 8431 /** 8432 * TODO: Add mController hook 8433 */ 8434 @Override 8435 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8436 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8437 "moveTaskToFront()"); 8438 8439 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8440 synchronized(this) { 8441 moveTaskToFrontLocked(taskId, flags, options); 8442 } 8443 } 8444 8445 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8446 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8447 Binder.getCallingUid(), -1, -1, "Task to front")) { 8448 ActivityOptions.abort(options); 8449 return; 8450 } 8451 final long origId = Binder.clearCallingIdentity(); 8452 try { 8453 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8454 if (task == null) { 8455 Slog.d(TAG, "Could not find task for id: "+ taskId); 8456 return; 8457 } 8458 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8459 mStackSupervisor.showLockTaskToast(); 8460 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8461 return; 8462 } 8463 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8464 if (prev != null && prev.isRecentsActivity()) { 8465 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8466 } 8467 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8468 } finally { 8469 Binder.restoreCallingIdentity(origId); 8470 } 8471 ActivityOptions.abort(options); 8472 } 8473 8474 @Override 8475 public void moveTaskToBack(int taskId) { 8476 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8477 "moveTaskToBack()"); 8478 8479 synchronized(this) { 8480 TaskRecord tr = taskForIdLocked(taskId); 8481 if (tr != null) { 8482 if (tr == mStackSupervisor.mLockTaskModeTask) { 8483 mStackSupervisor.showLockTaskToast(); 8484 return; 8485 } 8486 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8487 ActivityStack stack = tr.stack; 8488 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8489 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8490 Binder.getCallingUid(), -1, -1, "Task to back")) { 8491 return; 8492 } 8493 } 8494 final long origId = Binder.clearCallingIdentity(); 8495 try { 8496 stack.moveTaskToBackLocked(taskId, null); 8497 } finally { 8498 Binder.restoreCallingIdentity(origId); 8499 } 8500 } 8501 } 8502 } 8503 8504 /** 8505 * Moves an activity, and all of the other activities within the same task, to the bottom 8506 * of the history stack. The activity's order within the task is unchanged. 8507 * 8508 * @param token A reference to the activity we wish to move 8509 * @param nonRoot If false then this only works if the activity is the root 8510 * of a task; if true it will work for any activity in a task. 8511 * @return Returns true if the move completed, false if not. 8512 */ 8513 @Override 8514 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8515 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8516 synchronized(this) { 8517 final long origId = Binder.clearCallingIdentity(); 8518 try { 8519 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8520 if (taskId >= 0) { 8521 if ((mStackSupervisor.mLockTaskModeTask != null) 8522 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8523 mStackSupervisor.showLockTaskToast(); 8524 return false; 8525 } 8526 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8527 } 8528 } finally { 8529 Binder.restoreCallingIdentity(origId); 8530 } 8531 } 8532 return false; 8533 } 8534 8535 @Override 8536 public void moveTaskBackwards(int task) { 8537 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8538 "moveTaskBackwards()"); 8539 8540 synchronized(this) { 8541 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8542 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8543 return; 8544 } 8545 final long origId = Binder.clearCallingIdentity(); 8546 moveTaskBackwardsLocked(task); 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 } 8550 8551 private final void moveTaskBackwardsLocked(int task) { 8552 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8553 } 8554 8555 @Override 8556 public IBinder getHomeActivityToken() throws RemoteException { 8557 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8558 "getHomeActivityToken()"); 8559 synchronized (this) { 8560 return mStackSupervisor.getHomeActivityToken(); 8561 } 8562 } 8563 8564 @Override 8565 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8566 IActivityContainerCallback callback) throws RemoteException { 8567 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8568 "createActivityContainer()"); 8569 synchronized (this) { 8570 if (parentActivityToken == null) { 8571 throw new IllegalArgumentException("parent token must not be null"); 8572 } 8573 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8574 if (r == null) { 8575 return null; 8576 } 8577 if (callback == null) { 8578 throw new IllegalArgumentException("callback must not be null"); 8579 } 8580 return mStackSupervisor.createActivityContainer(r, callback); 8581 } 8582 } 8583 8584 @Override 8585 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8586 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8587 "deleteActivityContainer()"); 8588 synchronized (this) { 8589 mStackSupervisor.deleteActivityContainer(container); 8590 } 8591 } 8592 8593 @Override 8594 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8595 throws RemoteException { 8596 synchronized (this) { 8597 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8598 if (stack != null) { 8599 return stack.mActivityContainer; 8600 } 8601 return null; 8602 } 8603 } 8604 8605 @Override 8606 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8607 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8608 "moveTaskToStack()"); 8609 if (stackId == HOME_STACK_ID) { 8610 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8611 new RuntimeException("here").fillInStackTrace()); 8612 } 8613 synchronized (this) { 8614 long ident = Binder.clearCallingIdentity(); 8615 try { 8616 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8617 + stackId + " toTop=" + toTop); 8618 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8619 } finally { 8620 Binder.restoreCallingIdentity(ident); 8621 } 8622 } 8623 } 8624 8625 @Override 8626 public void resizeStack(int stackBoxId, Rect bounds) { 8627 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8628 "resizeStackBox()"); 8629 long ident = Binder.clearCallingIdentity(); 8630 try { 8631 mWindowManager.resizeStack(stackBoxId, bounds); 8632 } finally { 8633 Binder.restoreCallingIdentity(ident); 8634 } 8635 } 8636 8637 @Override 8638 public List<StackInfo> getAllStackInfos() { 8639 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8640 "getAllStackInfos()"); 8641 long ident = Binder.clearCallingIdentity(); 8642 try { 8643 synchronized (this) { 8644 return mStackSupervisor.getAllStackInfosLocked(); 8645 } 8646 } finally { 8647 Binder.restoreCallingIdentity(ident); 8648 } 8649 } 8650 8651 @Override 8652 public StackInfo getStackInfo(int stackId) { 8653 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8654 "getStackInfo()"); 8655 long ident = Binder.clearCallingIdentity(); 8656 try { 8657 synchronized (this) { 8658 return mStackSupervisor.getStackInfoLocked(stackId); 8659 } 8660 } finally { 8661 Binder.restoreCallingIdentity(ident); 8662 } 8663 } 8664 8665 @Override 8666 public boolean isInHomeStack(int taskId) { 8667 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8668 "getStackInfo()"); 8669 long ident = Binder.clearCallingIdentity(); 8670 try { 8671 synchronized (this) { 8672 TaskRecord tr = taskForIdLocked(taskId); 8673 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8674 } 8675 } finally { 8676 Binder.restoreCallingIdentity(ident); 8677 } 8678 } 8679 8680 @Override 8681 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8682 synchronized(this) { 8683 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8684 } 8685 } 8686 8687 private boolean isLockTaskAuthorized(String pkg) { 8688 final DevicePolicyManager dpm = (DevicePolicyManager) 8689 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8690 try { 8691 int uid = mContext.getPackageManager().getPackageUid(pkg, 8692 Binder.getCallingUserHandle().getIdentifier()); 8693 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8694 } catch (NameNotFoundException e) { 8695 return false; 8696 } 8697 } 8698 8699 void startLockTaskMode(TaskRecord task) { 8700 final String pkg; 8701 synchronized (this) { 8702 pkg = task.intent.getComponent().getPackageName(); 8703 } 8704 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8705 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8706 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8707 StatusBarManagerInternal.class); 8708 if (statusBarManager != null) { 8709 statusBarManager.showScreenPinningRequest(); 8710 } 8711 return; 8712 } 8713 long ident = Binder.clearCallingIdentity(); 8714 try { 8715 synchronized (this) { 8716 // Since we lost lock on task, make sure it is still there. 8717 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8718 if (task != null) { 8719 if (!isSystemInitiated 8720 && ((mStackSupervisor.getFocusedStack() == null) 8721 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8722 throw new IllegalArgumentException("Invalid task, not in foreground"); 8723 } 8724 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8725 } 8726 } 8727 } finally { 8728 Binder.restoreCallingIdentity(ident); 8729 } 8730 } 8731 8732 @Override 8733 public void startLockTaskMode(int taskId) { 8734 final TaskRecord task; 8735 long ident = Binder.clearCallingIdentity(); 8736 try { 8737 synchronized (this) { 8738 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8739 } 8740 } finally { 8741 Binder.restoreCallingIdentity(ident); 8742 } 8743 if (task != null) { 8744 startLockTaskMode(task); 8745 } 8746 } 8747 8748 @Override 8749 public void startLockTaskMode(IBinder token) { 8750 final TaskRecord task; 8751 long ident = Binder.clearCallingIdentity(); 8752 try { 8753 synchronized (this) { 8754 final ActivityRecord r = ActivityRecord.forToken(token); 8755 if (r == null) { 8756 return; 8757 } 8758 task = r.task; 8759 } 8760 } finally { 8761 Binder.restoreCallingIdentity(ident); 8762 } 8763 if (task != null) { 8764 startLockTaskMode(task); 8765 } 8766 } 8767 8768 @Override 8769 public void startLockTaskModeOnCurrent() throws RemoteException { 8770 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8771 "startLockTaskModeOnCurrent"); 8772 long ident = Binder.clearCallingIdentity(); 8773 try { 8774 ActivityRecord r = null; 8775 synchronized (this) { 8776 r = mStackSupervisor.topRunningActivityLocked(); 8777 } 8778 startLockTaskMode(r.task); 8779 } finally { 8780 Binder.restoreCallingIdentity(ident); 8781 } 8782 } 8783 8784 @Override 8785 public void stopLockTaskMode() { 8786 // Verify that the user matches the package of the intent for the TaskRecord 8787 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8788 // and stopLockTaskMode. 8789 final int callingUid = Binder.getCallingUid(); 8790 if (callingUid != Process.SYSTEM_UID) { 8791 try { 8792 String pkg = 8793 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8794 int uid = mContext.getPackageManager().getPackageUid(pkg, 8795 Binder.getCallingUserHandle().getIdentifier()); 8796 if (uid != callingUid) { 8797 throw new SecurityException("Invalid uid, expected " + uid); 8798 } 8799 } catch (NameNotFoundException e) { 8800 Log.d(TAG, "stopLockTaskMode " + e); 8801 return; 8802 } 8803 } 8804 long ident = Binder.clearCallingIdentity(); 8805 try { 8806 Log.d(TAG, "stopLockTaskMode"); 8807 // Stop lock task 8808 synchronized (this) { 8809 mStackSupervisor.setLockTaskModeLocked(null, false); 8810 } 8811 } finally { 8812 Binder.restoreCallingIdentity(ident); 8813 } 8814 } 8815 8816 @Override 8817 public void stopLockTaskModeOnCurrent() throws RemoteException { 8818 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8819 "stopLockTaskModeOnCurrent"); 8820 long ident = Binder.clearCallingIdentity(); 8821 try { 8822 stopLockTaskMode(); 8823 } finally { 8824 Binder.restoreCallingIdentity(ident); 8825 } 8826 } 8827 8828 @Override 8829 public boolean isInLockTaskMode() { 8830 synchronized (this) { 8831 return mStackSupervisor.isInLockTaskMode(); 8832 } 8833 } 8834 8835 // ========================================================= 8836 // CONTENT PROVIDERS 8837 // ========================================================= 8838 8839 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8840 List<ProviderInfo> providers = null; 8841 try { 8842 providers = AppGlobals.getPackageManager(). 8843 queryContentProviders(app.processName, app.uid, 8844 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8845 } catch (RemoteException ex) { 8846 } 8847 if (DEBUG_MU) 8848 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8849 int userId = app.userId; 8850 if (providers != null) { 8851 int N = providers.size(); 8852 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8853 for (int i=0; i<N; i++) { 8854 ProviderInfo cpi = 8855 (ProviderInfo)providers.get(i); 8856 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8857 cpi.name, cpi.flags); 8858 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8859 // This is a singleton provider, but a user besides the 8860 // default user is asking to initialize a process it runs 8861 // in... well, no, it doesn't actually run in this process, 8862 // it runs in the process of the default user. Get rid of it. 8863 providers.remove(i); 8864 N--; 8865 i--; 8866 continue; 8867 } 8868 8869 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8870 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8871 if (cpr == null) { 8872 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8873 mProviderMap.putProviderByClass(comp, cpr); 8874 } 8875 if (DEBUG_MU) 8876 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8877 app.pubProviders.put(cpi.name, cpr); 8878 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8879 // Don't add this if it is a platform component that is marked 8880 // to run in multiple processes, because this is actually 8881 // part of the framework so doesn't make sense to track as a 8882 // separate apk in the process. 8883 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8884 mProcessStats); 8885 } 8886 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8887 } 8888 } 8889 return providers; 8890 } 8891 8892 /** 8893 * Check if {@link ProcessRecord} has a possible chance at accessing the 8894 * given {@link ProviderInfo}. Final permission checking is always done 8895 * in {@link ContentProvider}. 8896 */ 8897 private final String checkContentProviderPermissionLocked( 8898 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8899 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8900 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8901 boolean checkedGrants = false; 8902 if (checkUser) { 8903 // Looking for cross-user grants before enforcing the typical cross-users permissions 8904 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8905 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8906 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8907 return null; 8908 } 8909 checkedGrants = true; 8910 } 8911 userId = handleIncomingUser(callingPid, callingUid, userId, 8912 false, ALLOW_NON_FULL, 8913 "checkContentProviderPermissionLocked " + cpi.authority, null); 8914 if (userId != tmpTargetUserId) { 8915 // When we actually went to determine the final targer user ID, this ended 8916 // up different than our initial check for the authority. This is because 8917 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8918 // SELF. So we need to re-check the grants again. 8919 checkedGrants = false; 8920 } 8921 } 8922 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8923 cpi.applicationInfo.uid, cpi.exported) 8924 == PackageManager.PERMISSION_GRANTED) { 8925 return null; 8926 } 8927 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8928 cpi.applicationInfo.uid, cpi.exported) 8929 == PackageManager.PERMISSION_GRANTED) { 8930 return null; 8931 } 8932 8933 PathPermission[] pps = cpi.pathPermissions; 8934 if (pps != null) { 8935 int i = pps.length; 8936 while (i > 0) { 8937 i--; 8938 PathPermission pp = pps[i]; 8939 String pprperm = pp.getReadPermission(); 8940 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8941 cpi.applicationInfo.uid, cpi.exported) 8942 == PackageManager.PERMISSION_GRANTED) { 8943 return null; 8944 } 8945 String ppwperm = pp.getWritePermission(); 8946 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8947 cpi.applicationInfo.uid, cpi.exported) 8948 == PackageManager.PERMISSION_GRANTED) { 8949 return null; 8950 } 8951 } 8952 } 8953 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8954 return null; 8955 } 8956 8957 String msg; 8958 if (!cpi.exported) { 8959 msg = "Permission Denial: opening provider " + cpi.name 8960 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8961 + ", uid=" + callingUid + ") that is not exported from uid " 8962 + cpi.applicationInfo.uid; 8963 } else { 8964 msg = "Permission Denial: opening provider " + cpi.name 8965 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8966 + ", uid=" + callingUid + ") requires " 8967 + cpi.readPermission + " or " + cpi.writePermission; 8968 } 8969 Slog.w(TAG, msg); 8970 return msg; 8971 } 8972 8973 /** 8974 * Returns if the ContentProvider has granted a uri to callingUid 8975 */ 8976 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8977 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8978 if (perms != null) { 8979 for (int i=perms.size()-1; i>=0; i--) { 8980 GrantUri grantUri = perms.keyAt(i); 8981 if (grantUri.sourceUserId == userId || !checkUser) { 8982 if (matchesProvider(grantUri.uri, cpi)) { 8983 return true; 8984 } 8985 } 8986 } 8987 } 8988 return false; 8989 } 8990 8991 /** 8992 * Returns true if the uri authority is one of the authorities specified in the provider. 8993 */ 8994 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8995 String uriAuth = uri.getAuthority(); 8996 String cpiAuth = cpi.authority; 8997 if (cpiAuth.indexOf(';') == -1) { 8998 return cpiAuth.equals(uriAuth); 8999 } 9000 String[] cpiAuths = cpiAuth.split(";"); 9001 int length = cpiAuths.length; 9002 for (int i = 0; i < length; i++) { 9003 if (cpiAuths[i].equals(uriAuth)) return true; 9004 } 9005 return false; 9006 } 9007 9008 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9009 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9010 if (r != null) { 9011 for (int i=0; i<r.conProviders.size(); i++) { 9012 ContentProviderConnection conn = r.conProviders.get(i); 9013 if (conn.provider == cpr) { 9014 if (DEBUG_PROVIDER) Slog.v(TAG, 9015 "Adding provider requested by " 9016 + r.processName + " from process " 9017 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9018 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9019 if (stable) { 9020 conn.stableCount++; 9021 conn.numStableIncs++; 9022 } else { 9023 conn.unstableCount++; 9024 conn.numUnstableIncs++; 9025 } 9026 return conn; 9027 } 9028 } 9029 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9030 if (stable) { 9031 conn.stableCount = 1; 9032 conn.numStableIncs = 1; 9033 } else { 9034 conn.unstableCount = 1; 9035 conn.numUnstableIncs = 1; 9036 } 9037 cpr.connections.add(conn); 9038 r.conProviders.add(conn); 9039 return conn; 9040 } 9041 cpr.addExternalProcessHandleLocked(externalProcessToken); 9042 return null; 9043 } 9044 9045 boolean decProviderCountLocked(ContentProviderConnection conn, 9046 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9047 if (conn != null) { 9048 cpr = conn.provider; 9049 if (DEBUG_PROVIDER) Slog.v(TAG, 9050 "Removing provider requested by " 9051 + conn.client.processName + " from process " 9052 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9053 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9054 if (stable) { 9055 conn.stableCount--; 9056 } else { 9057 conn.unstableCount--; 9058 } 9059 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9060 cpr.connections.remove(conn); 9061 conn.client.conProviders.remove(conn); 9062 return true; 9063 } 9064 return false; 9065 } 9066 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9067 return false; 9068 } 9069 9070 private void checkTime(long startTime, String where) { 9071 long now = SystemClock.elapsedRealtime(); 9072 if ((now-startTime) > 1000) { 9073 // If we are taking more than a second, log about it. 9074 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9075 } 9076 } 9077 9078 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9079 String name, IBinder token, boolean stable, int userId) { 9080 ContentProviderRecord cpr; 9081 ContentProviderConnection conn = null; 9082 ProviderInfo cpi = null; 9083 9084 synchronized(this) { 9085 long startTime = SystemClock.elapsedRealtime(); 9086 9087 ProcessRecord r = null; 9088 if (caller != null) { 9089 r = getRecordForAppLocked(caller); 9090 if (r == null) { 9091 throw new SecurityException( 9092 "Unable to find app for caller " + caller 9093 + " (pid=" + Binder.getCallingPid() 9094 + ") when getting content provider " + name); 9095 } 9096 } 9097 9098 boolean checkCrossUser = true; 9099 9100 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9101 9102 // First check if this content provider has been published... 9103 cpr = mProviderMap.getProviderByName(name, userId); 9104 // If that didn't work, check if it exists for user 0 and then 9105 // verify that it's a singleton provider before using it. 9106 if (cpr == null && userId != UserHandle.USER_OWNER) { 9107 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9108 if (cpr != null) { 9109 cpi = cpr.info; 9110 if (isSingleton(cpi.processName, cpi.applicationInfo, 9111 cpi.name, cpi.flags) 9112 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9113 userId = UserHandle.USER_OWNER; 9114 checkCrossUser = false; 9115 } else { 9116 cpr = null; 9117 cpi = null; 9118 } 9119 } 9120 } 9121 9122 boolean providerRunning = cpr != null; 9123 if (providerRunning) { 9124 cpi = cpr.info; 9125 String msg; 9126 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9127 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9128 != null) { 9129 throw new SecurityException(msg); 9130 } 9131 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9132 9133 if (r != null && cpr.canRunHere(r)) { 9134 // This provider has been published or is in the process 9135 // of being published... but it is also allowed to run 9136 // in the caller's process, so don't make a connection 9137 // and just let the caller instantiate its own instance. 9138 ContentProviderHolder holder = cpr.newHolder(null); 9139 // don't give caller the provider object, it needs 9140 // to make its own. 9141 holder.provider = null; 9142 return holder; 9143 } 9144 9145 final long origId = Binder.clearCallingIdentity(); 9146 9147 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9148 9149 // In this case the provider instance already exists, so we can 9150 // return it right away. 9151 conn = incProviderCountLocked(r, cpr, token, stable); 9152 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9153 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9154 // If this is a perceptible app accessing the provider, 9155 // make sure to count it as being accessed and thus 9156 // back up on the LRU list. This is good because 9157 // content providers are often expensive to start. 9158 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9159 updateLruProcessLocked(cpr.proc, false, null); 9160 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9161 } 9162 } 9163 9164 if (cpr.proc != null) { 9165 if (false) { 9166 if (cpr.name.flattenToShortString().equals( 9167 "com.android.providers.calendar/.CalendarProvider2")) { 9168 Slog.v(TAG, "****************** KILLING " 9169 + cpr.name.flattenToShortString()); 9170 Process.killProcess(cpr.proc.pid); 9171 } 9172 } 9173 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9174 boolean success = updateOomAdjLocked(cpr.proc); 9175 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9176 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9177 // NOTE: there is still a race here where a signal could be 9178 // pending on the process even though we managed to update its 9179 // adj level. Not sure what to do about this, but at least 9180 // the race is now smaller. 9181 if (!success) { 9182 // Uh oh... it looks like the provider's process 9183 // has been killed on us. We need to wait for a new 9184 // process to be started, and make sure its death 9185 // doesn't kill our process. 9186 Slog.i(TAG, 9187 "Existing provider " + cpr.name.flattenToShortString() 9188 + " is crashing; detaching " + r); 9189 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9190 checkTime(startTime, "getContentProviderImpl: before appDied"); 9191 appDiedLocked(cpr.proc); 9192 checkTime(startTime, "getContentProviderImpl: after appDied"); 9193 if (!lastRef) { 9194 // This wasn't the last ref our process had on 9195 // the provider... we have now been killed, bail. 9196 return null; 9197 } 9198 providerRunning = false; 9199 conn = null; 9200 } 9201 } 9202 9203 Binder.restoreCallingIdentity(origId); 9204 } 9205 9206 boolean singleton; 9207 if (!providerRunning) { 9208 try { 9209 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9210 cpi = AppGlobals.getPackageManager(). 9211 resolveContentProvider(name, 9212 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9213 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9214 } catch (RemoteException ex) { 9215 } 9216 if (cpi == null) { 9217 return null; 9218 } 9219 // If the provider is a singleton AND 9220 // (it's a call within the same user || the provider is a 9221 // privileged app) 9222 // Then allow connecting to the singleton provider 9223 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9224 cpi.name, cpi.flags) 9225 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9226 if (singleton) { 9227 userId = UserHandle.USER_OWNER; 9228 } 9229 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9230 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9231 9232 String msg; 9233 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9234 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9235 != null) { 9236 throw new SecurityException(msg); 9237 } 9238 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9239 9240 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9241 && !cpi.processName.equals("system")) { 9242 // If this content provider does not run in the system 9243 // process, and the system is not yet ready to run other 9244 // processes, then fail fast instead of hanging. 9245 throw new IllegalArgumentException( 9246 "Attempt to launch content provider before system ready"); 9247 } 9248 9249 // Make sure that the user who owns this provider is running. If not, 9250 // we don't want to allow it to run. 9251 if (!isUserRunningLocked(userId, false)) { 9252 Slog.w(TAG, "Unable to launch app " 9253 + cpi.applicationInfo.packageName + "/" 9254 + cpi.applicationInfo.uid + " for provider " 9255 + name + ": user " + userId + " is stopped"); 9256 return null; 9257 } 9258 9259 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9260 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9261 cpr = mProviderMap.getProviderByClass(comp, userId); 9262 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9263 final boolean firstClass = cpr == null; 9264 if (firstClass) { 9265 final long ident = Binder.clearCallingIdentity(); 9266 try { 9267 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9268 ApplicationInfo ai = 9269 AppGlobals.getPackageManager(). 9270 getApplicationInfo( 9271 cpi.applicationInfo.packageName, 9272 STOCK_PM_FLAGS, userId); 9273 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9274 if (ai == null) { 9275 Slog.w(TAG, "No package info for content provider " 9276 + cpi.name); 9277 return null; 9278 } 9279 ai = getAppInfoForUser(ai, userId); 9280 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9281 } catch (RemoteException ex) { 9282 // pm is in same process, this will never happen. 9283 } finally { 9284 Binder.restoreCallingIdentity(ident); 9285 } 9286 } 9287 9288 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9289 9290 if (r != null && cpr.canRunHere(r)) { 9291 // If this is a multiprocess provider, then just return its 9292 // info and allow the caller to instantiate it. Only do 9293 // this if the provider is the same user as the caller's 9294 // process, or can run as root (so can be in any process). 9295 return cpr.newHolder(null); 9296 } 9297 9298 if (DEBUG_PROVIDER) { 9299 RuntimeException e = new RuntimeException("here"); 9300 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9301 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9302 } 9303 9304 // This is single process, and our app is now connecting to it. 9305 // See if we are already in the process of launching this 9306 // provider. 9307 final int N = mLaunchingProviders.size(); 9308 int i; 9309 for (i=0; i<N; i++) { 9310 if (mLaunchingProviders.get(i) == cpr) { 9311 break; 9312 } 9313 } 9314 9315 // If the provider is not already being launched, then get it 9316 // started. 9317 if (i >= N) { 9318 final long origId = Binder.clearCallingIdentity(); 9319 9320 try { 9321 // Content provider is now in use, its package can't be stopped. 9322 try { 9323 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9324 AppGlobals.getPackageManager().setPackageStoppedState( 9325 cpr.appInfo.packageName, false, userId); 9326 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9327 } catch (RemoteException e) { 9328 } catch (IllegalArgumentException e) { 9329 Slog.w(TAG, "Failed trying to unstop package " 9330 + cpr.appInfo.packageName + ": " + e); 9331 } 9332 9333 // Use existing process if already started 9334 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9335 ProcessRecord proc = getProcessRecordLocked( 9336 cpi.processName, cpr.appInfo.uid, false); 9337 if (proc != null && proc.thread != null) { 9338 if (DEBUG_PROVIDER) { 9339 Slog.d(TAG, "Installing in existing process " + proc); 9340 } 9341 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9342 proc.pubProviders.put(cpi.name, cpr); 9343 try { 9344 proc.thread.scheduleInstallProvider(cpi); 9345 } catch (RemoteException e) { 9346 } 9347 } else { 9348 checkTime(startTime, "getContentProviderImpl: before start process"); 9349 proc = startProcessLocked(cpi.processName, 9350 cpr.appInfo, false, 0, "content provider", 9351 new ComponentName(cpi.applicationInfo.packageName, 9352 cpi.name), false, false, false); 9353 checkTime(startTime, "getContentProviderImpl: after start process"); 9354 if (proc == null) { 9355 Slog.w(TAG, "Unable to launch app " 9356 + cpi.applicationInfo.packageName + "/" 9357 + cpi.applicationInfo.uid + " for provider " 9358 + name + ": process is bad"); 9359 return null; 9360 } 9361 } 9362 cpr.launchingApp = proc; 9363 mLaunchingProviders.add(cpr); 9364 } finally { 9365 Binder.restoreCallingIdentity(origId); 9366 } 9367 } 9368 9369 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9370 9371 // Make sure the provider is published (the same provider class 9372 // may be published under multiple names). 9373 if (firstClass) { 9374 mProviderMap.putProviderByClass(comp, cpr); 9375 } 9376 9377 mProviderMap.putProviderByName(name, cpr); 9378 conn = incProviderCountLocked(r, cpr, token, stable); 9379 if (conn != null) { 9380 conn.waiting = true; 9381 } 9382 } 9383 checkTime(startTime, "getContentProviderImpl: done!"); 9384 } 9385 9386 // Wait for the provider to be published... 9387 synchronized (cpr) { 9388 while (cpr.provider == null) { 9389 if (cpr.launchingApp == null) { 9390 Slog.w(TAG, "Unable to launch app " 9391 + cpi.applicationInfo.packageName + "/" 9392 + cpi.applicationInfo.uid + " for provider " 9393 + name + ": launching app became null"); 9394 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9395 UserHandle.getUserId(cpi.applicationInfo.uid), 9396 cpi.applicationInfo.packageName, 9397 cpi.applicationInfo.uid, name); 9398 return null; 9399 } 9400 try { 9401 if (DEBUG_MU) { 9402 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9403 + cpr.launchingApp); 9404 } 9405 if (conn != null) { 9406 conn.waiting = true; 9407 } 9408 cpr.wait(); 9409 } catch (InterruptedException ex) { 9410 } finally { 9411 if (conn != null) { 9412 conn.waiting = false; 9413 } 9414 } 9415 } 9416 } 9417 return cpr != null ? cpr.newHolder(conn) : null; 9418 } 9419 9420 @Override 9421 public final ContentProviderHolder getContentProvider( 9422 IApplicationThread caller, String name, int userId, boolean stable) { 9423 enforceNotIsolatedCaller("getContentProvider"); 9424 if (caller == null) { 9425 String msg = "null IApplicationThread when getting content provider " 9426 + name; 9427 Slog.w(TAG, msg); 9428 throw new SecurityException(msg); 9429 } 9430 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9431 // with cross-user grant. 9432 return getContentProviderImpl(caller, name, null, stable, userId); 9433 } 9434 9435 public ContentProviderHolder getContentProviderExternal( 9436 String name, int userId, IBinder token) { 9437 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9438 "Do not have permission in call getContentProviderExternal()"); 9439 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9440 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9441 return getContentProviderExternalUnchecked(name, token, userId); 9442 } 9443 9444 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9445 IBinder token, int userId) { 9446 return getContentProviderImpl(null, name, token, true, userId); 9447 } 9448 9449 /** 9450 * Drop a content provider from a ProcessRecord's bookkeeping 9451 */ 9452 public void removeContentProvider(IBinder connection, boolean stable) { 9453 enforceNotIsolatedCaller("removeContentProvider"); 9454 long ident = Binder.clearCallingIdentity(); 9455 try { 9456 synchronized (this) { 9457 ContentProviderConnection conn; 9458 try { 9459 conn = (ContentProviderConnection)connection; 9460 } catch (ClassCastException e) { 9461 String msg ="removeContentProvider: " + connection 9462 + " not a ContentProviderConnection"; 9463 Slog.w(TAG, msg); 9464 throw new IllegalArgumentException(msg); 9465 } 9466 if (conn == null) { 9467 throw new NullPointerException("connection is null"); 9468 } 9469 if (decProviderCountLocked(conn, null, null, stable)) { 9470 updateOomAdjLocked(); 9471 } 9472 } 9473 } finally { 9474 Binder.restoreCallingIdentity(ident); 9475 } 9476 } 9477 9478 public void removeContentProviderExternal(String name, IBinder token) { 9479 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9480 "Do not have permission in call removeContentProviderExternal()"); 9481 int userId = UserHandle.getCallingUserId(); 9482 long ident = Binder.clearCallingIdentity(); 9483 try { 9484 removeContentProviderExternalUnchecked(name, token, userId); 9485 } finally { 9486 Binder.restoreCallingIdentity(ident); 9487 } 9488 } 9489 9490 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9491 synchronized (this) { 9492 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9493 if(cpr == null) { 9494 //remove from mProvidersByClass 9495 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9496 return; 9497 } 9498 9499 //update content provider record entry info 9500 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9501 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9502 if (localCpr.hasExternalProcessHandles()) { 9503 if (localCpr.removeExternalProcessHandleLocked(token)) { 9504 updateOomAdjLocked(); 9505 } else { 9506 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9507 + " with no external reference for token: " 9508 + token + "."); 9509 } 9510 } else { 9511 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9512 + " with no external references."); 9513 } 9514 } 9515 } 9516 9517 public final void publishContentProviders(IApplicationThread caller, 9518 List<ContentProviderHolder> providers) { 9519 if (providers == null) { 9520 return; 9521 } 9522 9523 enforceNotIsolatedCaller("publishContentProviders"); 9524 synchronized (this) { 9525 final ProcessRecord r = getRecordForAppLocked(caller); 9526 if (DEBUG_MU) 9527 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9528 if (r == null) { 9529 throw new SecurityException( 9530 "Unable to find app for caller " + caller 9531 + " (pid=" + Binder.getCallingPid() 9532 + ") when publishing content providers"); 9533 } 9534 9535 final long origId = Binder.clearCallingIdentity(); 9536 9537 final int N = providers.size(); 9538 for (int i=0; i<N; i++) { 9539 ContentProviderHolder src = providers.get(i); 9540 if (src == null || src.info == null || src.provider == null) { 9541 continue; 9542 } 9543 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9544 if (DEBUG_MU) 9545 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9546 if (dst != null) { 9547 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9548 mProviderMap.putProviderByClass(comp, dst); 9549 String names[] = dst.info.authority.split(";"); 9550 for (int j = 0; j < names.length; j++) { 9551 mProviderMap.putProviderByName(names[j], dst); 9552 } 9553 9554 int NL = mLaunchingProviders.size(); 9555 int j; 9556 for (j=0; j<NL; j++) { 9557 if (mLaunchingProviders.get(j) == dst) { 9558 mLaunchingProviders.remove(j); 9559 j--; 9560 NL--; 9561 } 9562 } 9563 synchronized (dst) { 9564 dst.provider = src.provider; 9565 dst.proc = r; 9566 dst.notifyAll(); 9567 } 9568 updateOomAdjLocked(r); 9569 } 9570 } 9571 9572 Binder.restoreCallingIdentity(origId); 9573 } 9574 } 9575 9576 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9577 ContentProviderConnection conn; 9578 try { 9579 conn = (ContentProviderConnection)connection; 9580 } catch (ClassCastException e) { 9581 String msg ="refContentProvider: " + connection 9582 + " not a ContentProviderConnection"; 9583 Slog.w(TAG, msg); 9584 throw new IllegalArgumentException(msg); 9585 } 9586 if (conn == null) { 9587 throw new NullPointerException("connection is null"); 9588 } 9589 9590 synchronized (this) { 9591 if (stable > 0) { 9592 conn.numStableIncs += stable; 9593 } 9594 stable = conn.stableCount + stable; 9595 if (stable < 0) { 9596 throw new IllegalStateException("stableCount < 0: " + stable); 9597 } 9598 9599 if (unstable > 0) { 9600 conn.numUnstableIncs += unstable; 9601 } 9602 unstable = conn.unstableCount + unstable; 9603 if (unstable < 0) { 9604 throw new IllegalStateException("unstableCount < 0: " + unstable); 9605 } 9606 9607 if ((stable+unstable) <= 0) { 9608 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9609 + stable + " unstable=" + unstable); 9610 } 9611 conn.stableCount = stable; 9612 conn.unstableCount = unstable; 9613 return !conn.dead; 9614 } 9615 } 9616 9617 public void unstableProviderDied(IBinder connection) { 9618 ContentProviderConnection conn; 9619 try { 9620 conn = (ContentProviderConnection)connection; 9621 } catch (ClassCastException e) { 9622 String msg ="refContentProvider: " + connection 9623 + " not a ContentProviderConnection"; 9624 Slog.w(TAG, msg); 9625 throw new IllegalArgumentException(msg); 9626 } 9627 if (conn == null) { 9628 throw new NullPointerException("connection is null"); 9629 } 9630 9631 // Safely retrieve the content provider associated with the connection. 9632 IContentProvider provider; 9633 synchronized (this) { 9634 provider = conn.provider.provider; 9635 } 9636 9637 if (provider == null) { 9638 // Um, yeah, we're way ahead of you. 9639 return; 9640 } 9641 9642 // Make sure the caller is being honest with us. 9643 if (provider.asBinder().pingBinder()) { 9644 // Er, no, still looks good to us. 9645 synchronized (this) { 9646 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9647 + " says " + conn + " died, but we don't agree"); 9648 return; 9649 } 9650 } 9651 9652 // Well look at that! It's dead! 9653 synchronized (this) { 9654 if (conn.provider.provider != provider) { 9655 // But something changed... good enough. 9656 return; 9657 } 9658 9659 ProcessRecord proc = conn.provider.proc; 9660 if (proc == null || proc.thread == null) { 9661 // Seems like the process is already cleaned up. 9662 return; 9663 } 9664 9665 // As far as we're concerned, this is just like receiving a 9666 // death notification... just a bit prematurely. 9667 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9668 + ") early provider death"); 9669 final long ident = Binder.clearCallingIdentity(); 9670 try { 9671 appDiedLocked(proc); 9672 } finally { 9673 Binder.restoreCallingIdentity(ident); 9674 } 9675 } 9676 } 9677 9678 @Override 9679 public void appNotRespondingViaProvider(IBinder connection) { 9680 enforceCallingPermission( 9681 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9682 9683 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9684 if (conn == null) { 9685 Slog.w(TAG, "ContentProviderConnection is null"); 9686 return; 9687 } 9688 9689 final ProcessRecord host = conn.provider.proc; 9690 if (host == null) { 9691 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9692 return; 9693 } 9694 9695 final long token = Binder.clearCallingIdentity(); 9696 try { 9697 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9698 } finally { 9699 Binder.restoreCallingIdentity(token); 9700 } 9701 } 9702 9703 public final void installSystemProviders() { 9704 List<ProviderInfo> providers; 9705 synchronized (this) { 9706 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9707 providers = generateApplicationProvidersLocked(app); 9708 if (providers != null) { 9709 for (int i=providers.size()-1; i>=0; i--) { 9710 ProviderInfo pi = (ProviderInfo)providers.get(i); 9711 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9712 Slog.w(TAG, "Not installing system proc provider " + pi.name 9713 + ": not system .apk"); 9714 providers.remove(i); 9715 } 9716 } 9717 } 9718 } 9719 if (providers != null) { 9720 mSystemThread.installSystemProviders(providers); 9721 } 9722 9723 mCoreSettingsObserver = new CoreSettingsObserver(this); 9724 9725 //mUsageStatsService.monitorPackages(); 9726 } 9727 9728 /** 9729 * Allows apps to retrieve the MIME type of a URI. 9730 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9731 * users, then it does not need permission to access the ContentProvider. 9732 * Either, it needs cross-user uri grants. 9733 * 9734 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9735 * 9736 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9737 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9738 */ 9739 public String getProviderMimeType(Uri uri, int userId) { 9740 enforceNotIsolatedCaller("getProviderMimeType"); 9741 final String name = uri.getAuthority(); 9742 int callingUid = Binder.getCallingUid(); 9743 int callingPid = Binder.getCallingPid(); 9744 long ident = 0; 9745 boolean clearedIdentity = false; 9746 userId = unsafeConvertIncomingUser(userId); 9747 if (canClearIdentity(callingPid, callingUid, userId)) { 9748 clearedIdentity = true; 9749 ident = Binder.clearCallingIdentity(); 9750 } 9751 ContentProviderHolder holder = null; 9752 try { 9753 holder = getContentProviderExternalUnchecked(name, null, userId); 9754 if (holder != null) { 9755 return holder.provider.getType(uri); 9756 } 9757 } catch (RemoteException e) { 9758 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9759 return null; 9760 } finally { 9761 // We need to clear the identity to call removeContentProviderExternalUnchecked 9762 if (!clearedIdentity) { 9763 ident = Binder.clearCallingIdentity(); 9764 } 9765 try { 9766 if (holder != null) { 9767 removeContentProviderExternalUnchecked(name, null, userId); 9768 } 9769 } finally { 9770 Binder.restoreCallingIdentity(ident); 9771 } 9772 } 9773 9774 return null; 9775 } 9776 9777 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9778 if (UserHandle.getUserId(callingUid) == userId) { 9779 return true; 9780 } 9781 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9782 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9783 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9784 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9785 return true; 9786 } 9787 return false; 9788 } 9789 9790 // ========================================================= 9791 // GLOBAL MANAGEMENT 9792 // ========================================================= 9793 9794 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9795 boolean isolated, int isolatedUid) { 9796 String proc = customProcess != null ? customProcess : info.processName; 9797 BatteryStatsImpl.Uid.Proc ps = null; 9798 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9799 int uid = info.uid; 9800 if (isolated) { 9801 if (isolatedUid == 0) { 9802 int userId = UserHandle.getUserId(uid); 9803 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9804 while (true) { 9805 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9806 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9807 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9808 } 9809 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9810 mNextIsolatedProcessUid++; 9811 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9812 // No process for this uid, use it. 9813 break; 9814 } 9815 stepsLeft--; 9816 if (stepsLeft <= 0) { 9817 return null; 9818 } 9819 } 9820 } else { 9821 // Special case for startIsolatedProcess (internal only), where 9822 // the uid of the isolated process is specified by the caller. 9823 uid = isolatedUid; 9824 } 9825 } 9826 return new ProcessRecord(stats, info, proc, uid); 9827 } 9828 9829 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9830 String abiOverride) { 9831 ProcessRecord app; 9832 if (!isolated) { 9833 app = getProcessRecordLocked(info.processName, info.uid, true); 9834 } else { 9835 app = null; 9836 } 9837 9838 if (app == null) { 9839 app = newProcessRecordLocked(info, null, isolated, 0); 9840 mProcessNames.put(info.processName, app.uid, app); 9841 if (isolated) { 9842 mIsolatedProcesses.put(app.uid, app); 9843 } 9844 updateLruProcessLocked(app, false, null); 9845 updateOomAdjLocked(); 9846 } 9847 9848 // This package really, really can not be stopped. 9849 try { 9850 AppGlobals.getPackageManager().setPackageStoppedState( 9851 info.packageName, false, UserHandle.getUserId(app.uid)); 9852 } catch (RemoteException e) { 9853 } catch (IllegalArgumentException e) { 9854 Slog.w(TAG, "Failed trying to unstop package " 9855 + info.packageName + ": " + e); 9856 } 9857 9858 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9859 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9860 app.persistent = true; 9861 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9862 } 9863 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9864 mPersistentStartingProcesses.add(app); 9865 startProcessLocked(app, "added application", app.processName, abiOverride, 9866 null /* entryPoint */, null /* entryPointArgs */); 9867 } 9868 9869 return app; 9870 } 9871 9872 public void unhandledBack() { 9873 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9874 "unhandledBack()"); 9875 9876 synchronized(this) { 9877 final long origId = Binder.clearCallingIdentity(); 9878 try { 9879 getFocusedStack().unhandledBackLocked(); 9880 } finally { 9881 Binder.restoreCallingIdentity(origId); 9882 } 9883 } 9884 } 9885 9886 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9887 enforceNotIsolatedCaller("openContentUri"); 9888 final int userId = UserHandle.getCallingUserId(); 9889 String name = uri.getAuthority(); 9890 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9891 ParcelFileDescriptor pfd = null; 9892 if (cph != null) { 9893 // We record the binder invoker's uid in thread-local storage before 9894 // going to the content provider to open the file. Later, in the code 9895 // that handles all permissions checks, we look for this uid and use 9896 // that rather than the Activity Manager's own uid. The effect is that 9897 // we do the check against the caller's permissions even though it looks 9898 // to the content provider like the Activity Manager itself is making 9899 // the request. 9900 Binder token = new Binder(); 9901 sCallerIdentity.set(new Identity( 9902 token, Binder.getCallingPid(), Binder.getCallingUid())); 9903 try { 9904 pfd = cph.provider.openFile(null, uri, "r", null, token); 9905 } catch (FileNotFoundException e) { 9906 // do nothing; pfd will be returned null 9907 } finally { 9908 // Ensure that whatever happens, we clean up the identity state 9909 sCallerIdentity.remove(); 9910 } 9911 9912 // We've got the fd now, so we're done with the provider. 9913 removeContentProviderExternalUnchecked(name, null, userId); 9914 } else { 9915 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9916 } 9917 return pfd; 9918 } 9919 9920 // Actually is sleeping or shutting down or whatever else in the future 9921 // is an inactive state. 9922 public boolean isSleepingOrShuttingDown() { 9923 return isSleeping() || mShuttingDown; 9924 } 9925 9926 public boolean isSleeping() { 9927 return mSleeping; 9928 } 9929 9930 void onWakefulnessChanged(int wakefulness) { 9931 synchronized(this) { 9932 mWakefulness = wakefulness; 9933 updateSleepIfNeededLocked(); 9934 } 9935 } 9936 9937 void finishRunningVoiceLocked() { 9938 if (mRunningVoice) { 9939 mRunningVoice = false; 9940 updateSleepIfNeededLocked(); 9941 } 9942 } 9943 9944 void updateSleepIfNeededLocked() { 9945 if (mSleeping && !shouldSleepLocked()) { 9946 mSleeping = false; 9947 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9948 } else if (!mSleeping && shouldSleepLocked()) { 9949 mSleeping = true; 9950 mStackSupervisor.goingToSleepLocked(); 9951 9952 // Initialize the wake times of all processes. 9953 checkExcessivePowerUsageLocked(false); 9954 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9955 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9956 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9957 } 9958 } 9959 9960 private boolean shouldSleepLocked() { 9961 // Resume applications while running a voice interactor. 9962 if (mRunningVoice) { 9963 return false; 9964 } 9965 9966 switch (mWakefulness) { 9967 case PowerManagerInternal.WAKEFULNESS_AWAKE: 9968 case PowerManagerInternal.WAKEFULNESS_DREAMING: 9969 // If we're interactive but applications are already paused then defer 9970 // resuming them until the lock screen is hidden. 9971 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 9972 case PowerManagerInternal.WAKEFULNESS_DOZING: 9973 // If we're dozing then pause applications whenever the lock screen is shown. 9974 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 9975 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 9976 default: 9977 // If we're asleep then pause applications unconditionally. 9978 return true; 9979 } 9980 } 9981 9982 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9983 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9984 // Never persist the home stack. 9985 return; 9986 } 9987 mTaskPersister.wakeup(task, flush); 9988 } 9989 9990 @Override 9991 public boolean shutdown(int timeout) { 9992 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9993 != PackageManager.PERMISSION_GRANTED) { 9994 throw new SecurityException("Requires permission " 9995 + android.Manifest.permission.SHUTDOWN); 9996 } 9997 9998 boolean timedout = false; 9999 10000 synchronized(this) { 10001 mShuttingDown = true; 10002 updateEventDispatchingLocked(); 10003 timedout = mStackSupervisor.shutdownLocked(timeout); 10004 } 10005 10006 mAppOpsService.shutdown(); 10007 if (mUsageStatsService != null) { 10008 mUsageStatsService.prepareShutdown(); 10009 } 10010 mBatteryStatsService.shutdown(); 10011 synchronized (this) { 10012 mProcessStats.shutdownLocked(); 10013 } 10014 notifyTaskPersisterLocked(null, true); 10015 10016 return timedout; 10017 } 10018 10019 public final void activitySlept(IBinder token) { 10020 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10021 10022 final long origId = Binder.clearCallingIdentity(); 10023 10024 synchronized (this) { 10025 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10026 if (r != null) { 10027 mStackSupervisor.activitySleptLocked(r); 10028 } 10029 } 10030 10031 Binder.restoreCallingIdentity(origId); 10032 } 10033 10034 private String lockScreenShownToString() { 10035 switch (mLockScreenShown) { 10036 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10037 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10038 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10039 default: return "Unknown=" + mLockScreenShown; 10040 } 10041 } 10042 10043 void logLockScreen(String msg) { 10044 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10045 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10046 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10047 + " mSleeping=" + mSleeping); 10048 } 10049 10050 void startRunningVoiceLocked() { 10051 if (!mRunningVoice) { 10052 mRunningVoice = true; 10053 updateSleepIfNeededLocked(); 10054 } 10055 } 10056 10057 private void updateEventDispatchingLocked() { 10058 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10059 } 10060 10061 public void setLockScreenShown(boolean shown) { 10062 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10063 != PackageManager.PERMISSION_GRANTED) { 10064 throw new SecurityException("Requires permission " 10065 + android.Manifest.permission.DEVICE_POWER); 10066 } 10067 10068 synchronized(this) { 10069 long ident = Binder.clearCallingIdentity(); 10070 try { 10071 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10072 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10073 updateSleepIfNeededLocked(); 10074 } finally { 10075 Binder.restoreCallingIdentity(ident); 10076 } 10077 } 10078 } 10079 10080 @Override 10081 public void stopAppSwitches() { 10082 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10083 != PackageManager.PERMISSION_GRANTED) { 10084 throw new SecurityException("Requires permission " 10085 + android.Manifest.permission.STOP_APP_SWITCHES); 10086 } 10087 10088 synchronized(this) { 10089 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10090 + APP_SWITCH_DELAY_TIME; 10091 mDidAppSwitch = false; 10092 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10093 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10094 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10095 } 10096 } 10097 10098 public void resumeAppSwitches() { 10099 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10100 != PackageManager.PERMISSION_GRANTED) { 10101 throw new SecurityException("Requires permission " 10102 + android.Manifest.permission.STOP_APP_SWITCHES); 10103 } 10104 10105 synchronized(this) { 10106 // Note that we don't execute any pending app switches... we will 10107 // let those wait until either the timeout, or the next start 10108 // activity request. 10109 mAppSwitchesAllowedTime = 0; 10110 } 10111 } 10112 10113 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10114 int callingPid, int callingUid, String name) { 10115 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10116 return true; 10117 } 10118 10119 int perm = checkComponentPermission( 10120 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10121 sourceUid, -1, true); 10122 if (perm == PackageManager.PERMISSION_GRANTED) { 10123 return true; 10124 } 10125 10126 // If the actual IPC caller is different from the logical source, then 10127 // also see if they are allowed to control app switches. 10128 if (callingUid != -1 && callingUid != sourceUid) { 10129 perm = checkComponentPermission( 10130 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10131 callingUid, -1, true); 10132 if (perm == PackageManager.PERMISSION_GRANTED) { 10133 return true; 10134 } 10135 } 10136 10137 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10138 return false; 10139 } 10140 10141 public void setDebugApp(String packageName, boolean waitForDebugger, 10142 boolean persistent) { 10143 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10144 "setDebugApp()"); 10145 10146 long ident = Binder.clearCallingIdentity(); 10147 try { 10148 // Note that this is not really thread safe if there are multiple 10149 // callers into it at the same time, but that's not a situation we 10150 // care about. 10151 if (persistent) { 10152 final ContentResolver resolver = mContext.getContentResolver(); 10153 Settings.Global.putString( 10154 resolver, Settings.Global.DEBUG_APP, 10155 packageName); 10156 Settings.Global.putInt( 10157 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10158 waitForDebugger ? 1 : 0); 10159 } 10160 10161 synchronized (this) { 10162 if (!persistent) { 10163 mOrigDebugApp = mDebugApp; 10164 mOrigWaitForDebugger = mWaitForDebugger; 10165 } 10166 mDebugApp = packageName; 10167 mWaitForDebugger = waitForDebugger; 10168 mDebugTransient = !persistent; 10169 if (packageName != null) { 10170 forceStopPackageLocked(packageName, -1, false, false, true, true, 10171 false, UserHandle.USER_ALL, "set debug app"); 10172 } 10173 } 10174 } finally { 10175 Binder.restoreCallingIdentity(ident); 10176 } 10177 } 10178 10179 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10180 synchronized (this) { 10181 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10182 if (!isDebuggable) { 10183 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10184 throw new SecurityException("Process not debuggable: " + app.packageName); 10185 } 10186 } 10187 10188 mOpenGlTraceApp = processName; 10189 } 10190 } 10191 10192 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10193 synchronized (this) { 10194 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10195 if (!isDebuggable) { 10196 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10197 throw new SecurityException("Process not debuggable: " + app.packageName); 10198 } 10199 } 10200 mProfileApp = processName; 10201 mProfileFile = profilerInfo.profileFile; 10202 if (mProfileFd != null) { 10203 try { 10204 mProfileFd.close(); 10205 } catch (IOException e) { 10206 } 10207 mProfileFd = null; 10208 } 10209 mProfileFd = profilerInfo.profileFd; 10210 mSamplingInterval = profilerInfo.samplingInterval; 10211 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10212 mProfileType = 0; 10213 } 10214 } 10215 10216 @Override 10217 public void setAlwaysFinish(boolean enabled) { 10218 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10219 "setAlwaysFinish()"); 10220 10221 Settings.Global.putInt( 10222 mContext.getContentResolver(), 10223 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10224 10225 synchronized (this) { 10226 mAlwaysFinishActivities = enabled; 10227 } 10228 } 10229 10230 @Override 10231 public void setActivityController(IActivityController controller) { 10232 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10233 "setActivityController()"); 10234 synchronized (this) { 10235 mController = controller; 10236 Watchdog.getInstance().setActivityController(controller); 10237 } 10238 } 10239 10240 @Override 10241 public void setUserIsMonkey(boolean userIsMonkey) { 10242 synchronized (this) { 10243 synchronized (mPidsSelfLocked) { 10244 final int callingPid = Binder.getCallingPid(); 10245 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10246 if (precessRecord == null) { 10247 throw new SecurityException("Unknown process: " + callingPid); 10248 } 10249 if (precessRecord.instrumentationUiAutomationConnection == null) { 10250 throw new SecurityException("Only an instrumentation process " 10251 + "with a UiAutomation can call setUserIsMonkey"); 10252 } 10253 } 10254 mUserIsMonkey = userIsMonkey; 10255 } 10256 } 10257 10258 @Override 10259 public boolean isUserAMonkey() { 10260 synchronized (this) { 10261 // If there is a controller also implies the user is a monkey. 10262 return (mUserIsMonkey || mController != null); 10263 } 10264 } 10265 10266 public void requestBugReport() { 10267 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10268 SystemProperties.set("ctl.start", "bugreport"); 10269 } 10270 10271 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10272 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10273 } 10274 10275 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10276 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10277 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10278 } 10279 return KEY_DISPATCHING_TIMEOUT; 10280 } 10281 10282 @Override 10283 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10284 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10285 != PackageManager.PERMISSION_GRANTED) { 10286 throw new SecurityException("Requires permission " 10287 + android.Manifest.permission.FILTER_EVENTS); 10288 } 10289 ProcessRecord proc; 10290 long timeout; 10291 synchronized (this) { 10292 synchronized (mPidsSelfLocked) { 10293 proc = mPidsSelfLocked.get(pid); 10294 } 10295 timeout = getInputDispatchingTimeoutLocked(proc); 10296 } 10297 10298 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10299 return -1; 10300 } 10301 10302 return timeout; 10303 } 10304 10305 /** 10306 * Handle input dispatching timeouts. 10307 * Returns whether input dispatching should be aborted or not. 10308 */ 10309 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10310 final ActivityRecord activity, final ActivityRecord parent, 10311 final boolean aboveSystem, String reason) { 10312 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10313 != PackageManager.PERMISSION_GRANTED) { 10314 throw new SecurityException("Requires permission " 10315 + android.Manifest.permission.FILTER_EVENTS); 10316 } 10317 10318 final String annotation; 10319 if (reason == null) { 10320 annotation = "Input dispatching timed out"; 10321 } else { 10322 annotation = "Input dispatching timed out (" + reason + ")"; 10323 } 10324 10325 if (proc != null) { 10326 synchronized (this) { 10327 if (proc.debugging) { 10328 return false; 10329 } 10330 10331 if (mDidDexOpt) { 10332 // Give more time since we were dexopting. 10333 mDidDexOpt = false; 10334 return false; 10335 } 10336 10337 if (proc.instrumentationClass != null) { 10338 Bundle info = new Bundle(); 10339 info.putString("shortMsg", "keyDispatchingTimedOut"); 10340 info.putString("longMsg", annotation); 10341 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10342 return true; 10343 } 10344 } 10345 mHandler.post(new Runnable() { 10346 @Override 10347 public void run() { 10348 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10349 } 10350 }); 10351 } 10352 10353 return true; 10354 } 10355 10356 public Bundle getAssistContextExtras(int requestType) { 10357 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10358 UserHandle.getCallingUserId()); 10359 if (pae == null) { 10360 return null; 10361 } 10362 synchronized (pae) { 10363 while (!pae.haveResult) { 10364 try { 10365 pae.wait(); 10366 } catch (InterruptedException e) { 10367 } 10368 } 10369 if (pae.result != null) { 10370 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10371 } 10372 } 10373 synchronized (this) { 10374 mPendingAssistExtras.remove(pae); 10375 mHandler.removeCallbacks(pae); 10376 } 10377 return pae.extras; 10378 } 10379 10380 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10381 int userHandle) { 10382 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10383 "getAssistContextExtras()"); 10384 PendingAssistExtras pae; 10385 Bundle extras = new Bundle(); 10386 synchronized (this) { 10387 ActivityRecord activity = getFocusedStack().mResumedActivity; 10388 if (activity == null) { 10389 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10390 return null; 10391 } 10392 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10393 if (activity.app == null || activity.app.thread == null) { 10394 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10395 return null; 10396 } 10397 if (activity.app.pid == Binder.getCallingPid()) { 10398 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10399 return null; 10400 } 10401 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10402 try { 10403 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10404 requestType); 10405 mPendingAssistExtras.add(pae); 10406 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10407 } catch (RemoteException e) { 10408 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10409 return null; 10410 } 10411 return pae; 10412 } 10413 } 10414 10415 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10416 PendingAssistExtras pae = (PendingAssistExtras)token; 10417 synchronized (pae) { 10418 pae.result = extras; 10419 pae.haveResult = true; 10420 pae.notifyAll(); 10421 if (pae.intent == null) { 10422 // Caller is just waiting for the result. 10423 return; 10424 } 10425 } 10426 10427 // We are now ready to launch the assist activity. 10428 synchronized (this) { 10429 boolean exists = mPendingAssistExtras.remove(pae); 10430 mHandler.removeCallbacks(pae); 10431 if (!exists) { 10432 // Timed out. 10433 return; 10434 } 10435 } 10436 pae.intent.replaceExtras(extras); 10437 if (pae.hint != null) { 10438 pae.intent.putExtra(pae.hint, true); 10439 } 10440 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10441 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10442 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10443 closeSystemDialogs("assist"); 10444 try { 10445 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10446 } catch (ActivityNotFoundException e) { 10447 Slog.w(TAG, "No activity to handle assist action.", e); 10448 } 10449 } 10450 10451 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10452 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10453 } 10454 10455 public void registerProcessObserver(IProcessObserver observer) { 10456 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10457 "registerProcessObserver()"); 10458 synchronized (this) { 10459 mProcessObservers.register(observer); 10460 } 10461 } 10462 10463 @Override 10464 public void unregisterProcessObserver(IProcessObserver observer) { 10465 synchronized (this) { 10466 mProcessObservers.unregister(observer); 10467 } 10468 } 10469 10470 @Override 10471 public boolean convertFromTranslucent(IBinder token) { 10472 final long origId = Binder.clearCallingIdentity(); 10473 try { 10474 synchronized (this) { 10475 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10476 if (r == null) { 10477 return false; 10478 } 10479 final boolean translucentChanged = r.changeWindowTranslucency(true); 10480 if (translucentChanged) { 10481 r.task.stack.releaseBackgroundResources(); 10482 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10483 } 10484 mWindowManager.setAppFullscreen(token, true); 10485 return translucentChanged; 10486 } 10487 } finally { 10488 Binder.restoreCallingIdentity(origId); 10489 } 10490 } 10491 10492 @Override 10493 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10494 final long origId = Binder.clearCallingIdentity(); 10495 try { 10496 synchronized (this) { 10497 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10498 if (r == null) { 10499 return false; 10500 } 10501 int index = r.task.mActivities.lastIndexOf(r); 10502 if (index > 0) { 10503 ActivityRecord under = r.task.mActivities.get(index - 1); 10504 under.returningOptions = options; 10505 } 10506 final boolean translucentChanged = r.changeWindowTranslucency(false); 10507 if (translucentChanged) { 10508 r.task.stack.convertToTranslucent(r); 10509 } 10510 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10511 mWindowManager.setAppFullscreen(token, false); 10512 return translucentChanged; 10513 } 10514 } finally { 10515 Binder.restoreCallingIdentity(origId); 10516 } 10517 } 10518 10519 @Override 10520 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10521 final long origId = Binder.clearCallingIdentity(); 10522 try { 10523 synchronized (this) { 10524 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10525 if (r != null) { 10526 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10527 } 10528 } 10529 return false; 10530 } finally { 10531 Binder.restoreCallingIdentity(origId); 10532 } 10533 } 10534 10535 @Override 10536 public boolean isBackgroundVisibleBehind(IBinder token) { 10537 final long origId = Binder.clearCallingIdentity(); 10538 try { 10539 synchronized (this) { 10540 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10541 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10542 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10543 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10544 return visible; 10545 } 10546 } finally { 10547 Binder.restoreCallingIdentity(origId); 10548 } 10549 } 10550 10551 @Override 10552 public ActivityOptions getActivityOptions(IBinder token) { 10553 final long origId = Binder.clearCallingIdentity(); 10554 try { 10555 synchronized (this) { 10556 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10557 if (r != null) { 10558 final ActivityOptions activityOptions = r.pendingOptions; 10559 r.pendingOptions = null; 10560 return activityOptions; 10561 } 10562 return null; 10563 } 10564 } finally { 10565 Binder.restoreCallingIdentity(origId); 10566 } 10567 } 10568 10569 @Override 10570 public void setImmersive(IBinder token, boolean immersive) { 10571 synchronized(this) { 10572 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10573 if (r == null) { 10574 throw new IllegalArgumentException(); 10575 } 10576 r.immersive = immersive; 10577 10578 // update associated state if we're frontmost 10579 if (r == mFocusedActivity) { 10580 if (DEBUG_IMMERSIVE) { 10581 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10582 } 10583 applyUpdateLockStateLocked(r); 10584 } 10585 } 10586 } 10587 10588 @Override 10589 public boolean isImmersive(IBinder token) { 10590 synchronized (this) { 10591 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10592 if (r == null) { 10593 throw new IllegalArgumentException(); 10594 } 10595 return r.immersive; 10596 } 10597 } 10598 10599 public boolean isTopActivityImmersive() { 10600 enforceNotIsolatedCaller("startActivity"); 10601 synchronized (this) { 10602 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10603 return (r != null) ? r.immersive : false; 10604 } 10605 } 10606 10607 @Override 10608 public boolean isTopOfTask(IBinder token) { 10609 synchronized (this) { 10610 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10611 if (r == null) { 10612 throw new IllegalArgumentException(); 10613 } 10614 return r.task.getTopActivity() == r; 10615 } 10616 } 10617 10618 public final void enterSafeMode() { 10619 synchronized(this) { 10620 // It only makes sense to do this before the system is ready 10621 // and started launching other packages. 10622 if (!mSystemReady) { 10623 try { 10624 AppGlobals.getPackageManager().enterSafeMode(); 10625 } catch (RemoteException e) { 10626 } 10627 } 10628 10629 mSafeMode = true; 10630 } 10631 } 10632 10633 public final void showSafeModeOverlay() { 10634 View v = LayoutInflater.from(mContext).inflate( 10635 com.android.internal.R.layout.safe_mode, null); 10636 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10637 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10638 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10639 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10640 lp.gravity = Gravity.BOTTOM | Gravity.START; 10641 lp.format = v.getBackground().getOpacity(); 10642 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10643 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10644 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10645 ((WindowManager)mContext.getSystemService( 10646 Context.WINDOW_SERVICE)).addView(v, lp); 10647 } 10648 10649 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10650 if (!(sender instanceof PendingIntentRecord)) { 10651 return; 10652 } 10653 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10654 synchronized (stats) { 10655 if (mBatteryStatsService.isOnBattery()) { 10656 mBatteryStatsService.enforceCallingPermission(); 10657 PendingIntentRecord rec = (PendingIntentRecord)sender; 10658 int MY_UID = Binder.getCallingUid(); 10659 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10660 BatteryStatsImpl.Uid.Pkg pkg = 10661 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10662 sourcePkg != null ? sourcePkg : rec.key.packageName); 10663 pkg.incWakeupsLocked(); 10664 } 10665 } 10666 } 10667 10668 public boolean killPids(int[] pids, String pReason, boolean secure) { 10669 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10670 throw new SecurityException("killPids only available to the system"); 10671 } 10672 String reason = (pReason == null) ? "Unknown" : pReason; 10673 // XXX Note: don't acquire main activity lock here, because the window 10674 // manager calls in with its locks held. 10675 10676 boolean killed = false; 10677 synchronized (mPidsSelfLocked) { 10678 int[] types = new int[pids.length]; 10679 int worstType = 0; 10680 for (int i=0; i<pids.length; i++) { 10681 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10682 if (proc != null) { 10683 int type = proc.setAdj; 10684 types[i] = type; 10685 if (type > worstType) { 10686 worstType = type; 10687 } 10688 } 10689 } 10690 10691 // If the worst oom_adj is somewhere in the cached proc LRU range, 10692 // then constrain it so we will kill all cached procs. 10693 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10694 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10695 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10696 } 10697 10698 // If this is not a secure call, don't let it kill processes that 10699 // are important. 10700 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10701 worstType = ProcessList.SERVICE_ADJ; 10702 } 10703 10704 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10705 for (int i=0; i<pids.length; i++) { 10706 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10707 if (proc == null) { 10708 continue; 10709 } 10710 int adj = proc.setAdj; 10711 if (adj >= worstType && !proc.killedByAm) { 10712 proc.kill(reason, true); 10713 killed = true; 10714 } 10715 } 10716 } 10717 return killed; 10718 } 10719 10720 @Override 10721 public void killUid(int uid, String reason) { 10722 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10723 throw new SecurityException("killUid only available to the system"); 10724 } 10725 synchronized (this) { 10726 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10727 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10728 reason != null ? reason : "kill uid"); 10729 } 10730 } 10731 10732 @Override 10733 public boolean killProcessesBelowForeground(String reason) { 10734 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10735 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10736 } 10737 10738 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10739 } 10740 10741 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10742 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10743 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10744 } 10745 10746 boolean killed = false; 10747 synchronized (mPidsSelfLocked) { 10748 final int size = mPidsSelfLocked.size(); 10749 for (int i = 0; i < size; i++) { 10750 final int pid = mPidsSelfLocked.keyAt(i); 10751 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10752 if (proc == null) continue; 10753 10754 final int adj = proc.setAdj; 10755 if (adj > belowAdj && !proc.killedByAm) { 10756 proc.kill(reason, true); 10757 killed = true; 10758 } 10759 } 10760 } 10761 return killed; 10762 } 10763 10764 @Override 10765 public void hang(final IBinder who, boolean allowRestart) { 10766 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10767 != PackageManager.PERMISSION_GRANTED) { 10768 throw new SecurityException("Requires permission " 10769 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10770 } 10771 10772 final IBinder.DeathRecipient death = new DeathRecipient() { 10773 @Override 10774 public void binderDied() { 10775 synchronized (this) { 10776 notifyAll(); 10777 } 10778 } 10779 }; 10780 10781 try { 10782 who.linkToDeath(death, 0); 10783 } catch (RemoteException e) { 10784 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10785 return; 10786 } 10787 10788 synchronized (this) { 10789 Watchdog.getInstance().setAllowRestart(allowRestart); 10790 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10791 synchronized (death) { 10792 while (who.isBinderAlive()) { 10793 try { 10794 death.wait(); 10795 } catch (InterruptedException e) { 10796 } 10797 } 10798 } 10799 Watchdog.getInstance().setAllowRestart(true); 10800 } 10801 } 10802 10803 @Override 10804 public void restart() { 10805 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10806 != PackageManager.PERMISSION_GRANTED) { 10807 throw new SecurityException("Requires permission " 10808 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10809 } 10810 10811 Log.i(TAG, "Sending shutdown broadcast..."); 10812 10813 BroadcastReceiver br = new BroadcastReceiver() { 10814 @Override public void onReceive(Context context, Intent intent) { 10815 // Now the broadcast is done, finish up the low-level shutdown. 10816 Log.i(TAG, "Shutting down activity manager..."); 10817 shutdown(10000); 10818 Log.i(TAG, "Shutdown complete, restarting!"); 10819 Process.killProcess(Process.myPid()); 10820 System.exit(10); 10821 } 10822 }; 10823 10824 // First send the high-level shut down broadcast. 10825 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10826 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10827 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10828 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10829 mContext.sendOrderedBroadcastAsUser(intent, 10830 UserHandle.ALL, null, br, mHandler, 0, null, null); 10831 */ 10832 br.onReceive(mContext, intent); 10833 } 10834 10835 private long getLowRamTimeSinceIdle(long now) { 10836 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10837 } 10838 10839 @Override 10840 public void performIdleMaintenance() { 10841 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10842 != PackageManager.PERMISSION_GRANTED) { 10843 throw new SecurityException("Requires permission " 10844 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10845 } 10846 10847 synchronized (this) { 10848 final long now = SystemClock.uptimeMillis(); 10849 final long timeSinceLastIdle = now - mLastIdleTime; 10850 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10851 mLastIdleTime = now; 10852 mLowRamTimeSinceLastIdle = 0; 10853 if (mLowRamStartTime != 0) { 10854 mLowRamStartTime = now; 10855 } 10856 10857 StringBuilder sb = new StringBuilder(128); 10858 sb.append("Idle maintenance over "); 10859 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10860 sb.append(" low RAM for "); 10861 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10862 Slog.i(TAG, sb.toString()); 10863 10864 // If at least 1/3 of our time since the last idle period has been spent 10865 // with RAM low, then we want to kill processes. 10866 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10867 10868 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10869 ProcessRecord proc = mLruProcesses.get(i); 10870 if (proc.notCachedSinceIdle) { 10871 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10872 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10873 if (doKilling && proc.initialIdlePss != 0 10874 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10875 proc.kill("idle maint (pss " + proc.lastPss 10876 + " from " + proc.initialIdlePss + ")", true); 10877 } 10878 } 10879 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10880 proc.notCachedSinceIdle = true; 10881 proc.initialIdlePss = 0; 10882 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10883 isSleeping(), now); 10884 } 10885 } 10886 10887 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10888 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10889 } 10890 } 10891 10892 private void retrieveSettings() { 10893 final ContentResolver resolver = mContext.getContentResolver(); 10894 String debugApp = Settings.Global.getString( 10895 resolver, Settings.Global.DEBUG_APP); 10896 boolean waitForDebugger = Settings.Global.getInt( 10897 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10898 boolean alwaysFinishActivities = Settings.Global.getInt( 10899 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10900 boolean forceRtl = Settings.Global.getInt( 10901 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10902 // Transfer any global setting for forcing RTL layout, into a System Property 10903 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10904 10905 Configuration configuration = new Configuration(); 10906 Settings.System.getConfiguration(resolver, configuration); 10907 if (forceRtl) { 10908 // This will take care of setting the correct layout direction flags 10909 configuration.setLayoutDirection(configuration.locale); 10910 } 10911 10912 synchronized (this) { 10913 mDebugApp = mOrigDebugApp = debugApp; 10914 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10915 mAlwaysFinishActivities = alwaysFinishActivities; 10916 // This happens before any activities are started, so we can 10917 // change mConfiguration in-place. 10918 updateConfigurationLocked(configuration, null, false, true); 10919 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10920 } 10921 } 10922 10923 /** Loads resources after the current configuration has been set. */ 10924 private void loadResourcesOnSystemReady() { 10925 final Resources res = mContext.getResources(); 10926 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10927 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10928 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10929 } 10930 10931 public boolean testIsSystemReady() { 10932 // no need to synchronize(this) just to read & return the value 10933 return mSystemReady; 10934 } 10935 10936 private static File getCalledPreBootReceiversFile() { 10937 File dataDir = Environment.getDataDirectory(); 10938 File systemDir = new File(dataDir, "system"); 10939 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10940 return fname; 10941 } 10942 10943 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10944 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10945 File file = getCalledPreBootReceiversFile(); 10946 FileInputStream fis = null; 10947 try { 10948 fis = new FileInputStream(file); 10949 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10950 int fvers = dis.readInt(); 10951 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10952 String vers = dis.readUTF(); 10953 String codename = dis.readUTF(); 10954 String build = dis.readUTF(); 10955 if (android.os.Build.VERSION.RELEASE.equals(vers) 10956 && android.os.Build.VERSION.CODENAME.equals(codename) 10957 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10958 int num = dis.readInt(); 10959 while (num > 0) { 10960 num--; 10961 String pkg = dis.readUTF(); 10962 String cls = dis.readUTF(); 10963 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10964 } 10965 } 10966 } 10967 } catch (FileNotFoundException e) { 10968 } catch (IOException e) { 10969 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10970 } finally { 10971 if (fis != null) { 10972 try { 10973 fis.close(); 10974 } catch (IOException e) { 10975 } 10976 } 10977 } 10978 return lastDoneReceivers; 10979 } 10980 10981 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10982 File file = getCalledPreBootReceiversFile(); 10983 FileOutputStream fos = null; 10984 DataOutputStream dos = null; 10985 try { 10986 fos = new FileOutputStream(file); 10987 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10988 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10989 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10990 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10991 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10992 dos.writeInt(list.size()); 10993 for (int i=0; i<list.size(); i++) { 10994 dos.writeUTF(list.get(i).getPackageName()); 10995 dos.writeUTF(list.get(i).getClassName()); 10996 } 10997 } catch (IOException e) { 10998 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10999 file.delete(); 11000 } finally { 11001 FileUtils.sync(fos); 11002 if (dos != null) { 11003 try { 11004 dos.close(); 11005 } catch (IOException e) { 11006 // TODO Auto-generated catch block 11007 e.printStackTrace(); 11008 } 11009 } 11010 } 11011 } 11012 11013 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11014 ArrayList<ComponentName> doneReceivers, int userId) { 11015 boolean waitingUpdate = false; 11016 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11017 List<ResolveInfo> ris = null; 11018 try { 11019 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11020 intent, null, 0, userId); 11021 } catch (RemoteException e) { 11022 } 11023 if (ris != null) { 11024 for (int i=ris.size()-1; i>=0; i--) { 11025 if ((ris.get(i).activityInfo.applicationInfo.flags 11026 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11027 ris.remove(i); 11028 } 11029 } 11030 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11031 11032 // For User 0, load the version number. When delivering to a new user, deliver 11033 // to all receivers. 11034 if (userId == UserHandle.USER_OWNER) { 11035 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11036 for (int i=0; i<ris.size(); i++) { 11037 ActivityInfo ai = ris.get(i).activityInfo; 11038 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11039 if (lastDoneReceivers.contains(comp)) { 11040 // We already did the pre boot receiver for this app with the current 11041 // platform version, so don't do it again... 11042 ris.remove(i); 11043 i--; 11044 // ...however, do keep it as one that has been done, so we don't 11045 // forget about it when rewriting the file of last done receivers. 11046 doneReceivers.add(comp); 11047 } 11048 } 11049 } 11050 11051 // If primary user, send broadcast to all available users, else just to userId 11052 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11053 : new int[] { userId }; 11054 for (int i = 0; i < ris.size(); i++) { 11055 ActivityInfo ai = ris.get(i).activityInfo; 11056 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11057 doneReceivers.add(comp); 11058 intent.setComponent(comp); 11059 for (int j=0; j<users.length; j++) { 11060 IIntentReceiver finisher = null; 11061 // On last receiver and user, set up a completion callback 11062 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11063 finisher = new IIntentReceiver.Stub() { 11064 public void performReceive(Intent intent, int resultCode, 11065 String data, Bundle extras, boolean ordered, 11066 boolean sticky, int sendingUser) { 11067 // The raw IIntentReceiver interface is called 11068 // with the AM lock held, so redispatch to 11069 // execute our code without the lock. 11070 mHandler.post(onFinishCallback); 11071 } 11072 }; 11073 } 11074 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11075 + " for user " + users[j]); 11076 broadcastIntentLocked(null, null, intent, null, finisher, 11077 0, null, null, null, AppOpsManager.OP_NONE, 11078 true, false, MY_PID, Process.SYSTEM_UID, 11079 users[j]); 11080 if (finisher != null) { 11081 waitingUpdate = true; 11082 } 11083 } 11084 } 11085 } 11086 11087 return waitingUpdate; 11088 } 11089 11090 public void systemReady(final Runnable goingCallback) { 11091 synchronized(this) { 11092 if (mSystemReady) { 11093 // If we're done calling all the receivers, run the next "boot phase" passed in 11094 // by the SystemServer 11095 if (goingCallback != null) { 11096 goingCallback.run(); 11097 } 11098 return; 11099 } 11100 11101 // Make sure we have the current profile info, since it is needed for 11102 // security checks. 11103 updateCurrentProfileIdsLocked(); 11104 11105 if (mRecentTasks == null) { 11106 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11107 if (!mRecentTasks.isEmpty()) { 11108 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11109 } 11110 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11111 mTaskPersister.startPersisting(); 11112 } 11113 11114 // Check to see if there are any update receivers to run. 11115 if (!mDidUpdate) { 11116 if (mWaitingUpdate) { 11117 return; 11118 } 11119 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11120 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11121 public void run() { 11122 synchronized (ActivityManagerService.this) { 11123 mDidUpdate = true; 11124 } 11125 writeLastDonePreBootReceivers(doneReceivers); 11126 showBootMessage(mContext.getText( 11127 R.string.android_upgrading_complete), 11128 false); 11129 systemReady(goingCallback); 11130 } 11131 }, doneReceivers, UserHandle.USER_OWNER); 11132 11133 if (mWaitingUpdate) { 11134 return; 11135 } 11136 mDidUpdate = true; 11137 } 11138 11139 mAppOpsService.systemReady(); 11140 mSystemReady = true; 11141 } 11142 11143 ArrayList<ProcessRecord> procsToKill = null; 11144 synchronized(mPidsSelfLocked) { 11145 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11146 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11147 if (!isAllowedWhileBooting(proc.info)){ 11148 if (procsToKill == null) { 11149 procsToKill = new ArrayList<ProcessRecord>(); 11150 } 11151 procsToKill.add(proc); 11152 } 11153 } 11154 } 11155 11156 synchronized(this) { 11157 if (procsToKill != null) { 11158 for (int i=procsToKill.size()-1; i>=0; i--) { 11159 ProcessRecord proc = procsToKill.get(i); 11160 Slog.i(TAG, "Removing system update proc: " + proc); 11161 removeProcessLocked(proc, true, false, "system update done"); 11162 } 11163 } 11164 11165 // Now that we have cleaned up any update processes, we 11166 // are ready to start launching real processes and know that 11167 // we won't trample on them any more. 11168 mProcessesReady = true; 11169 } 11170 11171 Slog.i(TAG, "System now ready"); 11172 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11173 SystemClock.uptimeMillis()); 11174 11175 synchronized(this) { 11176 // Make sure we have no pre-ready processes sitting around. 11177 11178 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11179 ResolveInfo ri = mContext.getPackageManager() 11180 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11181 STOCK_PM_FLAGS); 11182 CharSequence errorMsg = null; 11183 if (ri != null) { 11184 ActivityInfo ai = ri.activityInfo; 11185 ApplicationInfo app = ai.applicationInfo; 11186 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11187 mTopAction = Intent.ACTION_FACTORY_TEST; 11188 mTopData = null; 11189 mTopComponent = new ComponentName(app.packageName, 11190 ai.name); 11191 } else { 11192 errorMsg = mContext.getResources().getText( 11193 com.android.internal.R.string.factorytest_not_system); 11194 } 11195 } else { 11196 errorMsg = mContext.getResources().getText( 11197 com.android.internal.R.string.factorytest_no_action); 11198 } 11199 if (errorMsg != null) { 11200 mTopAction = null; 11201 mTopData = null; 11202 mTopComponent = null; 11203 Message msg = Message.obtain(); 11204 msg.what = SHOW_FACTORY_ERROR_MSG; 11205 msg.getData().putCharSequence("msg", errorMsg); 11206 mHandler.sendMessage(msg); 11207 } 11208 } 11209 } 11210 11211 retrieveSettings(); 11212 loadResourcesOnSystemReady(); 11213 11214 synchronized (this) { 11215 readGrantedUriPermissionsLocked(); 11216 } 11217 11218 if (goingCallback != null) goingCallback.run(); 11219 11220 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11221 Integer.toString(mCurrentUserId), mCurrentUserId); 11222 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11223 Integer.toString(mCurrentUserId), mCurrentUserId); 11224 mSystemServiceManager.startUser(mCurrentUserId); 11225 11226 synchronized (this) { 11227 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11228 try { 11229 List apps = AppGlobals.getPackageManager(). 11230 getPersistentApplications(STOCK_PM_FLAGS); 11231 if (apps != null) { 11232 int N = apps.size(); 11233 int i; 11234 for (i=0; i<N; i++) { 11235 ApplicationInfo info 11236 = (ApplicationInfo)apps.get(i); 11237 if (info != null && 11238 !info.packageName.equals("android")) { 11239 addAppLocked(info, false, null /* ABI override */); 11240 } 11241 } 11242 } 11243 } catch (RemoteException ex) { 11244 // pm is in same process, this will never happen. 11245 } 11246 } 11247 11248 // Start up initial activity. 11249 mBooting = true; 11250 startHomeActivityLocked(mCurrentUserId); 11251 11252 try { 11253 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11254 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11255 + " data partition or your device will be unstable."); 11256 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11257 } 11258 } catch (RemoteException e) { 11259 } 11260 11261 if (!Build.isFingerprintConsistent()) { 11262 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11263 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11264 } 11265 11266 long ident = Binder.clearCallingIdentity(); 11267 try { 11268 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11269 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11270 | Intent.FLAG_RECEIVER_FOREGROUND); 11271 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11272 broadcastIntentLocked(null, null, intent, 11273 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11274 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11275 intent = new Intent(Intent.ACTION_USER_STARTING); 11276 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11277 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11278 broadcastIntentLocked(null, null, intent, 11279 null, new IIntentReceiver.Stub() { 11280 @Override 11281 public void performReceive(Intent intent, int resultCode, String data, 11282 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11283 throws RemoteException { 11284 } 11285 }, 0, null, null, 11286 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11287 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11288 } catch (Throwable t) { 11289 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11290 } finally { 11291 Binder.restoreCallingIdentity(ident); 11292 } 11293 mStackSupervisor.resumeTopActivitiesLocked(); 11294 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11295 } 11296 } 11297 11298 private boolean makeAppCrashingLocked(ProcessRecord app, 11299 String shortMsg, String longMsg, String stackTrace) { 11300 app.crashing = true; 11301 app.crashingReport = generateProcessError(app, 11302 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11303 startAppProblemLocked(app); 11304 app.stopFreezingAllLocked(); 11305 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11306 } 11307 11308 private void makeAppNotRespondingLocked(ProcessRecord app, 11309 String activity, String shortMsg, String longMsg) { 11310 app.notResponding = true; 11311 app.notRespondingReport = generateProcessError(app, 11312 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11313 activity, shortMsg, longMsg, null); 11314 startAppProblemLocked(app); 11315 app.stopFreezingAllLocked(); 11316 } 11317 11318 /** 11319 * Generate a process error record, suitable for attachment to a ProcessRecord. 11320 * 11321 * @param app The ProcessRecord in which the error occurred. 11322 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11323 * ActivityManager.AppErrorStateInfo 11324 * @param activity The activity associated with the crash, if known. 11325 * @param shortMsg Short message describing the crash. 11326 * @param longMsg Long message describing the crash. 11327 * @param stackTrace Full crash stack trace, may be null. 11328 * 11329 * @return Returns a fully-formed AppErrorStateInfo record. 11330 */ 11331 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11332 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11333 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11334 11335 report.condition = condition; 11336 report.processName = app.processName; 11337 report.pid = app.pid; 11338 report.uid = app.info.uid; 11339 report.tag = activity; 11340 report.shortMsg = shortMsg; 11341 report.longMsg = longMsg; 11342 report.stackTrace = stackTrace; 11343 11344 return report; 11345 } 11346 11347 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11348 synchronized (this) { 11349 app.crashing = false; 11350 app.crashingReport = null; 11351 app.notResponding = false; 11352 app.notRespondingReport = null; 11353 if (app.anrDialog == fromDialog) { 11354 app.anrDialog = null; 11355 } 11356 if (app.waitDialog == fromDialog) { 11357 app.waitDialog = null; 11358 } 11359 if (app.pid > 0 && app.pid != MY_PID) { 11360 handleAppCrashLocked(app, null, null, null); 11361 app.kill("user request after error", true); 11362 } 11363 } 11364 } 11365 11366 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11367 String stackTrace) { 11368 long now = SystemClock.uptimeMillis(); 11369 11370 Long crashTime; 11371 if (!app.isolated) { 11372 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11373 } else { 11374 crashTime = null; 11375 } 11376 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11377 // This process loses! 11378 Slog.w(TAG, "Process " + app.info.processName 11379 + " has crashed too many times: killing!"); 11380 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11381 app.userId, app.info.processName, app.uid); 11382 mStackSupervisor.handleAppCrashLocked(app); 11383 if (!app.persistent) { 11384 // We don't want to start this process again until the user 11385 // explicitly does so... but for persistent process, we really 11386 // need to keep it running. If a persistent process is actually 11387 // repeatedly crashing, then badness for everyone. 11388 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11389 app.info.processName); 11390 if (!app.isolated) { 11391 // XXX We don't have a way to mark isolated processes 11392 // as bad, since they don't have a peristent identity. 11393 mBadProcesses.put(app.info.processName, app.uid, 11394 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11395 mProcessCrashTimes.remove(app.info.processName, app.uid); 11396 } 11397 app.bad = true; 11398 app.removed = true; 11399 // Don't let services in this process be restarted and potentially 11400 // annoy the user repeatedly. Unless it is persistent, since those 11401 // processes run critical code. 11402 removeProcessLocked(app, false, false, "crash"); 11403 mStackSupervisor.resumeTopActivitiesLocked(); 11404 return false; 11405 } 11406 mStackSupervisor.resumeTopActivitiesLocked(); 11407 } else { 11408 mStackSupervisor.finishTopRunningActivityLocked(app); 11409 } 11410 11411 // Bump up the crash count of any services currently running in the proc. 11412 for (int i=app.services.size()-1; i>=0; i--) { 11413 // Any services running in the application need to be placed 11414 // back in the pending list. 11415 ServiceRecord sr = app.services.valueAt(i); 11416 sr.crashCount++; 11417 } 11418 11419 // If the crashing process is what we consider to be the "home process" and it has been 11420 // replaced by a third-party app, clear the package preferred activities from packages 11421 // with a home activity running in the process to prevent a repeatedly crashing app 11422 // from blocking the user to manually clear the list. 11423 final ArrayList<ActivityRecord> activities = app.activities; 11424 if (app == mHomeProcess && activities.size() > 0 11425 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11426 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11427 final ActivityRecord r = activities.get(activityNdx); 11428 if (r.isHomeActivity()) { 11429 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11430 try { 11431 ActivityThread.getPackageManager() 11432 .clearPackagePreferredActivities(r.packageName); 11433 } catch (RemoteException c) { 11434 // pm is in same process, this will never happen. 11435 } 11436 } 11437 } 11438 } 11439 11440 if (!app.isolated) { 11441 // XXX Can't keep track of crash times for isolated processes, 11442 // because they don't have a perisistent identity. 11443 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11444 } 11445 11446 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11447 return true; 11448 } 11449 11450 void startAppProblemLocked(ProcessRecord app) { 11451 // If this app is not running under the current user, then we 11452 // can't give it a report button because that would require 11453 // launching the report UI under a different user. 11454 app.errorReportReceiver = null; 11455 11456 for (int userId : mCurrentProfileIds) { 11457 if (app.userId == userId) { 11458 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11459 mContext, app.info.packageName, app.info.flags); 11460 } 11461 } 11462 skipCurrentReceiverLocked(app); 11463 } 11464 11465 void skipCurrentReceiverLocked(ProcessRecord app) { 11466 for (BroadcastQueue queue : mBroadcastQueues) { 11467 queue.skipCurrentReceiverLocked(app); 11468 } 11469 } 11470 11471 /** 11472 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11473 * The application process will exit immediately after this call returns. 11474 * @param app object of the crashing app, null for the system server 11475 * @param crashInfo describing the exception 11476 */ 11477 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11478 ProcessRecord r = findAppProcess(app, "Crash"); 11479 final String processName = app == null ? "system_server" 11480 : (r == null ? "unknown" : r.processName); 11481 11482 handleApplicationCrashInner("crash", r, processName, crashInfo); 11483 } 11484 11485 /* Native crash reporting uses this inner version because it needs to be somewhat 11486 * decoupled from the AM-managed cleanup lifecycle 11487 */ 11488 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11489 ApplicationErrorReport.CrashInfo crashInfo) { 11490 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11491 UserHandle.getUserId(Binder.getCallingUid()), processName, 11492 r == null ? -1 : r.info.flags, 11493 crashInfo.exceptionClassName, 11494 crashInfo.exceptionMessage, 11495 crashInfo.throwFileName, 11496 crashInfo.throwLineNumber); 11497 11498 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11499 11500 crashApplication(r, crashInfo); 11501 } 11502 11503 public void handleApplicationStrictModeViolation( 11504 IBinder app, 11505 int violationMask, 11506 StrictMode.ViolationInfo info) { 11507 ProcessRecord r = findAppProcess(app, "StrictMode"); 11508 if (r == null) { 11509 return; 11510 } 11511 11512 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11513 Integer stackFingerprint = info.hashCode(); 11514 boolean logIt = true; 11515 synchronized (mAlreadyLoggedViolatedStacks) { 11516 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11517 logIt = false; 11518 // TODO: sub-sample into EventLog for these, with 11519 // the info.durationMillis? Then we'd get 11520 // the relative pain numbers, without logging all 11521 // the stack traces repeatedly. We'd want to do 11522 // likewise in the client code, which also does 11523 // dup suppression, before the Binder call. 11524 } else { 11525 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11526 mAlreadyLoggedViolatedStacks.clear(); 11527 } 11528 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11529 } 11530 } 11531 if (logIt) { 11532 logStrictModeViolationToDropBox(r, info); 11533 } 11534 } 11535 11536 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11537 AppErrorResult result = new AppErrorResult(); 11538 synchronized (this) { 11539 final long origId = Binder.clearCallingIdentity(); 11540 11541 Message msg = Message.obtain(); 11542 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11543 HashMap<String, Object> data = new HashMap<String, Object>(); 11544 data.put("result", result); 11545 data.put("app", r); 11546 data.put("violationMask", violationMask); 11547 data.put("info", info); 11548 msg.obj = data; 11549 mHandler.sendMessage(msg); 11550 11551 Binder.restoreCallingIdentity(origId); 11552 } 11553 int res = result.get(); 11554 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11555 } 11556 } 11557 11558 // Depending on the policy in effect, there could be a bunch of 11559 // these in quick succession so we try to batch these together to 11560 // minimize disk writes, number of dropbox entries, and maximize 11561 // compression, by having more fewer, larger records. 11562 private void logStrictModeViolationToDropBox( 11563 ProcessRecord process, 11564 StrictMode.ViolationInfo info) { 11565 if (info == null) { 11566 return; 11567 } 11568 final boolean isSystemApp = process == null || 11569 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11570 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11571 final String processName = process == null ? "unknown" : process.processName; 11572 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11573 final DropBoxManager dbox = (DropBoxManager) 11574 mContext.getSystemService(Context.DROPBOX_SERVICE); 11575 11576 // Exit early if the dropbox isn't configured to accept this report type. 11577 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11578 11579 boolean bufferWasEmpty; 11580 boolean needsFlush; 11581 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11582 synchronized (sb) { 11583 bufferWasEmpty = sb.length() == 0; 11584 appendDropBoxProcessHeaders(process, processName, sb); 11585 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11586 sb.append("System-App: ").append(isSystemApp).append("\n"); 11587 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11588 if (info.violationNumThisLoop != 0) { 11589 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11590 } 11591 if (info.numAnimationsRunning != 0) { 11592 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11593 } 11594 if (info.broadcastIntentAction != null) { 11595 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11596 } 11597 if (info.durationMillis != -1) { 11598 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11599 } 11600 if (info.numInstances != -1) { 11601 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11602 } 11603 if (info.tags != null) { 11604 for (String tag : info.tags) { 11605 sb.append("Span-Tag: ").append(tag).append("\n"); 11606 } 11607 } 11608 sb.append("\n"); 11609 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11610 sb.append(info.crashInfo.stackTrace); 11611 } 11612 sb.append("\n"); 11613 11614 // Only buffer up to ~64k. Various logging bits truncate 11615 // things at 128k. 11616 needsFlush = (sb.length() > 64 * 1024); 11617 } 11618 11619 // Flush immediately if the buffer's grown too large, or this 11620 // is a non-system app. Non-system apps are isolated with a 11621 // different tag & policy and not batched. 11622 // 11623 // Batching is useful during internal testing with 11624 // StrictMode settings turned up high. Without batching, 11625 // thousands of separate files could be created on boot. 11626 if (!isSystemApp || needsFlush) { 11627 new Thread("Error dump: " + dropboxTag) { 11628 @Override 11629 public void run() { 11630 String report; 11631 synchronized (sb) { 11632 report = sb.toString(); 11633 sb.delete(0, sb.length()); 11634 sb.trimToSize(); 11635 } 11636 if (report.length() != 0) { 11637 dbox.addText(dropboxTag, report); 11638 } 11639 } 11640 }.start(); 11641 return; 11642 } 11643 11644 // System app batching: 11645 if (!bufferWasEmpty) { 11646 // An existing dropbox-writing thread is outstanding, so 11647 // we don't need to start it up. The existing thread will 11648 // catch the buffer appends we just did. 11649 return; 11650 } 11651 11652 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11653 // (After this point, we shouldn't access AMS internal data structures.) 11654 new Thread("Error dump: " + dropboxTag) { 11655 @Override 11656 public void run() { 11657 // 5 second sleep to let stacks arrive and be batched together 11658 try { 11659 Thread.sleep(5000); // 5 seconds 11660 } catch (InterruptedException e) {} 11661 11662 String errorReport; 11663 synchronized (mStrictModeBuffer) { 11664 errorReport = mStrictModeBuffer.toString(); 11665 if (errorReport.length() == 0) { 11666 return; 11667 } 11668 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11669 mStrictModeBuffer.trimToSize(); 11670 } 11671 dbox.addText(dropboxTag, errorReport); 11672 } 11673 }.start(); 11674 } 11675 11676 /** 11677 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11678 * @param app object of the crashing app, null for the system server 11679 * @param tag reported by the caller 11680 * @param system whether this wtf is coming from the system 11681 * @param crashInfo describing the context of the error 11682 * @return true if the process should exit immediately (WTF is fatal) 11683 */ 11684 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11685 final ApplicationErrorReport.CrashInfo crashInfo) { 11686 final int callingUid = Binder.getCallingUid(); 11687 final int callingPid = Binder.getCallingPid(); 11688 11689 if (system) { 11690 // If this is coming from the system, we could very well have low-level 11691 // system locks held, so we want to do this all asynchronously. And we 11692 // never want this to become fatal, so there is that too. 11693 mHandler.post(new Runnable() { 11694 @Override public void run() { 11695 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11696 } 11697 }); 11698 return false; 11699 } 11700 11701 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11702 crashInfo); 11703 11704 if (r != null && r.pid != Process.myPid() && 11705 Settings.Global.getInt(mContext.getContentResolver(), 11706 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11707 crashApplication(r, crashInfo); 11708 return true; 11709 } else { 11710 return false; 11711 } 11712 } 11713 11714 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11715 final ApplicationErrorReport.CrashInfo crashInfo) { 11716 final ProcessRecord r = findAppProcess(app, "WTF"); 11717 final String processName = app == null ? "system_server" 11718 : (r == null ? "unknown" : r.processName); 11719 11720 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11721 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11722 11723 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11724 11725 return r; 11726 } 11727 11728 /** 11729 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11730 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11731 */ 11732 private ProcessRecord findAppProcess(IBinder app, String reason) { 11733 if (app == null) { 11734 return null; 11735 } 11736 11737 synchronized (this) { 11738 final int NP = mProcessNames.getMap().size(); 11739 for (int ip=0; ip<NP; ip++) { 11740 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11741 final int NA = apps.size(); 11742 for (int ia=0; ia<NA; ia++) { 11743 ProcessRecord p = apps.valueAt(ia); 11744 if (p.thread != null && p.thread.asBinder() == app) { 11745 return p; 11746 } 11747 } 11748 } 11749 11750 Slog.w(TAG, "Can't find mystery application for " + reason 11751 + " from pid=" + Binder.getCallingPid() 11752 + " uid=" + Binder.getCallingUid() + ": " + app); 11753 return null; 11754 } 11755 } 11756 11757 /** 11758 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11759 * to append various headers to the dropbox log text. 11760 */ 11761 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11762 StringBuilder sb) { 11763 // Watchdog thread ends up invoking this function (with 11764 // a null ProcessRecord) to add the stack file to dropbox. 11765 // Do not acquire a lock on this (am) in such cases, as it 11766 // could cause a potential deadlock, if and when watchdog 11767 // is invoked due to unavailability of lock on am and it 11768 // would prevent watchdog from killing system_server. 11769 if (process == null) { 11770 sb.append("Process: ").append(processName).append("\n"); 11771 return; 11772 } 11773 // Note: ProcessRecord 'process' is guarded by the service 11774 // instance. (notably process.pkgList, which could otherwise change 11775 // concurrently during execution of this method) 11776 synchronized (this) { 11777 sb.append("Process: ").append(processName).append("\n"); 11778 int flags = process.info.flags; 11779 IPackageManager pm = AppGlobals.getPackageManager(); 11780 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11781 for (int ip=0; ip<process.pkgList.size(); ip++) { 11782 String pkg = process.pkgList.keyAt(ip); 11783 sb.append("Package: ").append(pkg); 11784 try { 11785 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11786 if (pi != null) { 11787 sb.append(" v").append(pi.versionCode); 11788 if (pi.versionName != null) { 11789 sb.append(" (").append(pi.versionName).append(")"); 11790 } 11791 } 11792 } catch (RemoteException e) { 11793 Slog.e(TAG, "Error getting package info: " + pkg, e); 11794 } 11795 sb.append("\n"); 11796 } 11797 } 11798 } 11799 11800 private static String processClass(ProcessRecord process) { 11801 if (process == null || process.pid == MY_PID) { 11802 return "system_server"; 11803 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11804 return "system_app"; 11805 } else { 11806 return "data_app"; 11807 } 11808 } 11809 11810 /** 11811 * Write a description of an error (crash, WTF, ANR) to the drop box. 11812 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11813 * @param process which caused the error, null means the system server 11814 * @param activity which triggered the error, null if unknown 11815 * @param parent activity related to the error, null if unknown 11816 * @param subject line related to the error, null if absent 11817 * @param report in long form describing the error, null if absent 11818 * @param logFile to include in the report, null if none 11819 * @param crashInfo giving an application stack trace, null if absent 11820 */ 11821 public void addErrorToDropBox(String eventType, 11822 ProcessRecord process, String processName, ActivityRecord activity, 11823 ActivityRecord parent, String subject, 11824 final String report, final File logFile, 11825 final ApplicationErrorReport.CrashInfo crashInfo) { 11826 // NOTE -- this must never acquire the ActivityManagerService lock, 11827 // otherwise the watchdog may be prevented from resetting the system. 11828 11829 final String dropboxTag = processClass(process) + "_" + eventType; 11830 final DropBoxManager dbox = (DropBoxManager) 11831 mContext.getSystemService(Context.DROPBOX_SERVICE); 11832 11833 // Exit early if the dropbox isn't configured to accept this report type. 11834 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11835 11836 final StringBuilder sb = new StringBuilder(1024); 11837 appendDropBoxProcessHeaders(process, processName, sb); 11838 if (activity != null) { 11839 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11840 } 11841 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11842 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11843 } 11844 if (parent != null && parent != activity) { 11845 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11846 } 11847 if (subject != null) { 11848 sb.append("Subject: ").append(subject).append("\n"); 11849 } 11850 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11851 if (Debug.isDebuggerConnected()) { 11852 sb.append("Debugger: Connected\n"); 11853 } 11854 sb.append("\n"); 11855 11856 // Do the rest in a worker thread to avoid blocking the caller on I/O 11857 // (After this point, we shouldn't access AMS internal data structures.) 11858 Thread worker = new Thread("Error dump: " + dropboxTag) { 11859 @Override 11860 public void run() { 11861 if (report != null) { 11862 sb.append(report); 11863 } 11864 if (logFile != null) { 11865 try { 11866 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11867 "\n\n[[TRUNCATED]]")); 11868 } catch (IOException e) { 11869 Slog.e(TAG, "Error reading " + logFile, e); 11870 } 11871 } 11872 if (crashInfo != null && crashInfo.stackTrace != null) { 11873 sb.append(crashInfo.stackTrace); 11874 } 11875 11876 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11877 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11878 if (lines > 0) { 11879 sb.append("\n"); 11880 11881 // Merge several logcat streams, and take the last N lines 11882 InputStreamReader input = null; 11883 try { 11884 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11885 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11886 "-b", "crash", 11887 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11888 11889 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11890 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11891 input = new InputStreamReader(logcat.getInputStream()); 11892 11893 int num; 11894 char[] buf = new char[8192]; 11895 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11896 } catch (IOException e) { 11897 Slog.e(TAG, "Error running logcat", e); 11898 } finally { 11899 if (input != null) try { input.close(); } catch (IOException e) {} 11900 } 11901 } 11902 11903 dbox.addText(dropboxTag, sb.toString()); 11904 } 11905 }; 11906 11907 if (process == null) { 11908 // If process is null, we are being called from some internal code 11909 // and may be about to die -- run this synchronously. 11910 worker.run(); 11911 } else { 11912 worker.start(); 11913 } 11914 } 11915 11916 /** 11917 * Bring up the "unexpected error" dialog box for a crashing app. 11918 * Deal with edge cases (intercepts from instrumented applications, 11919 * ActivityController, error intent receivers, that sort of thing). 11920 * @param r the application crashing 11921 * @param crashInfo describing the failure 11922 */ 11923 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11924 long timeMillis = System.currentTimeMillis(); 11925 String shortMsg = crashInfo.exceptionClassName; 11926 String longMsg = crashInfo.exceptionMessage; 11927 String stackTrace = crashInfo.stackTrace; 11928 if (shortMsg != null && longMsg != null) { 11929 longMsg = shortMsg + ": " + longMsg; 11930 } else if (shortMsg != null) { 11931 longMsg = shortMsg; 11932 } 11933 11934 AppErrorResult result = new AppErrorResult(); 11935 synchronized (this) { 11936 if (mController != null) { 11937 try { 11938 String name = r != null ? r.processName : null; 11939 int pid = r != null ? r.pid : Binder.getCallingPid(); 11940 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11941 if (!mController.appCrashed(name, pid, 11942 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11943 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11944 && "Native crash".equals(crashInfo.exceptionClassName)) { 11945 Slog.w(TAG, "Skip killing native crashed app " + name 11946 + "(" + pid + ") during testing"); 11947 } else { 11948 Slog.w(TAG, "Force-killing crashed app " + name 11949 + " at watcher's request"); 11950 if (r != null) { 11951 r.kill("crash", true); 11952 } else { 11953 // Huh. 11954 Process.killProcess(pid); 11955 Process.killProcessGroup(uid, pid); 11956 } 11957 } 11958 return; 11959 } 11960 } catch (RemoteException e) { 11961 mController = null; 11962 Watchdog.getInstance().setActivityController(null); 11963 } 11964 } 11965 11966 final long origId = Binder.clearCallingIdentity(); 11967 11968 // If this process is running instrumentation, finish it. 11969 if (r != null && r.instrumentationClass != null) { 11970 Slog.w(TAG, "Error in app " + r.processName 11971 + " running instrumentation " + r.instrumentationClass + ":"); 11972 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11973 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11974 Bundle info = new Bundle(); 11975 info.putString("shortMsg", shortMsg); 11976 info.putString("longMsg", longMsg); 11977 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11978 Binder.restoreCallingIdentity(origId); 11979 return; 11980 } 11981 11982 // If we can't identify the process or it's already exceeded its crash quota, 11983 // quit right away without showing a crash dialog. 11984 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11985 Binder.restoreCallingIdentity(origId); 11986 return; 11987 } 11988 11989 Message msg = Message.obtain(); 11990 msg.what = SHOW_ERROR_MSG; 11991 HashMap data = new HashMap(); 11992 data.put("result", result); 11993 data.put("app", r); 11994 msg.obj = data; 11995 mHandler.sendMessage(msg); 11996 11997 Binder.restoreCallingIdentity(origId); 11998 } 11999 12000 int res = result.get(); 12001 12002 Intent appErrorIntent = null; 12003 synchronized (this) { 12004 if (r != null && !r.isolated) { 12005 // XXX Can't keep track of crash time for isolated processes, 12006 // since they don't have a persistent identity. 12007 mProcessCrashTimes.put(r.info.processName, r.uid, 12008 SystemClock.uptimeMillis()); 12009 } 12010 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12011 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12012 } 12013 } 12014 12015 if (appErrorIntent != null) { 12016 try { 12017 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12018 } catch (ActivityNotFoundException e) { 12019 Slog.w(TAG, "bug report receiver dissappeared", e); 12020 } 12021 } 12022 } 12023 12024 Intent createAppErrorIntentLocked(ProcessRecord r, 12025 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12026 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12027 if (report == null) { 12028 return null; 12029 } 12030 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12031 result.setComponent(r.errorReportReceiver); 12032 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12033 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12034 return result; 12035 } 12036 12037 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12038 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12039 if (r.errorReportReceiver == null) { 12040 return null; 12041 } 12042 12043 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12044 return null; 12045 } 12046 12047 ApplicationErrorReport report = new ApplicationErrorReport(); 12048 report.packageName = r.info.packageName; 12049 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12050 report.processName = r.processName; 12051 report.time = timeMillis; 12052 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12053 12054 if (r.crashing || r.forceCrashReport) { 12055 report.type = ApplicationErrorReport.TYPE_CRASH; 12056 report.crashInfo = crashInfo; 12057 } else if (r.notResponding) { 12058 report.type = ApplicationErrorReport.TYPE_ANR; 12059 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12060 12061 report.anrInfo.activity = r.notRespondingReport.tag; 12062 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12063 report.anrInfo.info = r.notRespondingReport.longMsg; 12064 } 12065 12066 return report; 12067 } 12068 12069 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12070 enforceNotIsolatedCaller("getProcessesInErrorState"); 12071 // assume our apps are happy - lazy create the list 12072 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12073 12074 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12075 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12076 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12077 12078 synchronized (this) { 12079 12080 // iterate across all processes 12081 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12082 ProcessRecord app = mLruProcesses.get(i); 12083 if (!allUsers && app.userId != userId) { 12084 continue; 12085 } 12086 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12087 // This one's in trouble, so we'll generate a report for it 12088 // crashes are higher priority (in case there's a crash *and* an anr) 12089 ActivityManager.ProcessErrorStateInfo report = null; 12090 if (app.crashing) { 12091 report = app.crashingReport; 12092 } else if (app.notResponding) { 12093 report = app.notRespondingReport; 12094 } 12095 12096 if (report != null) { 12097 if (errList == null) { 12098 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12099 } 12100 errList.add(report); 12101 } else { 12102 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12103 " crashing = " + app.crashing + 12104 " notResponding = " + app.notResponding); 12105 } 12106 } 12107 } 12108 } 12109 12110 return errList; 12111 } 12112 12113 static int procStateToImportance(int procState, int memAdj, 12114 ActivityManager.RunningAppProcessInfo currApp) { 12115 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12116 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12117 currApp.lru = memAdj; 12118 } else { 12119 currApp.lru = 0; 12120 } 12121 return imp; 12122 } 12123 12124 private void fillInProcMemInfo(ProcessRecord app, 12125 ActivityManager.RunningAppProcessInfo outInfo) { 12126 outInfo.pid = app.pid; 12127 outInfo.uid = app.info.uid; 12128 if (mHeavyWeightProcess == app) { 12129 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12130 } 12131 if (app.persistent) { 12132 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12133 } 12134 if (app.activities.size() > 0) { 12135 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12136 } 12137 outInfo.lastTrimLevel = app.trimMemoryLevel; 12138 int adj = app.curAdj; 12139 int procState = app.curProcState; 12140 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12141 outInfo.importanceReasonCode = app.adjTypeCode; 12142 outInfo.processState = app.curProcState; 12143 } 12144 12145 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12146 enforceNotIsolatedCaller("getRunningAppProcesses"); 12147 // Lazy instantiation of list 12148 List<ActivityManager.RunningAppProcessInfo> runList = null; 12149 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12150 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12151 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12152 synchronized (this) { 12153 // Iterate across all processes 12154 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12155 ProcessRecord app = mLruProcesses.get(i); 12156 if (!allUsers && app.userId != userId) { 12157 continue; 12158 } 12159 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12160 // Generate process state info for running application 12161 ActivityManager.RunningAppProcessInfo currApp = 12162 new ActivityManager.RunningAppProcessInfo(app.processName, 12163 app.pid, app.getPackageList()); 12164 fillInProcMemInfo(app, currApp); 12165 if (app.adjSource instanceof ProcessRecord) { 12166 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12167 currApp.importanceReasonImportance = 12168 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12169 app.adjSourceProcState); 12170 } else if (app.adjSource instanceof ActivityRecord) { 12171 ActivityRecord r = (ActivityRecord)app.adjSource; 12172 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12173 } 12174 if (app.adjTarget instanceof ComponentName) { 12175 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12176 } 12177 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12178 // + " lru=" + currApp.lru); 12179 if (runList == null) { 12180 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12181 } 12182 runList.add(currApp); 12183 } 12184 } 12185 } 12186 return runList; 12187 } 12188 12189 public List<ApplicationInfo> getRunningExternalApplications() { 12190 enforceNotIsolatedCaller("getRunningExternalApplications"); 12191 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12192 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12193 if (runningApps != null && runningApps.size() > 0) { 12194 Set<String> extList = new HashSet<String>(); 12195 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12196 if (app.pkgList != null) { 12197 for (String pkg : app.pkgList) { 12198 extList.add(pkg); 12199 } 12200 } 12201 } 12202 IPackageManager pm = AppGlobals.getPackageManager(); 12203 for (String pkg : extList) { 12204 try { 12205 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12206 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12207 retList.add(info); 12208 } 12209 } catch (RemoteException e) { 12210 } 12211 } 12212 } 12213 return retList; 12214 } 12215 12216 @Override 12217 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12218 enforceNotIsolatedCaller("getMyMemoryState"); 12219 synchronized (this) { 12220 ProcessRecord proc; 12221 synchronized (mPidsSelfLocked) { 12222 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12223 } 12224 fillInProcMemInfo(proc, outInfo); 12225 } 12226 } 12227 12228 @Override 12229 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12230 if (checkCallingPermission(android.Manifest.permission.DUMP) 12231 != PackageManager.PERMISSION_GRANTED) { 12232 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12233 + Binder.getCallingPid() 12234 + ", uid=" + Binder.getCallingUid() 12235 + " without permission " 12236 + android.Manifest.permission.DUMP); 12237 return; 12238 } 12239 12240 boolean dumpAll = false; 12241 boolean dumpClient = false; 12242 String dumpPackage = null; 12243 12244 int opti = 0; 12245 while (opti < args.length) { 12246 String opt = args[opti]; 12247 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12248 break; 12249 } 12250 opti++; 12251 if ("-a".equals(opt)) { 12252 dumpAll = true; 12253 } else if ("-c".equals(opt)) { 12254 dumpClient = true; 12255 } else if ("-h".equals(opt)) { 12256 pw.println("Activity manager dump options:"); 12257 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12258 pw.println(" cmd may be one of:"); 12259 pw.println(" a[ctivities]: activity stack state"); 12260 pw.println(" r[recents]: recent activities state"); 12261 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12262 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12263 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12264 pw.println(" o[om]: out of memory management"); 12265 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12266 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12267 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12268 pw.println(" service [COMP_SPEC]: service client-side state"); 12269 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12270 pw.println(" all: dump all activities"); 12271 pw.println(" top: dump the top activity"); 12272 pw.println(" write: write all pending state to storage"); 12273 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12274 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12275 pw.println(" a partial substring in a component name, a"); 12276 pw.println(" hex object identifier."); 12277 pw.println(" -a: include all available server state."); 12278 pw.println(" -c: include client state."); 12279 return; 12280 } else { 12281 pw.println("Unknown argument: " + opt + "; use -h for help"); 12282 } 12283 } 12284 12285 long origId = Binder.clearCallingIdentity(); 12286 boolean more = false; 12287 // Is the caller requesting to dump a particular piece of data? 12288 if (opti < args.length) { 12289 String cmd = args[opti]; 12290 opti++; 12291 if ("activities".equals(cmd) || "a".equals(cmd)) { 12292 synchronized (this) { 12293 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12294 } 12295 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12296 synchronized (this) { 12297 dumpRecentsLocked(fd, pw, args, opti, true, null); 12298 } 12299 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12300 String[] newArgs; 12301 String name; 12302 if (opti >= args.length) { 12303 name = null; 12304 newArgs = EMPTY_STRING_ARRAY; 12305 } else { 12306 name = args[opti]; 12307 opti++; 12308 newArgs = new String[args.length - opti]; 12309 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12310 args.length - opti); 12311 } 12312 synchronized (this) { 12313 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12314 } 12315 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12316 String[] newArgs; 12317 String name; 12318 if (opti >= args.length) { 12319 name = null; 12320 newArgs = EMPTY_STRING_ARRAY; 12321 } else { 12322 name = args[opti]; 12323 opti++; 12324 newArgs = new String[args.length - opti]; 12325 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12326 args.length - opti); 12327 } 12328 synchronized (this) { 12329 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12330 } 12331 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12332 String[] newArgs; 12333 String name; 12334 if (opti >= args.length) { 12335 name = null; 12336 newArgs = EMPTY_STRING_ARRAY; 12337 } else { 12338 name = args[opti]; 12339 opti++; 12340 newArgs = new String[args.length - opti]; 12341 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12342 args.length - opti); 12343 } 12344 synchronized (this) { 12345 dumpProcessesLocked(fd, pw, args, opti, true, name); 12346 } 12347 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12348 synchronized (this) { 12349 dumpOomLocked(fd, pw, args, opti, true); 12350 } 12351 } else if ("provider".equals(cmd)) { 12352 String[] newArgs; 12353 String name; 12354 if (opti >= args.length) { 12355 name = null; 12356 newArgs = EMPTY_STRING_ARRAY; 12357 } else { 12358 name = args[opti]; 12359 opti++; 12360 newArgs = new String[args.length - opti]; 12361 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12362 } 12363 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12364 pw.println("No providers match: " + name); 12365 pw.println("Use -h for help."); 12366 } 12367 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12368 synchronized (this) { 12369 dumpProvidersLocked(fd, pw, args, opti, true, null); 12370 } 12371 } else if ("service".equals(cmd)) { 12372 String[] newArgs; 12373 String name; 12374 if (opti >= args.length) { 12375 name = null; 12376 newArgs = EMPTY_STRING_ARRAY; 12377 } else { 12378 name = args[opti]; 12379 opti++; 12380 newArgs = new String[args.length - opti]; 12381 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12382 args.length - opti); 12383 } 12384 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12385 pw.println("No services match: " + name); 12386 pw.println("Use -h for help."); 12387 } 12388 } else if ("package".equals(cmd)) { 12389 String[] newArgs; 12390 if (opti >= args.length) { 12391 pw.println("package: no package name specified"); 12392 pw.println("Use -h for help."); 12393 } else { 12394 dumpPackage = args[opti]; 12395 opti++; 12396 newArgs = new String[args.length - opti]; 12397 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12398 args.length - opti); 12399 args = newArgs; 12400 opti = 0; 12401 more = true; 12402 } 12403 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12404 synchronized (this) { 12405 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12406 } 12407 } else if ("write".equals(cmd)) { 12408 mTaskPersister.flush(); 12409 pw.println("All tasks persisted."); 12410 return; 12411 } else { 12412 // Dumping a single activity? 12413 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12414 pw.println("Bad activity command, or no activities match: " + cmd); 12415 pw.println("Use -h for help."); 12416 } 12417 } 12418 if (!more) { 12419 Binder.restoreCallingIdentity(origId); 12420 return; 12421 } 12422 } 12423 12424 // No piece of data specified, dump everything. 12425 synchronized (this) { 12426 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12427 pw.println(); 12428 if (dumpAll) { 12429 pw.println("-------------------------------------------------------------------------------"); 12430 } 12431 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12432 pw.println(); 12433 if (dumpAll) { 12434 pw.println("-------------------------------------------------------------------------------"); 12435 } 12436 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12437 pw.println(); 12438 if (dumpAll) { 12439 pw.println("-------------------------------------------------------------------------------"); 12440 } 12441 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12442 pw.println(); 12443 if (dumpAll) { 12444 pw.println("-------------------------------------------------------------------------------"); 12445 } 12446 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12447 pw.println(); 12448 if (dumpAll) { 12449 pw.println("-------------------------------------------------------------------------------"); 12450 } 12451 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12452 pw.println(); 12453 if (dumpAll) { 12454 pw.println("-------------------------------------------------------------------------------"); 12455 } 12456 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12457 } 12458 Binder.restoreCallingIdentity(origId); 12459 } 12460 12461 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12462 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12463 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12464 12465 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12466 dumpPackage); 12467 boolean needSep = printedAnything; 12468 12469 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12470 dumpPackage, needSep, " mFocusedActivity: "); 12471 if (printed) { 12472 printedAnything = true; 12473 needSep = false; 12474 } 12475 12476 if (dumpPackage == null) { 12477 if (needSep) { 12478 pw.println(); 12479 } 12480 needSep = true; 12481 printedAnything = true; 12482 mStackSupervisor.dump(pw, " "); 12483 } 12484 12485 if (!printedAnything) { 12486 pw.println(" (nothing)"); 12487 } 12488 } 12489 12490 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12491 int opti, boolean dumpAll, String dumpPackage) { 12492 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12493 12494 boolean printedAnything = false; 12495 12496 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12497 boolean printedHeader = false; 12498 12499 final int N = mRecentTasks.size(); 12500 for (int i=0; i<N; i++) { 12501 TaskRecord tr = mRecentTasks.get(i); 12502 if (dumpPackage != null) { 12503 if (tr.realActivity == null || 12504 !dumpPackage.equals(tr.realActivity)) { 12505 continue; 12506 } 12507 } 12508 if (!printedHeader) { 12509 pw.println(" Recent tasks:"); 12510 printedHeader = true; 12511 printedAnything = true; 12512 } 12513 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12514 pw.println(tr); 12515 if (dumpAll) { 12516 mRecentTasks.get(i).dump(pw, " "); 12517 } 12518 } 12519 } 12520 12521 if (!printedAnything) { 12522 pw.println(" (nothing)"); 12523 } 12524 } 12525 12526 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12527 int opti, boolean dumpAll, String dumpPackage) { 12528 boolean needSep = false; 12529 boolean printedAnything = false; 12530 int numPers = 0; 12531 12532 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12533 12534 if (dumpAll) { 12535 final int NP = mProcessNames.getMap().size(); 12536 for (int ip=0; ip<NP; ip++) { 12537 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12538 final int NA = procs.size(); 12539 for (int ia=0; ia<NA; ia++) { 12540 ProcessRecord r = procs.valueAt(ia); 12541 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12542 continue; 12543 } 12544 if (!needSep) { 12545 pw.println(" All known processes:"); 12546 needSep = true; 12547 printedAnything = true; 12548 } 12549 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12550 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12551 pw.print(" "); pw.println(r); 12552 r.dump(pw, " "); 12553 if (r.persistent) { 12554 numPers++; 12555 } 12556 } 12557 } 12558 } 12559 12560 if (mIsolatedProcesses.size() > 0) { 12561 boolean printed = false; 12562 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12563 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12564 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12565 continue; 12566 } 12567 if (!printed) { 12568 if (needSep) { 12569 pw.println(); 12570 } 12571 pw.println(" Isolated process list (sorted by uid):"); 12572 printedAnything = true; 12573 printed = true; 12574 needSep = true; 12575 } 12576 pw.println(String.format("%sIsolated #%2d: %s", 12577 " ", i, r.toString())); 12578 } 12579 } 12580 12581 if (mLruProcesses.size() > 0) { 12582 if (needSep) { 12583 pw.println(); 12584 } 12585 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12586 pw.print(" total, non-act at "); 12587 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12588 pw.print(", non-svc at "); 12589 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12590 pw.println("):"); 12591 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12592 needSep = true; 12593 printedAnything = true; 12594 } 12595 12596 if (dumpAll || dumpPackage != null) { 12597 synchronized (mPidsSelfLocked) { 12598 boolean printed = false; 12599 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12600 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12601 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12602 continue; 12603 } 12604 if (!printed) { 12605 if (needSep) pw.println(); 12606 needSep = true; 12607 pw.println(" PID mappings:"); 12608 printed = true; 12609 printedAnything = true; 12610 } 12611 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12612 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12613 } 12614 } 12615 } 12616 12617 if (mForegroundProcesses.size() > 0) { 12618 synchronized (mPidsSelfLocked) { 12619 boolean printed = false; 12620 for (int i=0; i<mForegroundProcesses.size(); i++) { 12621 ProcessRecord r = mPidsSelfLocked.get( 12622 mForegroundProcesses.valueAt(i).pid); 12623 if (dumpPackage != null && (r == null 12624 || !r.pkgList.containsKey(dumpPackage))) { 12625 continue; 12626 } 12627 if (!printed) { 12628 if (needSep) pw.println(); 12629 needSep = true; 12630 pw.println(" Foreground Processes:"); 12631 printed = true; 12632 printedAnything = true; 12633 } 12634 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12635 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12636 } 12637 } 12638 } 12639 12640 if (mPersistentStartingProcesses.size() > 0) { 12641 if (needSep) pw.println(); 12642 needSep = true; 12643 printedAnything = true; 12644 pw.println(" Persisent processes that are starting:"); 12645 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12646 "Starting Norm", "Restarting PERS", dumpPackage); 12647 } 12648 12649 if (mRemovedProcesses.size() > 0) { 12650 if (needSep) pw.println(); 12651 needSep = true; 12652 printedAnything = true; 12653 pw.println(" Processes that are being removed:"); 12654 dumpProcessList(pw, this, mRemovedProcesses, " ", 12655 "Removed Norm", "Removed PERS", dumpPackage); 12656 } 12657 12658 if (mProcessesOnHold.size() > 0) { 12659 if (needSep) pw.println(); 12660 needSep = true; 12661 printedAnything = true; 12662 pw.println(" Processes that are on old until the system is ready:"); 12663 dumpProcessList(pw, this, mProcessesOnHold, " ", 12664 "OnHold Norm", "OnHold PERS", dumpPackage); 12665 } 12666 12667 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12668 12669 if (mProcessCrashTimes.getMap().size() > 0) { 12670 boolean printed = false; 12671 long now = SystemClock.uptimeMillis(); 12672 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12673 final int NP = pmap.size(); 12674 for (int ip=0; ip<NP; ip++) { 12675 String pname = pmap.keyAt(ip); 12676 SparseArray<Long> uids = pmap.valueAt(ip); 12677 final int N = uids.size(); 12678 for (int i=0; i<N; i++) { 12679 int puid = uids.keyAt(i); 12680 ProcessRecord r = mProcessNames.get(pname, puid); 12681 if (dumpPackage != null && (r == null 12682 || !r.pkgList.containsKey(dumpPackage))) { 12683 continue; 12684 } 12685 if (!printed) { 12686 if (needSep) pw.println(); 12687 needSep = true; 12688 pw.println(" Time since processes crashed:"); 12689 printed = true; 12690 printedAnything = true; 12691 } 12692 pw.print(" Process "); pw.print(pname); 12693 pw.print(" uid "); pw.print(puid); 12694 pw.print(": last crashed "); 12695 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12696 pw.println(" ago"); 12697 } 12698 } 12699 } 12700 12701 if (mBadProcesses.getMap().size() > 0) { 12702 boolean printed = false; 12703 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12704 final int NP = pmap.size(); 12705 for (int ip=0; ip<NP; ip++) { 12706 String pname = pmap.keyAt(ip); 12707 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12708 final int N = uids.size(); 12709 for (int i=0; i<N; i++) { 12710 int puid = uids.keyAt(i); 12711 ProcessRecord r = mProcessNames.get(pname, puid); 12712 if (dumpPackage != null && (r == null 12713 || !r.pkgList.containsKey(dumpPackage))) { 12714 continue; 12715 } 12716 if (!printed) { 12717 if (needSep) pw.println(); 12718 needSep = true; 12719 pw.println(" Bad processes:"); 12720 printedAnything = true; 12721 } 12722 BadProcessInfo info = uids.valueAt(i); 12723 pw.print(" Bad process "); pw.print(pname); 12724 pw.print(" uid "); pw.print(puid); 12725 pw.print(": crashed at time "); pw.println(info.time); 12726 if (info.shortMsg != null) { 12727 pw.print(" Short msg: "); pw.println(info.shortMsg); 12728 } 12729 if (info.longMsg != null) { 12730 pw.print(" Long msg: "); pw.println(info.longMsg); 12731 } 12732 if (info.stack != null) { 12733 pw.println(" Stack:"); 12734 int lastPos = 0; 12735 for (int pos=0; pos<info.stack.length(); pos++) { 12736 if (info.stack.charAt(pos) == '\n') { 12737 pw.print(" "); 12738 pw.write(info.stack, lastPos, pos-lastPos); 12739 pw.println(); 12740 lastPos = pos+1; 12741 } 12742 } 12743 if (lastPos < info.stack.length()) { 12744 pw.print(" "); 12745 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12746 pw.println(); 12747 } 12748 } 12749 } 12750 } 12751 } 12752 12753 if (dumpPackage == null) { 12754 pw.println(); 12755 needSep = false; 12756 pw.println(" mStartedUsers:"); 12757 for (int i=0; i<mStartedUsers.size(); i++) { 12758 UserStartedState uss = mStartedUsers.valueAt(i); 12759 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12760 pw.print(": "); uss.dump("", pw); 12761 } 12762 pw.print(" mStartedUserArray: ["); 12763 for (int i=0; i<mStartedUserArray.length; i++) { 12764 if (i > 0) pw.print(", "); 12765 pw.print(mStartedUserArray[i]); 12766 } 12767 pw.println("]"); 12768 pw.print(" mUserLru: ["); 12769 for (int i=0; i<mUserLru.size(); i++) { 12770 if (i > 0) pw.print(", "); 12771 pw.print(mUserLru.get(i)); 12772 } 12773 pw.println("]"); 12774 if (dumpAll) { 12775 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12776 } 12777 synchronized (mUserProfileGroupIdsSelfLocked) { 12778 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12779 pw.println(" mUserProfileGroupIds:"); 12780 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12781 pw.print(" User #"); 12782 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12783 pw.print(" -> profile #"); 12784 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12785 } 12786 } 12787 } 12788 } 12789 if (mHomeProcess != null && (dumpPackage == null 12790 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12791 if (needSep) { 12792 pw.println(); 12793 needSep = false; 12794 } 12795 pw.println(" mHomeProcess: " + mHomeProcess); 12796 } 12797 if (mPreviousProcess != null && (dumpPackage == null 12798 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12799 if (needSep) { 12800 pw.println(); 12801 needSep = false; 12802 } 12803 pw.println(" mPreviousProcess: " + mPreviousProcess); 12804 } 12805 if (dumpAll) { 12806 StringBuilder sb = new StringBuilder(128); 12807 sb.append(" mPreviousProcessVisibleTime: "); 12808 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12809 pw.println(sb); 12810 } 12811 if (mHeavyWeightProcess != null && (dumpPackage == null 12812 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12813 if (needSep) { 12814 pw.println(); 12815 needSep = false; 12816 } 12817 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12818 } 12819 if (dumpPackage == null) { 12820 pw.println(" mConfiguration: " + mConfiguration); 12821 } 12822 if (dumpAll) { 12823 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12824 if (mCompatModePackages.getPackages().size() > 0) { 12825 boolean printed = false; 12826 for (Map.Entry<String, Integer> entry 12827 : mCompatModePackages.getPackages().entrySet()) { 12828 String pkg = entry.getKey(); 12829 int mode = entry.getValue(); 12830 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12831 continue; 12832 } 12833 if (!printed) { 12834 pw.println(" mScreenCompatPackages:"); 12835 printed = true; 12836 } 12837 pw.print(" "); pw.print(pkg); pw.print(": "); 12838 pw.print(mode); pw.println(); 12839 } 12840 } 12841 } 12842 if (dumpPackage == null) { 12843 pw.println(" mWakefulness=" 12844 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12845 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12846 + lockScreenShownToString()); 12847 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12848 } 12849 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12850 || mOrigWaitForDebugger) { 12851 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12852 || dumpPackage.equals(mOrigDebugApp)) { 12853 if (needSep) { 12854 pw.println(); 12855 needSep = false; 12856 } 12857 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12858 + " mDebugTransient=" + mDebugTransient 12859 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12860 } 12861 } 12862 if (mOpenGlTraceApp != null) { 12863 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12864 if (needSep) { 12865 pw.println(); 12866 needSep = false; 12867 } 12868 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12869 } 12870 } 12871 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12872 || mProfileFd != null) { 12873 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12874 if (needSep) { 12875 pw.println(); 12876 needSep = false; 12877 } 12878 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12879 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12880 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12881 + mAutoStopProfiler); 12882 pw.println(" mProfileType=" + mProfileType); 12883 } 12884 } 12885 if (dumpPackage == null) { 12886 if (mAlwaysFinishActivities || mController != null) { 12887 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12888 + " mController=" + mController); 12889 } 12890 if (dumpAll) { 12891 pw.println(" Total persistent processes: " + numPers); 12892 pw.println(" mProcessesReady=" + mProcessesReady 12893 + " mSystemReady=" + mSystemReady 12894 + " mBooted=" + mBooted 12895 + " mFactoryTest=" + mFactoryTest); 12896 pw.println(" mBooting=" + mBooting 12897 + " mCallFinishBooting=" + mCallFinishBooting 12898 + " mBootAnimationComplete=" + mBootAnimationComplete); 12899 pw.print(" mLastPowerCheckRealtime="); 12900 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12901 pw.println(""); 12902 pw.print(" mLastPowerCheckUptime="); 12903 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12904 pw.println(""); 12905 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12906 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12907 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12908 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12909 + " (" + mLruProcesses.size() + " total)" 12910 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12911 + " mNumServiceProcs=" + mNumServiceProcs 12912 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12913 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12914 + " mLastMemoryLevel" + mLastMemoryLevel 12915 + " mLastNumProcesses" + mLastNumProcesses); 12916 long now = SystemClock.uptimeMillis(); 12917 pw.print(" mLastIdleTime="); 12918 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12919 pw.print(" mLowRamSinceLastIdle="); 12920 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12921 pw.println(); 12922 } 12923 } 12924 12925 if (!printedAnything) { 12926 pw.println(" (nothing)"); 12927 } 12928 } 12929 12930 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12931 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12932 if (mProcessesToGc.size() > 0) { 12933 boolean printed = false; 12934 long now = SystemClock.uptimeMillis(); 12935 for (int i=0; i<mProcessesToGc.size(); i++) { 12936 ProcessRecord proc = mProcessesToGc.get(i); 12937 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12938 continue; 12939 } 12940 if (!printed) { 12941 if (needSep) pw.println(); 12942 needSep = true; 12943 pw.println(" Processes that are waiting to GC:"); 12944 printed = true; 12945 } 12946 pw.print(" Process "); pw.println(proc); 12947 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12948 pw.print(", last gced="); 12949 pw.print(now-proc.lastRequestedGc); 12950 pw.print(" ms ago, last lowMem="); 12951 pw.print(now-proc.lastLowMemory); 12952 pw.println(" ms ago"); 12953 12954 } 12955 } 12956 return needSep; 12957 } 12958 12959 void printOomLevel(PrintWriter pw, String name, int adj) { 12960 pw.print(" "); 12961 if (adj >= 0) { 12962 pw.print(' '); 12963 if (adj < 10) pw.print(' '); 12964 } else { 12965 if (adj > -10) pw.print(' '); 12966 } 12967 pw.print(adj); 12968 pw.print(": "); 12969 pw.print(name); 12970 pw.print(" ("); 12971 pw.print(mProcessList.getMemLevel(adj)/1024); 12972 pw.println(" kB)"); 12973 } 12974 12975 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12976 int opti, boolean dumpAll) { 12977 boolean needSep = false; 12978 12979 if (mLruProcesses.size() > 0) { 12980 if (needSep) pw.println(); 12981 needSep = true; 12982 pw.println(" OOM levels:"); 12983 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12984 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12985 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12986 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12987 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12988 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12989 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12990 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12991 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12992 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12993 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12994 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12995 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12996 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12997 12998 if (needSep) pw.println(); 12999 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13000 pw.print(" total, non-act at "); 13001 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13002 pw.print(", non-svc at "); 13003 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13004 pw.println("):"); 13005 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13006 needSep = true; 13007 } 13008 13009 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13010 13011 pw.println(); 13012 pw.println(" mHomeProcess: " + mHomeProcess); 13013 pw.println(" mPreviousProcess: " + mPreviousProcess); 13014 if (mHeavyWeightProcess != null) { 13015 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13016 } 13017 13018 return true; 13019 } 13020 13021 /** 13022 * There are three ways to call this: 13023 * - no provider specified: dump all the providers 13024 * - a flattened component name that matched an existing provider was specified as the 13025 * first arg: dump that one provider 13026 * - the first arg isn't the flattened component name of an existing provider: 13027 * dump all providers whose component contains the first arg as a substring 13028 */ 13029 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13030 int opti, boolean dumpAll) { 13031 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13032 } 13033 13034 static class ItemMatcher { 13035 ArrayList<ComponentName> components; 13036 ArrayList<String> strings; 13037 ArrayList<Integer> objects; 13038 boolean all; 13039 13040 ItemMatcher() { 13041 all = true; 13042 } 13043 13044 void build(String name) { 13045 ComponentName componentName = ComponentName.unflattenFromString(name); 13046 if (componentName != null) { 13047 if (components == null) { 13048 components = new ArrayList<ComponentName>(); 13049 } 13050 components.add(componentName); 13051 all = false; 13052 } else { 13053 int objectId = 0; 13054 // Not a '/' separated full component name; maybe an object ID? 13055 try { 13056 objectId = Integer.parseInt(name, 16); 13057 if (objects == null) { 13058 objects = new ArrayList<Integer>(); 13059 } 13060 objects.add(objectId); 13061 all = false; 13062 } catch (RuntimeException e) { 13063 // Not an integer; just do string match. 13064 if (strings == null) { 13065 strings = new ArrayList<String>(); 13066 } 13067 strings.add(name); 13068 all = false; 13069 } 13070 } 13071 } 13072 13073 int build(String[] args, int opti) { 13074 for (; opti<args.length; opti++) { 13075 String name = args[opti]; 13076 if ("--".equals(name)) { 13077 return opti+1; 13078 } 13079 build(name); 13080 } 13081 return opti; 13082 } 13083 13084 boolean match(Object object, ComponentName comp) { 13085 if (all) { 13086 return true; 13087 } 13088 if (components != null) { 13089 for (int i=0; i<components.size(); i++) { 13090 if (components.get(i).equals(comp)) { 13091 return true; 13092 } 13093 } 13094 } 13095 if (objects != null) { 13096 for (int i=0; i<objects.size(); i++) { 13097 if (System.identityHashCode(object) == objects.get(i)) { 13098 return true; 13099 } 13100 } 13101 } 13102 if (strings != null) { 13103 String flat = comp.flattenToString(); 13104 for (int i=0; i<strings.size(); i++) { 13105 if (flat.contains(strings.get(i))) { 13106 return true; 13107 } 13108 } 13109 } 13110 return false; 13111 } 13112 } 13113 13114 /** 13115 * There are three things that cmd can be: 13116 * - a flattened component name that matches an existing activity 13117 * - the cmd arg isn't the flattened component name of an existing activity: 13118 * dump all activity whose component contains the cmd as a substring 13119 * - A hex number of the ActivityRecord object instance. 13120 */ 13121 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13122 int opti, boolean dumpAll) { 13123 ArrayList<ActivityRecord> activities; 13124 13125 synchronized (this) { 13126 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13127 } 13128 13129 if (activities.size() <= 0) { 13130 return false; 13131 } 13132 13133 String[] newArgs = new String[args.length - opti]; 13134 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13135 13136 TaskRecord lastTask = null; 13137 boolean needSep = false; 13138 for (int i=activities.size()-1; i>=0; i--) { 13139 ActivityRecord r = activities.get(i); 13140 if (needSep) { 13141 pw.println(); 13142 } 13143 needSep = true; 13144 synchronized (this) { 13145 if (lastTask != r.task) { 13146 lastTask = r.task; 13147 pw.print("TASK "); pw.print(lastTask.affinity); 13148 pw.print(" id="); pw.println(lastTask.taskId); 13149 if (dumpAll) { 13150 lastTask.dump(pw, " "); 13151 } 13152 } 13153 } 13154 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13155 } 13156 return true; 13157 } 13158 13159 /** 13160 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13161 * there is a thread associated with the activity. 13162 */ 13163 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13164 final ActivityRecord r, String[] args, boolean dumpAll) { 13165 String innerPrefix = prefix + " "; 13166 synchronized (this) { 13167 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13168 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13169 pw.print(" pid="); 13170 if (r.app != null) pw.println(r.app.pid); 13171 else pw.println("(not running)"); 13172 if (dumpAll) { 13173 r.dump(pw, innerPrefix); 13174 } 13175 } 13176 if (r.app != null && r.app.thread != null) { 13177 // flush anything that is already in the PrintWriter since the thread is going 13178 // to write to the file descriptor directly 13179 pw.flush(); 13180 try { 13181 TransferPipe tp = new TransferPipe(); 13182 try { 13183 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13184 r.appToken, innerPrefix, args); 13185 tp.go(fd); 13186 } finally { 13187 tp.kill(); 13188 } 13189 } catch (IOException e) { 13190 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13191 } catch (RemoteException e) { 13192 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13193 } 13194 } 13195 } 13196 13197 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13198 int opti, boolean dumpAll, String dumpPackage) { 13199 boolean needSep = false; 13200 boolean onlyHistory = false; 13201 boolean printedAnything = false; 13202 13203 if ("history".equals(dumpPackage)) { 13204 if (opti < args.length && "-s".equals(args[opti])) { 13205 dumpAll = false; 13206 } 13207 onlyHistory = true; 13208 dumpPackage = null; 13209 } 13210 13211 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13212 if (!onlyHistory && dumpAll) { 13213 if (mRegisteredReceivers.size() > 0) { 13214 boolean printed = false; 13215 Iterator it = mRegisteredReceivers.values().iterator(); 13216 while (it.hasNext()) { 13217 ReceiverList r = (ReceiverList)it.next(); 13218 if (dumpPackage != null && (r.app == null || 13219 !dumpPackage.equals(r.app.info.packageName))) { 13220 continue; 13221 } 13222 if (!printed) { 13223 pw.println(" Registered Receivers:"); 13224 needSep = true; 13225 printed = true; 13226 printedAnything = true; 13227 } 13228 pw.print(" * "); pw.println(r); 13229 r.dump(pw, " "); 13230 } 13231 } 13232 13233 if (mReceiverResolver.dump(pw, needSep ? 13234 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13235 " ", dumpPackage, false, false)) { 13236 needSep = true; 13237 printedAnything = true; 13238 } 13239 } 13240 13241 for (BroadcastQueue q : mBroadcastQueues) { 13242 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13243 printedAnything |= needSep; 13244 } 13245 13246 needSep = true; 13247 13248 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13249 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13250 if (needSep) { 13251 pw.println(); 13252 } 13253 needSep = true; 13254 printedAnything = true; 13255 pw.print(" Sticky broadcasts for user "); 13256 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13257 StringBuilder sb = new StringBuilder(128); 13258 for (Map.Entry<String, ArrayList<Intent>> ent 13259 : mStickyBroadcasts.valueAt(user).entrySet()) { 13260 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13261 if (dumpAll) { 13262 pw.println(":"); 13263 ArrayList<Intent> intents = ent.getValue(); 13264 final int N = intents.size(); 13265 for (int i=0; i<N; i++) { 13266 sb.setLength(0); 13267 sb.append(" Intent: "); 13268 intents.get(i).toShortString(sb, false, true, false, false); 13269 pw.println(sb.toString()); 13270 Bundle bundle = intents.get(i).getExtras(); 13271 if (bundle != null) { 13272 pw.print(" "); 13273 pw.println(bundle.toString()); 13274 } 13275 } 13276 } else { 13277 pw.println(""); 13278 } 13279 } 13280 } 13281 } 13282 13283 if (!onlyHistory && dumpAll) { 13284 pw.println(); 13285 for (BroadcastQueue queue : mBroadcastQueues) { 13286 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13287 + queue.mBroadcastsScheduled); 13288 } 13289 pw.println(" mHandler:"); 13290 mHandler.dump(new PrintWriterPrinter(pw), " "); 13291 needSep = true; 13292 printedAnything = true; 13293 } 13294 13295 if (!printedAnything) { 13296 pw.println(" (nothing)"); 13297 } 13298 } 13299 13300 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13301 int opti, boolean dumpAll, String dumpPackage) { 13302 boolean needSep; 13303 boolean printedAnything = false; 13304 13305 ItemMatcher matcher = new ItemMatcher(); 13306 matcher.build(args, opti); 13307 13308 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13309 13310 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13311 printedAnything |= needSep; 13312 13313 if (mLaunchingProviders.size() > 0) { 13314 boolean printed = false; 13315 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13316 ContentProviderRecord r = mLaunchingProviders.get(i); 13317 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13318 continue; 13319 } 13320 if (!printed) { 13321 if (needSep) pw.println(); 13322 needSep = true; 13323 pw.println(" Launching content providers:"); 13324 printed = true; 13325 printedAnything = true; 13326 } 13327 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13328 pw.println(r); 13329 } 13330 } 13331 13332 if (mGrantedUriPermissions.size() > 0) { 13333 boolean printed = false; 13334 int dumpUid = -2; 13335 if (dumpPackage != null) { 13336 try { 13337 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13338 } catch (NameNotFoundException e) { 13339 dumpUid = -1; 13340 } 13341 } 13342 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13343 int uid = mGrantedUriPermissions.keyAt(i); 13344 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13345 continue; 13346 } 13347 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13348 if (!printed) { 13349 if (needSep) pw.println(); 13350 needSep = true; 13351 pw.println(" Granted Uri Permissions:"); 13352 printed = true; 13353 printedAnything = true; 13354 } 13355 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13356 for (UriPermission perm : perms.values()) { 13357 pw.print(" "); pw.println(perm); 13358 if (dumpAll) { 13359 perm.dump(pw, " "); 13360 } 13361 } 13362 } 13363 } 13364 13365 if (!printedAnything) { 13366 pw.println(" (nothing)"); 13367 } 13368 } 13369 13370 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13371 int opti, boolean dumpAll, String dumpPackage) { 13372 boolean printed = false; 13373 13374 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13375 13376 if (mIntentSenderRecords.size() > 0) { 13377 Iterator<WeakReference<PendingIntentRecord>> it 13378 = mIntentSenderRecords.values().iterator(); 13379 while (it.hasNext()) { 13380 WeakReference<PendingIntentRecord> ref = it.next(); 13381 PendingIntentRecord rec = ref != null ? ref.get(): null; 13382 if (dumpPackage != null && (rec == null 13383 || !dumpPackage.equals(rec.key.packageName))) { 13384 continue; 13385 } 13386 printed = true; 13387 if (rec != null) { 13388 pw.print(" * "); pw.println(rec); 13389 if (dumpAll) { 13390 rec.dump(pw, " "); 13391 } 13392 } else { 13393 pw.print(" * "); pw.println(ref); 13394 } 13395 } 13396 } 13397 13398 if (!printed) { 13399 pw.println(" (nothing)"); 13400 } 13401 } 13402 13403 private static final int dumpProcessList(PrintWriter pw, 13404 ActivityManagerService service, List list, 13405 String prefix, String normalLabel, String persistentLabel, 13406 String dumpPackage) { 13407 int numPers = 0; 13408 final int N = list.size()-1; 13409 for (int i=N; i>=0; i--) { 13410 ProcessRecord r = (ProcessRecord)list.get(i); 13411 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13412 continue; 13413 } 13414 pw.println(String.format("%s%s #%2d: %s", 13415 prefix, (r.persistent ? persistentLabel : normalLabel), 13416 i, r.toString())); 13417 if (r.persistent) { 13418 numPers++; 13419 } 13420 } 13421 return numPers; 13422 } 13423 13424 private static final boolean dumpProcessOomList(PrintWriter pw, 13425 ActivityManagerService service, List<ProcessRecord> origList, 13426 String prefix, String normalLabel, String persistentLabel, 13427 boolean inclDetails, String dumpPackage) { 13428 13429 ArrayList<Pair<ProcessRecord, Integer>> list 13430 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13431 for (int i=0; i<origList.size(); i++) { 13432 ProcessRecord r = origList.get(i); 13433 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13434 continue; 13435 } 13436 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13437 } 13438 13439 if (list.size() <= 0) { 13440 return false; 13441 } 13442 13443 Comparator<Pair<ProcessRecord, Integer>> comparator 13444 = new Comparator<Pair<ProcessRecord, Integer>>() { 13445 @Override 13446 public int compare(Pair<ProcessRecord, Integer> object1, 13447 Pair<ProcessRecord, Integer> object2) { 13448 if (object1.first.setAdj != object2.first.setAdj) { 13449 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13450 } 13451 if (object1.second.intValue() != object2.second.intValue()) { 13452 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13453 } 13454 return 0; 13455 } 13456 }; 13457 13458 Collections.sort(list, comparator); 13459 13460 final long curRealtime = SystemClock.elapsedRealtime(); 13461 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13462 final long curUptime = SystemClock.uptimeMillis(); 13463 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13464 13465 for (int i=list.size()-1; i>=0; i--) { 13466 ProcessRecord r = list.get(i).first; 13467 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13468 char schedGroup; 13469 switch (r.setSchedGroup) { 13470 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13471 schedGroup = 'B'; 13472 break; 13473 case Process.THREAD_GROUP_DEFAULT: 13474 schedGroup = 'F'; 13475 break; 13476 default: 13477 schedGroup = '?'; 13478 break; 13479 } 13480 char foreground; 13481 if (r.foregroundActivities) { 13482 foreground = 'A'; 13483 } else if (r.foregroundServices) { 13484 foreground = 'S'; 13485 } else { 13486 foreground = ' '; 13487 } 13488 String procState = ProcessList.makeProcStateString(r.curProcState); 13489 pw.print(prefix); 13490 pw.print(r.persistent ? persistentLabel : normalLabel); 13491 pw.print(" #"); 13492 int num = (origList.size()-1)-list.get(i).second; 13493 if (num < 10) pw.print(' '); 13494 pw.print(num); 13495 pw.print(": "); 13496 pw.print(oomAdj); 13497 pw.print(' '); 13498 pw.print(schedGroup); 13499 pw.print('/'); 13500 pw.print(foreground); 13501 pw.print('/'); 13502 pw.print(procState); 13503 pw.print(" trm:"); 13504 if (r.trimMemoryLevel < 10) pw.print(' '); 13505 pw.print(r.trimMemoryLevel); 13506 pw.print(' '); 13507 pw.print(r.toShortString()); 13508 pw.print(" ("); 13509 pw.print(r.adjType); 13510 pw.println(')'); 13511 if (r.adjSource != null || r.adjTarget != null) { 13512 pw.print(prefix); 13513 pw.print(" "); 13514 if (r.adjTarget instanceof ComponentName) { 13515 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13516 } else if (r.adjTarget != null) { 13517 pw.print(r.adjTarget.toString()); 13518 } else { 13519 pw.print("{null}"); 13520 } 13521 pw.print("<="); 13522 if (r.adjSource instanceof ProcessRecord) { 13523 pw.print("Proc{"); 13524 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13525 pw.println("}"); 13526 } else if (r.adjSource != null) { 13527 pw.println(r.adjSource.toString()); 13528 } else { 13529 pw.println("{null}"); 13530 } 13531 } 13532 if (inclDetails) { 13533 pw.print(prefix); 13534 pw.print(" "); 13535 pw.print("oom: max="); pw.print(r.maxAdj); 13536 pw.print(" curRaw="); pw.print(r.curRawAdj); 13537 pw.print(" setRaw="); pw.print(r.setRawAdj); 13538 pw.print(" cur="); pw.print(r.curAdj); 13539 pw.print(" set="); pw.println(r.setAdj); 13540 pw.print(prefix); 13541 pw.print(" "); 13542 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13543 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13544 pw.print(" lastPss="); pw.print(r.lastPss); 13545 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13546 pw.print(prefix); 13547 pw.print(" "); 13548 pw.print("cached="); pw.print(r.cached); 13549 pw.print(" empty="); pw.print(r.empty); 13550 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13551 13552 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13553 if (r.lastWakeTime != 0) { 13554 long wtime; 13555 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13556 synchronized (stats) { 13557 wtime = stats.getProcessWakeTime(r.info.uid, 13558 r.pid, curRealtime); 13559 } 13560 long timeUsed = wtime - r.lastWakeTime; 13561 pw.print(prefix); 13562 pw.print(" "); 13563 pw.print("keep awake over "); 13564 TimeUtils.formatDuration(realtimeSince, pw); 13565 pw.print(" used "); 13566 TimeUtils.formatDuration(timeUsed, pw); 13567 pw.print(" ("); 13568 pw.print((timeUsed*100)/realtimeSince); 13569 pw.println("%)"); 13570 } 13571 if (r.lastCpuTime != 0) { 13572 long timeUsed = r.curCpuTime - r.lastCpuTime; 13573 pw.print(prefix); 13574 pw.print(" "); 13575 pw.print("run cpu over "); 13576 TimeUtils.formatDuration(uptimeSince, pw); 13577 pw.print(" used "); 13578 TimeUtils.formatDuration(timeUsed, pw); 13579 pw.print(" ("); 13580 pw.print((timeUsed*100)/uptimeSince); 13581 pw.println("%)"); 13582 } 13583 } 13584 } 13585 } 13586 return true; 13587 } 13588 13589 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13590 String[] args) { 13591 ArrayList<ProcessRecord> procs; 13592 synchronized (this) { 13593 if (args != null && args.length > start 13594 && args[start].charAt(0) != '-') { 13595 procs = new ArrayList<ProcessRecord>(); 13596 int pid = -1; 13597 try { 13598 pid = Integer.parseInt(args[start]); 13599 } catch (NumberFormatException e) { 13600 } 13601 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13602 ProcessRecord proc = mLruProcesses.get(i); 13603 if (proc.pid == pid) { 13604 procs.add(proc); 13605 } else if (allPkgs && proc.pkgList != null 13606 && proc.pkgList.containsKey(args[start])) { 13607 procs.add(proc); 13608 } else if (proc.processName.equals(args[start])) { 13609 procs.add(proc); 13610 } 13611 } 13612 if (procs.size() <= 0) { 13613 return null; 13614 } 13615 } else { 13616 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13617 } 13618 } 13619 return procs; 13620 } 13621 13622 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13623 PrintWriter pw, String[] args) { 13624 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13625 if (procs == null) { 13626 pw.println("No process found for: " + args[0]); 13627 return; 13628 } 13629 13630 long uptime = SystemClock.uptimeMillis(); 13631 long realtime = SystemClock.elapsedRealtime(); 13632 pw.println("Applications Graphics Acceleration Info:"); 13633 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13634 13635 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13636 ProcessRecord r = procs.get(i); 13637 if (r.thread != null) { 13638 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13639 pw.flush(); 13640 try { 13641 TransferPipe tp = new TransferPipe(); 13642 try { 13643 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13644 tp.go(fd); 13645 } finally { 13646 tp.kill(); 13647 } 13648 } catch (IOException e) { 13649 pw.println("Failure while dumping the app: " + r); 13650 pw.flush(); 13651 } catch (RemoteException e) { 13652 pw.println("Got a RemoteException while dumping the app " + r); 13653 pw.flush(); 13654 } 13655 } 13656 } 13657 } 13658 13659 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13660 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13661 if (procs == null) { 13662 pw.println("No process found for: " + args[0]); 13663 return; 13664 } 13665 13666 pw.println("Applications Database Info:"); 13667 13668 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13669 ProcessRecord r = procs.get(i); 13670 if (r.thread != null) { 13671 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13672 pw.flush(); 13673 try { 13674 TransferPipe tp = new TransferPipe(); 13675 try { 13676 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13677 tp.go(fd); 13678 } finally { 13679 tp.kill(); 13680 } 13681 } catch (IOException e) { 13682 pw.println("Failure while dumping the app: " + r); 13683 pw.flush(); 13684 } catch (RemoteException e) { 13685 pw.println("Got a RemoteException while dumping the app " + r); 13686 pw.flush(); 13687 } 13688 } 13689 } 13690 } 13691 13692 final static class MemItem { 13693 final boolean isProc; 13694 final String label; 13695 final String shortLabel; 13696 final long pss; 13697 final int id; 13698 final boolean hasActivities; 13699 ArrayList<MemItem> subitems; 13700 13701 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13702 boolean _hasActivities) { 13703 isProc = true; 13704 label = _label; 13705 shortLabel = _shortLabel; 13706 pss = _pss; 13707 id = _id; 13708 hasActivities = _hasActivities; 13709 } 13710 13711 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13712 isProc = false; 13713 label = _label; 13714 shortLabel = _shortLabel; 13715 pss = _pss; 13716 id = _id; 13717 hasActivities = false; 13718 } 13719 } 13720 13721 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13722 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13723 if (sort && !isCompact) { 13724 Collections.sort(items, new Comparator<MemItem>() { 13725 @Override 13726 public int compare(MemItem lhs, MemItem rhs) { 13727 if (lhs.pss < rhs.pss) { 13728 return 1; 13729 } else if (lhs.pss > rhs.pss) { 13730 return -1; 13731 } 13732 return 0; 13733 } 13734 }); 13735 } 13736 13737 for (int i=0; i<items.size(); i++) { 13738 MemItem mi = items.get(i); 13739 if (!isCompact) { 13740 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13741 } else if (mi.isProc) { 13742 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13743 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13744 pw.println(mi.hasActivities ? ",a" : ",e"); 13745 } else { 13746 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13747 pw.println(mi.pss); 13748 } 13749 if (mi.subitems != null) { 13750 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13751 true, isCompact); 13752 } 13753 } 13754 } 13755 13756 // These are in KB. 13757 static final long[] DUMP_MEM_BUCKETS = new long[] { 13758 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13759 120*1024, 160*1024, 200*1024, 13760 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13761 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13762 }; 13763 13764 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13765 boolean stackLike) { 13766 int start = label.lastIndexOf('.'); 13767 if (start >= 0) start++; 13768 else start = 0; 13769 int end = label.length(); 13770 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13771 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13772 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13773 out.append(bucket); 13774 out.append(stackLike ? "MB." : "MB "); 13775 out.append(label, start, end); 13776 return; 13777 } 13778 } 13779 out.append(memKB/1024); 13780 out.append(stackLike ? "MB." : "MB "); 13781 out.append(label, start, end); 13782 } 13783 13784 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13785 ProcessList.NATIVE_ADJ, 13786 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13787 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13788 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13789 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13790 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13791 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13792 }; 13793 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13794 "Native", 13795 "System", "Persistent", "Persistent Service", "Foreground", 13796 "Visible", "Perceptible", 13797 "Heavy Weight", "Backup", 13798 "A Services", "Home", 13799 "Previous", "B Services", "Cached" 13800 }; 13801 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13802 "native", 13803 "sys", "pers", "persvc", "fore", 13804 "vis", "percept", 13805 "heavy", "backup", 13806 "servicea", "home", 13807 "prev", "serviceb", "cached" 13808 }; 13809 13810 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13811 long realtime, boolean isCheckinRequest, boolean isCompact) { 13812 if (isCheckinRequest || isCompact) { 13813 // short checkin version 13814 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13815 } else { 13816 pw.println("Applications Memory Usage (kB):"); 13817 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13818 } 13819 } 13820 13821 private static final int KSM_SHARED = 0; 13822 private static final int KSM_SHARING = 1; 13823 private static final int KSM_UNSHARED = 2; 13824 private static final int KSM_VOLATILE = 3; 13825 13826 private final long[] getKsmInfo() { 13827 long[] longOut = new long[4]; 13828 final int[] SINGLE_LONG_FORMAT = new int[] { 13829 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13830 }; 13831 long[] longTmp = new long[1]; 13832 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13833 SINGLE_LONG_FORMAT, null, longTmp, null); 13834 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13835 longTmp[0] = 0; 13836 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13837 SINGLE_LONG_FORMAT, null, longTmp, null); 13838 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13839 longTmp[0] = 0; 13840 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13841 SINGLE_LONG_FORMAT, null, longTmp, null); 13842 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13843 longTmp[0] = 0; 13844 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13845 SINGLE_LONG_FORMAT, null, longTmp, null); 13846 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13847 return longOut; 13848 } 13849 13850 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13851 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13852 boolean dumpDetails = false; 13853 boolean dumpFullDetails = false; 13854 boolean dumpDalvik = false; 13855 boolean oomOnly = false; 13856 boolean isCompact = false; 13857 boolean localOnly = false; 13858 boolean packages = false; 13859 13860 int opti = 0; 13861 while (opti < args.length) { 13862 String opt = args[opti]; 13863 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13864 break; 13865 } 13866 opti++; 13867 if ("-a".equals(opt)) { 13868 dumpDetails = true; 13869 dumpFullDetails = true; 13870 dumpDalvik = true; 13871 } else if ("-d".equals(opt)) { 13872 dumpDalvik = true; 13873 } else if ("-c".equals(opt)) { 13874 isCompact = true; 13875 } else if ("--oom".equals(opt)) { 13876 oomOnly = true; 13877 } else if ("--local".equals(opt)) { 13878 localOnly = true; 13879 } else if ("--package".equals(opt)) { 13880 packages = true; 13881 } else if ("-h".equals(opt)) { 13882 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13883 pw.println(" -a: include all available information for each process."); 13884 pw.println(" -d: include dalvik details when dumping process details."); 13885 pw.println(" -c: dump in a compact machine-parseable representation."); 13886 pw.println(" --oom: only show processes organized by oom adj."); 13887 pw.println(" --local: only collect details locally, don't call process."); 13888 pw.println(" --package: interpret process arg as package, dumping all"); 13889 pw.println(" processes that have loaded that package."); 13890 pw.println("If [process] is specified it can be the name or "); 13891 pw.println("pid of a specific process to dump."); 13892 return; 13893 } else { 13894 pw.println("Unknown argument: " + opt + "; use -h for help"); 13895 } 13896 } 13897 13898 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13899 long uptime = SystemClock.uptimeMillis(); 13900 long realtime = SystemClock.elapsedRealtime(); 13901 final long[] tmpLong = new long[1]; 13902 13903 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13904 if (procs == null) { 13905 // No Java processes. Maybe they want to print a native process. 13906 if (args != null && args.length > opti 13907 && args[opti].charAt(0) != '-') { 13908 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13909 = new ArrayList<ProcessCpuTracker.Stats>(); 13910 updateCpuStatsNow(); 13911 int findPid = -1; 13912 try { 13913 findPid = Integer.parseInt(args[opti]); 13914 } catch (NumberFormatException e) { 13915 } 13916 synchronized (mProcessCpuTracker) { 13917 final int N = mProcessCpuTracker.countStats(); 13918 for (int i=0; i<N; i++) { 13919 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13920 if (st.pid == findPid || (st.baseName != null 13921 && st.baseName.equals(args[opti]))) { 13922 nativeProcs.add(st); 13923 } 13924 } 13925 } 13926 if (nativeProcs.size() > 0) { 13927 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13928 isCompact); 13929 Debug.MemoryInfo mi = null; 13930 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13931 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13932 final int pid = r.pid; 13933 if (!isCheckinRequest && dumpDetails) { 13934 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13935 } 13936 if (mi == null) { 13937 mi = new Debug.MemoryInfo(); 13938 } 13939 if (dumpDetails || (!brief && !oomOnly)) { 13940 Debug.getMemoryInfo(pid, mi); 13941 } else { 13942 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13943 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13944 } 13945 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13946 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13947 if (isCheckinRequest) { 13948 pw.println(); 13949 } 13950 } 13951 return; 13952 } 13953 } 13954 pw.println("No process found for: " + args[opti]); 13955 return; 13956 } 13957 13958 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13959 dumpDetails = true; 13960 } 13961 13962 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13963 13964 String[] innerArgs = new String[args.length-opti]; 13965 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13966 13967 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13968 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13969 long nativePss = 0; 13970 long dalvikPss = 0; 13971 long otherPss = 0; 13972 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13973 13974 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13975 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13976 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13977 13978 long totalPss = 0; 13979 long cachedPss = 0; 13980 13981 Debug.MemoryInfo mi = null; 13982 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13983 final ProcessRecord r = procs.get(i); 13984 final IApplicationThread thread; 13985 final int pid; 13986 final int oomAdj; 13987 final boolean hasActivities; 13988 synchronized (this) { 13989 thread = r.thread; 13990 pid = r.pid; 13991 oomAdj = r.getSetAdjWithServices(); 13992 hasActivities = r.activities.size() > 0; 13993 } 13994 if (thread != null) { 13995 if (!isCheckinRequest && dumpDetails) { 13996 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13997 } 13998 if (mi == null) { 13999 mi = new Debug.MemoryInfo(); 14000 } 14001 if (dumpDetails || (!brief && !oomOnly)) { 14002 Debug.getMemoryInfo(pid, mi); 14003 } else { 14004 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14005 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14006 } 14007 if (dumpDetails) { 14008 if (localOnly) { 14009 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14010 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14011 if (isCheckinRequest) { 14012 pw.println(); 14013 } 14014 } else { 14015 try { 14016 pw.flush(); 14017 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14018 dumpDalvik, innerArgs); 14019 } catch (RemoteException e) { 14020 if (!isCheckinRequest) { 14021 pw.println("Got RemoteException!"); 14022 pw.flush(); 14023 } 14024 } 14025 } 14026 } 14027 14028 final long myTotalPss = mi.getTotalPss(); 14029 final long myTotalUss = mi.getTotalUss(); 14030 14031 synchronized (this) { 14032 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14033 // Record this for posterity if the process has been stable. 14034 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14035 } 14036 } 14037 14038 if (!isCheckinRequest && mi != null) { 14039 totalPss += myTotalPss; 14040 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14041 (hasActivities ? " / activities)" : ")"), 14042 r.processName, myTotalPss, pid, hasActivities); 14043 procMems.add(pssItem); 14044 procMemsMap.put(pid, pssItem); 14045 14046 nativePss += mi.nativePss; 14047 dalvikPss += mi.dalvikPss; 14048 otherPss += mi.otherPss; 14049 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14050 long mem = mi.getOtherPss(j); 14051 miscPss[j] += mem; 14052 otherPss -= mem; 14053 } 14054 14055 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14056 cachedPss += myTotalPss; 14057 } 14058 14059 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14060 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14061 || oomIndex == (oomPss.length-1)) { 14062 oomPss[oomIndex] += myTotalPss; 14063 if (oomProcs[oomIndex] == null) { 14064 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14065 } 14066 oomProcs[oomIndex].add(pssItem); 14067 break; 14068 } 14069 } 14070 } 14071 } 14072 } 14073 14074 long nativeProcTotalPss = 0; 14075 14076 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14077 // If we are showing aggregations, also look for native processes to 14078 // include so that our aggregations are more accurate. 14079 updateCpuStatsNow(); 14080 synchronized (mProcessCpuTracker) { 14081 final int N = mProcessCpuTracker.countStats(); 14082 for (int i=0; i<N; i++) { 14083 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14084 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14085 if (mi == null) { 14086 mi = new Debug.MemoryInfo(); 14087 } 14088 if (!brief && !oomOnly) { 14089 Debug.getMemoryInfo(st.pid, mi); 14090 } else { 14091 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14092 mi.nativePrivateDirty = (int)tmpLong[0]; 14093 } 14094 14095 final long myTotalPss = mi.getTotalPss(); 14096 totalPss += myTotalPss; 14097 nativeProcTotalPss += myTotalPss; 14098 14099 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14100 st.name, myTotalPss, st.pid, false); 14101 procMems.add(pssItem); 14102 14103 nativePss += mi.nativePss; 14104 dalvikPss += mi.dalvikPss; 14105 otherPss += mi.otherPss; 14106 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14107 long mem = mi.getOtherPss(j); 14108 miscPss[j] += mem; 14109 otherPss -= mem; 14110 } 14111 oomPss[0] += myTotalPss; 14112 if (oomProcs[0] == null) { 14113 oomProcs[0] = new ArrayList<MemItem>(); 14114 } 14115 oomProcs[0].add(pssItem); 14116 } 14117 } 14118 } 14119 14120 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14121 14122 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14123 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14124 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14125 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14126 String label = Debug.MemoryInfo.getOtherLabel(j); 14127 catMems.add(new MemItem(label, label, miscPss[j], j)); 14128 } 14129 14130 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14131 for (int j=0; j<oomPss.length; j++) { 14132 if (oomPss[j] != 0) { 14133 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14134 : DUMP_MEM_OOM_LABEL[j]; 14135 MemItem item = new MemItem(label, label, oomPss[j], 14136 DUMP_MEM_OOM_ADJ[j]); 14137 item.subitems = oomProcs[j]; 14138 oomMems.add(item); 14139 } 14140 } 14141 14142 if (!brief && !oomOnly && !isCompact) { 14143 pw.println(); 14144 pw.println("Total PSS by process:"); 14145 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14146 pw.println(); 14147 } 14148 if (!isCompact) { 14149 pw.println("Total PSS by OOM adjustment:"); 14150 } 14151 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14152 if (!brief && !oomOnly) { 14153 PrintWriter out = categoryPw != null ? categoryPw : pw; 14154 if (!isCompact) { 14155 out.println(); 14156 out.println("Total PSS by category:"); 14157 } 14158 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14159 } 14160 if (!isCompact) { 14161 pw.println(); 14162 } 14163 MemInfoReader memInfo = new MemInfoReader(); 14164 memInfo.readMemInfo(); 14165 if (nativeProcTotalPss > 0) { 14166 synchronized (this) { 14167 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14168 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14169 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14170 } 14171 } 14172 if (!brief) { 14173 if (!isCompact) { 14174 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14175 pw.print(" kB (status "); 14176 switch (mLastMemoryLevel) { 14177 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14178 pw.println("normal)"); 14179 break; 14180 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14181 pw.println("moderate)"); 14182 break; 14183 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14184 pw.println("low)"); 14185 break; 14186 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14187 pw.println("critical)"); 14188 break; 14189 default: 14190 pw.print(mLastMemoryLevel); 14191 pw.println(")"); 14192 break; 14193 } 14194 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14195 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14196 pw.print(cachedPss); pw.print(" cached pss + "); 14197 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14198 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14199 } else { 14200 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14201 pw.print(cachedPss + memInfo.getCachedSizeKb() 14202 + memInfo.getFreeSizeKb()); pw.print(","); 14203 pw.println(totalPss - cachedPss); 14204 } 14205 } 14206 if (!isCompact) { 14207 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14208 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14209 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14210 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14211 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14212 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14213 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14214 } 14215 if (!brief) { 14216 if (memInfo.getZramTotalSizeKb() != 0) { 14217 if (!isCompact) { 14218 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14219 pw.print(" kB physical used for "); 14220 pw.print(memInfo.getSwapTotalSizeKb() 14221 - memInfo.getSwapFreeSizeKb()); 14222 pw.print(" kB in swap ("); 14223 pw.print(memInfo.getSwapTotalSizeKb()); 14224 pw.println(" kB total swap)"); 14225 } else { 14226 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14227 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14228 pw.println(memInfo.getSwapFreeSizeKb()); 14229 } 14230 } 14231 final long[] ksm = getKsmInfo(); 14232 if (!isCompact) { 14233 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14234 || ksm[KSM_VOLATILE] != 0) { 14235 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14236 pw.print(" kB saved from shared "); 14237 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14238 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14239 pw.print(" kB unshared; "); 14240 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14241 } 14242 pw.print(" Tuning: "); 14243 pw.print(ActivityManager.staticGetMemoryClass()); 14244 pw.print(" (large "); 14245 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14246 pw.print("), oom "); 14247 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14248 pw.print(" kB"); 14249 pw.print(", restore limit "); 14250 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14251 pw.print(" kB"); 14252 if (ActivityManager.isLowRamDeviceStatic()) { 14253 pw.print(" (low-ram)"); 14254 } 14255 if (ActivityManager.isHighEndGfx()) { 14256 pw.print(" (high-end-gfx)"); 14257 } 14258 pw.println(); 14259 } else { 14260 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14261 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14262 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14263 pw.print("tuning,"); 14264 pw.print(ActivityManager.staticGetMemoryClass()); 14265 pw.print(','); 14266 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14267 pw.print(','); 14268 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14269 if (ActivityManager.isLowRamDeviceStatic()) { 14270 pw.print(",low-ram"); 14271 } 14272 if (ActivityManager.isHighEndGfx()) { 14273 pw.print(",high-end-gfx"); 14274 } 14275 pw.println(); 14276 } 14277 } 14278 } 14279 } 14280 14281 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14282 String name) { 14283 sb.append(" "); 14284 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14285 sb.append(' '); 14286 sb.append(ProcessList.makeProcStateString(procState)); 14287 sb.append(' '); 14288 ProcessList.appendRamKb(sb, pss); 14289 sb.append(" kB: "); 14290 sb.append(name); 14291 } 14292 14293 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14294 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14295 sb.append(" ("); 14296 sb.append(mi.pid); 14297 sb.append(") "); 14298 sb.append(mi.adjType); 14299 sb.append('\n'); 14300 if (mi.adjReason != null) { 14301 sb.append(" "); 14302 sb.append(mi.adjReason); 14303 sb.append('\n'); 14304 } 14305 } 14306 14307 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14308 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14309 for (int i=0, N=memInfos.size(); i<N; i++) { 14310 ProcessMemInfo mi = memInfos.get(i); 14311 infoMap.put(mi.pid, mi); 14312 } 14313 updateCpuStatsNow(); 14314 synchronized (mProcessCpuTracker) { 14315 final int N = mProcessCpuTracker.countStats(); 14316 for (int i=0; i<N; i++) { 14317 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14318 if (st.vsize > 0) { 14319 long pss = Debug.getPss(st.pid, null); 14320 if (pss > 0) { 14321 if (infoMap.indexOfKey(st.pid) < 0) { 14322 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14323 ProcessList.NATIVE_ADJ, -1, "native", null); 14324 mi.pss = pss; 14325 memInfos.add(mi); 14326 } 14327 } 14328 } 14329 } 14330 } 14331 14332 long totalPss = 0; 14333 for (int i=0, N=memInfos.size(); i<N; i++) { 14334 ProcessMemInfo mi = memInfos.get(i); 14335 if (mi.pss == 0) { 14336 mi.pss = Debug.getPss(mi.pid, null); 14337 } 14338 totalPss += mi.pss; 14339 } 14340 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14341 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14342 if (lhs.oomAdj != rhs.oomAdj) { 14343 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14344 } 14345 if (lhs.pss != rhs.pss) { 14346 return lhs.pss < rhs.pss ? 1 : -1; 14347 } 14348 return 0; 14349 } 14350 }); 14351 14352 StringBuilder tag = new StringBuilder(128); 14353 StringBuilder stack = new StringBuilder(128); 14354 tag.append("Low on memory -- "); 14355 appendMemBucket(tag, totalPss, "total", false); 14356 appendMemBucket(stack, totalPss, "total", true); 14357 14358 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14359 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14360 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14361 14362 boolean firstLine = true; 14363 int lastOomAdj = Integer.MIN_VALUE; 14364 long extraNativeRam = 0; 14365 long cachedPss = 0; 14366 for (int i=0, N=memInfos.size(); i<N; i++) { 14367 ProcessMemInfo mi = memInfos.get(i); 14368 14369 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14370 cachedPss += mi.pss; 14371 } 14372 14373 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14374 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14375 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14376 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14377 if (lastOomAdj != mi.oomAdj) { 14378 lastOomAdj = mi.oomAdj; 14379 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14380 tag.append(" / "); 14381 } 14382 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14383 if (firstLine) { 14384 stack.append(":"); 14385 firstLine = false; 14386 } 14387 stack.append("\n\t at "); 14388 } else { 14389 stack.append("$"); 14390 } 14391 } else { 14392 tag.append(" "); 14393 stack.append("$"); 14394 } 14395 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14396 appendMemBucket(tag, mi.pss, mi.name, false); 14397 } 14398 appendMemBucket(stack, mi.pss, mi.name, true); 14399 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14400 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14401 stack.append("("); 14402 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14403 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14404 stack.append(DUMP_MEM_OOM_LABEL[k]); 14405 stack.append(":"); 14406 stack.append(DUMP_MEM_OOM_ADJ[k]); 14407 } 14408 } 14409 stack.append(")"); 14410 } 14411 } 14412 14413 appendMemInfo(fullNativeBuilder, mi); 14414 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14415 // The short form only has native processes that are >= 1MB. 14416 if (mi.pss >= 1000) { 14417 appendMemInfo(shortNativeBuilder, mi); 14418 } else { 14419 extraNativeRam += mi.pss; 14420 } 14421 } else { 14422 // Short form has all other details, but if we have collected RAM 14423 // from smaller native processes let's dump a summary of that. 14424 if (extraNativeRam > 0) { 14425 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14426 -1, extraNativeRam, "(Other native)"); 14427 shortNativeBuilder.append('\n'); 14428 extraNativeRam = 0; 14429 } 14430 appendMemInfo(fullJavaBuilder, mi); 14431 } 14432 } 14433 14434 fullJavaBuilder.append(" "); 14435 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14436 fullJavaBuilder.append(" kB: TOTAL\n"); 14437 14438 MemInfoReader memInfo = new MemInfoReader(); 14439 memInfo.readMemInfo(); 14440 final long[] infos = memInfo.getRawInfo(); 14441 14442 StringBuilder memInfoBuilder = new StringBuilder(1024); 14443 Debug.getMemInfo(infos); 14444 memInfoBuilder.append(" MemInfo: "); 14445 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14446 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14447 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14448 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14449 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14450 memInfoBuilder.append(" "); 14451 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14452 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14453 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14454 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14455 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14456 memInfoBuilder.append(" ZRAM: "); 14457 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14458 memInfoBuilder.append(" kB RAM, "); 14459 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14460 memInfoBuilder.append(" kB swap total, "); 14461 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14462 memInfoBuilder.append(" kB swap free\n"); 14463 } 14464 final long[] ksm = getKsmInfo(); 14465 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14466 || ksm[KSM_VOLATILE] != 0) { 14467 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14468 memInfoBuilder.append(" kB saved from shared "); 14469 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14470 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14471 memInfoBuilder.append(" kB unshared; "); 14472 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14473 } 14474 memInfoBuilder.append(" Free RAM: "); 14475 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14476 + memInfo.getFreeSizeKb()); 14477 memInfoBuilder.append(" kB\n"); 14478 memInfoBuilder.append(" Used RAM: "); 14479 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14480 memInfoBuilder.append(" kB\n"); 14481 memInfoBuilder.append(" Lost RAM: "); 14482 memInfoBuilder.append(memInfo.getTotalSizeKb() 14483 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14484 - memInfo.getKernelUsedSizeKb()); 14485 memInfoBuilder.append(" kB\n"); 14486 Slog.i(TAG, "Low on memory:"); 14487 Slog.i(TAG, shortNativeBuilder.toString()); 14488 Slog.i(TAG, fullJavaBuilder.toString()); 14489 Slog.i(TAG, memInfoBuilder.toString()); 14490 14491 StringBuilder dropBuilder = new StringBuilder(1024); 14492 /* 14493 StringWriter oomSw = new StringWriter(); 14494 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14495 StringWriter catSw = new StringWriter(); 14496 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14497 String[] emptyArgs = new String[] { }; 14498 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14499 oomPw.flush(); 14500 String oomString = oomSw.toString(); 14501 */ 14502 dropBuilder.append("Low on memory:"); 14503 dropBuilder.append(stack); 14504 dropBuilder.append('\n'); 14505 dropBuilder.append(fullNativeBuilder); 14506 dropBuilder.append(fullJavaBuilder); 14507 dropBuilder.append('\n'); 14508 dropBuilder.append(memInfoBuilder); 14509 dropBuilder.append('\n'); 14510 /* 14511 dropBuilder.append(oomString); 14512 dropBuilder.append('\n'); 14513 */ 14514 StringWriter catSw = new StringWriter(); 14515 synchronized (ActivityManagerService.this) { 14516 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14517 String[] emptyArgs = new String[] { }; 14518 catPw.println(); 14519 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14520 catPw.println(); 14521 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14522 false, false, null); 14523 catPw.println(); 14524 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14525 catPw.flush(); 14526 } 14527 dropBuilder.append(catSw.toString()); 14528 addErrorToDropBox("lowmem", null, "system_server", null, 14529 null, tag.toString(), dropBuilder.toString(), null, null); 14530 //Slog.i(TAG, "Sent to dropbox:"); 14531 //Slog.i(TAG, dropBuilder.toString()); 14532 synchronized (ActivityManagerService.this) { 14533 long now = SystemClock.uptimeMillis(); 14534 if (mLastMemUsageReportTime < now) { 14535 mLastMemUsageReportTime = now; 14536 } 14537 } 14538 } 14539 14540 /** 14541 * Searches array of arguments for the specified string 14542 * @param args array of argument strings 14543 * @param value value to search for 14544 * @return true if the value is contained in the array 14545 */ 14546 private static boolean scanArgs(String[] args, String value) { 14547 if (args != null) { 14548 for (String arg : args) { 14549 if (value.equals(arg)) { 14550 return true; 14551 } 14552 } 14553 } 14554 return false; 14555 } 14556 14557 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14558 ContentProviderRecord cpr, boolean always) { 14559 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14560 14561 if (!inLaunching || always) { 14562 synchronized (cpr) { 14563 cpr.launchingApp = null; 14564 cpr.notifyAll(); 14565 } 14566 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14567 String names[] = cpr.info.authority.split(";"); 14568 for (int j = 0; j < names.length; j++) { 14569 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14570 } 14571 } 14572 14573 for (int i=0; i<cpr.connections.size(); i++) { 14574 ContentProviderConnection conn = cpr.connections.get(i); 14575 if (conn.waiting) { 14576 // If this connection is waiting for the provider, then we don't 14577 // need to mess with its process unless we are always removing 14578 // or for some reason the provider is not currently launching. 14579 if (inLaunching && !always) { 14580 continue; 14581 } 14582 } 14583 ProcessRecord capp = conn.client; 14584 conn.dead = true; 14585 if (conn.stableCount > 0) { 14586 if (!capp.persistent && capp.thread != null 14587 && capp.pid != 0 14588 && capp.pid != MY_PID) { 14589 capp.kill("depends on provider " 14590 + cpr.name.flattenToShortString() 14591 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14592 } 14593 } else if (capp.thread != null && conn.provider.provider != null) { 14594 try { 14595 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14596 } catch (RemoteException e) { 14597 } 14598 // In the protocol here, we don't expect the client to correctly 14599 // clean up this connection, we'll just remove it. 14600 cpr.connections.remove(i); 14601 conn.client.conProviders.remove(conn); 14602 } 14603 } 14604 14605 if (inLaunching && always) { 14606 mLaunchingProviders.remove(cpr); 14607 } 14608 return inLaunching; 14609 } 14610 14611 /** 14612 * Main code for cleaning up a process when it has gone away. This is 14613 * called both as a result of the process dying, or directly when stopping 14614 * a process when running in single process mode. 14615 * 14616 * @return Returns true if the given process has been restarted, so the 14617 * app that was passed in must remain on the process lists. 14618 */ 14619 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14620 boolean restarting, boolean allowRestart, int index) { 14621 if (index >= 0) { 14622 removeLruProcessLocked(app); 14623 ProcessList.remove(app.pid); 14624 } 14625 14626 mProcessesToGc.remove(app); 14627 mPendingPssProcesses.remove(app); 14628 14629 // Dismiss any open dialogs. 14630 if (app.crashDialog != null && !app.forceCrashReport) { 14631 app.crashDialog.dismiss(); 14632 app.crashDialog = null; 14633 } 14634 if (app.anrDialog != null) { 14635 app.anrDialog.dismiss(); 14636 app.anrDialog = null; 14637 } 14638 if (app.waitDialog != null) { 14639 app.waitDialog.dismiss(); 14640 app.waitDialog = null; 14641 } 14642 14643 app.crashing = false; 14644 app.notResponding = false; 14645 14646 app.resetPackageList(mProcessStats); 14647 app.unlinkDeathRecipient(); 14648 app.makeInactive(mProcessStats); 14649 app.waitingToKill = null; 14650 app.forcingToForeground = null; 14651 updateProcessForegroundLocked(app, false, false); 14652 app.foregroundActivities = false; 14653 app.hasShownUi = false; 14654 app.treatLikeActivity = false; 14655 app.hasAboveClient = false; 14656 app.hasClientActivities = false; 14657 14658 mServices.killServicesLocked(app, allowRestart); 14659 14660 boolean restart = false; 14661 14662 // Remove published content providers. 14663 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14664 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14665 final boolean always = app.bad || !allowRestart; 14666 if (removeDyingProviderLocked(app, cpr, always) || always) { 14667 // We left the provider in the launching list, need to 14668 // restart it. 14669 restart = true; 14670 } 14671 14672 cpr.provider = null; 14673 cpr.proc = null; 14674 } 14675 app.pubProviders.clear(); 14676 14677 // Take care of any launching providers waiting for this process. 14678 if (checkAppInLaunchingProvidersLocked(app, false)) { 14679 restart = true; 14680 } 14681 14682 // Unregister from connected content providers. 14683 if (!app.conProviders.isEmpty()) { 14684 for (int i=0; i<app.conProviders.size(); i++) { 14685 ContentProviderConnection conn = app.conProviders.get(i); 14686 conn.provider.connections.remove(conn); 14687 } 14688 app.conProviders.clear(); 14689 } 14690 14691 // At this point there may be remaining entries in mLaunchingProviders 14692 // where we were the only one waiting, so they are no longer of use. 14693 // Look for these and clean up if found. 14694 // XXX Commented out for now. Trying to figure out a way to reproduce 14695 // the actual situation to identify what is actually going on. 14696 if (false) { 14697 for (int i=0; i<mLaunchingProviders.size(); i++) { 14698 ContentProviderRecord cpr = (ContentProviderRecord) 14699 mLaunchingProviders.get(i); 14700 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14701 synchronized (cpr) { 14702 cpr.launchingApp = null; 14703 cpr.notifyAll(); 14704 } 14705 } 14706 } 14707 } 14708 14709 skipCurrentReceiverLocked(app); 14710 14711 // Unregister any receivers. 14712 for (int i=app.receivers.size()-1; i>=0; i--) { 14713 removeReceiverLocked(app.receivers.valueAt(i)); 14714 } 14715 app.receivers.clear(); 14716 14717 // If the app is undergoing backup, tell the backup manager about it 14718 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14719 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14720 + mBackupTarget.appInfo + " died during backup"); 14721 try { 14722 IBackupManager bm = IBackupManager.Stub.asInterface( 14723 ServiceManager.getService(Context.BACKUP_SERVICE)); 14724 bm.agentDisconnected(app.info.packageName); 14725 } catch (RemoteException e) { 14726 // can't happen; backup manager is local 14727 } 14728 } 14729 14730 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14731 ProcessChangeItem item = mPendingProcessChanges.get(i); 14732 if (item.pid == app.pid) { 14733 mPendingProcessChanges.remove(i); 14734 mAvailProcessChanges.add(item); 14735 } 14736 } 14737 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14738 14739 // If the caller is restarting this app, then leave it in its 14740 // current lists and let the caller take care of it. 14741 if (restarting) { 14742 return false; 14743 } 14744 14745 if (!app.persistent || app.isolated) { 14746 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14747 "Removing non-persistent process during cleanup: " + app); 14748 mProcessNames.remove(app.processName, app.uid); 14749 mIsolatedProcesses.remove(app.uid); 14750 if (mHeavyWeightProcess == app) { 14751 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14752 mHeavyWeightProcess.userId, 0)); 14753 mHeavyWeightProcess = null; 14754 } 14755 } else if (!app.removed) { 14756 // This app is persistent, so we need to keep its record around. 14757 // If it is not already on the pending app list, add it there 14758 // and start a new process for it. 14759 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14760 mPersistentStartingProcesses.add(app); 14761 restart = true; 14762 } 14763 } 14764 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14765 "Clean-up removing on hold: " + app); 14766 mProcessesOnHold.remove(app); 14767 14768 if (app == mHomeProcess) { 14769 mHomeProcess = null; 14770 } 14771 if (app == mPreviousProcess) { 14772 mPreviousProcess = null; 14773 } 14774 14775 if (restart && !app.isolated) { 14776 // We have components that still need to be running in the 14777 // process, so re-launch it. 14778 if (index < 0) { 14779 ProcessList.remove(app.pid); 14780 } 14781 mProcessNames.put(app.processName, app.uid, app); 14782 startProcessLocked(app, "restart", app.processName); 14783 return true; 14784 } else if (app.pid > 0 && app.pid != MY_PID) { 14785 // Goodbye! 14786 boolean removed; 14787 synchronized (mPidsSelfLocked) { 14788 mPidsSelfLocked.remove(app.pid); 14789 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14790 } 14791 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14792 if (app.isolated) { 14793 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14794 } 14795 app.setPid(0); 14796 } 14797 return false; 14798 } 14799 14800 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14801 // Look through the content providers we are waiting to have launched, 14802 // and if any run in this process then either schedule a restart of 14803 // the process or kill the client waiting for it if this process has 14804 // gone bad. 14805 int NL = mLaunchingProviders.size(); 14806 boolean restart = false; 14807 for (int i=0; i<NL; i++) { 14808 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14809 if (cpr.launchingApp == app) { 14810 if (!alwaysBad && !app.bad) { 14811 restart = true; 14812 } else { 14813 removeDyingProviderLocked(app, cpr, true); 14814 // cpr should have been removed from mLaunchingProviders 14815 NL = mLaunchingProviders.size(); 14816 i--; 14817 } 14818 } 14819 } 14820 return restart; 14821 } 14822 14823 // ========================================================= 14824 // SERVICES 14825 // ========================================================= 14826 14827 @Override 14828 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14829 int flags) { 14830 enforceNotIsolatedCaller("getServices"); 14831 synchronized (this) { 14832 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14833 } 14834 } 14835 14836 @Override 14837 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14838 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14839 synchronized (this) { 14840 return mServices.getRunningServiceControlPanelLocked(name); 14841 } 14842 } 14843 14844 @Override 14845 public ComponentName startService(IApplicationThread caller, Intent service, 14846 String resolvedType, int userId) { 14847 enforceNotIsolatedCaller("startService"); 14848 // Refuse possible leaked file descriptors 14849 if (service != null && service.hasFileDescriptors() == true) { 14850 throw new IllegalArgumentException("File descriptors passed in Intent"); 14851 } 14852 14853 if (DEBUG_SERVICE) 14854 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14855 synchronized(this) { 14856 final int callingPid = Binder.getCallingPid(); 14857 final int callingUid = Binder.getCallingUid(); 14858 final long origId = Binder.clearCallingIdentity(); 14859 ComponentName res = mServices.startServiceLocked(caller, service, 14860 resolvedType, callingPid, callingUid, userId); 14861 Binder.restoreCallingIdentity(origId); 14862 return res; 14863 } 14864 } 14865 14866 ComponentName startServiceInPackage(int uid, 14867 Intent service, String resolvedType, int userId) { 14868 synchronized(this) { 14869 if (DEBUG_SERVICE) 14870 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14871 final long origId = Binder.clearCallingIdentity(); 14872 ComponentName res = mServices.startServiceLocked(null, service, 14873 resolvedType, -1, uid, userId); 14874 Binder.restoreCallingIdentity(origId); 14875 return res; 14876 } 14877 } 14878 14879 @Override 14880 public int stopService(IApplicationThread caller, Intent service, 14881 String resolvedType, int userId) { 14882 enforceNotIsolatedCaller("stopService"); 14883 // Refuse possible leaked file descriptors 14884 if (service != null && service.hasFileDescriptors() == true) { 14885 throw new IllegalArgumentException("File descriptors passed in Intent"); 14886 } 14887 14888 synchronized(this) { 14889 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14890 } 14891 } 14892 14893 @Override 14894 public IBinder peekService(Intent service, String resolvedType) { 14895 enforceNotIsolatedCaller("peekService"); 14896 // Refuse possible leaked file descriptors 14897 if (service != null && service.hasFileDescriptors() == true) { 14898 throw new IllegalArgumentException("File descriptors passed in Intent"); 14899 } 14900 synchronized(this) { 14901 return mServices.peekServiceLocked(service, resolvedType); 14902 } 14903 } 14904 14905 @Override 14906 public boolean stopServiceToken(ComponentName className, IBinder token, 14907 int startId) { 14908 synchronized(this) { 14909 return mServices.stopServiceTokenLocked(className, token, startId); 14910 } 14911 } 14912 14913 @Override 14914 public void setServiceForeground(ComponentName className, IBinder token, 14915 int id, Notification notification, boolean removeNotification) { 14916 synchronized(this) { 14917 mServices.setServiceForegroundLocked(className, token, id, notification, 14918 removeNotification); 14919 } 14920 } 14921 14922 @Override 14923 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14924 boolean requireFull, String name, String callerPackage) { 14925 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14926 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14927 } 14928 14929 int unsafeConvertIncomingUser(int userId) { 14930 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14931 ? mCurrentUserId : userId; 14932 } 14933 14934 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14935 int allowMode, String name, String callerPackage) { 14936 final int callingUserId = UserHandle.getUserId(callingUid); 14937 if (callingUserId == userId) { 14938 return userId; 14939 } 14940 14941 // Note that we may be accessing mCurrentUserId outside of a lock... 14942 // shouldn't be a big deal, if this is being called outside 14943 // of a locked context there is intrinsically a race with 14944 // the value the caller will receive and someone else changing it. 14945 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14946 // we will switch to the calling user if access to the current user fails. 14947 int targetUserId = unsafeConvertIncomingUser(userId); 14948 14949 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14950 final boolean allow; 14951 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14952 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14953 // If the caller has this permission, they always pass go. And collect $200. 14954 allow = true; 14955 } else if (allowMode == ALLOW_FULL_ONLY) { 14956 // We require full access, sucks to be you. 14957 allow = false; 14958 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14959 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14960 // If the caller does not have either permission, they are always doomed. 14961 allow = false; 14962 } else if (allowMode == ALLOW_NON_FULL) { 14963 // We are blanket allowing non-full access, you lucky caller! 14964 allow = true; 14965 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14966 // We may or may not allow this depending on whether the two users are 14967 // in the same profile. 14968 synchronized (mUserProfileGroupIdsSelfLocked) { 14969 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14970 UserInfo.NO_PROFILE_GROUP_ID); 14971 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14972 UserInfo.NO_PROFILE_GROUP_ID); 14973 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14974 && callingProfile == targetProfile; 14975 } 14976 } else { 14977 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14978 } 14979 if (!allow) { 14980 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14981 // In this case, they would like to just execute as their 14982 // owner user instead of failing. 14983 targetUserId = callingUserId; 14984 } else { 14985 StringBuilder builder = new StringBuilder(128); 14986 builder.append("Permission Denial: "); 14987 builder.append(name); 14988 if (callerPackage != null) { 14989 builder.append(" from "); 14990 builder.append(callerPackage); 14991 } 14992 builder.append(" asks to run as user "); 14993 builder.append(userId); 14994 builder.append(" but is calling from user "); 14995 builder.append(UserHandle.getUserId(callingUid)); 14996 builder.append("; this requires "); 14997 builder.append(INTERACT_ACROSS_USERS_FULL); 14998 if (allowMode != ALLOW_FULL_ONLY) { 14999 builder.append(" or "); 15000 builder.append(INTERACT_ACROSS_USERS); 15001 } 15002 String msg = builder.toString(); 15003 Slog.w(TAG, msg); 15004 throw new SecurityException(msg); 15005 } 15006 } 15007 } 15008 if (!allowAll && targetUserId < 0) { 15009 throw new IllegalArgumentException( 15010 "Call does not support special user #" + targetUserId); 15011 } 15012 // Check shell permission 15013 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15014 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15015 targetUserId)) { 15016 throw new SecurityException("Shell does not have permission to access user " 15017 + targetUserId + "\n " + Debug.getCallers(3)); 15018 } 15019 } 15020 return targetUserId; 15021 } 15022 15023 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15024 String className, int flags) { 15025 boolean result = false; 15026 // For apps that don't have pre-defined UIDs, check for permission 15027 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15028 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15029 if (ActivityManager.checkUidPermission( 15030 INTERACT_ACROSS_USERS, 15031 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15032 ComponentName comp = new ComponentName(aInfo.packageName, className); 15033 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15034 + " requests FLAG_SINGLE_USER, but app does not hold " 15035 + INTERACT_ACROSS_USERS; 15036 Slog.w(TAG, msg); 15037 throw new SecurityException(msg); 15038 } 15039 // Permission passed 15040 result = true; 15041 } 15042 } else if ("system".equals(componentProcessName)) { 15043 result = true; 15044 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15045 // Phone app and persistent apps are allowed to export singleuser providers. 15046 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15047 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15048 } 15049 if (DEBUG_MU) { 15050 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15051 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15052 } 15053 return result; 15054 } 15055 15056 /** 15057 * Checks to see if the caller is in the same app as the singleton 15058 * component, or the component is in a special app. It allows special apps 15059 * to export singleton components but prevents exporting singleton 15060 * components for regular apps. 15061 */ 15062 boolean isValidSingletonCall(int callingUid, int componentUid) { 15063 int componentAppId = UserHandle.getAppId(componentUid); 15064 return UserHandle.isSameApp(callingUid, componentUid) 15065 || componentAppId == Process.SYSTEM_UID 15066 || componentAppId == Process.PHONE_UID 15067 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15068 == PackageManager.PERMISSION_GRANTED; 15069 } 15070 15071 public int bindService(IApplicationThread caller, IBinder token, 15072 Intent service, String resolvedType, 15073 IServiceConnection connection, int flags, int userId) { 15074 enforceNotIsolatedCaller("bindService"); 15075 15076 // Refuse possible leaked file descriptors 15077 if (service != null && service.hasFileDescriptors() == true) { 15078 throw new IllegalArgumentException("File descriptors passed in Intent"); 15079 } 15080 15081 synchronized(this) { 15082 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15083 connection, flags, userId); 15084 } 15085 } 15086 15087 public boolean unbindService(IServiceConnection connection) { 15088 synchronized (this) { 15089 return mServices.unbindServiceLocked(connection); 15090 } 15091 } 15092 15093 public void publishService(IBinder token, Intent intent, IBinder service) { 15094 // Refuse possible leaked file descriptors 15095 if (intent != null && intent.hasFileDescriptors() == true) { 15096 throw new IllegalArgumentException("File descriptors passed in Intent"); 15097 } 15098 15099 synchronized(this) { 15100 if (!(token instanceof ServiceRecord)) { 15101 throw new IllegalArgumentException("Invalid service token"); 15102 } 15103 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15104 } 15105 } 15106 15107 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15108 // Refuse possible leaked file descriptors 15109 if (intent != null && intent.hasFileDescriptors() == true) { 15110 throw new IllegalArgumentException("File descriptors passed in Intent"); 15111 } 15112 15113 synchronized(this) { 15114 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15115 } 15116 } 15117 15118 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15119 synchronized(this) { 15120 if (!(token instanceof ServiceRecord)) { 15121 throw new IllegalArgumentException("Invalid service token"); 15122 } 15123 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15124 } 15125 } 15126 15127 // ========================================================= 15128 // BACKUP AND RESTORE 15129 // ========================================================= 15130 15131 // Cause the target app to be launched if necessary and its backup agent 15132 // instantiated. The backup agent will invoke backupAgentCreated() on the 15133 // activity manager to announce its creation. 15134 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15135 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15136 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15137 15138 synchronized(this) { 15139 // !!! TODO: currently no check here that we're already bound 15140 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15141 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15142 synchronized (stats) { 15143 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15144 } 15145 15146 // Backup agent is now in use, its package can't be stopped. 15147 try { 15148 AppGlobals.getPackageManager().setPackageStoppedState( 15149 app.packageName, false, UserHandle.getUserId(app.uid)); 15150 } catch (RemoteException e) { 15151 } catch (IllegalArgumentException e) { 15152 Slog.w(TAG, "Failed trying to unstop package " 15153 + app.packageName + ": " + e); 15154 } 15155 15156 BackupRecord r = new BackupRecord(ss, app, backupMode); 15157 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15158 ? new ComponentName(app.packageName, app.backupAgentName) 15159 : new ComponentName("android", "FullBackupAgent"); 15160 // startProcessLocked() returns existing proc's record if it's already running 15161 ProcessRecord proc = startProcessLocked(app.processName, app, 15162 false, 0, "backup", hostingName, false, false, false); 15163 if (proc == null) { 15164 Slog.e(TAG, "Unable to start backup agent process " + r); 15165 return false; 15166 } 15167 15168 r.app = proc; 15169 mBackupTarget = r; 15170 mBackupAppName = app.packageName; 15171 15172 // Try not to kill the process during backup 15173 updateOomAdjLocked(proc); 15174 15175 // If the process is already attached, schedule the creation of the backup agent now. 15176 // If it is not yet live, this will be done when it attaches to the framework. 15177 if (proc.thread != null) { 15178 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15179 try { 15180 proc.thread.scheduleCreateBackupAgent(app, 15181 compatibilityInfoForPackageLocked(app), backupMode); 15182 } catch (RemoteException e) { 15183 // Will time out on the backup manager side 15184 } 15185 } else { 15186 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15187 } 15188 // Invariants: at this point, the target app process exists and the application 15189 // is either already running or in the process of coming up. mBackupTarget and 15190 // mBackupAppName describe the app, so that when it binds back to the AM we 15191 // know that it's scheduled for a backup-agent operation. 15192 } 15193 15194 return true; 15195 } 15196 15197 @Override 15198 public void clearPendingBackup() { 15199 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15200 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15201 15202 synchronized (this) { 15203 mBackupTarget = null; 15204 mBackupAppName = null; 15205 } 15206 } 15207 15208 // A backup agent has just come up 15209 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15210 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15211 + " = " + agent); 15212 15213 synchronized(this) { 15214 if (!agentPackageName.equals(mBackupAppName)) { 15215 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15216 return; 15217 } 15218 } 15219 15220 long oldIdent = Binder.clearCallingIdentity(); 15221 try { 15222 IBackupManager bm = IBackupManager.Stub.asInterface( 15223 ServiceManager.getService(Context.BACKUP_SERVICE)); 15224 bm.agentConnected(agentPackageName, agent); 15225 } catch (RemoteException e) { 15226 // can't happen; the backup manager service is local 15227 } catch (Exception e) { 15228 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15229 e.printStackTrace(); 15230 } finally { 15231 Binder.restoreCallingIdentity(oldIdent); 15232 } 15233 } 15234 15235 // done with this agent 15236 public void unbindBackupAgent(ApplicationInfo appInfo) { 15237 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15238 if (appInfo == null) { 15239 Slog.w(TAG, "unbind backup agent for null app"); 15240 return; 15241 } 15242 15243 synchronized(this) { 15244 try { 15245 if (mBackupAppName == null) { 15246 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15247 return; 15248 } 15249 15250 if (!mBackupAppName.equals(appInfo.packageName)) { 15251 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15252 return; 15253 } 15254 15255 // Not backing this app up any more; reset its OOM adjustment 15256 final ProcessRecord proc = mBackupTarget.app; 15257 updateOomAdjLocked(proc); 15258 15259 // If the app crashed during backup, 'thread' will be null here 15260 if (proc.thread != null) { 15261 try { 15262 proc.thread.scheduleDestroyBackupAgent(appInfo, 15263 compatibilityInfoForPackageLocked(appInfo)); 15264 } catch (Exception e) { 15265 Slog.e(TAG, "Exception when unbinding backup agent:"); 15266 e.printStackTrace(); 15267 } 15268 } 15269 } finally { 15270 mBackupTarget = null; 15271 mBackupAppName = null; 15272 } 15273 } 15274 } 15275 // ========================================================= 15276 // BROADCASTS 15277 // ========================================================= 15278 15279 private final List getStickiesLocked(String action, IntentFilter filter, 15280 List cur, int userId) { 15281 final ContentResolver resolver = mContext.getContentResolver(); 15282 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15283 if (stickies == null) { 15284 return cur; 15285 } 15286 final ArrayList<Intent> list = stickies.get(action); 15287 if (list == null) { 15288 return cur; 15289 } 15290 int N = list.size(); 15291 for (int i=0; i<N; i++) { 15292 Intent intent = list.get(i); 15293 if (filter.match(resolver, intent, true, TAG) >= 0) { 15294 if (cur == null) { 15295 cur = new ArrayList<Intent>(); 15296 } 15297 cur.add(intent); 15298 } 15299 } 15300 return cur; 15301 } 15302 15303 boolean isPendingBroadcastProcessLocked(int pid) { 15304 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15305 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15306 } 15307 15308 void skipPendingBroadcastLocked(int pid) { 15309 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15310 for (BroadcastQueue queue : mBroadcastQueues) { 15311 queue.skipPendingBroadcastLocked(pid); 15312 } 15313 } 15314 15315 // The app just attached; send any pending broadcasts that it should receive 15316 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15317 boolean didSomething = false; 15318 for (BroadcastQueue queue : mBroadcastQueues) { 15319 didSomething |= queue.sendPendingBroadcastsLocked(app); 15320 } 15321 return didSomething; 15322 } 15323 15324 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15325 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15326 enforceNotIsolatedCaller("registerReceiver"); 15327 int callingUid; 15328 int callingPid; 15329 synchronized(this) { 15330 ProcessRecord callerApp = null; 15331 if (caller != null) { 15332 callerApp = getRecordForAppLocked(caller); 15333 if (callerApp == null) { 15334 throw new SecurityException( 15335 "Unable to find app for caller " + caller 15336 + " (pid=" + Binder.getCallingPid() 15337 + ") when registering receiver " + receiver); 15338 } 15339 if (callerApp.info.uid != Process.SYSTEM_UID && 15340 !callerApp.pkgList.containsKey(callerPackage) && 15341 !"android".equals(callerPackage)) { 15342 throw new SecurityException("Given caller package " + callerPackage 15343 + " is not running in process " + callerApp); 15344 } 15345 callingUid = callerApp.info.uid; 15346 callingPid = callerApp.pid; 15347 } else { 15348 callerPackage = null; 15349 callingUid = Binder.getCallingUid(); 15350 callingPid = Binder.getCallingPid(); 15351 } 15352 15353 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15354 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15355 15356 List allSticky = null; 15357 15358 // Look for any matching sticky broadcasts... 15359 Iterator actions = filter.actionsIterator(); 15360 if (actions != null) { 15361 while (actions.hasNext()) { 15362 String action = (String)actions.next(); 15363 allSticky = getStickiesLocked(action, filter, allSticky, 15364 UserHandle.USER_ALL); 15365 allSticky = getStickiesLocked(action, filter, allSticky, 15366 UserHandle.getUserId(callingUid)); 15367 } 15368 } else { 15369 allSticky = getStickiesLocked(null, filter, allSticky, 15370 UserHandle.USER_ALL); 15371 allSticky = getStickiesLocked(null, filter, allSticky, 15372 UserHandle.getUserId(callingUid)); 15373 } 15374 15375 // The first sticky in the list is returned directly back to 15376 // the client. 15377 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15378 15379 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15380 + ": " + sticky); 15381 15382 if (receiver == null) { 15383 return sticky; 15384 } 15385 15386 ReceiverList rl 15387 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15388 if (rl == null) { 15389 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15390 userId, receiver); 15391 if (rl.app != null) { 15392 rl.app.receivers.add(rl); 15393 } else { 15394 try { 15395 receiver.asBinder().linkToDeath(rl, 0); 15396 } catch (RemoteException e) { 15397 return sticky; 15398 } 15399 rl.linkedToDeath = true; 15400 } 15401 mRegisteredReceivers.put(receiver.asBinder(), rl); 15402 } else if (rl.uid != callingUid) { 15403 throw new IllegalArgumentException( 15404 "Receiver requested to register for uid " + callingUid 15405 + " was previously registered for uid " + rl.uid); 15406 } else if (rl.pid != callingPid) { 15407 throw new IllegalArgumentException( 15408 "Receiver requested to register for pid " + callingPid 15409 + " was previously registered for pid " + rl.pid); 15410 } else if (rl.userId != userId) { 15411 throw new IllegalArgumentException( 15412 "Receiver requested to register for user " + userId 15413 + " was previously registered for user " + rl.userId); 15414 } 15415 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15416 permission, callingUid, userId); 15417 rl.add(bf); 15418 if (!bf.debugCheck()) { 15419 Slog.w(TAG, "==> For Dynamic broadast"); 15420 } 15421 mReceiverResolver.addFilter(bf); 15422 15423 // Enqueue broadcasts for all existing stickies that match 15424 // this filter. 15425 if (allSticky != null) { 15426 ArrayList receivers = new ArrayList(); 15427 receivers.add(bf); 15428 15429 int N = allSticky.size(); 15430 for (int i=0; i<N; i++) { 15431 Intent intent = (Intent)allSticky.get(i); 15432 BroadcastQueue queue = broadcastQueueForIntent(intent); 15433 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15434 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15435 null, null, false, true, true, -1); 15436 queue.enqueueParallelBroadcastLocked(r); 15437 queue.scheduleBroadcastsLocked(); 15438 } 15439 } 15440 15441 return sticky; 15442 } 15443 } 15444 15445 public void unregisterReceiver(IIntentReceiver receiver) { 15446 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15447 15448 final long origId = Binder.clearCallingIdentity(); 15449 try { 15450 boolean doTrim = false; 15451 15452 synchronized(this) { 15453 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15454 if (rl != null) { 15455 if (rl.curBroadcast != null) { 15456 BroadcastRecord r = rl.curBroadcast; 15457 final boolean doNext = finishReceiverLocked( 15458 receiver.asBinder(), r.resultCode, r.resultData, 15459 r.resultExtras, r.resultAbort); 15460 if (doNext) { 15461 doTrim = true; 15462 r.queue.processNextBroadcast(false); 15463 } 15464 } 15465 15466 if (rl.app != null) { 15467 rl.app.receivers.remove(rl); 15468 } 15469 removeReceiverLocked(rl); 15470 if (rl.linkedToDeath) { 15471 rl.linkedToDeath = false; 15472 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15473 } 15474 } 15475 } 15476 15477 // If we actually concluded any broadcasts, we might now be able 15478 // to trim the recipients' apps from our working set 15479 if (doTrim) { 15480 trimApplications(); 15481 return; 15482 } 15483 15484 } finally { 15485 Binder.restoreCallingIdentity(origId); 15486 } 15487 } 15488 15489 void removeReceiverLocked(ReceiverList rl) { 15490 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15491 int N = rl.size(); 15492 for (int i=0; i<N; i++) { 15493 mReceiverResolver.removeFilter(rl.get(i)); 15494 } 15495 } 15496 15497 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15498 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15499 ProcessRecord r = mLruProcesses.get(i); 15500 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15501 try { 15502 r.thread.dispatchPackageBroadcast(cmd, packages); 15503 } catch (RemoteException ex) { 15504 } 15505 } 15506 } 15507 } 15508 15509 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15510 int callingUid, int[] users) { 15511 List<ResolveInfo> receivers = null; 15512 try { 15513 HashSet<ComponentName> singleUserReceivers = null; 15514 boolean scannedFirstReceivers = false; 15515 for (int user : users) { 15516 // Skip users that have Shell restrictions 15517 if (callingUid == Process.SHELL_UID 15518 && getUserManagerLocked().hasUserRestriction( 15519 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15520 continue; 15521 } 15522 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15523 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15524 if (user != 0 && newReceivers != null) { 15525 // If this is not the primary user, we need to check for 15526 // any receivers that should be filtered out. 15527 for (int i=0; i<newReceivers.size(); i++) { 15528 ResolveInfo ri = newReceivers.get(i); 15529 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15530 newReceivers.remove(i); 15531 i--; 15532 } 15533 } 15534 } 15535 if (newReceivers != null && newReceivers.size() == 0) { 15536 newReceivers = null; 15537 } 15538 if (receivers == null) { 15539 receivers = newReceivers; 15540 } else if (newReceivers != null) { 15541 // We need to concatenate the additional receivers 15542 // found with what we have do far. This would be easy, 15543 // but we also need to de-dup any receivers that are 15544 // singleUser. 15545 if (!scannedFirstReceivers) { 15546 // Collect any single user receivers we had already retrieved. 15547 scannedFirstReceivers = true; 15548 for (int i=0; i<receivers.size(); i++) { 15549 ResolveInfo ri = receivers.get(i); 15550 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15551 ComponentName cn = new ComponentName( 15552 ri.activityInfo.packageName, ri.activityInfo.name); 15553 if (singleUserReceivers == null) { 15554 singleUserReceivers = new HashSet<ComponentName>(); 15555 } 15556 singleUserReceivers.add(cn); 15557 } 15558 } 15559 } 15560 // Add the new results to the existing results, tracking 15561 // and de-dupping single user receivers. 15562 for (int i=0; i<newReceivers.size(); i++) { 15563 ResolveInfo ri = newReceivers.get(i); 15564 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15565 ComponentName cn = new ComponentName( 15566 ri.activityInfo.packageName, ri.activityInfo.name); 15567 if (singleUserReceivers == null) { 15568 singleUserReceivers = new HashSet<ComponentName>(); 15569 } 15570 if (!singleUserReceivers.contains(cn)) { 15571 singleUserReceivers.add(cn); 15572 receivers.add(ri); 15573 } 15574 } else { 15575 receivers.add(ri); 15576 } 15577 } 15578 } 15579 } 15580 } catch (RemoteException ex) { 15581 // pm is in same process, this will never happen. 15582 } 15583 return receivers; 15584 } 15585 15586 private final int broadcastIntentLocked(ProcessRecord callerApp, 15587 String callerPackage, Intent intent, String resolvedType, 15588 IIntentReceiver resultTo, int resultCode, String resultData, 15589 Bundle map, String requiredPermission, int appOp, 15590 boolean ordered, boolean sticky, int callingPid, int callingUid, 15591 int userId) { 15592 intent = new Intent(intent); 15593 15594 // By default broadcasts do not go to stopped apps. 15595 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15596 15597 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15598 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15599 + " ordered=" + ordered + " userid=" + userId); 15600 if ((resultTo != null) && !ordered) { 15601 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15602 } 15603 15604 userId = handleIncomingUser(callingPid, callingUid, userId, 15605 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15606 15607 // Make sure that the user who is receiving this broadcast is running. 15608 // If not, we will just skip it. 15609 15610 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15611 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15612 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15613 Slog.w(TAG, "Skipping broadcast of " + intent 15614 + ": user " + userId + " is stopped"); 15615 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15616 } 15617 } 15618 15619 /* 15620 * Prevent non-system code (defined here to be non-persistent 15621 * processes) from sending protected broadcasts. 15622 */ 15623 int callingAppId = UserHandle.getAppId(callingUid); 15624 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15625 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15626 || callingAppId == Process.NFC_UID || callingUid == 0) { 15627 // Always okay. 15628 } else if (callerApp == null || !callerApp.persistent) { 15629 try { 15630 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15631 intent.getAction())) { 15632 String msg = "Permission Denial: not allowed to send broadcast " 15633 + intent.getAction() + " from pid=" 15634 + callingPid + ", uid=" + callingUid; 15635 Slog.w(TAG, msg); 15636 throw new SecurityException(msg); 15637 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15638 // Special case for compatibility: we don't want apps to send this, 15639 // but historically it has not been protected and apps may be using it 15640 // to poke their own app widget. So, instead of making it protected, 15641 // just limit it to the caller. 15642 if (callerApp == null) { 15643 String msg = "Permission Denial: not allowed to send broadcast " 15644 + intent.getAction() + " from unknown caller."; 15645 Slog.w(TAG, msg); 15646 throw new SecurityException(msg); 15647 } else if (intent.getComponent() != null) { 15648 // They are good enough to send to an explicit component... verify 15649 // it is being sent to the calling app. 15650 if (!intent.getComponent().getPackageName().equals( 15651 callerApp.info.packageName)) { 15652 String msg = "Permission Denial: not allowed to send broadcast " 15653 + intent.getAction() + " to " 15654 + intent.getComponent().getPackageName() + " from " 15655 + callerApp.info.packageName; 15656 Slog.w(TAG, msg); 15657 throw new SecurityException(msg); 15658 } 15659 } else { 15660 // Limit broadcast to their own package. 15661 intent.setPackage(callerApp.info.packageName); 15662 } 15663 } 15664 } catch (RemoteException e) { 15665 Slog.w(TAG, "Remote exception", e); 15666 return ActivityManager.BROADCAST_SUCCESS; 15667 } 15668 } 15669 15670 final String action = intent.getAction(); 15671 if (action != null) { 15672 switch (action) { 15673 case Intent.ACTION_UID_REMOVED: 15674 case Intent.ACTION_PACKAGE_REMOVED: 15675 case Intent.ACTION_PACKAGE_CHANGED: 15676 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15677 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15678 // Handle special intents: if this broadcast is from the package 15679 // manager about a package being removed, we need to remove all of 15680 // its activities from the history stack. 15681 if (checkComponentPermission( 15682 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15683 callingPid, callingUid, -1, true) 15684 != PackageManager.PERMISSION_GRANTED) { 15685 String msg = "Permission Denial: " + intent.getAction() 15686 + " broadcast from " + callerPackage + " (pid=" + callingPid 15687 + ", uid=" + callingUid + ")" 15688 + " requires " 15689 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15690 Slog.w(TAG, msg); 15691 throw new SecurityException(msg); 15692 } 15693 switch (action) { 15694 case Intent.ACTION_UID_REMOVED: 15695 final Bundle intentExtras = intent.getExtras(); 15696 final int uid = intentExtras != null 15697 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15698 if (uid >= 0) { 15699 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15700 synchronized (bs) { 15701 bs.removeUidStatsLocked(uid); 15702 } 15703 mAppOpsService.uidRemoved(uid); 15704 } 15705 break; 15706 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15707 // If resources are unavailable just force stop all those packages 15708 // and flush the attribute cache as well. 15709 String list[] = 15710 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15711 if (list != null && list.length > 0) { 15712 for (int i = 0; i < list.length; i++) { 15713 forceStopPackageLocked(list[i], -1, false, true, true, 15714 false, false, userId, "storage unmount"); 15715 } 15716 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15717 sendPackageBroadcastLocked( 15718 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15719 userId); 15720 } 15721 break; 15722 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15723 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15724 break; 15725 case Intent.ACTION_PACKAGE_REMOVED: 15726 case Intent.ACTION_PACKAGE_CHANGED: 15727 Uri data = intent.getData(); 15728 String ssp; 15729 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15730 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15731 boolean fullUninstall = removed && 15732 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15733 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15734 forceStopPackageLocked(ssp, UserHandle.getAppId( 15735 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15736 false, true, true, false, fullUninstall, userId, 15737 removed ? "pkg removed" : "pkg changed"); 15738 } 15739 if (removed) { 15740 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15741 new String[] {ssp}, userId); 15742 if (fullUninstall) { 15743 mAppOpsService.packageRemoved( 15744 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15745 15746 // Remove all permissions granted from/to this package 15747 removeUriPermissionsForPackageLocked(ssp, userId, true); 15748 15749 removeTasksByPackageNameLocked(ssp, userId); 15750 } 15751 } else { 15752 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15753 } 15754 } 15755 break; 15756 } 15757 break; 15758 case Intent.ACTION_PACKAGE_ADDED: 15759 // Special case for adding a package: by default turn on compatibility mode. 15760 Uri data = intent.getData(); 15761 String ssp; 15762 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15763 final boolean replacing = 15764 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15765 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15766 15767 if (replacing) { 15768 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15769 } 15770 } 15771 break; 15772 case Intent.ACTION_TIMEZONE_CHANGED: 15773 // If this is the time zone changed action, queue up a message that will reset 15774 // the timezone of all currently running processes. This message will get 15775 // queued up before the broadcast happens. 15776 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15777 break; 15778 case Intent.ACTION_TIME_CHANGED: 15779 // If the user set the time, let all running processes know. 15780 final int is24Hour = 15781 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15782 : 0; 15783 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15784 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15785 synchronized (stats) { 15786 stats.noteCurrentTimeChangedLocked(); 15787 } 15788 break; 15789 case Intent.ACTION_CLEAR_DNS_CACHE: 15790 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15791 break; 15792 case Proxy.PROXY_CHANGE_ACTION: 15793 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15794 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15795 break; 15796 } 15797 } 15798 15799 // Add to the sticky list if requested. 15800 if (sticky) { 15801 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15802 callingPid, callingUid) 15803 != PackageManager.PERMISSION_GRANTED) { 15804 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15805 + callingPid + ", uid=" + callingUid 15806 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15807 Slog.w(TAG, msg); 15808 throw new SecurityException(msg); 15809 } 15810 if (requiredPermission != null) { 15811 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15812 + " and enforce permission " + requiredPermission); 15813 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15814 } 15815 if (intent.getComponent() != null) { 15816 throw new SecurityException( 15817 "Sticky broadcasts can't target a specific component"); 15818 } 15819 // We use userId directly here, since the "all" target is maintained 15820 // as a separate set of sticky broadcasts. 15821 if (userId != UserHandle.USER_ALL) { 15822 // But first, if this is not a broadcast to all users, then 15823 // make sure it doesn't conflict with an existing broadcast to 15824 // all users. 15825 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15826 UserHandle.USER_ALL); 15827 if (stickies != null) { 15828 ArrayList<Intent> list = stickies.get(intent.getAction()); 15829 if (list != null) { 15830 int N = list.size(); 15831 int i; 15832 for (i=0; i<N; i++) { 15833 if (intent.filterEquals(list.get(i))) { 15834 throw new IllegalArgumentException( 15835 "Sticky broadcast " + intent + " for user " 15836 + userId + " conflicts with existing global broadcast"); 15837 } 15838 } 15839 } 15840 } 15841 } 15842 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15843 if (stickies == null) { 15844 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15845 mStickyBroadcasts.put(userId, stickies); 15846 } 15847 ArrayList<Intent> list = stickies.get(intent.getAction()); 15848 if (list == null) { 15849 list = new ArrayList<Intent>(); 15850 stickies.put(intent.getAction(), list); 15851 } 15852 int N = list.size(); 15853 int i; 15854 for (i=0; i<N; i++) { 15855 if (intent.filterEquals(list.get(i))) { 15856 // This sticky already exists, replace it. 15857 list.set(i, new Intent(intent)); 15858 break; 15859 } 15860 } 15861 if (i >= N) { 15862 list.add(new Intent(intent)); 15863 } 15864 } 15865 15866 int[] users; 15867 if (userId == UserHandle.USER_ALL) { 15868 // Caller wants broadcast to go to all started users. 15869 users = mStartedUserArray; 15870 } else { 15871 // Caller wants broadcast to go to one specific user. 15872 users = new int[] {userId}; 15873 } 15874 15875 // Figure out who all will receive this broadcast. 15876 List receivers = null; 15877 List<BroadcastFilter> registeredReceivers = null; 15878 // Need to resolve the intent to interested receivers... 15879 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15880 == 0) { 15881 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15882 } 15883 if (intent.getComponent() == null) { 15884 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15885 // Query one target user at a time, excluding shell-restricted users 15886 UserManagerService ums = getUserManagerLocked(); 15887 for (int i = 0; i < users.length; i++) { 15888 if (ums.hasUserRestriction( 15889 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15890 continue; 15891 } 15892 List<BroadcastFilter> registeredReceiversForUser = 15893 mReceiverResolver.queryIntent(intent, 15894 resolvedType, false, users[i]); 15895 if (registeredReceivers == null) { 15896 registeredReceivers = registeredReceiversForUser; 15897 } else if (registeredReceiversForUser != null) { 15898 registeredReceivers.addAll(registeredReceiversForUser); 15899 } 15900 } 15901 } else { 15902 registeredReceivers = mReceiverResolver.queryIntent(intent, 15903 resolvedType, false, userId); 15904 } 15905 } 15906 15907 final boolean replacePending = 15908 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15909 15910 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15911 + " replacePending=" + replacePending); 15912 15913 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15914 if (!ordered && NR > 0) { 15915 // If we are not serializing this broadcast, then send the 15916 // registered receivers separately so they don't wait for the 15917 // components to be launched. 15918 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15919 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15920 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15921 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15922 ordered, sticky, false, userId); 15923 if (DEBUG_BROADCAST) Slog.v( 15924 TAG, "Enqueueing parallel broadcast " + r); 15925 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15926 if (!replaced) { 15927 queue.enqueueParallelBroadcastLocked(r); 15928 queue.scheduleBroadcastsLocked(); 15929 } 15930 registeredReceivers = null; 15931 NR = 0; 15932 } 15933 15934 // Merge into one list. 15935 int ir = 0; 15936 if (receivers != null) { 15937 // A special case for PACKAGE_ADDED: do not allow the package 15938 // being added to see this broadcast. This prevents them from 15939 // using this as a back door to get run as soon as they are 15940 // installed. Maybe in the future we want to have a special install 15941 // broadcast or such for apps, but we'd like to deliberately make 15942 // this decision. 15943 String skipPackages[] = null; 15944 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15945 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15946 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15947 Uri data = intent.getData(); 15948 if (data != null) { 15949 String pkgName = data.getSchemeSpecificPart(); 15950 if (pkgName != null) { 15951 skipPackages = new String[] { pkgName }; 15952 } 15953 } 15954 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15955 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15956 } 15957 if (skipPackages != null && (skipPackages.length > 0)) { 15958 for (String skipPackage : skipPackages) { 15959 if (skipPackage != null) { 15960 int NT = receivers.size(); 15961 for (int it=0; it<NT; it++) { 15962 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15963 if (curt.activityInfo.packageName.equals(skipPackage)) { 15964 receivers.remove(it); 15965 it--; 15966 NT--; 15967 } 15968 } 15969 } 15970 } 15971 } 15972 15973 int NT = receivers != null ? receivers.size() : 0; 15974 int it = 0; 15975 ResolveInfo curt = null; 15976 BroadcastFilter curr = null; 15977 while (it < NT && ir < NR) { 15978 if (curt == null) { 15979 curt = (ResolveInfo)receivers.get(it); 15980 } 15981 if (curr == null) { 15982 curr = registeredReceivers.get(ir); 15983 } 15984 if (curr.getPriority() >= curt.priority) { 15985 // Insert this broadcast record into the final list. 15986 receivers.add(it, curr); 15987 ir++; 15988 curr = null; 15989 it++; 15990 NT++; 15991 } else { 15992 // Skip to the next ResolveInfo in the final list. 15993 it++; 15994 curt = null; 15995 } 15996 } 15997 } 15998 while (ir < NR) { 15999 if (receivers == null) { 16000 receivers = new ArrayList(); 16001 } 16002 receivers.add(registeredReceivers.get(ir)); 16003 ir++; 16004 } 16005 16006 if ((receivers != null && receivers.size() > 0) 16007 || resultTo != null) { 16008 BroadcastQueue queue = broadcastQueueForIntent(intent); 16009 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16010 callerPackage, callingPid, callingUid, resolvedType, 16011 requiredPermission, appOp, receivers, resultTo, resultCode, 16012 resultData, map, ordered, sticky, false, userId); 16013 if (DEBUG_BROADCAST) Slog.v( 16014 TAG, "Enqueueing ordered broadcast " + r 16015 + ": prev had " + queue.mOrderedBroadcasts.size()); 16016 if (DEBUG_BROADCAST) { 16017 int seq = r.intent.getIntExtra("seq", -1); 16018 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16019 } 16020 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16021 if (!replaced) { 16022 queue.enqueueOrderedBroadcastLocked(r); 16023 queue.scheduleBroadcastsLocked(); 16024 } 16025 } 16026 16027 return ActivityManager.BROADCAST_SUCCESS; 16028 } 16029 16030 final Intent verifyBroadcastLocked(Intent intent) { 16031 // Refuse possible leaked file descriptors 16032 if (intent != null && intent.hasFileDescriptors() == true) { 16033 throw new IllegalArgumentException("File descriptors passed in Intent"); 16034 } 16035 16036 int flags = intent.getFlags(); 16037 16038 if (!mProcessesReady) { 16039 // if the caller really truly claims to know what they're doing, go 16040 // ahead and allow the broadcast without launching any receivers 16041 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16042 intent = new Intent(intent); 16043 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16044 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16045 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16046 + " before boot completion"); 16047 throw new IllegalStateException("Cannot broadcast before boot completed"); 16048 } 16049 } 16050 16051 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16052 throw new IllegalArgumentException( 16053 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16054 } 16055 16056 return intent; 16057 } 16058 16059 public final int broadcastIntent(IApplicationThread caller, 16060 Intent intent, String resolvedType, IIntentReceiver resultTo, 16061 int resultCode, String resultData, Bundle map, 16062 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16063 enforceNotIsolatedCaller("broadcastIntent"); 16064 synchronized(this) { 16065 intent = verifyBroadcastLocked(intent); 16066 16067 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16068 final int callingPid = Binder.getCallingPid(); 16069 final int callingUid = Binder.getCallingUid(); 16070 final long origId = Binder.clearCallingIdentity(); 16071 int res = broadcastIntentLocked(callerApp, 16072 callerApp != null ? callerApp.info.packageName : null, 16073 intent, resolvedType, resultTo, 16074 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16075 callingPid, callingUid, userId); 16076 Binder.restoreCallingIdentity(origId); 16077 return res; 16078 } 16079 } 16080 16081 int broadcastIntentInPackage(String packageName, int uid, 16082 Intent intent, String resolvedType, IIntentReceiver resultTo, 16083 int resultCode, String resultData, Bundle map, 16084 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16085 synchronized(this) { 16086 intent = verifyBroadcastLocked(intent); 16087 16088 final long origId = Binder.clearCallingIdentity(); 16089 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16090 resultTo, resultCode, resultData, map, requiredPermission, 16091 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16092 Binder.restoreCallingIdentity(origId); 16093 return res; 16094 } 16095 } 16096 16097 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16098 // Refuse possible leaked file descriptors 16099 if (intent != null && intent.hasFileDescriptors() == true) { 16100 throw new IllegalArgumentException("File descriptors passed in Intent"); 16101 } 16102 16103 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16104 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16105 16106 synchronized(this) { 16107 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16108 != PackageManager.PERMISSION_GRANTED) { 16109 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16110 + Binder.getCallingPid() 16111 + ", uid=" + Binder.getCallingUid() 16112 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16113 Slog.w(TAG, msg); 16114 throw new SecurityException(msg); 16115 } 16116 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16117 if (stickies != null) { 16118 ArrayList<Intent> list = stickies.get(intent.getAction()); 16119 if (list != null) { 16120 int N = list.size(); 16121 int i; 16122 for (i=0; i<N; i++) { 16123 if (intent.filterEquals(list.get(i))) { 16124 list.remove(i); 16125 break; 16126 } 16127 } 16128 if (list.size() <= 0) { 16129 stickies.remove(intent.getAction()); 16130 } 16131 } 16132 if (stickies.size() <= 0) { 16133 mStickyBroadcasts.remove(userId); 16134 } 16135 } 16136 } 16137 } 16138 16139 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16140 String resultData, Bundle resultExtras, boolean resultAbort) { 16141 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16142 if (r == null) { 16143 Slog.w(TAG, "finishReceiver called but not found on queue"); 16144 return false; 16145 } 16146 16147 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16148 } 16149 16150 void backgroundServicesFinishedLocked(int userId) { 16151 for (BroadcastQueue queue : mBroadcastQueues) { 16152 queue.backgroundServicesFinishedLocked(userId); 16153 } 16154 } 16155 16156 public void finishReceiver(IBinder who, int resultCode, String resultData, 16157 Bundle resultExtras, boolean resultAbort) { 16158 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16159 16160 // Refuse possible leaked file descriptors 16161 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16162 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16163 } 16164 16165 final long origId = Binder.clearCallingIdentity(); 16166 try { 16167 boolean doNext = false; 16168 BroadcastRecord r; 16169 16170 synchronized(this) { 16171 r = broadcastRecordForReceiverLocked(who); 16172 if (r != null) { 16173 doNext = r.queue.finishReceiverLocked(r, resultCode, 16174 resultData, resultExtras, resultAbort, true); 16175 } 16176 } 16177 16178 if (doNext) { 16179 r.queue.processNextBroadcast(false); 16180 } 16181 trimApplications(); 16182 } finally { 16183 Binder.restoreCallingIdentity(origId); 16184 } 16185 } 16186 16187 // ========================================================= 16188 // INSTRUMENTATION 16189 // ========================================================= 16190 16191 public boolean startInstrumentation(ComponentName className, 16192 String profileFile, int flags, Bundle arguments, 16193 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16194 int userId, String abiOverride) { 16195 enforceNotIsolatedCaller("startInstrumentation"); 16196 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16197 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16198 // Refuse possible leaked file descriptors 16199 if (arguments != null && arguments.hasFileDescriptors()) { 16200 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16201 } 16202 16203 synchronized(this) { 16204 InstrumentationInfo ii = null; 16205 ApplicationInfo ai = null; 16206 try { 16207 ii = mContext.getPackageManager().getInstrumentationInfo( 16208 className, STOCK_PM_FLAGS); 16209 ai = AppGlobals.getPackageManager().getApplicationInfo( 16210 ii.targetPackage, STOCK_PM_FLAGS, userId); 16211 } catch (PackageManager.NameNotFoundException e) { 16212 } catch (RemoteException e) { 16213 } 16214 if (ii == null) { 16215 reportStartInstrumentationFailure(watcher, className, 16216 "Unable to find instrumentation info for: " + className); 16217 return false; 16218 } 16219 if (ai == null) { 16220 reportStartInstrumentationFailure(watcher, className, 16221 "Unable to find instrumentation target package: " + ii.targetPackage); 16222 return false; 16223 } 16224 16225 int match = mContext.getPackageManager().checkSignatures( 16226 ii.targetPackage, ii.packageName); 16227 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16228 String msg = "Permission Denial: starting instrumentation " 16229 + className + " from pid=" 16230 + Binder.getCallingPid() 16231 + ", uid=" + Binder.getCallingPid() 16232 + " not allowed because package " + ii.packageName 16233 + " does not have a signature matching the target " 16234 + ii.targetPackage; 16235 reportStartInstrumentationFailure(watcher, className, msg); 16236 throw new SecurityException(msg); 16237 } 16238 16239 final long origId = Binder.clearCallingIdentity(); 16240 // Instrumentation can kill and relaunch even persistent processes 16241 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16242 "start instr"); 16243 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16244 app.instrumentationClass = className; 16245 app.instrumentationInfo = ai; 16246 app.instrumentationProfileFile = profileFile; 16247 app.instrumentationArguments = arguments; 16248 app.instrumentationWatcher = watcher; 16249 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16250 app.instrumentationResultClass = className; 16251 Binder.restoreCallingIdentity(origId); 16252 } 16253 16254 return true; 16255 } 16256 16257 /** 16258 * Report errors that occur while attempting to start Instrumentation. Always writes the 16259 * error to the logs, but if somebody is watching, send the report there too. This enables 16260 * the "am" command to report errors with more information. 16261 * 16262 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16263 * @param cn The component name of the instrumentation. 16264 * @param report The error report. 16265 */ 16266 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16267 ComponentName cn, String report) { 16268 Slog.w(TAG, report); 16269 try { 16270 if (watcher != null) { 16271 Bundle results = new Bundle(); 16272 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16273 results.putString("Error", report); 16274 watcher.instrumentationStatus(cn, -1, results); 16275 } 16276 } catch (RemoteException e) { 16277 Slog.w(TAG, e); 16278 } 16279 } 16280 16281 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16282 if (app.instrumentationWatcher != null) { 16283 try { 16284 // NOTE: IInstrumentationWatcher *must* be oneway here 16285 app.instrumentationWatcher.instrumentationFinished( 16286 app.instrumentationClass, 16287 resultCode, 16288 results); 16289 } catch (RemoteException e) { 16290 } 16291 } 16292 if (app.instrumentationUiAutomationConnection != null) { 16293 try { 16294 app.instrumentationUiAutomationConnection.shutdown(); 16295 } catch (RemoteException re) { 16296 /* ignore */ 16297 } 16298 // Only a UiAutomation can set this flag and now that 16299 // it is finished we make sure it is reset to its default. 16300 mUserIsMonkey = false; 16301 } 16302 app.instrumentationWatcher = null; 16303 app.instrumentationUiAutomationConnection = null; 16304 app.instrumentationClass = null; 16305 app.instrumentationInfo = null; 16306 app.instrumentationProfileFile = null; 16307 app.instrumentationArguments = null; 16308 16309 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16310 "finished inst"); 16311 } 16312 16313 public void finishInstrumentation(IApplicationThread target, 16314 int resultCode, Bundle results) { 16315 int userId = UserHandle.getCallingUserId(); 16316 // Refuse possible leaked file descriptors 16317 if (results != null && results.hasFileDescriptors()) { 16318 throw new IllegalArgumentException("File descriptors passed in Intent"); 16319 } 16320 16321 synchronized(this) { 16322 ProcessRecord app = getRecordForAppLocked(target); 16323 if (app == null) { 16324 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16325 return; 16326 } 16327 final long origId = Binder.clearCallingIdentity(); 16328 finishInstrumentationLocked(app, resultCode, results); 16329 Binder.restoreCallingIdentity(origId); 16330 } 16331 } 16332 16333 // ========================================================= 16334 // CONFIGURATION 16335 // ========================================================= 16336 16337 public ConfigurationInfo getDeviceConfigurationInfo() { 16338 ConfigurationInfo config = new ConfigurationInfo(); 16339 synchronized (this) { 16340 config.reqTouchScreen = mConfiguration.touchscreen; 16341 config.reqKeyboardType = mConfiguration.keyboard; 16342 config.reqNavigation = mConfiguration.navigation; 16343 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16344 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16345 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16346 } 16347 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16348 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16349 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16350 } 16351 config.reqGlEsVersion = GL_ES_VERSION; 16352 } 16353 return config; 16354 } 16355 16356 ActivityStack getFocusedStack() { 16357 return mStackSupervisor.getFocusedStack(); 16358 } 16359 16360 public Configuration getConfiguration() { 16361 Configuration ci; 16362 synchronized(this) { 16363 ci = new Configuration(mConfiguration); 16364 } 16365 return ci; 16366 } 16367 16368 public void updatePersistentConfiguration(Configuration values) { 16369 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16370 "updateConfiguration()"); 16371 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16372 "updateConfiguration()"); 16373 if (values == null) { 16374 throw new NullPointerException("Configuration must not be null"); 16375 } 16376 16377 synchronized(this) { 16378 final long origId = Binder.clearCallingIdentity(); 16379 updateConfigurationLocked(values, null, true, false); 16380 Binder.restoreCallingIdentity(origId); 16381 } 16382 } 16383 16384 public void updateConfiguration(Configuration values) { 16385 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16386 "updateConfiguration()"); 16387 16388 synchronized(this) { 16389 if (values == null && mWindowManager != null) { 16390 // sentinel: fetch the current configuration from the window manager 16391 values = mWindowManager.computeNewConfiguration(); 16392 } 16393 16394 if (mWindowManager != null) { 16395 mProcessList.applyDisplaySize(mWindowManager); 16396 } 16397 16398 final long origId = Binder.clearCallingIdentity(); 16399 if (values != null) { 16400 Settings.System.clearConfiguration(values); 16401 } 16402 updateConfigurationLocked(values, null, false, false); 16403 Binder.restoreCallingIdentity(origId); 16404 } 16405 } 16406 16407 /** 16408 * Do either or both things: (1) change the current configuration, and (2) 16409 * make sure the given activity is running with the (now) current 16410 * configuration. Returns true if the activity has been left running, or 16411 * false if <var>starting</var> is being destroyed to match the new 16412 * configuration. 16413 * @param persistent TODO 16414 */ 16415 boolean updateConfigurationLocked(Configuration values, 16416 ActivityRecord starting, boolean persistent, boolean initLocale) { 16417 int changes = 0; 16418 16419 if (values != null) { 16420 Configuration newConfig = new Configuration(mConfiguration); 16421 changes = newConfig.updateFrom(values); 16422 if (changes != 0) { 16423 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16424 Slog.i(TAG, "Updating configuration to: " + values); 16425 } 16426 16427 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16428 16429 if (values.locale != null && !initLocale) { 16430 saveLocaleLocked(values.locale, 16431 !values.locale.equals(mConfiguration.locale), 16432 values.userSetLocale); 16433 } 16434 16435 mConfigurationSeq++; 16436 if (mConfigurationSeq <= 0) { 16437 mConfigurationSeq = 1; 16438 } 16439 newConfig.seq = mConfigurationSeq; 16440 mConfiguration = newConfig; 16441 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16442 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16443 //mUsageStatsService.noteStartConfig(newConfig); 16444 16445 final Configuration configCopy = new Configuration(mConfiguration); 16446 16447 // TODO: If our config changes, should we auto dismiss any currently 16448 // showing dialogs? 16449 mShowDialogs = shouldShowDialogs(newConfig); 16450 16451 AttributeCache ac = AttributeCache.instance(); 16452 if (ac != null) { 16453 ac.updateConfiguration(configCopy); 16454 } 16455 16456 // Make sure all resources in our process are updated 16457 // right now, so that anyone who is going to retrieve 16458 // resource values after we return will be sure to get 16459 // the new ones. This is especially important during 16460 // boot, where the first config change needs to guarantee 16461 // all resources have that config before following boot 16462 // code is executed. 16463 mSystemThread.applyConfigurationToResources(configCopy); 16464 16465 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16466 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16467 msg.obj = new Configuration(configCopy); 16468 mHandler.sendMessage(msg); 16469 } 16470 16471 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16472 ProcessRecord app = mLruProcesses.get(i); 16473 try { 16474 if (app.thread != null) { 16475 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16476 + app.processName + " new config " + mConfiguration); 16477 app.thread.scheduleConfigurationChanged(configCopy); 16478 } 16479 } catch (Exception e) { 16480 } 16481 } 16482 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16483 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16484 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16485 | Intent.FLAG_RECEIVER_FOREGROUND); 16486 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16487 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16488 Process.SYSTEM_UID, UserHandle.USER_ALL); 16489 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16490 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16491 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16492 broadcastIntentLocked(null, null, intent, 16493 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16494 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16495 } 16496 } 16497 } 16498 16499 boolean kept = true; 16500 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16501 // mainStack is null during startup. 16502 if (mainStack != null) { 16503 if (changes != 0 && starting == null) { 16504 // If the configuration changed, and the caller is not already 16505 // in the process of starting an activity, then find the top 16506 // activity to check if its configuration needs to change. 16507 starting = mainStack.topRunningActivityLocked(null); 16508 } 16509 16510 if (starting != null) { 16511 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16512 // And we need to make sure at this point that all other activities 16513 // are made visible with the correct configuration. 16514 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16515 } 16516 } 16517 16518 if (values != null && mWindowManager != null) { 16519 mWindowManager.setNewConfiguration(mConfiguration); 16520 } 16521 16522 return kept; 16523 } 16524 16525 /** 16526 * Decide based on the configuration whether we should shouw the ANR, 16527 * crash, etc dialogs. The idea is that if there is no affordnace to 16528 * press the on-screen buttons, we shouldn't show the dialog. 16529 * 16530 * A thought: SystemUI might also want to get told about this, the Power 16531 * dialog / global actions also might want different behaviors. 16532 */ 16533 private static final boolean shouldShowDialogs(Configuration config) { 16534 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16535 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16536 } 16537 16538 /** 16539 * Save the locale. You must be inside a synchronized (this) block. 16540 */ 16541 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16542 if(isDiff) { 16543 SystemProperties.set("user.language", l.getLanguage()); 16544 SystemProperties.set("user.region", l.getCountry()); 16545 } 16546 16547 if(isPersist) { 16548 SystemProperties.set("persist.sys.language", l.getLanguage()); 16549 SystemProperties.set("persist.sys.country", l.getCountry()); 16550 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16551 16552 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16553 } 16554 } 16555 16556 @Override 16557 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16558 synchronized (this) { 16559 ActivityRecord srec = ActivityRecord.forToken(token); 16560 if (srec.task != null && srec.task.stack != null) { 16561 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16562 } 16563 } 16564 return false; 16565 } 16566 16567 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16568 Intent resultData) { 16569 16570 synchronized (this) { 16571 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16572 if (stack != null) { 16573 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16574 } 16575 return false; 16576 } 16577 } 16578 16579 public int getLaunchedFromUid(IBinder activityToken) { 16580 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16581 if (srec == null) { 16582 return -1; 16583 } 16584 return srec.launchedFromUid; 16585 } 16586 16587 public String getLaunchedFromPackage(IBinder activityToken) { 16588 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16589 if (srec == null) { 16590 return null; 16591 } 16592 return srec.launchedFromPackage; 16593 } 16594 16595 // ========================================================= 16596 // LIFETIME MANAGEMENT 16597 // ========================================================= 16598 16599 // Returns which broadcast queue the app is the current [or imminent] receiver 16600 // on, or 'null' if the app is not an active broadcast recipient. 16601 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16602 BroadcastRecord r = app.curReceiver; 16603 if (r != null) { 16604 return r.queue; 16605 } 16606 16607 // It's not the current receiver, but it might be starting up to become one 16608 synchronized (this) { 16609 for (BroadcastQueue queue : mBroadcastQueues) { 16610 r = queue.mPendingBroadcast; 16611 if (r != null && r.curApp == app) { 16612 // found it; report which queue it's in 16613 return queue; 16614 } 16615 } 16616 } 16617 16618 return null; 16619 } 16620 16621 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16622 boolean doingAll, long now) { 16623 if (mAdjSeq == app.adjSeq) { 16624 // This adjustment has already been computed. 16625 return app.curRawAdj; 16626 } 16627 16628 if (app.thread == null) { 16629 app.adjSeq = mAdjSeq; 16630 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16631 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16632 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16633 } 16634 16635 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16636 app.adjSource = null; 16637 app.adjTarget = null; 16638 app.empty = false; 16639 app.cached = false; 16640 16641 final int activitiesSize = app.activities.size(); 16642 16643 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16644 // The max adjustment doesn't allow this app to be anything 16645 // below foreground, so it is not worth doing work for it. 16646 app.adjType = "fixed"; 16647 app.adjSeq = mAdjSeq; 16648 app.curRawAdj = app.maxAdj; 16649 app.foregroundActivities = false; 16650 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16651 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16652 // System processes can do UI, and when they do we want to have 16653 // them trim their memory after the user leaves the UI. To 16654 // facilitate this, here we need to determine whether or not it 16655 // is currently showing UI. 16656 app.systemNoUi = true; 16657 if (app == TOP_APP) { 16658 app.systemNoUi = false; 16659 } else if (activitiesSize > 0) { 16660 for (int j = 0; j < activitiesSize; j++) { 16661 final ActivityRecord r = app.activities.get(j); 16662 if (r.visible) { 16663 app.systemNoUi = false; 16664 } 16665 } 16666 } 16667 if (!app.systemNoUi) { 16668 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16669 } 16670 return (app.curAdj=app.maxAdj); 16671 } 16672 16673 app.systemNoUi = false; 16674 16675 // Determine the importance of the process, starting with most 16676 // important to least, and assign an appropriate OOM adjustment. 16677 int adj; 16678 int schedGroup; 16679 int procState; 16680 boolean foregroundActivities = false; 16681 BroadcastQueue queue; 16682 if (app == TOP_APP) { 16683 // The last app on the list is the foreground app. 16684 adj = ProcessList.FOREGROUND_APP_ADJ; 16685 schedGroup = Process.THREAD_GROUP_DEFAULT; 16686 app.adjType = "top-activity"; 16687 foregroundActivities = true; 16688 procState = ActivityManager.PROCESS_STATE_TOP; 16689 } else if (app.instrumentationClass != null) { 16690 // Don't want to kill running instrumentation. 16691 adj = ProcessList.FOREGROUND_APP_ADJ; 16692 schedGroup = Process.THREAD_GROUP_DEFAULT; 16693 app.adjType = "instrumentation"; 16694 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16695 } else if ((queue = isReceivingBroadcast(app)) != null) { 16696 // An app that is currently receiving a broadcast also 16697 // counts as being in the foreground for OOM killer purposes. 16698 // It's placed in a sched group based on the nature of the 16699 // broadcast as reflected by which queue it's active in. 16700 adj = ProcessList.FOREGROUND_APP_ADJ; 16701 schedGroup = (queue == mFgBroadcastQueue) 16702 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16703 app.adjType = "broadcast"; 16704 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16705 } else if (app.executingServices.size() > 0) { 16706 // An app that is currently executing a service callback also 16707 // counts as being in the foreground. 16708 adj = ProcessList.FOREGROUND_APP_ADJ; 16709 schedGroup = app.execServicesFg ? 16710 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16711 app.adjType = "exec-service"; 16712 procState = ActivityManager.PROCESS_STATE_SERVICE; 16713 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16714 } else { 16715 // As far as we know the process is empty. We may change our mind later. 16716 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16717 // At this point we don't actually know the adjustment. Use the cached adj 16718 // value that the caller wants us to. 16719 adj = cachedAdj; 16720 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16721 app.cached = true; 16722 app.empty = true; 16723 app.adjType = "cch-empty"; 16724 } 16725 16726 // Examine all activities if not already foreground. 16727 if (!foregroundActivities && activitiesSize > 0) { 16728 for (int j = 0; j < activitiesSize; j++) { 16729 final ActivityRecord r = app.activities.get(j); 16730 if (r.app != app) { 16731 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16732 + app + "?!?"); 16733 continue; 16734 } 16735 if (r.visible) { 16736 // App has a visible activity; only upgrade adjustment. 16737 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16738 adj = ProcessList.VISIBLE_APP_ADJ; 16739 app.adjType = "visible"; 16740 } 16741 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16742 procState = ActivityManager.PROCESS_STATE_TOP; 16743 } 16744 schedGroup = Process.THREAD_GROUP_DEFAULT; 16745 app.cached = false; 16746 app.empty = false; 16747 foregroundActivities = true; 16748 break; 16749 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16750 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16751 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16752 app.adjType = "pausing"; 16753 } 16754 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16755 procState = ActivityManager.PROCESS_STATE_TOP; 16756 } 16757 schedGroup = Process.THREAD_GROUP_DEFAULT; 16758 app.cached = false; 16759 app.empty = false; 16760 foregroundActivities = true; 16761 } else if (r.state == ActivityState.STOPPING) { 16762 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16763 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16764 app.adjType = "stopping"; 16765 } 16766 // For the process state, we will at this point consider the 16767 // process to be cached. It will be cached either as an activity 16768 // or empty depending on whether the activity is finishing. We do 16769 // this so that we can treat the process as cached for purposes of 16770 // memory trimming (determing current memory level, trim command to 16771 // send to process) since there can be an arbitrary number of stopping 16772 // processes and they should soon all go into the cached state. 16773 if (!r.finishing) { 16774 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16775 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16776 } 16777 } 16778 app.cached = false; 16779 app.empty = false; 16780 foregroundActivities = true; 16781 } else { 16782 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16783 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16784 app.adjType = "cch-act"; 16785 } 16786 } 16787 } 16788 } 16789 16790 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16791 if (app.foregroundServices) { 16792 // The user is aware of this app, so make it visible. 16793 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16794 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16795 app.cached = false; 16796 app.adjType = "fg-service"; 16797 schedGroup = Process.THREAD_GROUP_DEFAULT; 16798 } else if (app.forcingToForeground != null) { 16799 // The user is aware of this app, so make it visible. 16800 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16801 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16802 app.cached = false; 16803 app.adjType = "force-fg"; 16804 app.adjSource = app.forcingToForeground; 16805 schedGroup = Process.THREAD_GROUP_DEFAULT; 16806 } 16807 } 16808 16809 if (app == mHeavyWeightProcess) { 16810 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16811 // We don't want to kill the current heavy-weight process. 16812 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16813 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16814 app.cached = false; 16815 app.adjType = "heavy"; 16816 } 16817 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16818 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16819 } 16820 } 16821 16822 if (app == mHomeProcess) { 16823 if (adj > ProcessList.HOME_APP_ADJ) { 16824 // This process is hosting what we currently consider to be the 16825 // home app, so we don't want to let it go into the background. 16826 adj = ProcessList.HOME_APP_ADJ; 16827 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16828 app.cached = false; 16829 app.adjType = "home"; 16830 } 16831 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16832 procState = ActivityManager.PROCESS_STATE_HOME; 16833 } 16834 } 16835 16836 if (app == mPreviousProcess && app.activities.size() > 0) { 16837 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16838 // This was the previous process that showed UI to the user. 16839 // We want to try to keep it around more aggressively, to give 16840 // a good experience around switching between two apps. 16841 adj = ProcessList.PREVIOUS_APP_ADJ; 16842 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16843 app.cached = false; 16844 app.adjType = "previous"; 16845 } 16846 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16847 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16848 } 16849 } 16850 16851 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16852 + " reason=" + app.adjType); 16853 16854 // By default, we use the computed adjustment. It may be changed if 16855 // there are applications dependent on our services or providers, but 16856 // this gives us a baseline and makes sure we don't get into an 16857 // infinite recursion. 16858 app.adjSeq = mAdjSeq; 16859 app.curRawAdj = adj; 16860 app.hasStartedServices = false; 16861 16862 if (mBackupTarget != null && app == mBackupTarget.app) { 16863 // If possible we want to avoid killing apps while they're being backed up 16864 if (adj > ProcessList.BACKUP_APP_ADJ) { 16865 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16866 adj = ProcessList.BACKUP_APP_ADJ; 16867 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16868 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16869 } 16870 app.adjType = "backup"; 16871 app.cached = false; 16872 } 16873 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16874 procState = ActivityManager.PROCESS_STATE_BACKUP; 16875 } 16876 } 16877 16878 boolean mayBeTop = false; 16879 16880 for (int is = app.services.size()-1; 16881 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16882 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16883 || procState > ActivityManager.PROCESS_STATE_TOP); 16884 is--) { 16885 ServiceRecord s = app.services.valueAt(is); 16886 if (s.startRequested) { 16887 app.hasStartedServices = true; 16888 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16889 procState = ActivityManager.PROCESS_STATE_SERVICE; 16890 } 16891 if (app.hasShownUi && app != mHomeProcess) { 16892 // If this process has shown some UI, let it immediately 16893 // go to the LRU list because it may be pretty heavy with 16894 // UI stuff. We'll tag it with a label just to help 16895 // debug and understand what is going on. 16896 if (adj > ProcessList.SERVICE_ADJ) { 16897 app.adjType = "cch-started-ui-services"; 16898 } 16899 } else { 16900 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16901 // This service has seen some activity within 16902 // recent memory, so we will keep its process ahead 16903 // of the background processes. 16904 if (adj > ProcessList.SERVICE_ADJ) { 16905 adj = ProcessList.SERVICE_ADJ; 16906 app.adjType = "started-services"; 16907 app.cached = false; 16908 } 16909 } 16910 // If we have let the service slide into the background 16911 // state, still have some text describing what it is doing 16912 // even though the service no longer has an impact. 16913 if (adj > ProcessList.SERVICE_ADJ) { 16914 app.adjType = "cch-started-services"; 16915 } 16916 } 16917 } 16918 for (int conni = s.connections.size()-1; 16919 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16920 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16921 || procState > ActivityManager.PROCESS_STATE_TOP); 16922 conni--) { 16923 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16924 for (int i = 0; 16925 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16926 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16927 || procState > ActivityManager.PROCESS_STATE_TOP); 16928 i++) { 16929 // XXX should compute this based on the max of 16930 // all connected clients. 16931 ConnectionRecord cr = clist.get(i); 16932 if (cr.binding.client == app) { 16933 // Binding to ourself is not interesting. 16934 continue; 16935 } 16936 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16937 ProcessRecord client = cr.binding.client; 16938 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16939 TOP_APP, doingAll, now); 16940 int clientProcState = client.curProcState; 16941 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16942 // If the other app is cached for any reason, for purposes here 16943 // we are going to consider it empty. The specific cached state 16944 // doesn't propagate except under certain conditions. 16945 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16946 } 16947 String adjType = null; 16948 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16949 // Not doing bind OOM management, so treat 16950 // this guy more like a started service. 16951 if (app.hasShownUi && app != mHomeProcess) { 16952 // If this process has shown some UI, let it immediately 16953 // go to the LRU list because it may be pretty heavy with 16954 // UI stuff. We'll tag it with a label just to help 16955 // debug and understand what is going on. 16956 if (adj > clientAdj) { 16957 adjType = "cch-bound-ui-services"; 16958 } 16959 app.cached = false; 16960 clientAdj = adj; 16961 clientProcState = procState; 16962 } else { 16963 if (now >= (s.lastActivity 16964 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16965 // This service has not seen activity within 16966 // recent memory, so allow it to drop to the 16967 // LRU list if there is no other reason to keep 16968 // it around. We'll also tag it with a label just 16969 // to help debug and undertand what is going on. 16970 if (adj > clientAdj) { 16971 adjType = "cch-bound-services"; 16972 } 16973 clientAdj = adj; 16974 } 16975 } 16976 } 16977 if (adj > clientAdj) { 16978 // If this process has recently shown UI, and 16979 // the process that is binding to it is less 16980 // important than being visible, then we don't 16981 // care about the binding as much as we care 16982 // about letting this process get into the LRU 16983 // list to be killed and restarted if needed for 16984 // memory. 16985 if (app.hasShownUi && app != mHomeProcess 16986 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16987 adjType = "cch-bound-ui-services"; 16988 } else { 16989 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16990 |Context.BIND_IMPORTANT)) != 0) { 16991 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16992 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16993 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16994 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16995 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16996 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16997 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16998 adj = clientAdj; 16999 } else { 17000 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17001 adj = ProcessList.VISIBLE_APP_ADJ; 17002 } 17003 } 17004 if (!client.cached) { 17005 app.cached = false; 17006 } 17007 adjType = "service"; 17008 } 17009 } 17010 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17011 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17012 schedGroup = Process.THREAD_GROUP_DEFAULT; 17013 } 17014 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17015 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17016 // Special handling of clients who are in the top state. 17017 // We *may* want to consider this process to be in the 17018 // top state as well, but only if there is not another 17019 // reason for it to be running. Being on the top is a 17020 // special state, meaning you are specifically running 17021 // for the current top app. If the process is already 17022 // running in the background for some other reason, it 17023 // is more important to continue considering it to be 17024 // in the background state. 17025 mayBeTop = true; 17026 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17027 } else { 17028 // Special handling for above-top states (persistent 17029 // processes). These should not bring the current process 17030 // into the top state, since they are not on top. Instead 17031 // give them the best state after that. 17032 clientProcState = 17033 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17034 } 17035 } 17036 } else { 17037 if (clientProcState < 17038 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17039 clientProcState = 17040 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17041 } 17042 } 17043 if (procState > clientProcState) { 17044 procState = clientProcState; 17045 } 17046 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17047 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17048 app.pendingUiClean = true; 17049 } 17050 if (adjType != null) { 17051 app.adjType = adjType; 17052 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17053 .REASON_SERVICE_IN_USE; 17054 app.adjSource = cr.binding.client; 17055 app.adjSourceProcState = clientProcState; 17056 app.adjTarget = s.name; 17057 } 17058 } 17059 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17060 app.treatLikeActivity = true; 17061 } 17062 final ActivityRecord a = cr.activity; 17063 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17064 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17065 (a.visible || a.state == ActivityState.RESUMED 17066 || a.state == ActivityState.PAUSING)) { 17067 adj = ProcessList.FOREGROUND_APP_ADJ; 17068 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17069 schedGroup = Process.THREAD_GROUP_DEFAULT; 17070 } 17071 app.cached = false; 17072 app.adjType = "service"; 17073 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17074 .REASON_SERVICE_IN_USE; 17075 app.adjSource = a; 17076 app.adjSourceProcState = procState; 17077 app.adjTarget = s.name; 17078 } 17079 } 17080 } 17081 } 17082 } 17083 17084 for (int provi = app.pubProviders.size()-1; 17085 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17086 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17087 || procState > ActivityManager.PROCESS_STATE_TOP); 17088 provi--) { 17089 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17090 for (int i = cpr.connections.size()-1; 17091 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17092 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17093 || procState > ActivityManager.PROCESS_STATE_TOP); 17094 i--) { 17095 ContentProviderConnection conn = cpr.connections.get(i); 17096 ProcessRecord client = conn.client; 17097 if (client == app) { 17098 // Being our own client is not interesting. 17099 continue; 17100 } 17101 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17102 int clientProcState = client.curProcState; 17103 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17104 // If the other app is cached for any reason, for purposes here 17105 // we are going to consider it empty. 17106 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17107 } 17108 if (adj > clientAdj) { 17109 if (app.hasShownUi && app != mHomeProcess 17110 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17111 app.adjType = "cch-ui-provider"; 17112 } else { 17113 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17114 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17115 app.adjType = "provider"; 17116 } 17117 app.cached &= client.cached; 17118 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17119 .REASON_PROVIDER_IN_USE; 17120 app.adjSource = client; 17121 app.adjSourceProcState = clientProcState; 17122 app.adjTarget = cpr.name; 17123 } 17124 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17125 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17126 // Special handling of clients who are in the top state. 17127 // We *may* want to consider this process to be in the 17128 // top state as well, but only if there is not another 17129 // reason for it to be running. Being on the top is a 17130 // special state, meaning you are specifically running 17131 // for the current top app. If the process is already 17132 // running in the background for some other reason, it 17133 // is more important to continue considering it to be 17134 // in the background state. 17135 mayBeTop = true; 17136 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17137 } else { 17138 // Special handling for above-top states (persistent 17139 // processes). These should not bring the current process 17140 // into the top state, since they are not on top. Instead 17141 // give them the best state after that. 17142 clientProcState = 17143 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17144 } 17145 } 17146 if (procState > clientProcState) { 17147 procState = clientProcState; 17148 } 17149 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17150 schedGroup = Process.THREAD_GROUP_DEFAULT; 17151 } 17152 } 17153 // If the provider has external (non-framework) process 17154 // dependencies, ensure that its adjustment is at least 17155 // FOREGROUND_APP_ADJ. 17156 if (cpr.hasExternalProcessHandles()) { 17157 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17158 adj = ProcessList.FOREGROUND_APP_ADJ; 17159 schedGroup = Process.THREAD_GROUP_DEFAULT; 17160 app.cached = false; 17161 app.adjType = "provider"; 17162 app.adjTarget = cpr.name; 17163 } 17164 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17165 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17166 } 17167 } 17168 } 17169 17170 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17171 // A client of one of our services or providers is in the top state. We 17172 // *may* want to be in the top state, but not if we are already running in 17173 // the background for some other reason. For the decision here, we are going 17174 // to pick out a few specific states that we want to remain in when a client 17175 // is top (states that tend to be longer-term) and otherwise allow it to go 17176 // to the top state. 17177 switch (procState) { 17178 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17179 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17180 case ActivityManager.PROCESS_STATE_SERVICE: 17181 // These all are longer-term states, so pull them up to the top 17182 // of the background states, but not all the way to the top state. 17183 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17184 break; 17185 default: 17186 // Otherwise, top is a better choice, so take it. 17187 procState = ActivityManager.PROCESS_STATE_TOP; 17188 break; 17189 } 17190 } 17191 17192 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17193 if (app.hasClientActivities) { 17194 // This is a cached process, but with client activities. Mark it so. 17195 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17196 app.adjType = "cch-client-act"; 17197 } else if (app.treatLikeActivity) { 17198 // This is a cached process, but somebody wants us to treat it like it has 17199 // an activity, okay! 17200 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17201 app.adjType = "cch-as-act"; 17202 } 17203 } 17204 17205 if (adj == ProcessList.SERVICE_ADJ) { 17206 if (doingAll) { 17207 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17208 mNewNumServiceProcs++; 17209 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17210 if (!app.serviceb) { 17211 // This service isn't far enough down on the LRU list to 17212 // normally be a B service, but if we are low on RAM and it 17213 // is large we want to force it down since we would prefer to 17214 // keep launcher over it. 17215 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17216 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17217 app.serviceHighRam = true; 17218 app.serviceb = true; 17219 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17220 } else { 17221 mNewNumAServiceProcs++; 17222 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17223 } 17224 } else { 17225 app.serviceHighRam = false; 17226 } 17227 } 17228 if (app.serviceb) { 17229 adj = ProcessList.SERVICE_B_ADJ; 17230 } 17231 } 17232 17233 app.curRawAdj = adj; 17234 17235 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17236 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17237 if (adj > app.maxAdj) { 17238 adj = app.maxAdj; 17239 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17240 schedGroup = Process.THREAD_GROUP_DEFAULT; 17241 } 17242 } 17243 17244 // Do final modification to adj. Everything we do between here and applying 17245 // the final setAdj must be done in this function, because we will also use 17246 // it when computing the final cached adj later. Note that we don't need to 17247 // worry about this for max adj above, since max adj will always be used to 17248 // keep it out of the cached vaues. 17249 app.curAdj = app.modifyRawOomAdj(adj); 17250 app.curSchedGroup = schedGroup; 17251 app.curProcState = procState; 17252 app.foregroundActivities = foregroundActivities; 17253 17254 return app.curRawAdj; 17255 } 17256 17257 /** 17258 * Schedule PSS collection of a process. 17259 */ 17260 void requestPssLocked(ProcessRecord proc, int procState) { 17261 if (mPendingPssProcesses.contains(proc)) { 17262 return; 17263 } 17264 if (mPendingPssProcesses.size() == 0) { 17265 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17266 } 17267 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17268 proc.pssProcState = procState; 17269 mPendingPssProcesses.add(proc); 17270 } 17271 17272 /** 17273 * Schedule PSS collection of all processes. 17274 */ 17275 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17276 if (!always) { 17277 if (now < (mLastFullPssTime + 17278 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17279 return; 17280 } 17281 } 17282 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17283 mLastFullPssTime = now; 17284 mFullPssPending = true; 17285 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17286 mPendingPssProcesses.clear(); 17287 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17288 ProcessRecord app = mLruProcesses.get(i); 17289 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17290 app.pssProcState = app.setProcState; 17291 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17292 isSleeping(), now); 17293 mPendingPssProcesses.add(app); 17294 } 17295 } 17296 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17297 } 17298 17299 /** 17300 * Ask a given process to GC right now. 17301 */ 17302 final void performAppGcLocked(ProcessRecord app) { 17303 try { 17304 app.lastRequestedGc = SystemClock.uptimeMillis(); 17305 if (app.thread != null) { 17306 if (app.reportLowMemory) { 17307 app.reportLowMemory = false; 17308 app.thread.scheduleLowMemory(); 17309 } else { 17310 app.thread.processInBackground(); 17311 } 17312 } 17313 } catch (Exception e) { 17314 // whatever. 17315 } 17316 } 17317 17318 /** 17319 * Returns true if things are idle enough to perform GCs. 17320 */ 17321 private final boolean canGcNowLocked() { 17322 boolean processingBroadcasts = false; 17323 for (BroadcastQueue q : mBroadcastQueues) { 17324 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17325 processingBroadcasts = true; 17326 } 17327 } 17328 return !processingBroadcasts 17329 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17330 } 17331 17332 /** 17333 * Perform GCs on all processes that are waiting for it, but only 17334 * if things are idle. 17335 */ 17336 final void performAppGcsLocked() { 17337 final int N = mProcessesToGc.size(); 17338 if (N <= 0) { 17339 return; 17340 } 17341 if (canGcNowLocked()) { 17342 while (mProcessesToGc.size() > 0) { 17343 ProcessRecord proc = mProcessesToGc.remove(0); 17344 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17345 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17346 <= SystemClock.uptimeMillis()) { 17347 // To avoid spamming the system, we will GC processes one 17348 // at a time, waiting a few seconds between each. 17349 performAppGcLocked(proc); 17350 scheduleAppGcsLocked(); 17351 return; 17352 } else { 17353 // It hasn't been long enough since we last GCed this 17354 // process... put it in the list to wait for its time. 17355 addProcessToGcListLocked(proc); 17356 break; 17357 } 17358 } 17359 } 17360 17361 scheduleAppGcsLocked(); 17362 } 17363 } 17364 17365 /** 17366 * If all looks good, perform GCs on all processes waiting for them. 17367 */ 17368 final void performAppGcsIfAppropriateLocked() { 17369 if (canGcNowLocked()) { 17370 performAppGcsLocked(); 17371 return; 17372 } 17373 // Still not idle, wait some more. 17374 scheduleAppGcsLocked(); 17375 } 17376 17377 /** 17378 * Schedule the execution of all pending app GCs. 17379 */ 17380 final void scheduleAppGcsLocked() { 17381 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17382 17383 if (mProcessesToGc.size() > 0) { 17384 // Schedule a GC for the time to the next process. 17385 ProcessRecord proc = mProcessesToGc.get(0); 17386 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17387 17388 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17389 long now = SystemClock.uptimeMillis(); 17390 if (when < (now+GC_TIMEOUT)) { 17391 when = now + GC_TIMEOUT; 17392 } 17393 mHandler.sendMessageAtTime(msg, when); 17394 } 17395 } 17396 17397 /** 17398 * Add a process to the array of processes waiting to be GCed. Keeps the 17399 * list in sorted order by the last GC time. The process can't already be 17400 * on the list. 17401 */ 17402 final void addProcessToGcListLocked(ProcessRecord proc) { 17403 boolean added = false; 17404 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17405 if (mProcessesToGc.get(i).lastRequestedGc < 17406 proc.lastRequestedGc) { 17407 added = true; 17408 mProcessesToGc.add(i+1, proc); 17409 break; 17410 } 17411 } 17412 if (!added) { 17413 mProcessesToGc.add(0, proc); 17414 } 17415 } 17416 17417 /** 17418 * Set up to ask a process to GC itself. This will either do it 17419 * immediately, or put it on the list of processes to gc the next 17420 * time things are idle. 17421 */ 17422 final void scheduleAppGcLocked(ProcessRecord app) { 17423 long now = SystemClock.uptimeMillis(); 17424 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17425 return; 17426 } 17427 if (!mProcessesToGc.contains(app)) { 17428 addProcessToGcListLocked(app); 17429 scheduleAppGcsLocked(); 17430 } 17431 } 17432 17433 final void checkExcessivePowerUsageLocked(boolean doKills) { 17434 updateCpuStatsNow(); 17435 17436 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17437 boolean doWakeKills = doKills; 17438 boolean doCpuKills = doKills; 17439 if (mLastPowerCheckRealtime == 0) { 17440 doWakeKills = false; 17441 } 17442 if (mLastPowerCheckUptime == 0) { 17443 doCpuKills = false; 17444 } 17445 if (stats.isScreenOn()) { 17446 doWakeKills = false; 17447 } 17448 final long curRealtime = SystemClock.elapsedRealtime(); 17449 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17450 final long curUptime = SystemClock.uptimeMillis(); 17451 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17452 mLastPowerCheckRealtime = curRealtime; 17453 mLastPowerCheckUptime = curUptime; 17454 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17455 doWakeKills = false; 17456 } 17457 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17458 doCpuKills = false; 17459 } 17460 int i = mLruProcesses.size(); 17461 while (i > 0) { 17462 i--; 17463 ProcessRecord app = mLruProcesses.get(i); 17464 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17465 long wtime; 17466 synchronized (stats) { 17467 wtime = stats.getProcessWakeTime(app.info.uid, 17468 app.pid, curRealtime); 17469 } 17470 long wtimeUsed = wtime - app.lastWakeTime; 17471 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17472 if (DEBUG_POWER) { 17473 StringBuilder sb = new StringBuilder(128); 17474 sb.append("Wake for "); 17475 app.toShortString(sb); 17476 sb.append(": over "); 17477 TimeUtils.formatDuration(realtimeSince, sb); 17478 sb.append(" used "); 17479 TimeUtils.formatDuration(wtimeUsed, sb); 17480 sb.append(" ("); 17481 sb.append((wtimeUsed*100)/realtimeSince); 17482 sb.append("%)"); 17483 Slog.i(TAG, sb.toString()); 17484 sb.setLength(0); 17485 sb.append("CPU for "); 17486 app.toShortString(sb); 17487 sb.append(": over "); 17488 TimeUtils.formatDuration(uptimeSince, sb); 17489 sb.append(" used "); 17490 TimeUtils.formatDuration(cputimeUsed, sb); 17491 sb.append(" ("); 17492 sb.append((cputimeUsed*100)/uptimeSince); 17493 sb.append("%)"); 17494 Slog.i(TAG, sb.toString()); 17495 } 17496 // If a process has held a wake lock for more 17497 // than 50% of the time during this period, 17498 // that sounds bad. Kill! 17499 if (doWakeKills && realtimeSince > 0 17500 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17501 synchronized (stats) { 17502 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17503 realtimeSince, wtimeUsed); 17504 } 17505 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17506 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17507 } else if (doCpuKills && uptimeSince > 0 17508 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17509 synchronized (stats) { 17510 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17511 uptimeSince, cputimeUsed); 17512 } 17513 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17514 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17515 } else { 17516 app.lastWakeTime = wtime; 17517 app.lastCpuTime = app.curCpuTime; 17518 } 17519 } 17520 } 17521 } 17522 17523 private final boolean applyOomAdjLocked(ProcessRecord app, 17524 ProcessRecord TOP_APP, boolean doingAll, long now) { 17525 boolean success = true; 17526 17527 if (app.curRawAdj != app.setRawAdj) { 17528 app.setRawAdj = app.curRawAdj; 17529 } 17530 17531 int changes = 0; 17532 17533 if (app.curAdj != app.setAdj) { 17534 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17535 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17536 TAG, "Set " + app.pid + " " + app.processName + 17537 " adj " + app.curAdj + ": " + app.adjType); 17538 app.setAdj = app.curAdj; 17539 } 17540 17541 if (app.setSchedGroup != app.curSchedGroup) { 17542 app.setSchedGroup = app.curSchedGroup; 17543 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17544 "Setting process group of " + app.processName 17545 + " to " + app.curSchedGroup); 17546 if (app.waitingToKill != null && 17547 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17548 app.kill(app.waitingToKill, true); 17549 success = false; 17550 } else { 17551 if (true) { 17552 long oldId = Binder.clearCallingIdentity(); 17553 try { 17554 Process.setProcessGroup(app.pid, app.curSchedGroup); 17555 } catch (Exception e) { 17556 Slog.w(TAG, "Failed setting process group of " + app.pid 17557 + " to " + app.curSchedGroup); 17558 e.printStackTrace(); 17559 } finally { 17560 Binder.restoreCallingIdentity(oldId); 17561 } 17562 } else { 17563 if (app.thread != null) { 17564 try { 17565 app.thread.setSchedulingGroup(app.curSchedGroup); 17566 } catch (RemoteException e) { 17567 } 17568 } 17569 } 17570 Process.setSwappiness(app.pid, 17571 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17572 } 17573 } 17574 if (app.repForegroundActivities != app.foregroundActivities) { 17575 app.repForegroundActivities = app.foregroundActivities; 17576 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17577 } 17578 if (app.repProcState != app.curProcState) { 17579 app.repProcState = app.curProcState; 17580 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17581 if (app.thread != null) { 17582 try { 17583 if (false) { 17584 //RuntimeException h = new RuntimeException("here"); 17585 Slog.i(TAG, "Sending new process state " + app.repProcState 17586 + " to " + app /*, h*/); 17587 } 17588 app.thread.setProcessState(app.repProcState); 17589 } catch (RemoteException e) { 17590 } 17591 } 17592 } 17593 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17594 app.setProcState)) { 17595 app.lastStateTime = now; 17596 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17597 isSleeping(), now); 17598 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17599 + ProcessList.makeProcStateString(app.setProcState) + " to " 17600 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17601 + (app.nextPssTime-now) + ": " + app); 17602 } else { 17603 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17604 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17605 requestPssLocked(app, app.setProcState); 17606 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17607 isSleeping(), now); 17608 } else if (false && DEBUG_PSS) { 17609 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17610 } 17611 } 17612 if (app.setProcState != app.curProcState) { 17613 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17614 "Proc state change of " + app.processName 17615 + " to " + app.curProcState); 17616 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17617 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17618 if (setImportant && !curImportant) { 17619 // This app is no longer something we consider important enough to allow to 17620 // use arbitrary amounts of battery power. Note 17621 // its current wake lock time to later know to kill it if 17622 // it is not behaving well. 17623 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17624 synchronized (stats) { 17625 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17626 app.pid, SystemClock.elapsedRealtime()); 17627 } 17628 app.lastCpuTime = app.curCpuTime; 17629 17630 } 17631 app.setProcState = app.curProcState; 17632 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17633 app.notCachedSinceIdle = false; 17634 } 17635 if (!doingAll) { 17636 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17637 } else { 17638 app.procStateChanged = true; 17639 } 17640 } 17641 17642 if (changes != 0) { 17643 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17644 int i = mPendingProcessChanges.size()-1; 17645 ProcessChangeItem item = null; 17646 while (i >= 0) { 17647 item = mPendingProcessChanges.get(i); 17648 if (item.pid == app.pid) { 17649 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17650 break; 17651 } 17652 i--; 17653 } 17654 if (i < 0) { 17655 // No existing item in pending changes; need a new one. 17656 final int NA = mAvailProcessChanges.size(); 17657 if (NA > 0) { 17658 item = mAvailProcessChanges.remove(NA-1); 17659 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17660 } else { 17661 item = new ProcessChangeItem(); 17662 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17663 } 17664 item.changes = 0; 17665 item.pid = app.pid; 17666 item.uid = app.info.uid; 17667 if (mPendingProcessChanges.size() == 0) { 17668 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17669 "*** Enqueueing dispatch processes changed!"); 17670 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17671 } 17672 mPendingProcessChanges.add(item); 17673 } 17674 item.changes |= changes; 17675 item.processState = app.repProcState; 17676 item.foregroundActivities = app.repForegroundActivities; 17677 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17678 + Integer.toHexString(System.identityHashCode(item)) 17679 + " " + app.toShortString() + ": changes=" + item.changes 17680 + " procState=" + item.processState 17681 + " foreground=" + item.foregroundActivities 17682 + " type=" + app.adjType + " source=" + app.adjSource 17683 + " target=" + app.adjTarget); 17684 } 17685 17686 return success; 17687 } 17688 17689 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17690 if (proc.thread != null) { 17691 if (proc.baseProcessTracker != null) { 17692 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17693 } 17694 if (proc.repProcState >= 0) { 17695 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17696 proc.repProcState); 17697 } 17698 } 17699 } 17700 17701 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17702 ProcessRecord TOP_APP, boolean doingAll, long now) { 17703 if (app.thread == null) { 17704 return false; 17705 } 17706 17707 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17708 17709 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17710 } 17711 17712 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17713 boolean oomAdj) { 17714 if (isForeground != proc.foregroundServices) { 17715 proc.foregroundServices = isForeground; 17716 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17717 proc.info.uid); 17718 if (isForeground) { 17719 if (curProcs == null) { 17720 curProcs = new ArrayList<ProcessRecord>(); 17721 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17722 } 17723 if (!curProcs.contains(proc)) { 17724 curProcs.add(proc); 17725 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17726 proc.info.packageName, proc.info.uid); 17727 } 17728 } else { 17729 if (curProcs != null) { 17730 if (curProcs.remove(proc)) { 17731 mBatteryStatsService.noteEvent( 17732 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17733 proc.info.packageName, proc.info.uid); 17734 if (curProcs.size() <= 0) { 17735 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17736 } 17737 } 17738 } 17739 } 17740 if (oomAdj) { 17741 updateOomAdjLocked(); 17742 } 17743 } 17744 } 17745 17746 private final ActivityRecord resumedAppLocked() { 17747 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17748 String pkg; 17749 int uid; 17750 if (act != null) { 17751 pkg = act.packageName; 17752 uid = act.info.applicationInfo.uid; 17753 } else { 17754 pkg = null; 17755 uid = -1; 17756 } 17757 // Has the UID or resumed package name changed? 17758 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17759 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17760 if (mCurResumedPackage != null) { 17761 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17762 mCurResumedPackage, mCurResumedUid); 17763 } 17764 mCurResumedPackage = pkg; 17765 mCurResumedUid = uid; 17766 if (mCurResumedPackage != null) { 17767 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17768 mCurResumedPackage, mCurResumedUid); 17769 } 17770 } 17771 return act; 17772 } 17773 17774 final boolean updateOomAdjLocked(ProcessRecord app) { 17775 final ActivityRecord TOP_ACT = resumedAppLocked(); 17776 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17777 final boolean wasCached = app.cached; 17778 17779 mAdjSeq++; 17780 17781 // This is the desired cached adjusment we want to tell it to use. 17782 // If our app is currently cached, we know it, and that is it. Otherwise, 17783 // we don't know it yet, and it needs to now be cached we will then 17784 // need to do a complete oom adj. 17785 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17786 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17787 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17788 SystemClock.uptimeMillis()); 17789 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17790 // Changed to/from cached state, so apps after it in the LRU 17791 // list may also be changed. 17792 updateOomAdjLocked(); 17793 } 17794 return success; 17795 } 17796 17797 final void updateOomAdjLocked() { 17798 final ActivityRecord TOP_ACT = resumedAppLocked(); 17799 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17800 final long now = SystemClock.uptimeMillis(); 17801 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17802 final int N = mLruProcesses.size(); 17803 17804 if (false) { 17805 RuntimeException e = new RuntimeException(); 17806 e.fillInStackTrace(); 17807 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17808 } 17809 17810 mAdjSeq++; 17811 mNewNumServiceProcs = 0; 17812 mNewNumAServiceProcs = 0; 17813 17814 final int emptyProcessLimit; 17815 final int cachedProcessLimit; 17816 if (mProcessLimit <= 0) { 17817 emptyProcessLimit = cachedProcessLimit = 0; 17818 } else if (mProcessLimit == 1) { 17819 emptyProcessLimit = 1; 17820 cachedProcessLimit = 0; 17821 } else { 17822 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17823 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17824 } 17825 17826 // Let's determine how many processes we have running vs. 17827 // how many slots we have for background processes; we may want 17828 // to put multiple processes in a slot of there are enough of 17829 // them. 17830 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17831 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17832 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17833 if (numEmptyProcs > cachedProcessLimit) { 17834 // If there are more empty processes than our limit on cached 17835 // processes, then use the cached process limit for the factor. 17836 // This ensures that the really old empty processes get pushed 17837 // down to the bottom, so if we are running low on memory we will 17838 // have a better chance at keeping around more cached processes 17839 // instead of a gazillion empty processes. 17840 numEmptyProcs = cachedProcessLimit; 17841 } 17842 int emptyFactor = numEmptyProcs/numSlots; 17843 if (emptyFactor < 1) emptyFactor = 1; 17844 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17845 if (cachedFactor < 1) cachedFactor = 1; 17846 int stepCached = 0; 17847 int stepEmpty = 0; 17848 int numCached = 0; 17849 int numEmpty = 0; 17850 int numTrimming = 0; 17851 17852 mNumNonCachedProcs = 0; 17853 mNumCachedHiddenProcs = 0; 17854 17855 // First update the OOM adjustment for each of the 17856 // application processes based on their current state. 17857 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17858 int nextCachedAdj = curCachedAdj+1; 17859 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17860 int nextEmptyAdj = curEmptyAdj+2; 17861 for (int i=N-1; i>=0; i--) { 17862 ProcessRecord app = mLruProcesses.get(i); 17863 if (!app.killedByAm && app.thread != null) { 17864 app.procStateChanged = false; 17865 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17866 17867 // If we haven't yet assigned the final cached adj 17868 // to the process, do that now. 17869 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17870 switch (app.curProcState) { 17871 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17872 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17873 // This process is a cached process holding activities... 17874 // assign it the next cached value for that type, and then 17875 // step that cached level. 17876 app.curRawAdj = curCachedAdj; 17877 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17878 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17879 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17880 + ")"); 17881 if (curCachedAdj != nextCachedAdj) { 17882 stepCached++; 17883 if (stepCached >= cachedFactor) { 17884 stepCached = 0; 17885 curCachedAdj = nextCachedAdj; 17886 nextCachedAdj += 2; 17887 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17888 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17889 } 17890 } 17891 } 17892 break; 17893 default: 17894 // For everything else, assign next empty cached process 17895 // level and bump that up. Note that this means that 17896 // long-running services that have dropped down to the 17897 // cached level will be treated as empty (since their process 17898 // state is still as a service), which is what we want. 17899 app.curRawAdj = curEmptyAdj; 17900 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17901 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17902 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17903 + ")"); 17904 if (curEmptyAdj != nextEmptyAdj) { 17905 stepEmpty++; 17906 if (stepEmpty >= emptyFactor) { 17907 stepEmpty = 0; 17908 curEmptyAdj = nextEmptyAdj; 17909 nextEmptyAdj += 2; 17910 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17911 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17912 } 17913 } 17914 } 17915 break; 17916 } 17917 } 17918 17919 applyOomAdjLocked(app, TOP_APP, true, now); 17920 17921 // Count the number of process types. 17922 switch (app.curProcState) { 17923 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17924 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17925 mNumCachedHiddenProcs++; 17926 numCached++; 17927 if (numCached > cachedProcessLimit) { 17928 app.kill("cached #" + numCached, true); 17929 } 17930 break; 17931 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17932 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17933 && app.lastActivityTime < oldTime) { 17934 app.kill("empty for " 17935 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17936 / 1000) + "s", true); 17937 } else { 17938 numEmpty++; 17939 if (numEmpty > emptyProcessLimit) { 17940 app.kill("empty #" + numEmpty, true); 17941 } 17942 } 17943 break; 17944 default: 17945 mNumNonCachedProcs++; 17946 break; 17947 } 17948 17949 if (app.isolated && app.services.size() <= 0) { 17950 // If this is an isolated process, and there are no 17951 // services running in it, then the process is no longer 17952 // needed. We agressively kill these because we can by 17953 // definition not re-use the same process again, and it is 17954 // good to avoid having whatever code was running in them 17955 // left sitting around after no longer needed. 17956 app.kill("isolated not needed", true); 17957 } 17958 17959 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17960 && !app.killedByAm) { 17961 numTrimming++; 17962 } 17963 } 17964 } 17965 17966 mNumServiceProcs = mNewNumServiceProcs; 17967 17968 // Now determine the memory trimming level of background processes. 17969 // Unfortunately we need to start at the back of the list to do this 17970 // properly. We only do this if the number of background apps we 17971 // are managing to keep around is less than half the maximum we desire; 17972 // if we are keeping a good number around, we'll let them use whatever 17973 // memory they want. 17974 final int numCachedAndEmpty = numCached + numEmpty; 17975 int memFactor; 17976 if (numCached <= ProcessList.TRIM_CACHED_APPS 17977 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17978 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17979 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17980 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17981 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17982 } else { 17983 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17984 } 17985 } else { 17986 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17987 } 17988 // We always allow the memory level to go up (better). We only allow it to go 17989 // down if we are in a state where that is allowed, *and* the total number of processes 17990 // has gone down since last time. 17991 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17992 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17993 + " last=" + mLastNumProcesses); 17994 if (memFactor > mLastMemoryLevel) { 17995 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17996 memFactor = mLastMemoryLevel; 17997 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17998 } 17999 } 18000 mLastMemoryLevel = memFactor; 18001 mLastNumProcesses = mLruProcesses.size(); 18002 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18003 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18004 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18005 if (mLowRamStartTime == 0) { 18006 mLowRamStartTime = now; 18007 } 18008 int step = 0; 18009 int fgTrimLevel; 18010 switch (memFactor) { 18011 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18012 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18013 break; 18014 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18015 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18016 break; 18017 default: 18018 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18019 break; 18020 } 18021 int factor = numTrimming/3; 18022 int minFactor = 2; 18023 if (mHomeProcess != null) minFactor++; 18024 if (mPreviousProcess != null) minFactor++; 18025 if (factor < minFactor) factor = minFactor; 18026 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18027 for (int i=N-1; i>=0; i--) { 18028 ProcessRecord app = mLruProcesses.get(i); 18029 if (allChanged || app.procStateChanged) { 18030 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18031 app.procStateChanged = false; 18032 } 18033 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18034 && !app.killedByAm) { 18035 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18036 try { 18037 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18038 "Trimming memory of " + app.processName 18039 + " to " + curLevel); 18040 app.thread.scheduleTrimMemory(curLevel); 18041 } catch (RemoteException e) { 18042 } 18043 if (false) { 18044 // For now we won't do this; our memory trimming seems 18045 // to be good enough at this point that destroying 18046 // activities causes more harm than good. 18047 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18048 && app != mHomeProcess && app != mPreviousProcess) { 18049 // Need to do this on its own message because the stack may not 18050 // be in a consistent state at this point. 18051 // For these apps we will also finish their activities 18052 // to help them free memory. 18053 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18054 } 18055 } 18056 } 18057 app.trimMemoryLevel = curLevel; 18058 step++; 18059 if (step >= factor) { 18060 step = 0; 18061 switch (curLevel) { 18062 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18063 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18064 break; 18065 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18066 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18067 break; 18068 } 18069 } 18070 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18071 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18072 && app.thread != null) { 18073 try { 18074 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18075 "Trimming memory of heavy-weight " + app.processName 18076 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18077 app.thread.scheduleTrimMemory( 18078 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18079 } catch (RemoteException e) { 18080 } 18081 } 18082 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18083 } else { 18084 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18085 || app.systemNoUi) && app.pendingUiClean) { 18086 // If this application is now in the background and it 18087 // had done UI, then give it the special trim level to 18088 // have it free UI resources. 18089 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18090 if (app.trimMemoryLevel < level && app.thread != null) { 18091 try { 18092 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18093 "Trimming memory of bg-ui " + app.processName 18094 + " to " + level); 18095 app.thread.scheduleTrimMemory(level); 18096 } catch (RemoteException e) { 18097 } 18098 } 18099 app.pendingUiClean = false; 18100 } 18101 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18102 try { 18103 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18104 "Trimming memory of fg " + app.processName 18105 + " to " + fgTrimLevel); 18106 app.thread.scheduleTrimMemory(fgTrimLevel); 18107 } catch (RemoteException e) { 18108 } 18109 } 18110 app.trimMemoryLevel = fgTrimLevel; 18111 } 18112 } 18113 } else { 18114 if (mLowRamStartTime != 0) { 18115 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18116 mLowRamStartTime = 0; 18117 } 18118 for (int i=N-1; i>=0; i--) { 18119 ProcessRecord app = mLruProcesses.get(i); 18120 if (allChanged || app.procStateChanged) { 18121 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18122 app.procStateChanged = false; 18123 } 18124 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18125 || app.systemNoUi) && app.pendingUiClean) { 18126 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18127 && app.thread != null) { 18128 try { 18129 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18130 "Trimming memory of ui hidden " + app.processName 18131 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18132 app.thread.scheduleTrimMemory( 18133 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18134 } catch (RemoteException e) { 18135 } 18136 } 18137 app.pendingUiClean = false; 18138 } 18139 app.trimMemoryLevel = 0; 18140 } 18141 } 18142 18143 if (mAlwaysFinishActivities) { 18144 // Need to do this on its own message because the stack may not 18145 // be in a consistent state at this point. 18146 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18147 } 18148 18149 if (allChanged) { 18150 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18151 } 18152 18153 if (mProcessStats.shouldWriteNowLocked(now)) { 18154 mHandler.post(new Runnable() { 18155 @Override public void run() { 18156 synchronized (ActivityManagerService.this) { 18157 mProcessStats.writeStateAsyncLocked(); 18158 } 18159 } 18160 }); 18161 } 18162 18163 if (DEBUG_OOM_ADJ) { 18164 if (false) { 18165 RuntimeException here = new RuntimeException("here"); 18166 here.fillInStackTrace(); 18167 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18168 } else { 18169 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18170 } 18171 } 18172 } 18173 18174 final void trimApplications() { 18175 synchronized (this) { 18176 int i; 18177 18178 // First remove any unused application processes whose package 18179 // has been removed. 18180 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18181 final ProcessRecord app = mRemovedProcesses.get(i); 18182 if (app.activities.size() == 0 18183 && app.curReceiver == null && app.services.size() == 0) { 18184 Slog.i( 18185 TAG, "Exiting empty application process " 18186 + app.processName + " (" 18187 + (app.thread != null ? app.thread.asBinder() : null) 18188 + ")\n"); 18189 if (app.pid > 0 && app.pid != MY_PID) { 18190 app.kill("empty", false); 18191 } else { 18192 try { 18193 app.thread.scheduleExit(); 18194 } catch (Exception e) { 18195 // Ignore exceptions. 18196 } 18197 } 18198 cleanUpApplicationRecordLocked(app, false, true, -1); 18199 mRemovedProcesses.remove(i); 18200 18201 if (app.persistent) { 18202 addAppLocked(app.info, false, null /* ABI override */); 18203 } 18204 } 18205 } 18206 18207 // Now update the oom adj for all processes. 18208 updateOomAdjLocked(); 18209 } 18210 } 18211 18212 /** This method sends the specified signal to each of the persistent apps */ 18213 public void signalPersistentProcesses(int sig) throws RemoteException { 18214 if (sig != Process.SIGNAL_USR1) { 18215 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18216 } 18217 18218 synchronized (this) { 18219 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18220 != PackageManager.PERMISSION_GRANTED) { 18221 throw new SecurityException("Requires permission " 18222 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18223 } 18224 18225 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18226 ProcessRecord r = mLruProcesses.get(i); 18227 if (r.thread != null && r.persistent) { 18228 Process.sendSignal(r.pid, sig); 18229 } 18230 } 18231 } 18232 } 18233 18234 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18235 if (proc == null || proc == mProfileProc) { 18236 proc = mProfileProc; 18237 profileType = mProfileType; 18238 clearProfilerLocked(); 18239 } 18240 if (proc == null) { 18241 return; 18242 } 18243 try { 18244 proc.thread.profilerControl(false, null, profileType); 18245 } catch (RemoteException e) { 18246 throw new IllegalStateException("Process disappeared"); 18247 } 18248 } 18249 18250 private void clearProfilerLocked() { 18251 if (mProfileFd != null) { 18252 try { 18253 mProfileFd.close(); 18254 } catch (IOException e) { 18255 } 18256 } 18257 mProfileApp = null; 18258 mProfileProc = null; 18259 mProfileFile = null; 18260 mProfileType = 0; 18261 mAutoStopProfiler = false; 18262 mSamplingInterval = 0; 18263 } 18264 18265 public boolean profileControl(String process, int userId, boolean start, 18266 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18267 18268 try { 18269 synchronized (this) { 18270 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18271 // its own permission. 18272 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18273 != PackageManager.PERMISSION_GRANTED) { 18274 throw new SecurityException("Requires permission " 18275 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18276 } 18277 18278 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18279 throw new IllegalArgumentException("null profile info or fd"); 18280 } 18281 18282 ProcessRecord proc = null; 18283 if (process != null) { 18284 proc = findProcessLocked(process, userId, "profileControl"); 18285 } 18286 18287 if (start && (proc == null || proc.thread == null)) { 18288 throw new IllegalArgumentException("Unknown process: " + process); 18289 } 18290 18291 if (start) { 18292 stopProfilerLocked(null, 0); 18293 setProfileApp(proc.info, proc.processName, profilerInfo); 18294 mProfileProc = proc; 18295 mProfileType = profileType; 18296 ParcelFileDescriptor fd = profilerInfo.profileFd; 18297 try { 18298 fd = fd.dup(); 18299 } catch (IOException e) { 18300 fd = null; 18301 } 18302 profilerInfo.profileFd = fd; 18303 proc.thread.profilerControl(start, profilerInfo, profileType); 18304 fd = null; 18305 mProfileFd = null; 18306 } else { 18307 stopProfilerLocked(proc, profileType); 18308 if (profilerInfo != null && profilerInfo.profileFd != null) { 18309 try { 18310 profilerInfo.profileFd.close(); 18311 } catch (IOException e) { 18312 } 18313 } 18314 } 18315 18316 return true; 18317 } 18318 } catch (RemoteException e) { 18319 throw new IllegalStateException("Process disappeared"); 18320 } finally { 18321 if (profilerInfo != null && profilerInfo.profileFd != null) { 18322 try { 18323 profilerInfo.profileFd.close(); 18324 } catch (IOException e) { 18325 } 18326 } 18327 } 18328 } 18329 18330 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18331 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18332 userId, true, ALLOW_FULL_ONLY, callName, null); 18333 ProcessRecord proc = null; 18334 try { 18335 int pid = Integer.parseInt(process); 18336 synchronized (mPidsSelfLocked) { 18337 proc = mPidsSelfLocked.get(pid); 18338 } 18339 } catch (NumberFormatException e) { 18340 } 18341 18342 if (proc == null) { 18343 ArrayMap<String, SparseArray<ProcessRecord>> all 18344 = mProcessNames.getMap(); 18345 SparseArray<ProcessRecord> procs = all.get(process); 18346 if (procs != null && procs.size() > 0) { 18347 proc = procs.valueAt(0); 18348 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18349 for (int i=1; i<procs.size(); i++) { 18350 ProcessRecord thisProc = procs.valueAt(i); 18351 if (thisProc.userId == userId) { 18352 proc = thisProc; 18353 break; 18354 } 18355 } 18356 } 18357 } 18358 } 18359 18360 return proc; 18361 } 18362 18363 public boolean dumpHeap(String process, int userId, boolean managed, 18364 String path, ParcelFileDescriptor fd) throws RemoteException { 18365 18366 try { 18367 synchronized (this) { 18368 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18369 // its own permission (same as profileControl). 18370 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18371 != PackageManager.PERMISSION_GRANTED) { 18372 throw new SecurityException("Requires permission " 18373 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18374 } 18375 18376 if (fd == null) { 18377 throw new IllegalArgumentException("null fd"); 18378 } 18379 18380 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18381 if (proc == null || proc.thread == null) { 18382 throw new IllegalArgumentException("Unknown process: " + process); 18383 } 18384 18385 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18386 if (!isDebuggable) { 18387 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18388 throw new SecurityException("Process not debuggable: " + proc); 18389 } 18390 } 18391 18392 proc.thread.dumpHeap(managed, path, fd); 18393 fd = null; 18394 return true; 18395 } 18396 } catch (RemoteException e) { 18397 throw new IllegalStateException("Process disappeared"); 18398 } finally { 18399 if (fd != null) { 18400 try { 18401 fd.close(); 18402 } catch (IOException e) { 18403 } 18404 } 18405 } 18406 } 18407 18408 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18409 public void monitor() { 18410 synchronized (this) { } 18411 } 18412 18413 void onCoreSettingsChange(Bundle settings) { 18414 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18415 ProcessRecord processRecord = mLruProcesses.get(i); 18416 try { 18417 if (processRecord.thread != null) { 18418 processRecord.thread.setCoreSettings(settings); 18419 } 18420 } catch (RemoteException re) { 18421 /* ignore */ 18422 } 18423 } 18424 } 18425 18426 // Multi-user methods 18427 18428 /** 18429 * Start user, if its not already running, but don't bring it to foreground. 18430 */ 18431 @Override 18432 public boolean startUserInBackground(final int userId) { 18433 return startUser(userId, /* foreground */ false); 18434 } 18435 18436 /** 18437 * Start user, if its not already running, and bring it to foreground. 18438 */ 18439 boolean startUserInForeground(final int userId, Dialog dlg) { 18440 boolean result = startUser(userId, /* foreground */ true); 18441 dlg.dismiss(); 18442 return result; 18443 } 18444 18445 /** 18446 * Refreshes the list of users related to the current user when either a 18447 * user switch happens or when a new related user is started in the 18448 * background. 18449 */ 18450 private void updateCurrentProfileIdsLocked() { 18451 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18452 mCurrentUserId, false /* enabledOnly */); 18453 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18454 for (int i = 0; i < currentProfileIds.length; i++) { 18455 currentProfileIds[i] = profiles.get(i).id; 18456 } 18457 mCurrentProfileIds = currentProfileIds; 18458 18459 synchronized (mUserProfileGroupIdsSelfLocked) { 18460 mUserProfileGroupIdsSelfLocked.clear(); 18461 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18462 for (int i = 0; i < users.size(); i++) { 18463 UserInfo user = users.get(i); 18464 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18465 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18466 } 18467 } 18468 } 18469 } 18470 18471 private Set getProfileIdsLocked(int userId) { 18472 Set userIds = new HashSet<Integer>(); 18473 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18474 userId, false /* enabledOnly */); 18475 for (UserInfo user : profiles) { 18476 userIds.add(Integer.valueOf(user.id)); 18477 } 18478 return userIds; 18479 } 18480 18481 @Override 18482 public boolean switchUser(final int userId) { 18483 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18484 String userName; 18485 synchronized (this) { 18486 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18487 if (userInfo == null) { 18488 Slog.w(TAG, "No user info for user #" + userId); 18489 return false; 18490 } 18491 if (userInfo.isManagedProfile()) { 18492 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18493 return false; 18494 } 18495 userName = userInfo.name; 18496 mTargetUserId = userId; 18497 } 18498 mHandler.removeMessages(START_USER_SWITCH_MSG); 18499 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18500 return true; 18501 } 18502 18503 private void showUserSwitchDialog(int userId, String userName) { 18504 // The dialog will show and then initiate the user switch by calling startUserInForeground 18505 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18506 true /* above system */); 18507 d.show(); 18508 } 18509 18510 private boolean startUser(final int userId, final boolean foreground) { 18511 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18512 != PackageManager.PERMISSION_GRANTED) { 18513 String msg = "Permission Denial: switchUser() from pid=" 18514 + Binder.getCallingPid() 18515 + ", uid=" + Binder.getCallingUid() 18516 + " requires " + INTERACT_ACROSS_USERS_FULL; 18517 Slog.w(TAG, msg); 18518 throw new SecurityException(msg); 18519 } 18520 18521 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18522 18523 final long ident = Binder.clearCallingIdentity(); 18524 try { 18525 synchronized (this) { 18526 final int oldUserId = mCurrentUserId; 18527 if (oldUserId == userId) { 18528 return true; 18529 } 18530 18531 mStackSupervisor.setLockTaskModeLocked(null, false); 18532 18533 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18534 if (userInfo == null) { 18535 Slog.w(TAG, "No user info for user #" + userId); 18536 return false; 18537 } 18538 if (foreground && userInfo.isManagedProfile()) { 18539 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18540 return false; 18541 } 18542 18543 if (foreground) { 18544 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18545 R.anim.screen_user_enter); 18546 } 18547 18548 boolean needStart = false; 18549 18550 // If the user we are switching to is not currently started, then 18551 // we need to start it now. 18552 if (mStartedUsers.get(userId) == null) { 18553 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18554 updateStartedUserArrayLocked(); 18555 needStart = true; 18556 } 18557 18558 final Integer userIdInt = Integer.valueOf(userId); 18559 mUserLru.remove(userIdInt); 18560 mUserLru.add(userIdInt); 18561 18562 if (foreground) { 18563 mCurrentUserId = userId; 18564 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18565 updateCurrentProfileIdsLocked(); 18566 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18567 // Once the internal notion of the active user has switched, we lock the device 18568 // with the option to show the user switcher on the keyguard. 18569 mWindowManager.lockNow(null); 18570 } else { 18571 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18572 updateCurrentProfileIdsLocked(); 18573 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18574 mUserLru.remove(currentUserIdInt); 18575 mUserLru.add(currentUserIdInt); 18576 } 18577 18578 final UserStartedState uss = mStartedUsers.get(userId); 18579 18580 // Make sure user is in the started state. If it is currently 18581 // stopping, we need to knock that off. 18582 if (uss.mState == UserStartedState.STATE_STOPPING) { 18583 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18584 // so we can just fairly silently bring the user back from 18585 // the almost-dead. 18586 uss.mState = UserStartedState.STATE_RUNNING; 18587 updateStartedUserArrayLocked(); 18588 needStart = true; 18589 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18590 // This means ACTION_SHUTDOWN has been sent, so we will 18591 // need to treat this as a new boot of the user. 18592 uss.mState = UserStartedState.STATE_BOOTING; 18593 updateStartedUserArrayLocked(); 18594 needStart = true; 18595 } 18596 18597 if (uss.mState == UserStartedState.STATE_BOOTING) { 18598 // Booting up a new user, need to tell system services about it. 18599 // Note that this is on the same handler as scheduling of broadcasts, 18600 // which is important because it needs to go first. 18601 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18602 } 18603 18604 if (foreground) { 18605 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18606 oldUserId)); 18607 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18608 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18609 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18610 oldUserId, userId, uss)); 18611 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18612 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18613 } 18614 18615 if (needStart) { 18616 // Send USER_STARTED broadcast 18617 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18618 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18619 | Intent.FLAG_RECEIVER_FOREGROUND); 18620 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18621 broadcastIntentLocked(null, null, intent, 18622 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18623 false, false, MY_PID, Process.SYSTEM_UID, userId); 18624 } 18625 18626 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18627 if (userId != UserHandle.USER_OWNER) { 18628 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18629 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18630 broadcastIntentLocked(null, null, intent, null, 18631 new IIntentReceiver.Stub() { 18632 public void performReceive(Intent intent, int resultCode, 18633 String data, Bundle extras, boolean ordered, 18634 boolean sticky, int sendingUser) { 18635 onUserInitialized(uss, foreground, oldUserId, userId); 18636 } 18637 }, 0, null, null, null, AppOpsManager.OP_NONE, 18638 true, false, MY_PID, Process.SYSTEM_UID, 18639 userId); 18640 uss.initializing = true; 18641 } else { 18642 getUserManagerLocked().makeInitialized(userInfo.id); 18643 } 18644 } 18645 18646 if (foreground) { 18647 if (!uss.initializing) { 18648 moveUserToForeground(uss, oldUserId, userId); 18649 } 18650 } else { 18651 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18652 } 18653 18654 if (needStart) { 18655 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18656 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18657 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18658 broadcastIntentLocked(null, null, intent, 18659 null, new IIntentReceiver.Stub() { 18660 @Override 18661 public void performReceive(Intent intent, int resultCode, String data, 18662 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18663 throws RemoteException { 18664 } 18665 }, 0, null, null, 18666 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18667 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18668 } 18669 } 18670 } finally { 18671 Binder.restoreCallingIdentity(ident); 18672 } 18673 18674 return true; 18675 } 18676 18677 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18678 long ident = Binder.clearCallingIdentity(); 18679 try { 18680 Intent intent; 18681 if (oldUserId >= 0) { 18682 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18683 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18684 int count = profiles.size(); 18685 for (int i = 0; i < count; i++) { 18686 int profileUserId = profiles.get(i).id; 18687 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18688 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18689 | Intent.FLAG_RECEIVER_FOREGROUND); 18690 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18691 broadcastIntentLocked(null, null, intent, 18692 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18693 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18694 } 18695 } 18696 if (newUserId >= 0) { 18697 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18698 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18699 int count = profiles.size(); 18700 for (int i = 0; i < count; i++) { 18701 int profileUserId = profiles.get(i).id; 18702 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18703 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18704 | Intent.FLAG_RECEIVER_FOREGROUND); 18705 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18706 broadcastIntentLocked(null, null, intent, 18707 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18708 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18709 } 18710 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18711 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18712 | Intent.FLAG_RECEIVER_FOREGROUND); 18713 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18714 broadcastIntentLocked(null, null, intent, 18715 null, null, 0, null, null, 18716 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18717 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18718 } 18719 } finally { 18720 Binder.restoreCallingIdentity(ident); 18721 } 18722 } 18723 18724 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18725 final int newUserId) { 18726 final int N = mUserSwitchObservers.beginBroadcast(); 18727 if (N > 0) { 18728 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18729 int mCount = 0; 18730 @Override 18731 public void sendResult(Bundle data) throws RemoteException { 18732 synchronized (ActivityManagerService.this) { 18733 if (mCurUserSwitchCallback == this) { 18734 mCount++; 18735 if (mCount == N) { 18736 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18737 } 18738 } 18739 } 18740 } 18741 }; 18742 synchronized (this) { 18743 uss.switching = true; 18744 mCurUserSwitchCallback = callback; 18745 } 18746 for (int i=0; i<N; i++) { 18747 try { 18748 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18749 newUserId, callback); 18750 } catch (RemoteException e) { 18751 } 18752 } 18753 } else { 18754 synchronized (this) { 18755 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18756 } 18757 } 18758 mUserSwitchObservers.finishBroadcast(); 18759 } 18760 18761 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18762 synchronized (this) { 18763 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18764 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18765 } 18766 } 18767 18768 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18769 mCurUserSwitchCallback = null; 18770 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18771 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18772 oldUserId, newUserId, uss)); 18773 } 18774 18775 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18776 synchronized (this) { 18777 if (foreground) { 18778 moveUserToForeground(uss, oldUserId, newUserId); 18779 } 18780 } 18781 18782 completeSwitchAndInitalize(uss, newUserId, true, false); 18783 } 18784 18785 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18786 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18787 if (homeInFront) { 18788 startHomeActivityLocked(newUserId); 18789 } else { 18790 mStackSupervisor.resumeTopActivitiesLocked(); 18791 } 18792 EventLogTags.writeAmSwitchUser(newUserId); 18793 getUserManagerLocked().userForeground(newUserId); 18794 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18795 } 18796 18797 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18798 completeSwitchAndInitalize(uss, newUserId, false, true); 18799 } 18800 18801 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18802 boolean clearInitializing, boolean clearSwitching) { 18803 boolean unfrozen = false; 18804 synchronized (this) { 18805 if (clearInitializing) { 18806 uss.initializing = false; 18807 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18808 } 18809 if (clearSwitching) { 18810 uss.switching = false; 18811 } 18812 if (!uss.switching && !uss.initializing) { 18813 mWindowManager.stopFreezingScreen(); 18814 unfrozen = true; 18815 } 18816 } 18817 if (unfrozen) { 18818 final int N = mUserSwitchObservers.beginBroadcast(); 18819 for (int i=0; i<N; i++) { 18820 try { 18821 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18822 } catch (RemoteException e) { 18823 } 18824 } 18825 mUserSwitchObservers.finishBroadcast(); 18826 } 18827 } 18828 18829 void scheduleStartProfilesLocked() { 18830 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18831 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18832 DateUtils.SECOND_IN_MILLIS); 18833 } 18834 } 18835 18836 void startProfilesLocked() { 18837 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18838 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18839 mCurrentUserId, false /* enabledOnly */); 18840 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18841 for (UserInfo user : profiles) { 18842 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18843 && user.id != mCurrentUserId) { 18844 toStart.add(user); 18845 } 18846 } 18847 final int n = toStart.size(); 18848 int i = 0; 18849 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18850 startUserInBackground(toStart.get(i).id); 18851 } 18852 if (i < n) { 18853 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18854 } 18855 } 18856 18857 void finishUserBoot(UserStartedState uss) { 18858 synchronized (this) { 18859 if (uss.mState == UserStartedState.STATE_BOOTING 18860 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18861 uss.mState = UserStartedState.STATE_RUNNING; 18862 final int userId = uss.mHandle.getIdentifier(); 18863 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18864 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18865 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18866 broadcastIntentLocked(null, null, intent, 18867 null, null, 0, null, null, 18868 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18869 true, false, MY_PID, Process.SYSTEM_UID, userId); 18870 } 18871 } 18872 } 18873 18874 void finishUserSwitch(UserStartedState uss) { 18875 synchronized (this) { 18876 finishUserBoot(uss); 18877 18878 startProfilesLocked(); 18879 18880 int num = mUserLru.size(); 18881 int i = 0; 18882 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18883 Integer oldUserId = mUserLru.get(i); 18884 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18885 if (oldUss == null) { 18886 // Shouldn't happen, but be sane if it does. 18887 mUserLru.remove(i); 18888 num--; 18889 continue; 18890 } 18891 if (oldUss.mState == UserStartedState.STATE_STOPPING 18892 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18893 // This user is already stopping, doesn't count. 18894 num--; 18895 i++; 18896 continue; 18897 } 18898 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18899 // Owner and current can't be stopped, but count as running. 18900 i++; 18901 continue; 18902 } 18903 // This is a user to be stopped. 18904 stopUserLocked(oldUserId, null); 18905 num--; 18906 i++; 18907 } 18908 } 18909 } 18910 18911 @Override 18912 public int stopUser(final int userId, final IStopUserCallback callback) { 18913 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18914 != PackageManager.PERMISSION_GRANTED) { 18915 String msg = "Permission Denial: switchUser() from pid=" 18916 + Binder.getCallingPid() 18917 + ", uid=" + Binder.getCallingUid() 18918 + " requires " + INTERACT_ACROSS_USERS_FULL; 18919 Slog.w(TAG, msg); 18920 throw new SecurityException(msg); 18921 } 18922 if (userId <= 0) { 18923 throw new IllegalArgumentException("Can't stop primary user " + userId); 18924 } 18925 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18926 synchronized (this) { 18927 return stopUserLocked(userId, callback); 18928 } 18929 } 18930 18931 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18932 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18933 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18934 return ActivityManager.USER_OP_IS_CURRENT; 18935 } 18936 18937 final UserStartedState uss = mStartedUsers.get(userId); 18938 if (uss == null) { 18939 // User is not started, nothing to do... but we do need to 18940 // callback if requested. 18941 if (callback != null) { 18942 mHandler.post(new Runnable() { 18943 @Override 18944 public void run() { 18945 try { 18946 callback.userStopped(userId); 18947 } catch (RemoteException e) { 18948 } 18949 } 18950 }); 18951 } 18952 return ActivityManager.USER_OP_SUCCESS; 18953 } 18954 18955 if (callback != null) { 18956 uss.mStopCallbacks.add(callback); 18957 } 18958 18959 if (uss.mState != UserStartedState.STATE_STOPPING 18960 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18961 uss.mState = UserStartedState.STATE_STOPPING; 18962 updateStartedUserArrayLocked(); 18963 18964 long ident = Binder.clearCallingIdentity(); 18965 try { 18966 // We are going to broadcast ACTION_USER_STOPPING and then 18967 // once that is done send a final ACTION_SHUTDOWN and then 18968 // stop the user. 18969 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18970 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18971 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18972 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18973 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18974 // This is the result receiver for the final shutdown broadcast. 18975 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18976 @Override 18977 public void performReceive(Intent intent, int resultCode, String data, 18978 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18979 finishUserStop(uss); 18980 } 18981 }; 18982 // This is the result receiver for the initial stopping broadcast. 18983 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18984 @Override 18985 public void performReceive(Intent intent, int resultCode, String data, 18986 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18987 // On to the next. 18988 synchronized (ActivityManagerService.this) { 18989 if (uss.mState != UserStartedState.STATE_STOPPING) { 18990 // Whoops, we are being started back up. Abort, abort! 18991 return; 18992 } 18993 uss.mState = UserStartedState.STATE_SHUTDOWN; 18994 } 18995 mBatteryStatsService.noteEvent( 18996 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18997 Integer.toString(userId), userId); 18998 mSystemServiceManager.stopUser(userId); 18999 broadcastIntentLocked(null, null, shutdownIntent, 19000 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19001 true, false, MY_PID, Process.SYSTEM_UID, userId); 19002 } 19003 }; 19004 // Kick things off. 19005 broadcastIntentLocked(null, null, stoppingIntent, 19006 null, stoppingReceiver, 0, null, null, 19007 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19008 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19009 } finally { 19010 Binder.restoreCallingIdentity(ident); 19011 } 19012 } 19013 19014 return ActivityManager.USER_OP_SUCCESS; 19015 } 19016 19017 void finishUserStop(UserStartedState uss) { 19018 final int userId = uss.mHandle.getIdentifier(); 19019 boolean stopped; 19020 ArrayList<IStopUserCallback> callbacks; 19021 synchronized (this) { 19022 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19023 if (mStartedUsers.get(userId) != uss) { 19024 stopped = false; 19025 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19026 stopped = false; 19027 } else { 19028 stopped = true; 19029 // User can no longer run. 19030 mStartedUsers.remove(userId); 19031 mUserLru.remove(Integer.valueOf(userId)); 19032 updateStartedUserArrayLocked(); 19033 19034 // Clean up all state and processes associated with the user. 19035 // Kill all the processes for the user. 19036 forceStopUserLocked(userId, "finish user"); 19037 } 19038 19039 // Explicitly remove the old information in mRecentTasks. 19040 removeRecentTasksForUserLocked(userId); 19041 } 19042 19043 for (int i=0; i<callbacks.size(); i++) { 19044 try { 19045 if (stopped) callbacks.get(i).userStopped(userId); 19046 else callbacks.get(i).userStopAborted(userId); 19047 } catch (RemoteException e) { 19048 } 19049 } 19050 19051 if (stopped) { 19052 mSystemServiceManager.cleanupUser(userId); 19053 synchronized (this) { 19054 mStackSupervisor.removeUserLocked(userId); 19055 } 19056 } 19057 } 19058 19059 @Override 19060 public UserInfo getCurrentUser() { 19061 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19062 != PackageManager.PERMISSION_GRANTED) && ( 19063 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19064 != PackageManager.PERMISSION_GRANTED)) { 19065 String msg = "Permission Denial: getCurrentUser() from pid=" 19066 + Binder.getCallingPid() 19067 + ", uid=" + Binder.getCallingUid() 19068 + " requires " + INTERACT_ACROSS_USERS; 19069 Slog.w(TAG, msg); 19070 throw new SecurityException(msg); 19071 } 19072 synchronized (this) { 19073 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19074 return getUserManagerLocked().getUserInfo(userId); 19075 } 19076 } 19077 19078 int getCurrentUserIdLocked() { 19079 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19080 } 19081 19082 @Override 19083 public boolean isUserRunning(int userId, boolean orStopped) { 19084 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19085 != PackageManager.PERMISSION_GRANTED) { 19086 String msg = "Permission Denial: isUserRunning() from pid=" 19087 + Binder.getCallingPid() 19088 + ", uid=" + Binder.getCallingUid() 19089 + " requires " + INTERACT_ACROSS_USERS; 19090 Slog.w(TAG, msg); 19091 throw new SecurityException(msg); 19092 } 19093 synchronized (this) { 19094 return isUserRunningLocked(userId, orStopped); 19095 } 19096 } 19097 19098 boolean isUserRunningLocked(int userId, boolean orStopped) { 19099 UserStartedState state = mStartedUsers.get(userId); 19100 if (state == null) { 19101 return false; 19102 } 19103 if (orStopped) { 19104 return true; 19105 } 19106 return state.mState != UserStartedState.STATE_STOPPING 19107 && state.mState != UserStartedState.STATE_SHUTDOWN; 19108 } 19109 19110 @Override 19111 public int[] getRunningUserIds() { 19112 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19113 != PackageManager.PERMISSION_GRANTED) { 19114 String msg = "Permission Denial: isUserRunning() from pid=" 19115 + Binder.getCallingPid() 19116 + ", uid=" + Binder.getCallingUid() 19117 + " requires " + INTERACT_ACROSS_USERS; 19118 Slog.w(TAG, msg); 19119 throw new SecurityException(msg); 19120 } 19121 synchronized (this) { 19122 return mStartedUserArray; 19123 } 19124 } 19125 19126 private void updateStartedUserArrayLocked() { 19127 int num = 0; 19128 for (int i=0; i<mStartedUsers.size(); i++) { 19129 UserStartedState uss = mStartedUsers.valueAt(i); 19130 // This list does not include stopping users. 19131 if (uss.mState != UserStartedState.STATE_STOPPING 19132 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19133 num++; 19134 } 19135 } 19136 mStartedUserArray = new int[num]; 19137 num = 0; 19138 for (int i=0; i<mStartedUsers.size(); i++) { 19139 UserStartedState uss = mStartedUsers.valueAt(i); 19140 if (uss.mState != UserStartedState.STATE_STOPPING 19141 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19142 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19143 num++; 19144 } 19145 } 19146 } 19147 19148 @Override 19149 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19150 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19151 != PackageManager.PERMISSION_GRANTED) { 19152 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19153 + Binder.getCallingPid() 19154 + ", uid=" + Binder.getCallingUid() 19155 + " requires " + INTERACT_ACROSS_USERS_FULL; 19156 Slog.w(TAG, msg); 19157 throw new SecurityException(msg); 19158 } 19159 19160 mUserSwitchObservers.register(observer); 19161 } 19162 19163 @Override 19164 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19165 mUserSwitchObservers.unregister(observer); 19166 } 19167 19168 private boolean userExists(int userId) { 19169 if (userId == 0) { 19170 return true; 19171 } 19172 UserManagerService ums = getUserManagerLocked(); 19173 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19174 } 19175 19176 int[] getUsersLocked() { 19177 UserManagerService ums = getUserManagerLocked(); 19178 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19179 } 19180 19181 UserManagerService getUserManagerLocked() { 19182 if (mUserManager == null) { 19183 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19184 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19185 } 19186 return mUserManager; 19187 } 19188 19189 private int applyUserId(int uid, int userId) { 19190 return UserHandle.getUid(userId, uid); 19191 } 19192 19193 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19194 if (info == null) return null; 19195 ApplicationInfo newInfo = new ApplicationInfo(info); 19196 newInfo.uid = applyUserId(info.uid, userId); 19197 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19198 + info.packageName; 19199 return newInfo; 19200 } 19201 19202 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19203 if (aInfo == null 19204 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19205 return aInfo; 19206 } 19207 19208 ActivityInfo info = new ActivityInfo(aInfo); 19209 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19210 return info; 19211 } 19212 19213 private final class LocalService extends ActivityManagerInternal { 19214 @Override 19215 public void onWakefulnessChanged(int wakefulness) { 19216 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19217 } 19218 19219 @Override 19220 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19221 String processName, String abiOverride, int uid, Runnable crashHandler) { 19222 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19223 processName, abiOverride, uid, crashHandler); 19224 } 19225 } 19226 19227 /** 19228 * An implementation of IAppTask, that allows an app to manage its own tasks via 19229 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19230 * only the process that calls getAppTasks() can call the AppTask methods. 19231 */ 19232 class AppTaskImpl extends IAppTask.Stub { 19233 private int mTaskId; 19234 private int mCallingUid; 19235 19236 public AppTaskImpl(int taskId, int callingUid) { 19237 mTaskId = taskId; 19238 mCallingUid = callingUid; 19239 } 19240 19241 private void checkCaller() { 19242 if (mCallingUid != Binder.getCallingUid()) { 19243 throw new SecurityException("Caller " + mCallingUid 19244 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19245 } 19246 } 19247 19248 @Override 19249 public void finishAndRemoveTask() { 19250 checkCaller(); 19251 19252 synchronized (ActivityManagerService.this) { 19253 long origId = Binder.clearCallingIdentity(); 19254 try { 19255 if (!removeTaskByIdLocked(mTaskId, false)) { 19256 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19257 } 19258 } finally { 19259 Binder.restoreCallingIdentity(origId); 19260 } 19261 } 19262 } 19263 19264 @Override 19265 public ActivityManager.RecentTaskInfo getTaskInfo() { 19266 checkCaller(); 19267 19268 synchronized (ActivityManagerService.this) { 19269 long origId = Binder.clearCallingIdentity(); 19270 try { 19271 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19272 if (tr == null) { 19273 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19274 } 19275 return createRecentTaskInfoFromTaskRecord(tr); 19276 } finally { 19277 Binder.restoreCallingIdentity(origId); 19278 } 19279 } 19280 } 19281 19282 @Override 19283 public void moveToFront() { 19284 checkCaller(); 19285 19286 final TaskRecord tr; 19287 synchronized (ActivityManagerService.this) { 19288 tr = recentTaskForIdLocked(mTaskId); 19289 if (tr == null) { 19290 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19291 } 19292 if (tr.getRootActivity() != null) { 19293 moveTaskToFrontLocked(tr.taskId, 0, null); 19294 return; 19295 } 19296 } 19297 19298 startActivityFromRecentsInner(tr.taskId, null); 19299 } 19300 19301 @Override 19302 public int startActivity(IBinder whoThread, String callingPackage, 19303 Intent intent, String resolvedType, Bundle options) { 19304 checkCaller(); 19305 19306 int callingUser = UserHandle.getCallingUserId(); 19307 TaskRecord tr; 19308 IApplicationThread appThread; 19309 synchronized (ActivityManagerService.this) { 19310 tr = recentTaskForIdLocked(mTaskId); 19311 if (tr == null) { 19312 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19313 } 19314 appThread = ApplicationThreadNative.asInterface(whoThread); 19315 if (appThread == null) { 19316 throw new IllegalArgumentException("Bad app thread " + appThread); 19317 } 19318 } 19319 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19320 resolvedType, null, null, null, null, 0, 0, null, null, 19321 null, options, callingUser, null, tr); 19322 } 19323 19324 @Override 19325 public void setExcludeFromRecents(boolean exclude) { 19326 checkCaller(); 19327 19328 synchronized (ActivityManagerService.this) { 19329 long origId = Binder.clearCallingIdentity(); 19330 try { 19331 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19332 if (tr == null) { 19333 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19334 } 19335 Intent intent = tr.getBaseIntent(); 19336 if (exclude) { 19337 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19338 } else { 19339 intent.setFlags(intent.getFlags() 19340 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19341 } 19342 } finally { 19343 Binder.restoreCallingIdentity(origId); 19344 } 19345 } 19346 } 19347 } 19348} 19349